feat: adapt to Levilamina 26.10.5
Code references logic from ActorDamageCause.cc(GMLIB 0.13.5)
This commit is contained in:
@@ -16,3 +16,4 @@ build/
|
||||
/CMakeLists.txt
|
||||
/bin
|
||||
/.cache
|
||||
/.idea
|
||||
|
||||
+493
-63
@@ -1,123 +1,553 @@
|
||||
#include "Entry.h"
|
||||
#include "GMLIB/Mod/Addons/CustomDamageCause.h"
|
||||
#include "Global.h"
|
||||
#include "ll/api/event/player/PlayerConnectEvent.h"
|
||||
#include "ll/api/event/player/PlayerDisconnectEvent.h"
|
||||
#include "ll/api/memory/Hook.h"
|
||||
#include "ll/api/chrono/GameChrono.h"
|
||||
#include "ll/api/thread/ThreadPoolExecutor.h"
|
||||
#include <chrono>
|
||||
#include "mc/world/actor/Mob.h"
|
||||
#include "mc/world/actor/ActorDamageSource.h"
|
||||
#include "mc/world/actor/ActorDamageByActorSource.h"
|
||||
#include "mc/world/actor/ActorDamageByBlockSource.h"
|
||||
#include "mc/world/actor/ActorDamageByChildActorSource.h"
|
||||
#include "ll/api/service/Bedrock.h"
|
||||
#include "mc/world/level/Level.h"
|
||||
|
||||
|
||||
#include "mc/world/actor/Actor.h"
|
||||
phmap::flat_hash_map<int64, float> mFallHeightMap;
|
||||
phmap::flat_hash_map<int64, ActorUniqueID> mHurtByEntityMap;
|
||||
|
||||
LL_AUTO_TYPE_INSTANCE_HOOK(
|
||||
MobDieHook,
|
||||
HookPriority::Normal,
|
||||
Mob,
|
||||
&Mob::$die,
|
||||
void,
|
||||
ActorDamageSource const& ads
|
||||
) {
|
||||
auto uid = getOrCreateUniqueID();
|
||||
|
||||
if (ads.mCause == SharedTypes::Legacy::ActorDamageCause::Fall) {
|
||||
mFallHeightMap[uid.rawID] = getFallDistance();
|
||||
logger->info("跌落高度为 {}", getFallDistance());
|
||||
}
|
||||
if (hasCategory(ActorCategory::Player) || isTame()) {
|
||||
if (mLastHurtByMobTime != 0) {
|
||||
auto hm = getLastHurtByMob();
|
||||
mHurtByEntityMap[uid.rawID] = hm->getOrCreateUniqueID();
|
||||
if (!getLastHurtByMob()->getNameTag().empty()) logger->info("伤害来源为 {}", getLastHurtByMob()->getNameTag());
|
||||
logger->info("伤害来源为 {}", getLastHurtByMob()->getTypeName());
|
||||
|
||||
|
||||
if (!getLastHurtByMob()->getCarriedItem().getCustomName().empty()) logger->info("伤害来源为 {}", getLastHurtByMob()->getCarriedItem().getCustomName());
|
||||
}
|
||||
}
|
||||
origin(ads);
|
||||
|
||||
auto& executor = ll::thread::ThreadPoolExecutor::getDefault();
|
||||
auto callback = executor.executeAfter(
|
||||
[] {
|
||||
mHurtByEntityMap.clear();
|
||||
mFallHeightMap.clear();
|
||||
},
|
||||
ll::chrono::game::ticks(1)
|
||||
);
|
||||
}
|
||||
using DeathMessageResult = std::pair<std::string, std::vector<std::string>>;
|
||||
|
||||
int mMaxCauseId = 34;
|
||||
std::vector<std::pair<std::string, int>> mCustomCauseMap;
|
||||
phmap::flat_hash_map<int, std::string_view> mVanillaCauseMessage;
|
||||
|
||||
phmap::flat_hash_map<SharedTypes::Legacy::ActorDamageCause, phmap::flat_hash_map<std::string_view, std::string_view>> mHardCodedDeathMessage;
|
||||
|
||||
bool isCrystal = false;
|
||||
|
||||
bool isCustomDefinition(int cause) {
|
||||
if (cause >= 35) {
|
||||
return true;
|
||||
}
|
||||
if (mVanillaCauseMessage.count(cause)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCustomCauseExist(std::string const& causeName) {
|
||||
for (auto& key : mCustomCauseMap) {
|
||||
if (key.first == causeName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCustomCauseExist(int cause) {
|
||||
for (auto& key : mCustomCauseMap) {
|
||||
if (key.second == cause) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SharedTypes::Legacy::ActorDamageCause getCustomCause(std::string const& causeName) {
|
||||
for (auto& key : mCustomCauseMap) {
|
||||
if (key.first == causeName) {
|
||||
return (SharedTypes::Legacy::ActorDamageCause)key.second;
|
||||
}
|
||||
}
|
||||
return SharedTypes::Legacy::ActorDamageCause::None;
|
||||
}
|
||||
|
||||
std::string getCustomCause(SharedTypes::Legacy::ActorDamageCause cause) {
|
||||
for (auto& key : mCustomCauseMap) {
|
||||
if ((SharedTypes::Legacy::ActorDamageCause)key.second == cause) {
|
||||
return key.first;
|
||||
}
|
||||
}
|
||||
return "none";
|
||||
}
|
||||
|
||||
std::string getCause(SharedTypes::Legacy::ActorDamageCause cause) {
|
||||
auto id = (int)cause;
|
||||
if (isCustomCauseExist(id)) {
|
||||
return getCustomCause(cause);
|
||||
}
|
||||
if (mVanillaCauseMessage.count(id)) {
|
||||
return std::string(mVanillaCauseMessage[id]);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
Actor* getDamagingEntity(ActorDamageSource* ads) {
|
||||
auto id = ads->getDamagingEntityUniqueID();
|
||||
return ll::service::getLevel()->fetchEntity(id,true);
|
||||
}
|
||||
|
||||
// %entity.warden.name
|
||||
std::string getResourcePackKey(std::string const& name, Actor* ac) {
|
||||
if (ac->hasCategory(ActorCategory::Player)) {
|
||||
return name;
|
||||
}
|
||||
auto type = ac->getTypeName();
|
||||
ll::utils::string_utils::replaceAll(type, "minecraft:", "");
|
||||
std::string res = "%entity." + type + ".name";
|
||||
return res;
|
||||
}
|
||||
|
||||
// 构造死亡信息输出
|
||||
DeathMessageResult makeDeathMessage(
|
||||
int cause,
|
||||
DeathMessageResult& deathMessage,
|
||||
std::string& name,
|
||||
Actor* killer,
|
||||
std::string& weaponName,
|
||||
bool isEscaping,
|
||||
bool isHardCodedMessage = false
|
||||
) {
|
||||
// 自定义类型构造
|
||||
if (isCustomDefinition(cause) || isHardCodedMessage) {
|
||||
std::string msg = "death.attack.damageCause.item";
|
||||
ll::utils::string_utils::replaceAll(msg, "damageCause", getCause(SharedTypes::Legacy::ActorDamageCause(cause)));
|
||||
if (isHardCodedMessage) {
|
||||
msg = deathMessage.first;
|
||||
}
|
||||
// 没有武器名不使用.item结尾
|
||||
if (weaponName.empty()) {
|
||||
// 试图逃离 xx 使用.player
|
||||
if (killer) {
|
||||
if (isEscaping) {
|
||||
ll::utils::string_utils::replaceAll(msg, ".item", ".player");
|
||||
}
|
||||
} else {
|
||||
ll::utils::string_utils::replaceAll(msg, ".item", "");
|
||||
}
|
||||
}
|
||||
DeathMessageResult res = {msg, {name}};
|
||||
if (killer) {
|
||||
if (killer->isPlayer()) {
|
||||
res.second.push_back(((Player*)killer)->getRealName());
|
||||
} else {
|
||||
res.second.push_back(getResourcePackKey(name, killer));
|
||||
}
|
||||
auto weaponname = killer->getCarriedItem().getCustomName();
|
||||
if (!weaponname.empty()) {
|
||||
weaponname = "[" + weaponname + "§r]";
|
||||
res.second.push_back(weaponname);
|
||||
} else {
|
||||
ll::utils::string_utils::replaceAll(res.first, ".item", "");
|
||||
}
|
||||
} else {
|
||||
// 如果没有击杀者和试图逃离,那么不可能使用 .player 结尾
|
||||
ll::utils::string_utils::replaceAll(res.first, ".player", "");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
// 未定义返回vanilla值
|
||||
return deathMessage;
|
||||
}
|
||||
|
||||
DeathMessageResult tryTranslateHardCodedFallingDeathMessage(
|
||||
DeathMessageResult& deathMessage,
|
||||
std::string& name,
|
||||
Actor* killer,
|
||||
std::string& directKiller,
|
||||
std::string& weaponName,
|
||||
bool isEscaping,
|
||||
int64 deadUniqueId
|
||||
) {
|
||||
if (!directKiller.empty()) {
|
||||
deathMessage.first = "death.fell.finish.item";
|
||||
}
|
||||
// 低处
|
||||
else if (deathMessage.first == "death.attack.fall") {
|
||||
deathMessage.first = "death.attack.fall.item";
|
||||
}
|
||||
// 高处
|
||||
else if (deathMessage.first == "death.fell.accident.generic") {
|
||||
// 试图逃离而亡
|
||||
if (killer) {
|
||||
std::string weapon = killer->getCarriedItem().getCustomName();
|
||||
if (!weapon.empty()) {
|
||||
deathMessage.first = "death.fell.assist.item";
|
||||
} else {
|
||||
deathMessage.first = "death.fell.assist";
|
||||
}
|
||||
}
|
||||
// 超高
|
||||
else if (mFallHeightMap[deadUniqueId] >= 100) {
|
||||
deathMessage.first = "death.fell.killer";
|
||||
} else {
|
||||
deathMessage.first = "death.fell.accident.generic";
|
||||
}
|
||||
} else {
|
||||
deathMessage.first = "death.attack.generic";
|
||||
}
|
||||
return makeDeathMessage((int)SharedTypes::Legacy::ActorDamageCause::Fall, deathMessage, name, killer, weaponName, isEscaping, true);
|
||||
}
|
||||
|
||||
std::optional<DeathMessageResult> tryTranslateHardCodedDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause cause,
|
||||
DeathMessageResult& deathMessage,
|
||||
std::string& name,
|
||||
Actor* killer,
|
||||
std::string& directKiller,
|
||||
std::string& weaponName,
|
||||
bool isEscaping,
|
||||
int64 deadUniqueId
|
||||
) {
|
||||
switch (cause) {
|
||||
// 硬编码摔死信息
|
||||
case SharedTypes::Legacy::ActorDamageCause::Fall: {
|
||||
return tryTranslateHardCodedFallingDeathMessage(
|
||||
deathMessage,
|
||||
name,
|
||||
killer,
|
||||
directKiller,
|
||||
weaponName,
|
||||
isEscaping,
|
||||
deadUniqueId
|
||||
);
|
||||
}
|
||||
// 硬编码爆炸信息
|
||||
case SharedTypes::Legacy::ActorDamageCause::BlockExplosion: {
|
||||
if (!isCrystal) {
|
||||
deathMessage.first = "death.attack.badRespawnPoint.message";
|
||||
} else {
|
||||
deathMessage.first = "death.attack.explosion.item";
|
||||
}
|
||||
return makeDeathMessage((int)cause, deathMessage, name, killer, weaponName, isEscaping, true);
|
||||
}
|
||||
case SharedTypes::Legacy::ActorDamageCause::Contact: {
|
||||
switch (ll::hash_utils::doHash(deathMessage.first)) {
|
||||
case ll::hash_utils::doHash("death.attack.cactus"):
|
||||
deathMessage.first = "death.attack.cactus.item";
|
||||
break;
|
||||
case ll::hash_utils::doHash("death.attack.sweetBerry"):
|
||||
deathMessage.first = "death.attack.sweetBerry.item";
|
||||
break;
|
||||
default:
|
||||
deathMessage.first = "death.attack.generic.item";
|
||||
break;
|
||||
}
|
||||
return makeDeathMessage((int)cause, deathMessage, name, killer, weaponName, isEscaping, true);
|
||||
}
|
||||
}
|
||||
if (mHardCodedDeathMessage.contains(cause)) {
|
||||
if (directKiller.empty()) {
|
||||
directKiller = "empty";
|
||||
}
|
||||
if (mHardCodedDeathMessage[cause].contains(directKiller)) {
|
||||
deathMessage.first = std::string(mHardCodedDeathMessage[cause][directKiller]);
|
||||
return makeDeathMessage((int)cause, deathMessage, name, killer, weaponName, isEscaping, true);
|
||||
} else if (mHardCodedDeathMessage[cause].contains("all")) {
|
||||
deathMessage.first = std::string(mHardCodedDeathMessage[cause]["all"]);
|
||||
return makeDeathMessage((int)cause, deathMessage, name, killer, weaponName, isEscaping, true);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
DeathMessageResult translateDeathMessage(DeathMessageResult origin, std::string name, Actor* dead, ActorDamageSource* ads) {
|
||||
name = getResourcePackKey(name, dead);
|
||||
if (origin.first.length() > 65565) {
|
||||
return {"death.attack.even_more_magic", {name}};
|
||||
}
|
||||
auto damageCause = ads->mCause; // 伤害类型
|
||||
Actor* killer = nullptr; // 击杀者
|
||||
std::string directKiller; // 直接击杀实体
|
||||
std::string weaponName; // 是否持有武器
|
||||
bool isEscaping = false;
|
||||
int64 uid = dead->getOrCreateUniqueID().rawID;
|
||||
if (ads->isEntitySource()) {
|
||||
directKiller = getDamagingEntity(ads)->getTypeName();
|
||||
if (ads->isChildEntitySource()) {
|
||||
killer = getDamagingEntity(ads)->getOwner();
|
||||
} else {
|
||||
killer = getDamagingEntity(ads);
|
||||
}
|
||||
}
|
||||
if (killer == nullptr && mHurtByEntityMap.count(uid)) {
|
||||
killer = ll::service::getLevel()->fetchEntity(mHurtByEntityMap[uid],true);
|
||||
isEscaping = true;
|
||||
}
|
||||
if (killer != nullptr) {
|
||||
weaponName = killer->getCarriedItem().getCustomName();
|
||||
}
|
||||
// Vanilla的硬编码死亡信息类型
|
||||
auto result =
|
||||
tryTranslateHardCodedDeathMessage(damageCause, origin, name, killer, directKiller, weaponName, isEscaping, uid);
|
||||
if (result.has_value()) {
|
||||
return result.value();
|
||||
}
|
||||
return makeDeathMessage((int)damageCause, origin, name, killer, weaponName, isEscaping);
|
||||
}
|
||||
|
||||
LL_AUTO_TYPE_INSTANCE_HOOK(
|
||||
DeathMessageHook1,
|
||||
HookPriority::Lowest,
|
||||
ActorDamageSource,
|
||||
&ActorDamageSource::$getDeathMessage,
|
||||
|
||||
|
||||
DeathMessageResult,
|
||||
|
||||
std::string a1,
|
||||
Actor* a2
|
||||
) {
|
||||
|
||||
|
||||
|
||||
auto originl = origin(a1, a2);
|
||||
logger->info("原消息name为 {}", a1);
|
||||
logger->info("原消息为 {}", originl.first);
|
||||
auto res = translateDeathMessage(originl, a1, a2, this);
|
||||
return res;
|
||||
}
|
||||
|
||||
LL_AUTO_TYPE_INSTANCE_HOOK(
|
||||
DeathMessageHook2,
|
||||
HookPriority::Lowest,
|
||||
ActorDamageByActorSource,
|
||||
&ActorDamageByActorSource::$getDeathMessage,
|
||||
DeathMessageResult,
|
||||
std::string a1,
|
||||
Actor* a2
|
||||
) {
|
||||
auto originl = origin(a1, a2);
|
||||
logger->info("原消息name为 {}", a1);
|
||||
logger->info("原消息为 {}", originl.first);
|
||||
auto res = translateDeathMessage(originl, a1, a2, this);
|
||||
return res;
|
||||
}
|
||||
|
||||
LL_AUTO_TYPE_INSTANCE_HOOK(
|
||||
DeathMessageHook3,
|
||||
HookPriority::Lowest,
|
||||
ActorDamageByBlockSource,
|
||||
&ActorDamageByBlockSource::$getDeathMessage,
|
||||
|
||||
DeathMessageResult,
|
||||
std::string a1,
|
||||
Actor* a2
|
||||
) {
|
||||
auto originl = origin(a1, a2);
|
||||
logger->info("原消息name为 {}", a1);
|
||||
logger->info("原消息为 {}", originl.first);
|
||||
auto res = translateDeathMessage(originl, a1, a2, this);
|
||||
return res;
|
||||
}
|
||||
|
||||
LL_AUTO_TYPE_INSTANCE_HOOK(
|
||||
DeathMessageHook4,
|
||||
HookPriority::Lowest,
|
||||
ActorDamageByChildActorSource,
|
||||
&ActorDamageByChildActorSource::$getDeathMessage,
|
||||
|
||||
|
||||
DeathMessageResult,
|
||||
std::string a1,
|
||||
Actor* a2
|
||||
) {
|
||||
auto originl = origin(a1, a2);
|
||||
logger->info("原消息name为 {}", a1);
|
||||
logger->info("原消息为 {}", originl.first);
|
||||
auto res = translateDeathMessage(originl, a1, a2, this);
|
||||
return res;
|
||||
}
|
||||
int getNextCauseId() {
|
||||
mMaxCauseId++;
|
||||
return mMaxCauseId;
|
||||
}
|
||||
|
||||
bool registerDamageCause(std::string const& causeName) {
|
||||
if (!isCustomCauseExist(causeName)) {
|
||||
auto id = getNextCauseId();
|
||||
mCustomCauseMap.push_back({causeName, id});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause cause, std::string_view msg) {
|
||||
auto id = (int)cause;
|
||||
if (!mVanillaCauseMessage.count(id)) {
|
||||
mVanillaCauseMessage[id] = msg;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause cause,
|
||||
std::string_view message,
|
||||
std::string_view killerType
|
||||
) {
|
||||
if (mHardCodedDeathMessage.contains(cause)) {
|
||||
if (mHardCodedDeathMessage[cause].contains(killerType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mHardCodedDeathMessage[cause][killerType] = message;
|
||||
return true;
|
||||
}
|
||||
void RegisterDamageDefinition() {
|
||||
GMLIB::Mod::DamageCause::DamageCause::setCustomDamageCauseEnabled();
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Anvil, "anvil");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::EntityAttack, "mob");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::RamAttack, "mob");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Drowning, "drown");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::FallingBlock, "fallingBlock");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Fire, "inFire");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::FireTick, "onFire");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Fireworks, "fireworks");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::FlyIntoWall, "flyIntoWall");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Freezing, "freeze");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Lava, "lava");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Lightning, "lightningBolt");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Wither, "wither");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Magic, "indirectMagic");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Magma, "hotFloor");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Stalactite, "stalactite");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Stalagmite, "stalagmite");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Starve, "starve");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Suffocation, "inWall");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::SonicBoom, "sonicBoom");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Void, "outOfWorld");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::SelfDestruct, "genericKill");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Projectile, "thrown");
|
||||
GMLIB::Mod::DamageCause::DamageCause::setVanillaCauseMessage(ActorDamageCause::Thorns, "thorns");
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::Projectile,
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Anvil, "anvil");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::EntityAttack, "mob");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::RamAttack, "mob");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Drowning, "drown");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::FallingBlock, "fallingBlock");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Fire, "inFire");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::FireTick, "onFire");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Fireworks, "fireworks");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::FlyIntoWall, "flyIntoWall");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Freezing, "freeze");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Lava, "lava");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Lightning, "lightningBolt");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Wither, "wither");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Magic, "indirectMagic");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Magma, "hotFloor");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Stalactite, "stalactite");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Stalagmite, "stalagmite");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Starve, "starve");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Suffocation, "inWall");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::SonicBoom, "sonicBoom");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Void, "outOfWorld");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::SelfDestruct, "genericKill");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Projectile, "thrown");
|
||||
setVanillaCauseMessage(SharedTypes::Legacy::ActorDamageCause::Thorns, "thorns");
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::Projectile,
|
||||
"death.attack.fireball.item",
|
||||
"minecraft:small_fireball"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::Projectile,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::Projectile,
|
||||
"death.attack.trident.item",
|
||||
"minecraft:thrown_trident"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::Projectile,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::Projectile,
|
||||
"death.attack.spit",
|
||||
"minecraft:llama_spit"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::Projectile,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::Projectile,
|
||||
"death.attack.bullet",
|
||||
"minecraft:shulker_bullet"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::Projectile,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::Projectile,
|
||||
"death.attack.arrow.item",
|
||||
"minecraft:arrow"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::Projectile,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::Projectile,
|
||||
"death.attack.explosion.player",
|
||||
"minecraft:fireball"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::Projectile,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::Projectile,
|
||||
"death.attack.mob",
|
||||
"minecraft:breeze_wind_charge_projectile"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::Magic,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::Magic,
|
||||
"death.attack.magic",
|
||||
"empty"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::SonicBoom,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::SonicBoom,
|
||||
"death.attack.sonicBoom",
|
||||
"minecraft:warden"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::Thorns,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::Thorns,
|
||||
"death.attack.generic",
|
||||
"empty"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::EntityExplosion,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::EntityExplosion,
|
||||
"death.attack.explosion.player",
|
||||
"all"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::EntityExplosion,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::EntityExplosion,
|
||||
"minecraft:wither_skull",
|
||||
"death.attack.witherSkull.item"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::EntityExplosion,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::EntityExplosion,
|
||||
"minecraft:wither_skull_dangerous",
|
||||
"death.attack.witherSkull.item"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::EntityAttack,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::EntityAttack,
|
||||
"minecraft:player",
|
||||
"death.attack.player.item"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::EntityAttack,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::EntityAttack,
|
||||
"minecraft:bee",
|
||||
"death.attack.sting.item"
|
||||
);
|
||||
GMLIB::Mod::DamageCause::DamageCause::registerCustomDeathMessage(
|
||||
ActorDamageCause::RamAttack,
|
||||
registerCustomDeathMessage(
|
||||
SharedTypes::Legacy::ActorDamageCause::RamAttack,
|
||||
"minecraft:player",
|
||||
"death.attack.player.item"
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
void ListenEvents() {
|
||||
auto& config = DeathMessages::Entry::getInstance().getConfig();
|
||||
auto& eventBus = ll::event::EventBus::getInstance();
|
||||
if (config.ConsoleLog.JoinMessage) {
|
||||
eventBus.emplaceListener<ll::event::player::PlayerConnectEvent>([](ll::event::player::PlayerConnectEvent& ev) {
|
||||
infoLogger->info(fmt::format(fg(fmt::color::yellow), tr("multiplayer.player.joined", {ev.self().getName()}))
|
||||
infoLogger->info(fmt::format(fg(fmt::color::yellow), tr("multiplayer.player.joined", {ev.self().getRealName()}))
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -125,7 +555,7 @@ void ListenEvents() {
|
||||
eventBus.emplaceListener<ll::event::player::PlayerDisconnectEvent>(
|
||||
[](ll::event::player::PlayerDisconnectEvent& ev) {
|
||||
infoLogger->info(
|
||||
fmt::format(fg(fmt::color::yellow), tr("multiplayer.player.left", {ev.self().getName()}))
|
||||
fmt::format(fg(fmt::color::yellow), tr("multiplayer.player.left", {ev.self().getRealName()}))
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -140,4 +570,4 @@ void ListenEvents() {
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
+22
-9
@@ -1,6 +1,16 @@
|
||||
#include "Entry.h"
|
||||
#include "Global.h"
|
||||
#include "Language.h"
|
||||
#include "ll/api/mod/Mod.h"
|
||||
#include "ll/api/Config.h"
|
||||
#include "ll/api/io/PatternFormatter.h"
|
||||
#include "ll/api/io/Logger.h"
|
||||
#include "ll/api/io/LoggerRegistry.h"
|
||||
#include "ll/api/io/FileSink.h"
|
||||
#include "ll/api/mod/RegisterHelper.h"
|
||||
#include "ll/api/data/IndirectValue.h"
|
||||
#include "gmlib/gm/i18n/LangI18n.h"
|
||||
#include "gmlib/gm/i18n/ResourceI18n.h"
|
||||
|
||||
ll::io::LoggerRegistry& loggerRegistry = ll::io::LoggerRegistry::getInstance();
|
||||
std::shared_ptr<ll::io::Logger> logger = loggerRegistry.getOrCreate(MOD_NAME);
|
||||
@@ -35,8 +45,8 @@ bool Entry::load() {
|
||||
}
|
||||
|
||||
bool Entry::enable() {
|
||||
RegisterDamageDefinition();
|
||||
ListenEvents();
|
||||
/* RegisterDamageDefinition();
|
||||
ListenEvents();*/
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -51,10 +61,10 @@ bool Entry::unload() {
|
||||
|
||||
Config& Entry::getConfig() { return mConfig.value(); }
|
||||
|
||||
std::optional<GMLIB::Files::I18n::LangI18n> Entry::getI18n() { return mI18n; }
|
||||
std::unique_ptr<gmlib::i18n::LangI18n> Entry::getI18n() { return std::move(mI18n); }
|
||||
|
||||
void Entry::loadI18n() {
|
||||
mI18n.emplace(getSelf().getLangDir(), getConfig().ServerSideTranslation.Language);
|
||||
mI18n= std::make_unique<gmlib::i18n::LangI18n>(getSelf().getLangDir(), getConfig().ServerSideTranslation.Language);
|
||||
mI18n->updateOrCreateLanguage("en_US", en_US);
|
||||
mI18n->updateOrCreateLanguage("zh_CN", zh_CN);
|
||||
mI18n->loadAllLanguages();
|
||||
@@ -62,8 +72,7 @@ void Entry::loadI18n() {
|
||||
}
|
||||
|
||||
void Entry::loadResourcePack() {
|
||||
GMLIB::Mod::VanillaFix::setFixI18nEnabled();
|
||||
auto resource = GMLIB::Files::ResourceLanguage(getSelf().getModDir() / u8"resource", MOD_NAME, 0, 8, 0);
|
||||
auto resource = gmlib::i18n::ResourceI18n(getSelf().getModDir() / u8"resource", MOD_NAME, 0, 8, 0);
|
||||
resource.addLanguage("en_US", en_US);
|
||||
resource.addLanguage("zh_CN", zh_CN);
|
||||
}
|
||||
@@ -72,9 +81,13 @@ void Entry::loadResourcePack() {
|
||||
|
||||
LL_REGISTER_MOD(DeathMessages::Entry, DeathMessages::Entry::getInstance());
|
||||
|
||||
std::string tr(std::string const& key, std::vector<std::string> const& params) {
|
||||
/*std::string tr(std::string const& key, std::vector<std::string> const& params) {
|
||||
if (auto i18n = DeathMessages::Entry::getInstance().getI18n()) {
|
||||
return i18n->get(key, params);
|
||||
}
|
||||
return ::I18nAPI::get(key, params);
|
||||
}
|
||||
auto i18n = DeathMessages::Entry::getI18n();
|
||||
|
||||
return i18n->get(key, params);
|
||||
|
||||
|
||||
}*/
|
||||
+7
-2
@@ -1,6 +1,11 @@
|
||||
#pragma once
|
||||
#include "Config.h"
|
||||
#include "Global.h"
|
||||
#include "ll/api/mod/Mod.h"
|
||||
|
||||
#include <ll/api/mod/NativeMod.h>
|
||||
|
||||
#include <gmlib/gm/i18n/LangI18n.h>
|
||||
|
||||
namespace DeathMessages {
|
||||
|
||||
@@ -27,7 +32,7 @@ public:
|
||||
|
||||
Config& getConfig();
|
||||
|
||||
std::optional<GMLIB::Files::I18n::LangI18n> getI18n();
|
||||
std::unique_ptr<gmlib::i18n::LangI18n> getI18n();
|
||||
|
||||
void loadI18n();
|
||||
|
||||
@@ -36,7 +41,7 @@ public:
|
||||
private:
|
||||
ll::mod::NativeMod& mSelf;
|
||||
std::optional<Config> mConfig;
|
||||
std::optional<GMLIB::Files::I18n::LangI18n> mI18n;
|
||||
std::unique_ptr<gmlib::i18n::LangI18n> mI18n;
|
||||
};
|
||||
|
||||
} // namespace DeathMessages
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include <include_all.h>
|
||||
#include <ll/api/io/Logger.h>
|
||||
|
||||
#define MOD_NAME "DeathMessages"
|
||||
|
||||
@@ -7,7 +7,7 @@ extern std::shared_ptr<ll::io::Logger> logger;
|
||||
extern std::shared_ptr<ll::io::Logger> deathLogger;
|
||||
extern std::shared_ptr<ll::io::Logger> infoLogger;
|
||||
|
||||
extern std::string tr(std::string const& key, std::vector<std::string> const& data = {});
|
||||
/*extern std::string tr(std::string const& key, std::vector<std::string> const& data = {});
|
||||
|
||||
extern void RegisterDamageDefinition();
|
||||
extern void ListenEvents();
|
||||
extern void ListenEvents();*/
|
||||
@@ -7,45 +7,20 @@ if not has_config("vs_runtime") then
|
||||
set_runtimes("MD")
|
||||
end
|
||||
|
||||
add_requires("levilamina 1.0.0")
|
||||
add_requires("levibuildscript 0.3.0")
|
||||
add_requires("gmlib 0.13.10")
|
||||
add_requires("levilamina 26.10.5",{configs = {target_type = "server"}})
|
||||
add_requires("levibuildscript")
|
||||
add_requires("gmlib 26.10.0")
|
||||
|
||||
target("DeathMessages") -- Change this to your mod name.
|
||||
add_cxflags(
|
||||
"/EHa",
|
||||
"/utf-8"
|
||||
)
|
||||
add_files(
|
||||
"src/**.cpp"
|
||||
)
|
||||
add_includedirs(
|
||||
"src"
|
||||
)
|
||||
add_packages(
|
||||
"levilamina",
|
||||
"gmlib"
|
||||
)
|
||||
add_defines(
|
||||
"NOMINMAX",
|
||||
"UNICODE",
|
||||
"_HAS_CXX17",
|
||||
"_HAS_CXX20",
|
||||
"_HAS_CXX23"
|
||||
)
|
||||
add_rules("@levibuildscript/linkrule")
|
||||
set_exceptions("none")
|
||||
add_rules("@levibuildscript/modpacker")
|
||||
add_cxflags( "/EHa", "/utf-8", "/W4", "/w44265", "/w44289", "/w44296", "/w45263", "/w44738", "/w45204")
|
||||
add_defines("NOMINMAX", "UNICODE")
|
||||
add_packages("levilamina","gmlib")
|
||||
set_exceptions("none") -- To avoid conflicts with /EHa.
|
||||
set_kind("shared")
|
||||
set_languages("cxx20")
|
||||
set_languages("c++23")
|
||||
set_symbols("debug")
|
||||
|
||||
after_build(function (target)
|
||||
local mod_packer = import("scripts.after_build")
|
||||
|
||||
local mod_define = {
|
||||
modName = target:name(),
|
||||
modFile = path.filename(target:targetfile()),
|
||||
}
|
||||
|
||||
mod_packer.pack_mod(target,mod_define)
|
||||
end)
|
||||
add_headerfiles("src/**.h")
|
||||
add_files("src/**.cpp")
|
||||
add_includedirs("src")
|
||||
|
||||
Reference in New Issue
Block a user