[Quest API] Add Entity Variable Methods to Perl/Lua. (#2579)

* [Quest API] Add Entity Variable Methods to Perl/Lua.

# Perl
- Add `$mob->GetEntityVariables()`.
- Add `$object->GetEntityVariables()`.

# Lua
- Add `mob:GetEntityVariables()`.
- Add `object:GetEntityVariables()`.

# Notes
- Convert all overloads and methods to use `std::string` for entity variables.
- Allows operators to get a list of a Mob's entity variables.

* Update loottables.cpp
This commit is contained in:
Alex King 2022-11-26 16:24:01 -05:00 committed by GitHub
parent 290ebf3b26
commit 31d57342e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 231 additions and 144 deletions

View File

@ -11171,8 +11171,8 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
break; break;
case POPUPID_DIAWIND_ONE: case POPUPID_DIAWIND_ONE:
if (EntityVariableExists(DIAWIND_RESPONSE_ONE_KEY.c_str())) { if (EntityVariableExists(DIAWIND_RESPONSE_ONE_KEY)) {
response = GetEntityVariable(DIAWIND_RESPONSE_ONE_KEY.c_str()); response = GetEntityVariable(DIAWIND_RESPONSE_ONE_KEY);
if (!response.empty()) { if (!response.empty()) {
ChannelMessageReceived(8, 0, 100, response.c_str(), nullptr, true); ChannelMessageReceived(8, 0, 100, response.c_str(), nullptr, true);
} }
@ -11180,8 +11180,8 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
break; break;
case POPUPID_DIAWIND_TWO: case POPUPID_DIAWIND_TWO:
if (EntityVariableExists(DIAWIND_RESPONSE_TWO_KEY.c_str())) { if (EntityVariableExists(DIAWIND_RESPONSE_TWO_KEY)) {
response = GetEntityVariable(DIAWIND_RESPONSE_TWO_KEY.c_str()); response = GetEntityVariable(DIAWIND_RESPONSE_TWO_KEY);
if (!response.empty()) { if (!response.empty()) {
ChannelMessageReceived(8, 0, 100, response.c_str(), nullptr, true); ChannelMessageReceived(8, 0, 100, response.c_str(), nullptr, true);
} }

View File

@ -14,8 +14,8 @@ void DialogueWindow::Render(Client *c, std::string markdown)
Mob *target = c->GetTarget() ? c->GetTarget() : c; Mob *target = c->GetTarget() ? c->GetTarget() : c;
// zero this out // zero this out
c->SetEntityVariable(DIAWIND_RESPONSE_ONE_KEY.c_str(), ""); c->SetEntityVariable(DIAWIND_RESPONSE_ONE_KEY, "");
c->SetEntityVariable(DIAWIND_RESPONSE_TWO_KEY.c_str(), ""); c->SetEntityVariable(DIAWIND_RESPONSE_TWO_KEY, "");
// simple find and replace for the markdown // simple find and replace for the markdown
Strings::FindReplace(output, "~", "</c>"); Strings::FindReplace(output, "~", "</c>");
@ -335,14 +335,8 @@ void DialogueWindow::Render(Client *c, std::string markdown)
// Placed here to allow silent message or other message to override default for custom values. // Placed here to allow silent message or other message to override default for custom values.
if (!button_one_name.empty() && !button_two_name.empty()) { if (!button_one_name.empty() && !button_two_name.empty()) {
c->SetEntityVariable( c->SetEntityVariable(DIAWIND_RESPONSE_ONE_KEY, button_one_name);
DIAWIND_RESPONSE_ONE_KEY.c_str(), c->SetEntityVariable(DIAWIND_RESPONSE_TWO_KEY, button_two_name);
button_one_name.c_str()
);
c->SetEntityVariable(
DIAWIND_RESPONSE_TWO_KEY.c_str(),
button_two_name.c_str()
);
} }
// handle silent prompts from the [> silent syntax // handle silent prompts from the [> silent syntax
@ -351,7 +345,7 @@ void DialogueWindow::Render(Client *c, std::string markdown)
silent_message = Strings::GetBetween(output, "[", ">"); silent_message = Strings::GetBetween(output, "[", ">");
// temporary and used during the response // temporary and used during the response
c->SetEntityVariable(DIAWIND_RESPONSE_ONE_KEY.c_str(), silent_message.c_str()); c->SetEntityVariable(DIAWIND_RESPONSE_ONE_KEY, silent_message);
// pop the silent message off // pop the silent message off
Strings::FindReplace(output, fmt::format("[{}>", silent_message), ""); Strings::FindReplace(output, fmt::format("[{}>", silent_message), "");
@ -361,7 +355,7 @@ void DialogueWindow::Render(Client *c, std::string markdown)
silent_message = responses[0]; silent_message = responses[0];
// temporary and used during the response // temporary and used during the response
c->SetEntityVariable(DIAWIND_RESPONSE_ONE_KEY.c_str(), silent_message.c_str()); c->SetEntityVariable(DIAWIND_RESPONSE_ONE_KEY, silent_message);
// pop the silent message off // pop the silent message off
Strings::FindReplace(output, fmt::format("[{}]", silent_message), ""); Strings::FindReplace(output, fmt::format("[{}]", silent_message), "");

View File

@ -5829,9 +5829,13 @@ int EntityList::MovePlayerCorpsesToGraveyard(bool force_move_from_instance)
} }
void EntityList::DespawnGridNodes(int32 grid_id) { void EntityList::DespawnGridNodes(int32 grid_id) {
for (auto mob_iterator : mob_list) { for (auto m : mob_list) {
Mob *mob = mob_iterator.second; Mob *mob = m.second;
if (mob->IsNPC() && mob->GetRace() == 2254 && mob->EntityVariableExists("grid_id") && atoi(mob->GetEntityVariable("grid_id")) == grid_id) { if (
mob->IsNPC() &&
mob->GetRace() == 2254 &&
mob->EntityVariableExists("grid_id") &&
std::stoi(mob->GetEntityVariable("grid_id")) == grid_id) {
mob->Depop(); mob->Depop();
} }
} }

View File

@ -1357,21 +1357,6 @@ void Lua_Mob::SetOOCRegen(int64 new_ooc_regen) {
self->SetOOCRegen(new_ooc_regen); self->SetOOCRegen(new_ooc_regen);
} }
const char* Lua_Mob::GetEntityVariable(const char *name) {
Lua_Safe_Call_String();
return self->GetEntityVariable(name);
}
void Lua_Mob::SetEntityVariable(const char *name, const char *value) {
Lua_Safe_Call_Void();
self->SetEntityVariable(name, value);
}
bool Lua_Mob::EntityVariableExists(const char *name) {
Lua_Safe_Call_Bool();
return self->EntityVariableExists(name);
}
void Lua_Mob::Signal(int signal_id) { void Lua_Mob::Signal(int signal_id) {
Lua_Safe_Call_Void(); Lua_Safe_Call_Void();
@ -2684,6 +2669,36 @@ void Lua_Mob::DamageAreaNPCsPercentage(int64 damage, uint32 distance) {
self->DamageArea(damage, distance, EntityFilterType::NPCs, true); self->DamageArea(damage, distance, EntityFilterType::NPCs, true);
} }
std::string Lua_Mob::GetEntityVariable(std::string variable_name) {
Lua_Safe_Call_String();
return self->GetEntityVariable(variable_name);
}
luabind::object Lua_Mob::GetEntityVariables(lua_State* L) {
auto t = luabind::newtable(L);
if (d_) {
auto self = reinterpret_cast<NativeType*>(d_);
auto l = self->GetEntityVariables();
auto i = 0;
for (const auto& v : l) {
t[i] = v;
i++;
}
}
return t;
}
void Lua_Mob::SetEntityVariable(std::string variable_name, std::string variable_value) {
Lua_Safe_Call_Void();
self->SetEntityVariable(variable_name, variable_value);
}
bool Lua_Mob::EntityVariableExists(std::string variable_name) {
Lua_Safe_Call_Bool();
return self->EntityVariableExists(variable_name);
}
#ifdef BOTS #ifdef BOTS
void Lua_Mob::DamageAreaBots(int64 damage) { void Lua_Mob::DamageAreaBots(int64 damage) {
Lua_Safe_Call_Void(); Lua_Safe_Call_Void();
@ -2906,7 +2921,7 @@ luabind::scope lua_register_mob() {
.def("DoThrowingAttackDmg", (void(Lua_Mob::*)(Lua_Mob,Lua_ItemInst,Lua_Item,int,int,int))&Lua_Mob::DoThrowingAttackDmg) .def("DoThrowingAttackDmg", (void(Lua_Mob::*)(Lua_Mob,Lua_ItemInst,Lua_Item,int,int,int))&Lua_Mob::DoThrowingAttackDmg)
.def("DoubleAggro", &Lua_Mob::DoubleAggro) .def("DoubleAggro", &Lua_Mob::DoubleAggro)
.def("Emote", &Lua_Mob::Emote) .def("Emote", &Lua_Mob::Emote)
.def("EntityVariableExists", (bool(Lua_Mob::*)(const char*))&Lua_Mob::EntityVariableExists) .def("EntityVariableExists", &Lua_Mob::EntityVariableExists)
.def("FaceTarget", (void(Lua_Mob::*)(Lua_Mob))&Lua_Mob::FaceTarget) .def("FaceTarget", (void(Lua_Mob::*)(Lua_Mob))&Lua_Mob::FaceTarget)
.def("FindBuff", &Lua_Mob::FindBuff) .def("FindBuff", &Lua_Mob::FindBuff)
.def("FindBuffBySlot", (uint16(Lua_Mob::*)(int))&Lua_Mob::FindBuffBySlot) .def("FindBuffBySlot", (uint16(Lua_Mob::*)(int))&Lua_Mob::FindBuffBySlot)
@ -2955,7 +2970,8 @@ luabind::scope lua_register_mob() {
.def("GetDrakkinDetails", &Lua_Mob::GetDrakkinDetails) .def("GetDrakkinDetails", &Lua_Mob::GetDrakkinDetails)
.def("GetDrakkinHeritage", &Lua_Mob::GetDrakkinHeritage) .def("GetDrakkinHeritage", &Lua_Mob::GetDrakkinHeritage)
.def("GetDrakkinTattoo", &Lua_Mob::GetDrakkinTattoo) .def("GetDrakkinTattoo", &Lua_Mob::GetDrakkinTattoo)
.def("GetEntityVariable", (const char*(Lua_Mob::*)(const char*))&Lua_Mob::GetEntityVariable) .def("GetEntityVariable", &Lua_Mob::GetEntityVariable)
.def("GetEntityVariables",&Lua_Mob::GetEntityVariables)
.def("GetEyeColor1", &Lua_Mob::GetEyeColor1) .def("GetEyeColor1", &Lua_Mob::GetEyeColor1)
.def("GetEyeColor2", &Lua_Mob::GetEyeColor2) .def("GetEyeColor2", &Lua_Mob::GetEyeColor2)
.def("GetFR", &Lua_Mob::GetFR) .def("GetFR", &Lua_Mob::GetFR)
@ -3172,7 +3188,7 @@ luabind::scope lua_register_mob() {
.def("SetCurrentWP", &Lua_Mob::SetCurrentWP) .def("SetCurrentWP", &Lua_Mob::SetCurrentWP)
.def("SetDestructibleObject", (void(Lua_Mob::*)(bool))&Lua_Mob::SetDestructibleObject) .def("SetDestructibleObject", (void(Lua_Mob::*)(bool))&Lua_Mob::SetDestructibleObject)
.def("SetDisableMelee", (void(Lua_Mob::*)(bool))&Lua_Mob::SetDisableMelee) .def("SetDisableMelee", (void(Lua_Mob::*)(bool))&Lua_Mob::SetDisableMelee)
.def("SetEntityVariable", (void(Lua_Mob::*)(const char*,const char*))&Lua_Mob::SetEntityVariable) .def("SetEntityVariable", &Lua_Mob::SetEntityVariable)
.def("SetExtraHaste", (void(Lua_Mob::*)(int))&Lua_Mob::SetExtraHaste) .def("SetExtraHaste", (void(Lua_Mob::*)(int))&Lua_Mob::SetExtraHaste)
.def("SetFlurryChance", (void(Lua_Mob::*)(int))&Lua_Mob::SetFlurryChance) .def("SetFlurryChance", (void(Lua_Mob::*)(int))&Lua_Mob::SetFlurryChance)
.def("SetFlyMode", (void(Lua_Mob::*)(int))&Lua_Mob::SetFlyMode) .def("SetFlyMode", (void(Lua_Mob::*)(int))&Lua_Mob::SetFlyMode)

View File

@ -301,9 +301,10 @@ public:
bool SetAA(int rank_id, int new_value, int charges); bool SetAA(int rank_id, int new_value, int charges);
bool DivineAura(); bool DivineAura();
void SetOOCRegen(int64 new_ooc_regen); void SetOOCRegen(int64 new_ooc_regen);
const char* GetEntityVariable(const char *name); std::string GetEntityVariable(std::string variable_name);
void SetEntityVariable(const char *name, const char *value); luabind::object GetEntityVariables(lua_State* L);
bool EntityVariableExists(const char *name); void SetEntityVariable(std::string variable_name, std::string variable_value);
bool EntityVariableExists(std::string variable_name);
void Signal(int signal_id); void Signal(int signal_id);
bool CombatRange(Lua_Mob other); bool CombatRange(Lua_Mob other);
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage); void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage);

View File

@ -163,19 +163,34 @@ void Lua_Object::Close() {
self->Close(); self->Close();
} }
const char *Lua_Object::GetEntityVariable(const char *name) { std::string Lua_Object::GetEntityVariable(std::string variable_name) {
Lua_Safe_Call_String(); Lua_Safe_Call_String();
return self->GetEntityVariable(name); return self->GetEntityVariable(variable_name);
} }
void Lua_Object::SetEntityVariable(const char *name, const char *value) { luabind::object Lua_Object::GetEntityVariables(lua_State* L) {
auto t = luabind::newtable(L);
if (d_) {
auto self = reinterpret_cast<NativeType*>(d_);
auto l = self->GetEntityVariables();
auto i = 0;
for (const auto& v : l) {
t[i] = v;
i++;
}
}
return t;
}
void Lua_Object::SetEntityVariable(std::string variable_name, std::string variable_value) {
Lua_Safe_Call_Void(); Lua_Safe_Call_Void();
self->SetEntityVariable(name, value); self->SetEntityVariable(variable_name, variable_value);
} }
bool Lua_Object::EntityVariableExists(const char *name) { bool Lua_Object::EntityVariableExists(std::string variable_name) {
Lua_Safe_Call_Int(); Lua_Safe_Call_Int();
return self->EntityVariableExists(name); return self->EntityVariableExists(variable_name);
} }
luabind::scope lua_register_object() { luabind::scope lua_register_object() {
@ -189,9 +204,10 @@ luabind::scope lua_register_object() {
.def("Delete", (void(Lua_Object::*)(void))&Lua_Object::Delete) .def("Delete", (void(Lua_Object::*)(void))&Lua_Object::Delete)
.def("DeleteItem", (void(Lua_Object::*)(int))&Lua_Object::DeleteItem) .def("DeleteItem", (void(Lua_Object::*)(int))&Lua_Object::DeleteItem)
.def("Depop", (void(Lua_Object::*)(void))&Lua_Object::Depop) .def("Depop", (void(Lua_Object::*)(void))&Lua_Object::Depop)
.def("EntityVariableExists", (bool(Lua_Object::*)(const char*))&Lua_Object::EntityVariableExists) .def("EntityVariableExists", (bool(Lua_Object::*)(std::string))&Lua_Object::EntityVariableExists)
.def("GetDBID", (uint32(Lua_Object::*)(void))&Lua_Object::GetDBID) .def("GetDBID", (uint32(Lua_Object::*)(void))&Lua_Object::GetDBID)
.def("GetEntityVariable", (const char*(Lua_Object::*)(const char*))&Lua_Object::GetEntityVariable) .def("GetEntityVariable", (std::string(Lua_Object::*)(std::string))&Lua_Object::GetEntityVariable)
.def("GetEntityVariables", (luabind::object(Lua_Object::*)(lua_State*))&Lua_Object::GetEntityVariables)
.def("GetHeading", (float(Lua_Object::*)(void))&Lua_Object::GetHeading) .def("GetHeading", (float(Lua_Object::*)(void))&Lua_Object::GetHeading)
.def("GetID", (int(Lua_Object::*)(void))&Lua_Object::GetID) .def("GetID", (int(Lua_Object::*)(void))&Lua_Object::GetID)
.def("GetIcon", (uint32(Lua_Object::*)(void))&Lua_Object::GetIcon) .def("GetIcon", (uint32(Lua_Object::*)(void))&Lua_Object::GetIcon)
@ -204,7 +220,7 @@ luabind::scope lua_register_object() {
.def("IsGroundSpawn", (bool(Lua_Object::*)(void))&Lua_Object::IsGroundSpawn) .def("IsGroundSpawn", (bool(Lua_Object::*)(void))&Lua_Object::IsGroundSpawn)
.def("Repop", (void(Lua_Object::*)(void))&Lua_Object::Repop) .def("Repop", (void(Lua_Object::*)(void))&Lua_Object::Repop)
.def("Save", (bool(Lua_Object::*)(void))&Lua_Object::Save) .def("Save", (bool(Lua_Object::*)(void))&Lua_Object::Save)
.def("SetEntityVariable", (void(Lua_Object::*)(const char*,const char*))&Lua_Object::SetEntityVariable) .def("SetEntityVariable", (void(Lua_Object::*)(std::string,std::string))&Lua_Object::SetEntityVariable)
.def("SetHeading", (void(Lua_Object::*)(float))&Lua_Object::SetHeading) .def("SetHeading", (void(Lua_Object::*)(float))&Lua_Object::SetHeading)
.def("SetID", (void(Lua_Object::*)(int))&Lua_Object::SetID) .def("SetID", (void(Lua_Object::*)(int))&Lua_Object::SetID)
.def("SetIcon", (void(Lua_Object::*)(uint32))&Lua_Object::SetIcon) .def("SetIcon", (void(Lua_Object::*)(uint32))&Lua_Object::SetIcon)

View File

@ -60,9 +60,10 @@ public:
void Delete(bool reset_state); void Delete(bool reset_state);
bool IsGroundSpawn(); bool IsGroundSpawn();
void Close(); void Close();
const char *GetEntityVariable(const char *name); std::string GetEntityVariable(std::string variable_name);
void SetEntityVariable(const char *name, const char *value); luabind::object GetEntityVariables(lua_State* L);
bool EntityVariableExists(const char *name); void SetEntityVariable(std::string variable_name, std::string variable_value);
bool EntityVariableExists(std::string variable_name);
}; };
#endif #endif

View File

@ -4461,31 +4461,45 @@ void Mob::SetDelta(const glm::vec4& delta) {
m_Delta = delta; m_Delta = delta;
} }
void Mob::SetEntityVariable(const char *id, const char *m_var) std::string Mob::GetEntityVariable(std::string variable_name)
{ {
std::string n_m_var = m_var; const auto& v = m_EntityVariables.find(variable_name);
m_EntityVariables[id] = n_m_var; if (v != m_EntityVariables.end()) {
} return v->second;
const char *Mob::GetEntityVariable(const char *id)
{
auto iter = m_EntityVariables.find(id);
if (iter != m_EntityVariables.end()) {
return iter->second.c_str();
} }
return nullptr;
return std::string();
} }
bool Mob::EntityVariableExists(const char *id) std::vector<std::string> Mob::GetEntityVariables()
{ {
auto iter = m_EntityVariables.find(id); std::vector<std::string> l;
if(iter != m_EntityVariables.end()) if (m_EntityVariables.empty()) {
{ return l;
}
for (const auto& v : m_EntityVariables) {
l.push_back(v.first);
}
return l;
}
bool Mob::EntityVariableExists(std::string variable_name)
{
const auto& v = m_EntityVariables.find(variable_name);
if (v != m_EntityVariables.end()) {
return true; return true;
} }
return false; return false;
} }
void Mob::SetEntityVariable(std::string variable_name, std::string variable_value)
{
m_EntityVariables[variable_name] = variable_value;
}
void Mob::SetFlyMode(GravityBehavior flymode) void Mob::SetFlyMode(GravityBehavior flymode)
{ {
flymode = flymode; flymode = flymode;

View File

@ -1130,9 +1130,10 @@ public:
virtual void AI_ShutDown(); virtual void AI_ShutDown();
virtual void AI_Process(); virtual void AI_Process();
const char* GetEntityVariable(const char *id); std::string GetEntityVariable(std::string variable_name);
void SetEntityVariable(const char *id, const char *m_var); std::vector<std::string> GetEntityVariables();
bool EntityVariableExists(const char *id); void SetEntityVariable(std::string variable_name, std::string variable_value);
bool EntityVariableExists(std::string variable_name);
void AI_Event_Engaged(Mob* attacker, bool yell_for_help = true); void AI_Event_Engaged(Mob* attacker, bool yell_for_help = true);
void AI_Event_NoLongerEngaged(); void AI_Event_NoLongerEngaged();

View File

@ -29,12 +29,12 @@ inline std::string GetMobAttributeByString(Mob *mob, const std::string &attribut
{ {
std::string entity_variable = "modify_stat_" + attribute; std::string entity_variable = "modify_stat_" + attribute;
std::string scaling_modified; std::string scaling_modified;
if (mob->GetEntityVariable(entity_variable.c_str())) { if (mob->EntityVariableExists(entity_variable)) {
scaling_modified = " *"; scaling_modified = " *";
} }
if (attribute == "ac") { if (attribute == "ac") {
if (mob->GetEntityVariable(std::string("modify_stat_max_hp").c_str())) { if (mob->EntityVariableExists("modify_stat_max_hp")) {
scaling_modified = " *"; scaling_modified = " *";
} }
@ -59,7 +59,7 @@ inline std::string GetMobAttributeByString(Mob *mob, const std::string &attribut
} }
if (attribute == "hp_min_max") { if (attribute == "hp_min_max") {
if (mob->GetEntityVariable(std::string("modify_stat_max_hp").c_str())) { if (mob->EntityVariableExists("modify_stat_max_hp")) {
scaling_modified = " *"; scaling_modified = " *";
} }
@ -352,49 +352,49 @@ inline std::string GetMobAttributeByString(Mob *mob, const std::string &attribut
return std::to_string((int)npc->GetAccuracyRating()) + scaling_modified; return std::to_string((int)npc->GetAccuracyRating()) + scaling_modified;
} }
if (attribute == "slow_mitigation") { if (attribute == "slow_mitigation") {
if (mob->GetEntityVariable(std::string("modify_stat_slow_mitigation").c_str())) { if (mob->EntityVariableExists("modify_stat_slow_mitigation")) {
scaling_modified = " *"; scaling_modified = " *";
} }
return std::to_string((int)npc->GetSlowMitigation()) + scaling_modified; return std::to_string((int)npc->GetSlowMitigation()) + scaling_modified;
} }
if (attribute == "min_hit") { if (attribute == "min_hit") {
if (mob->GetEntityVariable(std::string("modify_stat_min_hit").c_str())) { if (mob->EntityVariableExists("modify_stat_min_hit")) {
scaling_modified = " *"; scaling_modified = " *";
} }
return Strings::Commify(std::to_string((int) npc->GetMinDMG())) + scaling_modified; return Strings::Commify(std::to_string((int) npc->GetMinDMG())) + scaling_modified;
} }
if (attribute == "max_hit") { if (attribute == "max_hit") {
if (mob->GetEntityVariable(std::string("modify_stat_max_hit").c_str())) { if (mob->EntityVariableExists("modify_stat_max_hit")) {
scaling_modified = " *"; scaling_modified = " *";
} }
return Strings::Commify(std::to_string((int) npc->GetMaxDMG())) + scaling_modified; return Strings::Commify(std::to_string((int) npc->GetMaxDMG())) + scaling_modified;
} }
if (attribute == "hp_regen") { if (attribute == "hp_regen") {
if (mob->GetEntityVariable(std::string("modify_stat_hp_regen").c_str())) { if (mob->EntityVariableExists("modify_stat_hp_regen")) {
scaling_modified = " *"; scaling_modified = " *";
} }
return Strings::Commify(std::to_string((int) npc->GetHPRegen())) + scaling_modified; return Strings::Commify(std::to_string((int) npc->GetHPRegen())) + scaling_modified;
} }
if (attribute == "attack_delay") { if (attribute == "attack_delay") {
if (mob->GetEntityVariable(std::string("modify_stat_attack_delay").c_str())) { if (mob->EntityVariableExists("modify_stat_attack_delay")) {
scaling_modified = " *"; scaling_modified = " *";
} }
return Strings::Commify(std::to_string(npc->GetAttackDelay())) + scaling_modified; return Strings::Commify(std::to_string(npc->GetAttackDelay())) + scaling_modified;
} }
if (attribute == "spell_scale") { if (attribute == "spell_scale") {
if (mob->GetEntityVariable(std::string("modify_stat_spell_scale").c_str())) { if (mob->EntityVariableExists("modify_stat_spell_scale")) {
scaling_modified = " *"; scaling_modified = " *";
} }
return Strings::Commify(std::to_string((int) npc->GetSpellScale())) + scaling_modified; return Strings::Commify(std::to_string((int) npc->GetSpellScale())) + scaling_modified;
} }
if (attribute == "heal_scale") { if (attribute == "heal_scale") {
if (mob->GetEntityVariable(std::string("modify_stat_heal_scale").c_str())) { if (mob->EntityVariableExists("modify_stat_heal_scale")) {
scaling_modified = " *"; scaling_modified = " *";
} }

View File

@ -2454,7 +2454,7 @@ void NPC::ModifyNPCStat(std::string stat, std::string value)
stat_lower stat_lower
); );
SetEntityVariable(variable_key.c_str(), value.c_str()); SetEntityVariable(variable_key, value);
LogNPCScaling("NPC::ModifyNPCStat: Key [{}] Value [{}] ", variable_key, value); LogNPCScaling("NPC::ModifyNPCStat: Key [{}] Value [{}] ", variable_key, value);

View File

@ -149,9 +149,9 @@ void NpcScaleManager::ScaleNPC(NPC *npc)
std::string scale_log; std::string scale_log;
for (const auto &stat : scaling_stats) { for (const auto &stat : scaling_stats) {
std::string variable = StringFormat("modify_stat_%s", stat.c_str()); auto v = fmt::format("modify_stat_{}", stat);
if (npc->EntityVariableExists(variable.c_str())) { if (npc->EntityVariableExists(v)) {
scale_log += stat + ": " + npc->GetEntityVariable(variable.c_str()) + " "; scale_log += fmt::format("{}: {} ", stat, npc->GetEntityVariable(v));
} }
} }
@ -169,9 +169,9 @@ void NpcScaleManager::ScaleNPC(NPC *npc)
void NpcScaleManager::ResetNPCScaling(NPC *npc) void NpcScaleManager::ResetNPCScaling(NPC *npc)
{ {
for (const auto &scaling_stat : scaling_stats) { for (const auto &scaling_stat : scaling_stats) {
std::string stat_name = fmt::format("modify_stat_{}", scaling_stat); auto stat_name = fmt::format("modify_stat_{}", scaling_stat);
std::string reset_value = "0"; auto reset_value = std::to_string(0);
if (npc->EntityVariableExists(stat_name.c_str())) { if (npc->EntityVariableExists(stat_name)) {
npc->ModifyNPCStat(scaling_stat.c_str(), reset_value.c_str()); npc->ModifyNPCStat(scaling_stat.c_str(), reset_value.c_str());
} }
} }

View File

@ -1057,34 +1057,49 @@ void Object::SetHeading(float heading)
safe_delete(app2); safe_delete(app2);
} }
void Object::SetEntityVariable(const char *id, const char *m_var) void Object::SetEntityVariable(std::string variable_name, std::string variable_value)
{ {
std::string n_m_var = m_var; o_EntityVariables[variable_name] = variable_value;
o_EntityVariables[id] = n_m_var;
} }
const char* Object::GetEntityVariable(const char *id) std::string Object::GetEntityVariable(std::string variable_name)
{ {
if(!id) if (variable_name.empty()) {
return nullptr; return std::string();
auto iter = o_EntityVariables.find(id);
if(iter != o_EntityVariables.end())
{
return iter->second.c_str();
} }
return nullptr;
const auto& v = o_EntityVariables.find(variable_name);
if (v != o_EntityVariables.end()) {
return v->second;
}
return std::string();
} }
bool Object::EntityVariableExists(const char * id) std::vector<std::string> Object::GetEntityVariables()
{ {
if(!id) std::vector<std::string> l;
return false; if (o_EntityVariables.empty()) {
return l;
}
auto iter = o_EntityVariables.find(id); for (const auto& v : o_EntityVariables) {
if(iter != o_EntityVariables.end()) l.push_back(v.first);
{ }
return l;
}
bool Object::EntityVariableExists(std::string variable_name)
{
if (variable_name.empty()) {
return false;
}
const auto& v = o_EntityVariables.find(variable_name);
if (v != o_EntityVariables.end()) {
return true; return true;
} }
return false; return false;
} }

View File

@ -171,9 +171,10 @@ public:
void SetDisplayName(const char *in_name); void SetDisplayName(const char *in_name);
const char *GetDisplayName() const { return m_display_name; } const char *GetDisplayName() const { return m_display_name; }
const char* GetEntityVariable(const char *id); std::string GetEntityVariable(std::string variable_name);
void SetEntityVariable(const char *id, const char *m_var); std::vector<std::string> GetEntityVariables();
bool EntityVariableExists(const char *id); void SetEntityVariable(std::string variable_name, std::string variable_value);
bool EntityVariableExists(std::string variable_name);
protected: protected:
void ResetState(); // Set state back to original void ResetState(); // Set state back to original

View File

@ -1465,22 +1465,6 @@ void Perl_Mob_SetOOCRegen(Mob* self, int64 new_ooc_regen) // @categories Stats a
self->SetOOCRegen(new_ooc_regen); self->SetOOCRegen(new_ooc_regen);
} }
const char* Perl_Mob_GetEntityVariable(Mob* self, const char* id) // @categories Script Utility
{
// supports possible nullptr return
return self->GetEntityVariable(id);
}
bool Perl_Mob_EntityVariableExists(Mob* self, const char* id)
{
return self->EntityVariableExists(id);
}
void Perl_Mob_SetEntityVariable(Mob* self, const char* id, const char* var) // @categories Script Utility
{
self->SetEntityVariable(id, var);
}
perl::array Perl_Mob_GetHateList(Mob* self) perl::array Perl_Mob_GetHateList(Mob* self)
{ {
perl::array result; perl::array result;
@ -2652,6 +2636,33 @@ perl::array Perl_Mob_GetHateListNPCs(Mob* self, uint32 distance)
return result; return result;
} }
bool Perl_Mob_EntityVariableExists(Mob* self, std::string variable_name) // @categories Script Utility
{
return self->EntityVariableExists(variable_name);
}
std::string Perl_Mob_GetEntityVariable(Mob* self, std::string variable_name) // @categories Script Utility
{
return self->GetEntityVariable(variable_name);
}
perl::array Perl_Mob_GetEntityVariables(Mob* self) // @categories Script Utility
{
perl::array a;
const auto& l = self->GetEntityVariables();
for (const auto& v : l) {
a.push_back(v);
}
return a;
}
void Perl_Mob_SetEntityVariable(Mob* self, std::string variable_name, std::string variable_value) // @categories Script Utility
{
self->SetEntityVariable(variable_name, variable_value);
}
#ifdef BOTS #ifdef BOTS
void Perl_Mob_DamageAreaBots(Mob* self, int64 damage) // @categories Hate and Aggro void Perl_Mob_DamageAreaBots(Mob* self, int64 damage) // @categories Hate and Aggro
{ {
@ -2921,6 +2932,7 @@ void perl_register_mob()
package.add("GetDrakkinHeritage", &Perl_Mob_GetDrakkinHeritage); package.add("GetDrakkinHeritage", &Perl_Mob_GetDrakkinHeritage);
package.add("GetDrakkinTattoo", &Perl_Mob_GetDrakkinTattoo); package.add("GetDrakkinTattoo", &Perl_Mob_GetDrakkinTattoo);
package.add("GetEntityVariable", &Perl_Mob_GetEntityVariable); package.add("GetEntityVariable", &Perl_Mob_GetEntityVariable);
package.add("GetEntityVariables", &Perl_Mob_GetEntityVariables);
package.add("GetEquipment", &Perl_Mob_GetEquipment); package.add("GetEquipment", &Perl_Mob_GetEquipment);
package.add("GetEquipmentColor", &Perl_Mob_GetEquipmentColor); package.add("GetEquipmentColor", &Perl_Mob_GetEquipmentColor);
package.add("GetEquipmentMaterial", &Perl_Mob_GetEquipmentMaterial); package.add("GetEquipmentMaterial", &Perl_Mob_GetEquipmentMaterial);

View File

@ -166,22 +166,6 @@ void Perl_Object_Depop(Object* self) // @categories Objects
self->Depop(); self->Depop();
} }
const char* Perl_Object_GetEntityVariable(Object* self, const char* key) // @categories Objects
{
// supports possible nullptr return
return self->GetEntityVariable(key);
}
bool Perl_Object_EntityVariableExists(Object* self, const char* key) // @categories Objects
{
return self->EntityVariableExists(key);
}
void Perl_Object_SetEntityVariable(Object* self, const char* key, const char* var) // @categories Objects
{
self->SetEntityVariable(key, var);
}
uint32_t Perl_Object_GetSolidType(Object* self) // @categories Objects uint32_t Perl_Object_GetSolidType(Object* self) // @categories Objects
{ {
return self->GetSolidType(); return self->GetSolidType();
@ -222,6 +206,33 @@ float Perl_Object_GetTiltY(Object* self) // @categories Objects
return self->GetTiltY(); return self->GetTiltY();
} }
bool Perl_Object_EntityVariableExists(Object* self, std::string variable_name) // @categories Objects
{
return self->EntityVariableExists(variable_name);
}
std::string Perl_Object_GetEntityVariable(Object* self, std::string variable_name) // @categories Objects
{
return self->GetEntityVariable(variable_name);
}
perl::array Perl_Object_GetEntityVariables(Object* self) // @categories Script Utility
{
perl::array a;
const auto& l = self->GetEntityVariables();
for (const auto& v : l) {
a.push_back(v);
}
return a;
}
void Perl_Object_SetEntityVariable(Object* self, std::string variable_name, std::string variable_value) // @categories Objects
{
self->SetEntityVariable(variable_name, variable_value);
}
void perl_register_object() void perl_register_object()
{ {
perl::interpreter perl(PERL_GET_THX); perl::interpreter perl(PERL_GET_THX);
@ -237,6 +248,7 @@ void perl_register_object()
package.add("EntityVariableExists", &Perl_Object_EntityVariableExists); package.add("EntityVariableExists", &Perl_Object_EntityVariableExists);
package.add("GetDBID", &Perl_Object_GetDBID); package.add("GetDBID", &Perl_Object_GetDBID);
package.add("GetEntityVariable", &Perl_Object_GetEntityVariable); package.add("GetEntityVariable", &Perl_Object_GetEntityVariable);
package.add("GetEntityVariables", &Perl_Object_GetEntityVariables);
package.add("GetHeading", &Perl_Object_GetHeading); package.add("GetHeading", &Perl_Object_GetHeading);
package.add("GetID", &Perl_Object_GetID); package.add("GetID", &Perl_Object_GetID);
package.add("GetIcon", &Perl_Object_GetIcon); package.add("GetIcon", &Perl_Object_GetIcon);

View File

@ -2556,8 +2556,8 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
CZSetEntityVariable_Struct* CZSEV = (CZSetEntityVariable_Struct*) pack->pBuffer; CZSetEntityVariable_Struct* CZSEV = (CZSetEntityVariable_Struct*) pack->pBuffer;
uint8 update_type = CZSEV->update_type; uint8 update_type = CZSEV->update_type;
int update_identifier = CZSEV->update_identifier; int update_identifier = CZSEV->update_identifier;
const char* variable_name = CZSEV->variable_name; std::string variable_name = CZSEV->variable_name;
const char* variable_value = CZSEV->variable_value; std::string variable_value = CZSEV->variable_value;
const char* client_name = CZSEV->client_name; const char* client_name = CZSEV->client_name;
if (update_type == CZUpdateType_Character) { if (update_type == CZUpdateType_Character) {
auto client = entity_list.GetClientByCharID(update_identifier); auto client = entity_list.GetClientByCharID(update_identifier);
@ -3062,8 +3062,8 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
{ {
WWSetEntityVariable_Struct* WWSEV = (WWSetEntityVariable_Struct*) pack->pBuffer; WWSetEntityVariable_Struct* WWSEV = (WWSetEntityVariable_Struct*) pack->pBuffer;
uint8 update_type = WWSEV->update_type; uint8 update_type = WWSEV->update_type;
const char* variable_name = WWSEV->variable_name; std::string variable_name = WWSEV->variable_name;
const char* variable_value = WWSEV->variable_value; std::string variable_value = WWSEV->variable_value;
uint8 min_status = WWSEV->min_status; uint8 min_status = WWSEV->min_status;
uint8 max_status = WWSEV->max_status; uint8 max_status = WWSEV->max_status;
if (update_type == WWSetEntityVariableUpdateType_Character) { if (update_type == WWSetEntityVariableUpdateType_Character) {