From 11a43cd320cbe43c9a06fe3c6a5a5aa30528bcb1 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 31 Dec 2018 03:18:59 -0600 Subject: [PATCH 01/11] Texture work --- common/eq_packet_structs.h | 16 +- common/eqemu_logsys.h | 4 +- common/item_instance.cpp | 4 + common/item_instance.h | 3 + common/patches/rof2.cpp | 10 +- common/textures.h | 23 ++ zone/CMakeLists.txt | 1 + zone/aa.cpp | 18 +- zone/attack.cpp | 6 +- zone/client.cpp | 15 +- zone/client.h | 4 +- zone/client_mods.cpp | 8 +- zone/client_packet.cpp | 41 +-- zone/client_process.cpp | 40 +-- zone/command.cpp | 127 +++++-- zone/command.h | 2 + zone/corpse.cpp | 4 +- zone/corpse.h | 2 +- zone/entity.cpp | 89 ++--- zone/horse.cpp | 2 +- zone/inventory.cpp | 20 +- zone/lua_general.cpp | 2 +- zone/merc.cpp | 10 +- zone/mob.cpp | 654 ++++++++++++----------------------- zone/mob.h | 174 +++++----- zone/mob_appearance.cpp | 544 +++++++++++++++++++++++++++++ zone/npc.cpp | 143 ++++---- zone/npc.h | 3 +- zone/pathfinder_waypoint.cpp | 2 +- zone/perl_mob.cpp | 2 +- zone/pets.cpp | 4 +- zone/trap.cpp | 2 +- zone/zonedb.cpp | 4 +- zone/zonedump.h | 2 +- 34 files changed, 1229 insertions(+), 756 deletions(-) create mode 100644 zone/mob_appearance.cpp diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index db97818a5..5ae2c1a93 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -1184,15 +1184,15 @@ struct SpecialMesg_Struct ** When somebody changes what they're wearing or give a pet a weapon (model changes) ** Length: 19 Bytes */ -struct WearChange_Struct{ -/*000*/ uint16 spawn_id; -/*002*/ uint32 material; -/*006*/ uint32 unknown06; -/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material -/*014*/ uint32 hero_forge_model; // New to VoA -/*018*/ uint32 unknown18; // New to RoF +struct WearChange_Struct { +/*000*/ uint16 spawn_id; +/*002*/ uint32 material; +/*006*/ uint32 unknown06; +/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material +/*014*/ uint32 hero_forge_model; // New to VoA +/*018*/ uint32 unknown18; // New to RoF /*022*/ EQEmu::textures::Tint_Struct color; -/*026*/ uint8 wear_slot_id; +/*026*/ uint8 wear_slot_id; /*027*/ }; diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index be646432a..fb42ac8b4 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -93,6 +93,7 @@ namespace Logs { Traps, NPCRoamBox, NPCScaling, + MobAppearance, MaxCategoryID /* Don't Remove this */ }; @@ -151,7 +152,8 @@ namespace Logs { "Food", "Traps", "NPC Roam Box", - "NPC Scaling" + "NPC Scaling", + "Mob Appearance" }; } diff --git a/common/item_instance.cpp b/common/item_instance.cpp index ea7e94428..2c186e066 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -84,6 +84,7 @@ EQEmu::ItemInstance::ItemInstance(const ItemData* item, int16 charges) { m_ornamentidfile = 0; m_ornament_hero_model = 0; m_recast_timestamp = 0; + m_new_id_file = 0; } EQEmu::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges) { @@ -117,6 +118,7 @@ EQEmu::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 char m_ornamentidfile = 0; m_ornament_hero_model = 0; m_recast_timestamp = 0; + m_new_id_file = 0; } EQEmu::ItemInstance::ItemInstance(ItemInstTypes use_type) { @@ -138,6 +140,7 @@ EQEmu::ItemInstance::ItemInstance(ItemInstTypes use_type) { m_ornamentidfile = 0; m_ornament_hero_model = 0; m_recast_timestamp = 0; + m_new_id_file = 0; } // Make a copy of an EQEmu::ItemInstance object @@ -195,6 +198,7 @@ EQEmu::ItemInstance::ItemInstance(const ItemInstance& copy) m_ornamentidfile = copy.m_ornamentidfile; m_ornament_hero_model = copy.m_ornament_hero_model; m_recast_timestamp = copy.m_recast_timestamp; + m_new_id_file = copy.m_new_id_file; } // Clean up container contents diff --git a/common/item_instance.h b/common/item_instance.h index 6566fd77e..d38ad0868 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -203,6 +203,8 @@ namespace EQEmu void SetOrnamentIcon(uint32 ornament_icon) { m_ornamenticon = ornament_icon; } uint32 GetOrnamentationIDFile() const { return m_ornamentidfile; } void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; } + uint32 GetNewIDFile() const { return m_new_id_file; } + void SetNewIDFile(uint32 new_id_file) { m_new_id_file = new_id_file; } uint32 GetOrnamentHeroModel(int32 material_slot = -1) const; void SetOrnamentHeroModel(uint32 ornament_hero_model) { m_ornament_hero_model = ornament_hero_model; } uint32 GetRecastTimestamp() const { return m_recast_timestamp; } @@ -306,6 +308,7 @@ namespace EQEmu bool m_scaling; uint32 m_ornamenticon; uint32 m_ornamentidfile; + uint32 m_new_id_file; uint32 m_ornament_hero_model; uint32 m_recast_timestamp; diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index d65ea4cba..cb9e468fb 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -5488,8 +5488,16 @@ namespace RoF2 ob.write(item->Lore, strlen(item->Lore)); ob.write("\0", 1); - if (strlen(item->IDFile) > 0) + if (inst->GetNewIDFile() > 0) { + char new_id_file[30]; + memset(new_id_file, 0x0, 30); + sprintf(new_id_file, "IT%d", inst->GetNewIDFile()); + ob.write(new_id_file, strlen(new_id_file)); + } + else if (strlen(item->IDFile) > 0) { ob.write(item->IDFile, strlen(item->IDFile)); + } + ob.write("\0", 1); ob.write("\0", 1); diff --git a/common/textures.h b/common/textures.h index a39f4c007..f489977ce 100644 --- a/common/textures.h +++ b/common/textures.h @@ -65,6 +65,12 @@ namespace EQEmu uint32 Unknown2; // same as material? }; + struct InternalTexture_Struct { + uint32 HerosForgeModel; + uint32 Material; + uint32 Color; + }; + struct TextureMaterial_Struct { uint32 Material; }; @@ -100,6 +106,23 @@ namespace EQEmu }; }; + struct InternalTextureProfile { + union { + struct { + textures::InternalTexture_Struct Head; + textures::InternalTexture_Struct Chest; + textures::InternalTexture_Struct Arms; + textures::InternalTexture_Struct Wrist; + textures::InternalTexture_Struct Hands; + textures::InternalTexture_Struct Legs; + textures::InternalTexture_Struct Feet; + textures::InternalTexture_Struct Primary; + textures::InternalTexture_Struct Secondary; + }; + textures::InternalTexture_Struct Slot[textures::materialCount]; + }; + }; + struct TextureMaterialProfile { union { struct { diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index 7eaafb9d7..c92102a2d 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -82,6 +82,7 @@ SET(zone_sources merc.cpp mob.cpp mob_ai.cpp + mob_appearance.cpp mob_movement_manager.cpp mob_info.cpp mod_functions.cpp diff --git a/zone/aa.cpp b/zone/aa.cpp index 1f5f9328d..cb2e6ab7e 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -286,7 +286,7 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration) make_npc->min_dmg = 1; //base stats - make_npc->cur_hp = (GetLevel() * 55); + make_npc->current_hp = (GetLevel() * 55); make_npc->max_hp = (GetLevel() * 55); make_npc->STR = 85 + (GetLevel() * 3); make_npc->STA = 85 + (GetLevel() * 3); @@ -356,51 +356,51 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration) case PALADIN: //SPECATK_TRIPLE strcpy(make_npc->special_abilities, "6,1"); - make_npc->cur_hp = make_npc->cur_hp * 150 / 100; + make_npc->current_hp = make_npc->current_hp * 150 / 100; make_npc->max_hp = make_npc->max_hp * 150 / 100; make_npc->npc_spells_id = 8; break; case SHADOWKNIGHT: strcpy(make_npc->special_abilities, "6,1"); - make_npc->cur_hp = make_npc->cur_hp * 150 / 100; + make_npc->current_hp = make_npc->current_hp * 150 / 100; make_npc->max_hp = make_npc->max_hp * 150 / 100; make_npc->npc_spells_id = 9; break; case RANGER: strcpy(make_npc->special_abilities, "7,1"); - make_npc->cur_hp = make_npc->cur_hp * 135 / 100; + make_npc->current_hp = make_npc->current_hp * 135 / 100; make_npc->max_hp = make_npc->max_hp * 135 / 100; make_npc->npc_spells_id = 10; break; case BARD: strcpy(make_npc->special_abilities, "6,1"); - make_npc->cur_hp = make_npc->cur_hp * 110 / 100; + make_npc->current_hp = make_npc->current_hp * 110 / 100; make_npc->max_hp = make_npc->max_hp * 110 / 100; make_npc->npc_spells_id = 11; break; case BEASTLORD: strcpy(make_npc->special_abilities, "7,1"); - make_npc->cur_hp = make_npc->cur_hp * 110 / 100; + make_npc->current_hp = make_npc->current_hp * 110 / 100; make_npc->max_hp = make_npc->max_hp * 110 / 100; make_npc->npc_spells_id = 12; break; case ROGUE: strcpy(make_npc->special_abilities, "7,1"); make_npc->max_dmg = make_npc->max_dmg * 150 /100; - make_npc->cur_hp = make_npc->cur_hp * 110 / 100; + make_npc->current_hp = make_npc->current_hp * 110 / 100; make_npc->max_hp = make_npc->max_hp * 110 / 100; break; case MONK: strcpy(make_npc->special_abilities, "7,1"); make_npc->max_dmg = make_npc->max_dmg * 150 /100; - make_npc->cur_hp = make_npc->cur_hp * 135 / 100; + make_npc->current_hp = make_npc->current_hp * 135 / 100; make_npc->max_hp = make_npc->max_hp * 135 / 100; break; case WARRIOR: case BERSERKER: strcpy(make_npc->special_abilities, "7,1"); make_npc->max_dmg = make_npc->max_dmg * 150 /100; - make_npc->cur_hp = make_npc->cur_hp * 175 / 100; + make_npc->current_hp = make_npc->current_hp * 175 / 100; make_npc->max_hp = make_npc->max_hp * 175 / 100; break; default: diff --git a/zone/attack.cpp b/zone/attack.cpp index 769568f34..771976ef1 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -33,6 +33,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "zone.h" #include "lua_parser.h" #include "fastmath.h" +#include "mob.h" + #include #include @@ -5444,7 +5446,7 @@ void Mob::DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts) // For now, SPECATK_QUAD means innate DW when Combat:UseLiveCombatRounds is true if ((GetSpecialAbility(SPECATK_INNATE_DW) || (RuleB(Combat, UseLiveCombatRounds) && GetSpecialAbility(SPECATK_QUAD))) || - GetEquipment(EQEmu::textures::weaponSecondary) != 0) { + GetEquippedItemFromTextureSlot(EQEmu::textures::weaponSecondary) != 0) { if (CheckDualWield()) { Attack(target, EQEmu::invslot::slotSecondary, false, false, false, opts); if (CanThisClassDoubleAttack() && GetLevel() > 35 && CheckDoubleAttack()) { @@ -5476,4 +5478,4 @@ int32 Mob::GetHPRegen() const int32 Mob::GetManaRegen() const { return mana_regen; -} +} \ No newline at end of file diff --git a/zone/client.cpp b/zone/client.cpp index 3bdd647a2..bb43a3e4f 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2965,13 +2965,12 @@ bool Client::BindWound(Mob *bindmob, bool start, bool fail) return true; } -void Client::SetMaterial(int16 in_slot, uint32 item_id) { - const EQEmu::ItemData* item = database.GetItem(item_id); - if (item && item->IsClassCommon()) - { +void Client::SetMaterial(int16 in_slot, uint32 item_id) +{ + const EQEmu::ItemData *item = database.GetItem(item_id); + if (item && item->IsClassCommon()) { uint8 matslot = EQEmu::InventoryProfile::CalcMaterialFromSlot(in_slot); - if (matslot != EQEmu::textures::materialInvalid) - { + if (matslot != EQEmu::textures::materialInvalid) { m_pp.item_material.Slot[matslot].Material = GetEquipmentMaterial(matslot); } } @@ -8527,11 +8526,11 @@ void Client::QuestReward(Mob* target, uint32 copper, uint32 silver, uint32 gold, } void Client::SendHPUpdateMarquee(){ - if (!this || !this->IsClient() || !this->cur_hp || !this->max_hp) + if (!this || !this->IsClient() || !this->current_hp || !this->max_hp) return; /* Health Update Marquee Display: Custom*/ - uint8 health_percentage = (uint8)(this->cur_hp * 100 / this->max_hp); + uint8 health_percentage = (uint8)(this->current_hp * 100 / this->max_hp); if (health_percentage >= 100) return; diff --git a/zone/client.h b/zone/client.h index 4f7b0d9a0..48efba685 100644 --- a/zone/client.h +++ b/zone/client.h @@ -352,7 +352,7 @@ public: void SetHideMe(bool hm); inline uint16 GetPort() const { return port; } bool IsDead() const { return(dead); } - bool IsUnconscious() const { return ((cur_hp <= 0) ? true : false); } + bool IsUnconscious() const { return ((current_hp <= 0) ? true : false); } inline bool IsLFP() { return LFP; } void UpdateLFP(); @@ -798,7 +798,7 @@ public: #ifdef PACKET_PROFILER void DumpPacketProfile() { if(eqs) eqs->DumpPacketProfile(); } #endif - uint32 GetEquipment(uint8 material_slot) const; // returns item id + uint32 GetEquippedItemFromTextureSlot(uint8 material_slot) const; // returns item id uint32 GetEquipmentColor(uint8 material_slot) const; virtual void UpdateEquipmentLight() { m_Light.Type[EQEmu::lightsource::LightEquipment] = m_inv.FindBrightestLightType(); m_Light.Level[EQEmu::lightsource::LightEquipment] = EQEmu::lightsource::TypeToLevel(m_Light.Type[EQEmu::lightsource::LightEquipment]); } diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index 8651a622f..299aa3f0b 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -325,15 +325,15 @@ int32 Client::CalcMaxHP() max_hp += spellbonuses.HP + aabonuses.HP; max_hp += GroupLeadershipAAHealthEnhancement(); max_hp += max_hp * ((spellbonuses.MaxHPChange + itembonuses.MaxHPChange) / 10000.0f); - if (cur_hp > max_hp) { - cur_hp = max_hp; + if (current_hp > max_hp) { + current_hp = max_hp; } int hp_perc_cap = spellbonuses.HPPercCap[0]; if (hp_perc_cap) { int curHP_cap = (max_hp * hp_perc_cap) / 100; - if (cur_hp > curHP_cap || (spellbonuses.HPPercCap[1] && cur_hp > spellbonuses.HPPercCap[1])) { + if (current_hp > curHP_cap || (spellbonuses.HPPercCap[1] && current_hp > spellbonuses.HPPercCap[1])) { - cur_hp = curHP_cap; + current_hp = curHP_cap; } } return max_hp; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 43034da6b..efaa05e0a 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -3237,42 +3237,40 @@ void Client::Handle_OP_AutoAttack(const EQApplicationPacket *app) return; } - if (app->pBuffer[0] == 0) - { + if (app->pBuffer[0] == 0) { auto_attack = false; - if (IsAIControlled()) + if (IsAIControlled()) { return; + } attack_timer.Disable(); ranged_timer.Disable(); attack_dw_timer.Disable(); - m_AutoAttackPosition = glm::vec4(); + m_AutoAttackPosition = glm::vec4(); m_AutoAttackTargetLocation = glm::vec3(); - aa_los_them_mob = nullptr; + aa_los_them_mob = nullptr; } - else if (app->pBuffer[0] == 1) - { + else if (app->pBuffer[0] == 1) { auto_attack = true; - auto_fire = false; - if (IsAIControlled()) + auto_fire = false; + if (IsAIControlled()) { return; + } SetAttackTimer(); - if (GetTarget()) - { - aa_los_them_mob = GetTarget(); - m_AutoAttackPosition = GetPosition(); + if (GetTarget()) { + aa_los_them_mob = GetTarget(); + m_AutoAttackPosition = GetPosition(); m_AutoAttackTargetLocation = glm::vec3(aa_los_them_mob->GetPosition()); - los_status = CheckLosFN(aa_los_them_mob); - los_status_facing = IsFacingMob(aa_los_them_mob); + los_status = CheckLosFN(aa_los_them_mob); + los_status_facing = IsFacingMob(aa_los_them_mob); } - else - { - m_AutoAttackPosition = GetPosition(); + else { + m_AutoAttackPosition = GetPosition(); m_AutoAttackTargetLocation = glm::vec3(); - aa_los_them_mob = nullptr; - los_status = false; - los_status_facing = false; + aa_los_them_mob = nullptr; + los_status = false; + los_status_facing = false; } } } @@ -14452,7 +14450,6 @@ void Client::Handle_OP_WearChange(const EQApplicationPacket *app) // we could maybe ignore this and just send our own from moveitem entity_list.QueueClients(this, app, true); - return; } void Client::Handle_OP_WhoAllRequest(const EQApplicationPacket *app) diff --git a/zone/client_process.cpp b/zone/client_process.cpp index fcfc1df53..82f118384 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -345,25 +345,22 @@ bool Client::Process() { } Mob *auto_attack_target = GetTarget(); - if (auto_attack && auto_attack_target != nullptr && may_use_attacks && attack_timer.Check()) - { + if (auto_attack && auto_attack_target != nullptr && may_use_attacks && attack_timer.Check()) { //check if change //only check on primary attack.. sorry offhand you gotta wait! - if (aa_los_them_mob) - { + if (aa_los_them_mob) { if (auto_attack_target != aa_los_them_mob || m_AutoAttackPosition.x != GetX() || m_AutoAttackPosition.y != GetY() || m_AutoAttackPosition.z != GetZ() || m_AutoAttackTargetLocation.x != aa_los_them_mob->GetX() || m_AutoAttackTargetLocation.y != aa_los_them_mob->GetY() || - m_AutoAttackTargetLocation.z != aa_los_them_mob->GetZ()) - { - aa_los_them_mob = auto_attack_target; - m_AutoAttackPosition = GetPosition(); + m_AutoAttackTargetLocation.z != aa_los_them_mob->GetZ()) { + aa_los_them_mob = auto_attack_target; + m_AutoAttackPosition = GetPosition(); m_AutoAttackTargetLocation = glm::vec3(aa_los_them_mob->GetPosition()); - los_status = CheckLosFN(auto_attack_target); - los_status_facing = IsFacingMob(aa_los_them_mob); + los_status = CheckLosFN(auto_attack_target); + los_status_facing = IsFacingMob(aa_los_them_mob); } // If only our heading changes, we can skip the CheckLosFN call // but above we still need to update los_status_facing @@ -372,25 +369,21 @@ bool Client::Process() { los_status_facing = IsFacingMob(aa_los_them_mob); } } - else - { - aa_los_them_mob = auto_attack_target; - m_AutoAttackPosition = GetPosition(); + else { + aa_los_them_mob = auto_attack_target; + m_AutoAttackPosition = GetPosition(); m_AutoAttackTargetLocation = glm::vec3(aa_los_them_mob->GetPosition()); - los_status = CheckLosFN(auto_attack_target); - los_status_facing = IsFacingMob(aa_los_them_mob); + los_status = CheckLosFN(auto_attack_target); + los_status_facing = IsFacingMob(aa_los_them_mob); } - if (!CombatRange(auto_attack_target)) - { + if (!CombatRange(auto_attack_target)) { Message_StringID(MT_TooFarAway, TARGET_TOO_FAR); } - else if (auto_attack_target == this) - { + else if (auto_attack_target == this) { Message_StringID(MT_TooFarAway, TRY_ATTACKING_SOMEONE); } - else if (!los_status || !los_status_facing) - { + else if (!los_status || !los_status_facing) { //you can't see your target } else if (auto_attack_target->GetHP() > -10) // -10 so we can watch people bleed in PvP @@ -400,8 +393,9 @@ bool Client::Process() { TriggerDefensiveProcs(auto_attack_target, EQEmu::invslot::slotPrimary, false); DoAttackRounds(auto_attack_target, EQEmu::invslot::slotPrimary); - if (CheckAATimer(aaTimerRampage)) + if (CheckAATimer(aaTimerRampage)) { entity_list.AEAttack(this, 30); + } } } diff --git a/zone/command.cpp b/zone/command.cpp index 1dc001a5c..681c22a7e 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -249,6 +249,7 @@ int command_init(void) command_add("itemsearch", "[search criteria] - Search for an item", 10, command_itemsearch) || command_add("kick", "[charname] - Disconnect charname", 150, command_kick) || command_add("kill", "- Kill your target", 100, command_kill) || + command_add("killallnpcs", "- Kills all npcs, also takes an optional npc name as parameter", 200, command_killallnpcs) || command_add("lastname", "[new lastname] - Set your or your player target's lastname", 50, command_lastname) || command_add("level", "[level] - Set your or your target's level", 10, command_level) || command_add("listnpcs", "[name/range] - Search NPCs", 20, command_listnpcs) || @@ -388,6 +389,7 @@ int command_init(void) command_add("tattoo", "- Change the tattoo of your target (Drakkin Only)", 80, command_tattoo) || command_add("tempname", "[newname] - Temporarily renames your target. Leave name blank to restore the original name.", 100, command_tempname) || command_add("petname", "[newname] - Temporarily renames your pet. Leave name blank to restore the original name.", 100, command_petname) || + command_add("test", "Test command", 200, command_test) || command_add("texture", "[texture] [helmtexture] - Change your or your target's appearance, use 255 to show equipment", 10, command_texture) || command_add("time", "[HH] [MM] - Set EQ time", 90, command_time) || command_add("timers", "- Display persistent timers for target", 200, command_timers) || @@ -748,21 +750,21 @@ void command_serversidename(Client *c, const Seperator *sep) void command_wc(Client *c, const Seperator *sep) { - if(sep->argnum < 2) - { - c->Message(0, "Usage: #wc [wear slot] [material] [ [hero_forge_model] [elite_material] [unknown06] [unknown18] ]"); + if (sep->argnum < 2) { + c->Message( + 0, + "Usage: #wc [wear slot] [material] [ [hero_forge_model] [elite_material] [unknown06] [unknown18] ]" + ); } - else if(c->GetTarget() == nullptr) { + else if (c->GetTarget() == nullptr) { c->Message(13, "You must have a target to do a wear change."); } - else - { + else { uint32 hero_forge_model = 0; - uint32 wearslot = atoi(sep->arg[1]); + uint32 wearslot = atoi(sep->arg[1]); // Hero Forge - if (sep->argnum > 2) - { + if (sep->argnum > 2) { hero_forge_model = atoi(sep->arg[3]); if (hero_forge_model != 0 && hero_forge_model < 1000) { @@ -778,45 +780,43 @@ void command_wc(Client *c, const Seperator *sep) else Color = c->GetTarget()->GetArmorTint(atoi(sep->arg[1])); */ - c->GetTarget()->SendTextureWC(wearslot, atoi(sep->arg[2]), hero_forge_model, atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6])); + c->GetTarget()->SendTextureWC( + wearslot, + atoi(sep->arg[2]), + hero_forge_model, + atoi(sep->arg[4]), + atoi(sep->arg[5]), + atoi(sep->arg[6])); } } void command_heromodel(Client *c, const Seperator *sep) { - if (sep->argnum < 1) - { + if (sep->argnum < 1) { c->Message(0, "Usage: #heromodel [hero forge model] [ [slot] ] (example: #heromodel 63)"); } - else if (c->GetTarget() == nullptr) - { + else if (c->GetTarget() == nullptr) { c->Message(13, "You must have a target to do a wear change for Hero's Forge Models."); } - else - { + else { uint32 hero_forge_model = atoi(sep->arg[1]); - if (sep->argnum > 1) - { - uint8 wearslot = (uint8)atoi(sep->arg[2]); + if (sep->argnum > 1) { + uint8 wearslot = (uint8) atoi(sep->arg[2]); c->GetTarget()->SendTextureWC(wearslot, 0, hero_forge_model, 0, 0, 0); } - else - { - if (hero_forge_model > 0) - { + else { + if (hero_forge_model > 0) { // Conversion to simplify the command arguments // Hero's Forge model is actually model * 1000 + texture * 100 + wearslot // Hero's Forge Model slot 7 is actually for Robes, but it still needs to use wearslot 1 in the packet hero_forge_model *= 100; - for (uint8 wearslot = 0; wearslot < 7; wearslot++) - { + for (uint8 wearslot = 0; wearslot < 7; wearslot++) { c->GetTarget()->SendTextureWC(wearslot, 0, (hero_forge_model + wearslot), 0, 0, 0); } } - else - { + else { c->Message(13, "Hero's Forge Model must be greater than 0."); } } @@ -827,12 +827,14 @@ void command_setanim(Client *c, const Seperator *sep) { if (c->GetTarget() && sep->IsNumber(1)) { int num = atoi(sep->arg[1]); - if(num < 0 || num >= _eaMaxAppearance) { - c->Message(0, "Invalid animation number, between 0 and %d", _eaMaxAppearance-1); + if (num < 0 || num >= _eaMaxAppearance) { + c->Message(0, "Invalid animation number, between 0 and %d", _eaMaxAppearance - 1); } c->GetTarget()->SetAppearance(EmuAppearance(num)); - } else + } + else { c->Message(0, "Usage: #setanim [animnum]"); + } } void command_serverinfo(Client *c, const Seperator *sep) @@ -2728,18 +2730,21 @@ void command_setskillall(Client *c, const Seperator *sep) void command_race(Client *c, const Seperator *sep) { - Mob *t=c->CastToMob(); + Mob *target = c->CastToMob(); if (sep->IsNumber(1)) { auto race = atoi(sep->arg[1]); if ((race >= 0 && race <= 732) || (race >= 2253 && race <= 2259)) { - if ((c->GetTarget()) && c->Admin() >= commandRaceOthers) - t = c->GetTarget(); - t->SendIllusionPacket(race); - } else { + if ((c->GetTarget()) && c->Admin() >= commandRaceOthers) { + target = c->GetTarget(); + } + target->SendIllusionPacket(race); + } + else { c->Message(0, "Usage: #race [0-732, 2253-2259] (0 for back to normal)"); } - } else { + } + else { c->Message(0, "Usage: #race [0-732, 2253-2259] (0 for back to normal)"); } } @@ -2817,6 +2822,21 @@ void command_spawn(Client *c, const Seperator *sep) } } +void command_test(Client *c, const Seperator *sep) +{ + c->Message(15, "Triggering test command"); + + // EQEmu::ItemInstance* fake_weapon_secondary = database.CreateItem(static_cast(c->GetItemIDAt(EQEmu::invslot::slotSecondary))); + // fake_weapon_secondary->SetNewIDFile(c->GetEquipmentMaterial(EQEmu::textures::weaponSecondary)); + // c->SendItemPacket(EQEmu::invslot::slotSecondary, fake_weapon_secondary, ItemPacketTrade); + // safe_delete(fake_weapon_secondary); + + EQEmu::ItemInstance* fake_weapon = database.CreateItem(static_cast(c->GetItemIDAt(EQEmu::invslot::slotPrimary))); + fake_weapon->SetNewIDFile(c->GetEquipmentMaterial(EQEmu::textures::weaponPrimary)); + c->SendItemPacket(EQEmu::invslot::slotPrimary, fake_weapon, ItemPacketTrade); + safe_delete(fake_weapon); +} + void command_texture(Client *c, const Seperator *sep) { @@ -5111,6 +5131,41 @@ void command_kill(Client *c, const Seperator *sep) c->GetTarget()->Kill(); } +void command_killallnpcs(Client *c, const Seperator *sep) +{ + std::string search_string; + if (sep->arg[1]) { + search_string = sep->arg[1]; + } + + int count = 0; + for (auto &itr : entity_list.GetMobList()) { + Mob *entity = itr.second; + if (!entity->IsNPC()) { + continue; + } + + std::string entity_name = entity->GetName(); + + /** + * Filter by name + */ + if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) { + continue; + } + + if (entity->IsInvisible() || !entity->IsAttackAllowed(c)) { + continue; + } + + entity->Damage(c, 1000000000, 0, EQEmu::skills::SkillDragonPunch); + + count++; + } + + c->Message(15, "Killed (%i) npc(s)", count); +} + void command_haste(Client *c, const Seperator *sep) { // #haste command to set client attack speed. Takes a percentage (100 = twice normal attack speed) diff --git a/zone/command.h b/zone/command.h index 1c4b21529..0a4eec014 100644 --- a/zone/command.h +++ b/zone/command.h @@ -149,6 +149,7 @@ void command_iteminfo(Client *c, const Seperator *sep); void command_itemsearch(Client *c, const Seperator *sep); void command_itemtest(Client *c, const Seperator *sep); void command_kick(Client *c, const Seperator *sep); +void command_killallnpcs(Client *c, const Seperator *sep); void command_kill(Client *c, const Seperator *sep); void command_lastname(Client *c, const Seperator *sep); void command_level(Client *c, const Seperator *sep); @@ -297,6 +298,7 @@ void command_task(Client *c, const Seperator *sep); void command_tattoo(Client *c, const Seperator *sep); void command_tempname(Client *c, const Seperator *sep); void command_petname(Client *c, const Seperator *sep); +void command_test(Client *c, const Seperator *sep); void command_testspawn(Client *c, const Seperator *sep); void command_testspawnkill(Client *c, const Seperator *sep); void command_texture(Client *c, const Seperator *sep); diff --git a/zone/corpse.cpp b/zone/corpse.cpp index c31a9a5d2..dd362fedb 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -1479,7 +1479,7 @@ void Corpse::Spawn() { safe_delete(app); } -uint32 Corpse::GetEquipment(uint8 material_slot) const { +uint32 Corpse::GetEquippedItemFromTextureSlot(uint8 material_slot) const { int16 invslot; if (material_slot > EQEmu::textures::LastTexture) { @@ -1500,7 +1500,7 @@ uint32 Corpse::GetEquipmentColor(uint8 material_slot) const { return 0; } - item = database.GetItem(GetEquipment(material_slot)); + item = database.GetItem(GetEquippedItemFromTextureSlot(material_slot)); if(item != 0) { return (item_tint.Slot[material_slot].UseTint ? item_tint.Slot[material_slot].Color : item->Color); } diff --git a/zone/corpse.h b/zone/corpse.h index ff323e791..e7a7c5805 100644 --- a/zone/corpse.h +++ b/zone/corpse.h @@ -126,7 +126,7 @@ class Corpse : public Mob { void Spawn(); char corpse_name[64]; - uint32 GetEquipment(uint8 material_slot) const; + uint32 GetEquippedItemFromTextureSlot(uint8 material_slot) const; uint32 GetEquipmentColor(uint8 material_slot) const; inline int GetRezExp() { return rez_experience; } diff --git a/zone/entity.cpp b/zone/entity.cpp index c2201f97b..e288493f8 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1274,32 +1274,35 @@ void EntityList::SendZoneSpawns(Client *client) void EntityList::SendZoneSpawnsBulk(Client *client) { - NewSpawn_Struct ns; - Mob *spawn; - uint32 maxspawns = 100; + NewSpawn_Struct ns{}; + Mob *spawn; EQApplicationPacket *app; - if (maxspawns > mob_list.size()) - maxspawns = mob_list.size(); - auto bzsp = new BulkZoneSpawnPacket(client, maxspawns); + uint32 max_spawns = 100; + + if (max_spawns > mob_list.size()) { + max_spawns = static_cast(mob_list.size()); + } + + auto bulk_zone_spawn_packet = new BulkZoneSpawnPacket(client, max_spawns); + const glm::vec4 &client_position = client->GetPosition(); + const float distance_max = (600.0 * 600.0); - bool delaypkt = false; - const glm::vec4& cpos = client->GetPosition(); - const float dmax = 600.0 * 600.0; for (auto it = mob_list.begin(); it != mob_list.end(); ++it) { spawn = it->second; if (spawn && spawn->GetID() > 0 && spawn->Spawned()) { - if (!spawn->ShouldISpawnFor(client)) + if (!spawn->ShouldISpawnFor(client)) { continue; + } -#if 1 - const glm::vec4& spos = spawn->GetPosition(); + const glm::vec4 &spawn_position = spawn->GetPosition(); - delaypkt = false; - if (DistanceSquared(cpos, spos) > dmax || (spawn->IsClient() && (spawn->GetRace() == MINOR_ILL_OBJ || spawn->GetRace() == TREE))) - delaypkt = true; + bool is_delayed_packet = ( + DistanceSquared(client_position, spawn_position) > distance_max || + (spawn->IsClient() && (spawn->GetRace() == MINOR_ILL_OBJ || spawn->GetRace() == TREE)) + ); - if (delaypkt) { + if (is_delayed_packet) { app = new EQApplicationPacket; spawn->CreateSpawnPacket(app); client->QueuePacket(app, true, Client::CLIENT_CONNECTED); @@ -1308,35 +1311,38 @@ void EntityList::SendZoneSpawnsBulk(Client *client) else { memset(&ns, 0, sizeof(NewSpawn_Struct)); spawn->FillSpawnStruct(&ns, client); - bzsp->AddSpawn(&ns); + bulk_zone_spawn_packet->AddSpawn(&ns); } spawn->SendArmorAppearance(client); -#else - /* original code kept for spawn packet research */ - int32 race = spawn->GetRace(); - - // Illusion races on PCs don't work as a mass spawn - // But they will work as an add_spawn AFTER CLIENT_CONNECTED. - if (spawn->IsClient() && (race == MINOR_ILL_OBJ || race == TREE)) { - app = new EQApplicationPacket; - spawn->CreateSpawnPacket(app); - client->QueuePacket(app, true, Client::CLIENT_CONNECTED); - safe_delete(app); - } - else { - memset(&ns, 0, sizeof(NewSpawn_Struct)); - spawn->FillSpawnStruct(&ns, client); - bzsp->AddSpawn(&ns); - } - // Despite being sent in the OP_ZoneSpawns packet, the client - // does not display worn armor correctly so display it. - spawn->SendArmorAppearance(client); -#endif + /** + * Original code kept for spawn packet research + * + * int32 race = spawn->GetRace(); + * + * Illusion races on PCs don't work as a mass spawn + * But they will work as an add_spawn AFTER CLIENT_CONNECTED. + * if (spawn->IsClient() && (race == MINOR_ILL_OBJ || race == TREE)) { + * app = new EQApplicationPacket; + * spawn->CreateSpawnPacket(app); + * client->QueuePacket(app, true, Client::CLIENT_CONNECTED); + * safe_delete(app); + * } + * else { + * memset(&ns, 0, sizeof(NewSpawn_Struct)); + * spawn->FillSpawnStruct(&ns, client); + * bzsp->AddSpawn(&ns); + * } + * + * Despite being sent in the OP_ZoneSpawns packet, the client + * does not display worn armor correctly so display it. + * spawn->SendArmorAppearance(client); + */ } } - safe_delete(bzsp); + + safe_delete(bulk_zone_spawn_packet); } //this is a hack to handle a broken spawn struct @@ -3967,8 +3973,9 @@ Mob *EntityList::GetTargetForMez(Mob *caster) void EntityList::SendZoneAppearance(Client *c) { - if (!c) + if (!c) { return; + } auto it = mob_list.begin(); while (it != mob_list.end()) { @@ -3983,7 +3990,7 @@ void EntityList::SendZoneAppearance(Client *c) cur->SendAppearancePacket(AT_Anim, cur->GetAppearanceValue(cur->GetAppearance()), false, true, c); } if (cur->GetSize() != cur->GetBaseSize()) { - cur->SendAppearancePacket(AT_Size, (uint32)cur->GetSize(), false, true, c); + cur->SendAppearancePacket(AT_Size, (uint32) cur->GetSize(), false, true, c); } } ++it; diff --git a/zone/horse.cpp b/zone/horse.cpp index 9f5c9b4d3..6c81b3d21 100644 --- a/zone/horse.cpp +++ b/zone/horse.cpp @@ -90,7 +90,7 @@ const NPCType *Horse::BuildHorseType(uint16 spell_id) { strcpy(npc_type->name, "Unclaimed_Mount"); // this should never get used strcpy(npc_type->special_abilities, "19,1^20,1^24,1"); - npc_type->cur_hp = 1; + npc_type->current_hp = 1; npc_type->max_hp = 1; npc_type->race = atoi(row[0]); npc_type->gender = atoi(row[1]); // Drogmor's are female horses. Yuck. diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 24fa86b30..7e9f2d9a1 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -2858,26 +2858,24 @@ void Client::MoveSlotNotAllowed(bool client_update) } // these functions operate with a material slot, which is from 0 to 8 -uint32 Client::GetEquipment(uint8 material_slot) const +uint32 Client::GetEquippedItemFromTextureSlot(uint8 material_slot) const { - int16 invslot; + int16 inventory_slot; + const EQEmu::ItemInstance *item; - if(material_slot > EQEmu::textures::LastTexture) - { + if (material_slot > EQEmu::textures::LastTexture) { return 0; } - invslot = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot); - if (invslot == INVALID_INDEX) - { + inventory_slot = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot); + if (inventory_slot == INVALID_INDEX) { return 0; } - item = m_inv.GetItem(invslot); + item = m_inv.GetItem(inventory_slot); - if(item && item->GetItem()) - { + if (item && item->GetItem()) { return item->GetItem()->ID; } @@ -2904,7 +2902,7 @@ uint32 Client::GetEquipmentColor(uint8 material_slot) const if (material_slot > EQEmu::textures::LastTexture) return 0; - const EQEmu::ItemData *item = database.GetItem(GetEquipment(material_slot)); + const EQEmu::ItemData *item = database.GetItem(GetEquippedItemFromTextureSlot(material_slot)); if(item != nullptr) return ((m_pp.item_tint.Slot[material_slot].UseTint) ? m_pp.item_tint.Slot[material_slot].Color : item->Color); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index f94194754..fdb3facc9 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -1413,7 +1413,7 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float luabind::adl::index_proxy cur = table["name"]; LuaCreateNPCParseString(name, 64, "_"); LuaCreateNPCParseString(lastname, 64, ""); - LuaCreateNPCParse(cur_hp, int32, 30); + LuaCreateNPCParse(current_hp, int32, 30); LuaCreateNPCParse(max_hp, int32, 30); LuaCreateNPCParse(size, float, 6.0f); LuaCreateNPCParse(runspeed, float, 1.25f); diff --git a/zone/merc.cpp b/zone/merc.cpp index f26531ccf..b33cade34 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -859,14 +859,14 @@ int32 Merc::CalcMaxHP() { max_hp += max_hp * ((spellbonuses.MaxHPChange + itembonuses.MaxHPChange) / 10000.0f); - if (cur_hp > max_hp) - cur_hp = max_hp; + if (current_hp > max_hp) + current_hp = max_hp; int hp_perc_cap = spellbonuses.HPPercCap[0]; if(hp_perc_cap) { int curHP_cap = (max_hp * hp_perc_cap) / 100; - if (cur_hp > curHP_cap || (spellbonuses.HPPercCap[1] && cur_hp > spellbonuses.HPPercCap[1])) - cur_hp = curHP_cap; + if (current_hp > curHP_cap || (spellbonuses.HPPercCap[1] && current_hp > spellbonuses.HPPercCap[1])) + current_hp = curHP_cap; } return max_hp; @@ -4949,7 +4949,7 @@ void Merc::ScaleStats(int scalepercent, bool setmax) { max_hp = (int)((float)base_hp * scalerate); base_hp = max_hp; if (setmax) - cur_hp = max_hp; + current_hp = max_hp; } if (base_mana) diff --git a/zone/mob.cpp b/zone/mob.cpp index d38121b06..a8eeb996a 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -140,7 +140,7 @@ Mob::Mob( if (in_lastname) { strn0cpy(lastname, in_lastname, 64); } - cur_hp = in_cur_hp; + current_hp = in_cur_hp; max_hp = in_max_hp; base_hp = in_max_hp; gender = in_gender; @@ -265,7 +265,7 @@ Mob::Mob( hidden = false; improved_hidden = false; invulnerable = false; - IsFullHP = (cur_hp == max_hp); + IsFullHP = (current_hp == max_hp); qglobal = 0; spawned = false; rare_spawn = false; @@ -935,77 +935,76 @@ uint8 Mob::GetArchetype() const { } } -void Mob::CreateSpawnPacket(EQApplicationPacket* app, Mob* ForWho) { +void Mob::CreateSpawnPacket(EQApplicationPacket *app, Mob *ForWho) +{ app->SetOpcode(OP_NewSpawn); - app->size = sizeof(NewSpawn_Struct); + app->size = sizeof(NewSpawn_Struct); app->pBuffer = new uchar[app->size]; memset(app->pBuffer, 0, app->size); - NewSpawn_Struct* ns = (NewSpawn_Struct*)app->pBuffer; + NewSpawn_Struct *ns = (NewSpawn_Struct *) app->pBuffer; FillSpawnStruct(ns, ForWho); - if(RuleB(NPC, UseClassAsLastName) && strlen(ns->spawn.lastName) == 0) - { - switch(ns->spawn.class_) - { - case TRIBUTE_MASTER: - strcpy(ns->spawn.lastName, "Tribute Master"); - break; - case ADVENTURERECRUITER: - strcpy(ns->spawn.lastName, "Adventure Recruiter"); - break; - case BANKER: - strcpy(ns->spawn.lastName, "Banker"); - break; - case ADVENTUREMERCHANT: - strcpy(ns->spawn.lastName,"Adventure Merchant"); - break; - case WARRIORGM: - strcpy(ns->spawn.lastName, "GM Warrior"); - break; - case PALADINGM: - strcpy(ns->spawn.lastName, "GM Paladin"); - break; - case RANGERGM: - strcpy(ns->spawn.lastName, "GM Ranger"); - break; - case SHADOWKNIGHTGM: - strcpy(ns->spawn.lastName, "GM Shadowknight"); - break; - case DRUIDGM: - strcpy(ns->spawn.lastName, "GM Druid"); - break; - case BARDGM: - strcpy(ns->spawn.lastName, "GM Bard"); - break; - case ROGUEGM: - strcpy(ns->spawn.lastName, "GM Rogue"); - break; - case SHAMANGM: - strcpy(ns->spawn.lastName, "GM Shaman"); - break; - case NECROMANCERGM: - strcpy(ns->spawn.lastName, "GM Necromancer"); - break; - case WIZARDGM: - strcpy(ns->spawn.lastName, "GM Wizard"); - break; - case MAGICIANGM: - strcpy(ns->spawn.lastName, "GM Magician"); - break; - case ENCHANTERGM: - strcpy(ns->spawn.lastName, "GM Enchanter"); - break; - case BEASTLORDGM: - strcpy(ns->spawn.lastName, "GM Beastlord"); - break; - case BERSERKERGM: - strcpy(ns->spawn.lastName, "GM Berserker"); - break; - case MERCERNARY_MASTER: - strcpy(ns->spawn.lastName, "Mercenary Recruiter"); - break; - default: - break; + if (RuleB(NPC, UseClassAsLastName) && strlen(ns->spawn.lastName) == 0) { + switch (ns->spawn.class_) { + case TRIBUTE_MASTER: + strcpy(ns->spawn.lastName, "Tribute Master"); + break; + case ADVENTURERECRUITER: + strcpy(ns->spawn.lastName, "Adventure Recruiter"); + break; + case BANKER: + strcpy(ns->spawn.lastName, "Banker"); + break; + case ADVENTUREMERCHANT: + strcpy(ns->spawn.lastName, "Adventure Merchant"); + break; + case WARRIORGM: + strcpy(ns->spawn.lastName, "GM Warrior"); + break; + case PALADINGM: + strcpy(ns->spawn.lastName, "GM Paladin"); + break; + case RANGERGM: + strcpy(ns->spawn.lastName, "GM Ranger"); + break; + case SHADOWKNIGHTGM: + strcpy(ns->spawn.lastName, "GM Shadowknight"); + break; + case DRUIDGM: + strcpy(ns->spawn.lastName, "GM Druid"); + break; + case BARDGM: + strcpy(ns->spawn.lastName, "GM Bard"); + break; + case ROGUEGM: + strcpy(ns->spawn.lastName, "GM Rogue"); + break; + case SHAMANGM: + strcpy(ns->spawn.lastName, "GM Shaman"); + break; + case NECROMANCERGM: + strcpy(ns->spawn.lastName, "GM Necromancer"); + break; + case WIZARDGM: + strcpy(ns->spawn.lastName, "GM Wizard"); + break; + case MAGICIANGM: + strcpy(ns->spawn.lastName, "GM Magician"); + break; + case ENCHANTERGM: + strcpy(ns->spawn.lastName, "GM Enchanter"); + break; + case BEASTLORDGM: + strcpy(ns->spawn.lastName, "GM Beastlord"); + break; + case BERSERKERGM: + strcpy(ns->spawn.lastName, "GM Berserker"); + break; + case MERCERNARY_MASTER: + strcpy(ns->spawn.lastName, "Mercenary Recruiter"); + break; + default: + break; } } } @@ -1269,7 +1268,7 @@ void Mob::CreateDespawnPacket(EQApplicationPacket* app, bool Decay) void Mob::CreateHPPacket(EQApplicationPacket* app) { - this->IsFullHP=(cur_hp>=max_hp); + this->IsFullHP=(current_hp>=max_hp); app->SetOpcode(OP_MobHealth); app->size = sizeof(SpawnHPUpdate_Struct2); app->pBuffer = new uchar[app->size]; @@ -1312,7 +1311,7 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal * If our HP is different from last HP update call - let's update selves */ if (IsClient()) { - if (cur_hp != last_hp || force_update_all) { + if (current_hp != last_hp || force_update_all) { /** * This is to prevent excessive packet sending under trains/fast combat @@ -1321,17 +1320,16 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal Log(Logs::General, Logs::HP_Update, "Mob::SendHPUpdate :: Update HP of self (%s) HP: %i last: %i skip_self: %s", this->GetCleanName(), - cur_hp, + current_hp, last_hp, (skip_self ? "true" : "false") ); if (!skip_self || this->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) { - auto client_packet = new EQApplicationPacket(OP_HPUpdate, sizeof(SpawnHPUpdate_Struct)); + auto client_packet = new EQApplicationPacket(OP_HPUpdate, sizeof(SpawnHPUpdate_Struct)); + auto *hp_packet_client = (SpawnHPUpdate_Struct *) client_packet->pBuffer; - SpawnHPUpdate_Struct *hp_packet_client = (SpawnHPUpdate_Struct *) client_packet->pBuffer; - - hp_packet_client->cur_hp = CastToClient()->GetHP() - itembonuses.HP; + hp_packet_client->cur_hp = static_cast(CastToClient()->GetHP() - itembonuses.HP); hp_packet_client->spawn_id = GetID(); hp_packet_client->max_hp = CastToClient()->GetMaxHP() - itembonuses.HP; @@ -1345,12 +1343,12 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal /** * Used to check if HP has changed to update self next round */ - last_hp = cur_hp; + last_hp = current_hp; } } } - int8 current_hp_percent = (max_hp == 0 ? 0 : static_cast(cur_hp * 100 / max_hp)); + int8 current_hp_percent = static_cast(max_hp == 0 ? 0 : static_cast(current_hp * 100 / max_hp)); Log(Logs::General, Logs::HP_Update, @@ -1680,129 +1678,171 @@ void Mob::GMMove(float x, float y, float z, float heading, bool SendUpdate) { } } -void Mob::SendIllusionPacket(uint16 in_race, uint8 in_gender, uint8 in_texture, uint8 in_helmtexture, uint8 in_haircolor, uint8 in_beardcolor, uint8 in_eyecolor1, uint8 in_eyecolor2, uint8 in_hairstyle, uint8 in_luclinface, uint8 in_beard, uint8 in_aa_title, uint32 in_drakkin_heritage, uint32 in_drakkin_tattoo, uint32 in_drakkin_details, float in_size) { +void Mob::SendIllusionPacket( + uint16 in_race, + uint8 in_gender, + uint8 in_texture, + uint8 in_helmtexture, + uint8 in_haircolor, + uint8 in_beardcolor, + uint8 in_eyecolor1, + uint8 in_eyecolor2, + uint8 in_hairstyle, + uint8 in_luclinface, + uint8 in_beard, + uint8 in_aa_title, + uint32 in_drakkin_heritage, + uint32 in_drakkin_tattoo, + uint32 in_drakkin_details, + float in_size +) +{ uint16 BaseRace = GetBaseRace(); - if (in_race == 0) - { + if (in_race == 0) { race = BaseRace; - if (in_gender == 0xFF) + if (in_gender == 0xFF) { gender = GetBaseGender(); - else + } + else { gender = in_gender; + } } - else - { + else { race = in_race; - if (in_gender == 0xFF) + if (in_gender == 0xFF) { gender = GetDefaultGender(race, gender); - else + } + else { gender = in_gender; + } } - if (in_texture == 0xFF) - { - if (IsPlayerRace(in_race)) + if (in_texture == 0xFF) { + if (IsPlayerRace(in_race)) { texture = 0xFF; - else + } + else { texture = GetTexture(); + } } - else - { + else { texture = in_texture; } - if (in_helmtexture == 0xFF) - { - if (IsPlayerRace(in_race)) + if (in_helmtexture == 0xFF) { + if (IsPlayerRace(in_race)) { helmtexture = 0xFF; - else if (in_texture != 0xFF) + } + else if (in_texture != 0xFF) { helmtexture = in_texture; - else + } + else { helmtexture = GetHelmTexture(); + } } - else - { + else { helmtexture = in_helmtexture; } - if (in_haircolor == 0xFF) + if (in_haircolor == 0xFF) { haircolor = GetHairColor(); - else + } + else { haircolor = in_haircolor; + } - if (in_beardcolor == 0xFF) + if (in_beardcolor == 0xFF) { beardcolor = GetBeardColor(); - else + } + else { beardcolor = in_beardcolor; + } - if (in_eyecolor1 == 0xFF) + if (in_eyecolor1 == 0xFF) { eyecolor1 = GetEyeColor1(); - else + } + else { eyecolor1 = in_eyecolor1; + } - if (in_eyecolor2 == 0xFF) + if (in_eyecolor2 == 0xFF) { eyecolor2 = GetEyeColor2(); - else + } + else { eyecolor2 = in_eyecolor2; + } - if (in_hairstyle == 0xFF) + if (in_hairstyle == 0xFF) { hairstyle = GetHairStyle(); - else + } + else { hairstyle = in_hairstyle; + } - if (in_luclinface == 0xFF) + if (in_luclinface == 0xFF) { luclinface = GetLuclinFace(); - else + } + else { luclinface = in_luclinface; + } - if (in_beard == 0xFF) + if (in_beard == 0xFF) { beard = GetBeard(); - else + } + else { beard = in_beard; + } aa_title = in_aa_title; - if (in_drakkin_heritage == 0xFFFFFFFF) + if (in_drakkin_heritage == 0xFFFFFFFF) { drakkin_heritage = GetDrakkinHeritage(); - else + } + else { drakkin_heritage = in_drakkin_heritage; + } - if (in_drakkin_tattoo == 0xFFFFFFFF) + if (in_drakkin_tattoo == 0xFFFFFFFF) { drakkin_tattoo = GetDrakkinTattoo(); - else + } + else { drakkin_tattoo = in_drakkin_tattoo; + } - if (in_drakkin_details == 0xFFFFFFFF) + if (in_drakkin_details == 0xFFFFFFFF) { drakkin_details = GetDrakkinDetails(); - else + } + else { drakkin_details = in_drakkin_details; + } - if (in_size <= 0.0f) + if (in_size <= 0.0f) { size = GetSize(); - else + } + else { size = in_size; + } // Reset features to Base from the Player Profile - if (IsClient() && in_race == 0) - { - race = CastToClient()->GetBaseRace(); - gender = CastToClient()->GetBaseGender(); - texture = 0xFF; - helmtexture = 0xFF; - haircolor = CastToClient()->GetBaseHairColor(); - beardcolor = CastToClient()->GetBaseBeardColor(); - eyecolor1 = CastToClient()->GetBaseEyeColor(); - eyecolor2 = CastToClient()->GetBaseEyeColor(); - hairstyle = CastToClient()->GetBaseHairStyle(); - luclinface = CastToClient()->GetBaseFace(); - beard = CastToClient()->GetBaseBeard(); - aa_title = 0xFF; + if (IsClient() && in_race == 0) { + race = CastToClient()->GetBaseRace(); + gender = CastToClient()->GetBaseGender(); + texture = 0xFF; + helmtexture = 0xFF; + haircolor = CastToClient()->GetBaseHairColor(); + beardcolor = CastToClient()->GetBaseBeardColor(); + eyecolor1 = CastToClient()->GetBaseEyeColor(); + eyecolor2 = CastToClient()->GetBaseEyeColor(); + hairstyle = CastToClient()->GetBaseHairStyle(); + luclinface = CastToClient()->GetBaseFace(); + beard = CastToClient()->GetBaseBeard(); + aa_title = 0xFF; drakkin_heritage = CastToClient()->GetBaseHeritage(); - drakkin_tattoo = CastToClient()->GetBaseTattoo(); - drakkin_details = CastToClient()->GetBaseDetails(); - switch(race){ + drakkin_tattoo = CastToClient()->GetBaseTattoo(); + drakkin_details = CastToClient()->GetBaseDetails(); + switch (race) { case OGRE: size = 9; break; @@ -1832,25 +1872,25 @@ void Mob::SendIllusionPacket(uint16 in_race, uint8 in_gender, uint8 in_texture, } } - auto outapp = new EQApplicationPacket(OP_Illusion, sizeof(Illusion_Struct)); - Illusion_Struct* is = (Illusion_Struct*) outapp->pBuffer; + auto outapp = new EQApplicationPacket(OP_Illusion, sizeof(Illusion_Struct)); + Illusion_Struct *is = (Illusion_Struct *) outapp->pBuffer; is->spawnid = GetID(); strcpy(is->charname, GetCleanName()); - is->race = race; - is->gender = gender; - is->texture = texture; - is->helmtexture = helmtexture; - is->haircolor = haircolor; - is->beardcolor = beardcolor; - is->beard = beard; - is->eyecolor1 = eyecolor1; - is->eyecolor2 = eyecolor2; - is->hairstyle = hairstyle; - is->face = luclinface; + is->race = race; + is->gender = gender; + is->texture = texture; + is->helmtexture = helmtexture; + is->haircolor = haircolor; + is->beardcolor = beardcolor; + is->beard = beard; + is->eyecolor1 = eyecolor1; + is->eyecolor2 = eyecolor2; + is->hairstyle = hairstyle; + is->face = luclinface; is->drakkin_heritage = drakkin_heritage; - is->drakkin_tattoo = drakkin_tattoo; - is->drakkin_details = drakkin_details; - is->size = size; + is->drakkin_tattoo = drakkin_tattoo; + is->drakkin_details = drakkin_details; + is->size = size; entity_list.QueueClients(this, outapp); safe_delete(outapp); @@ -1858,8 +1898,23 @@ void Mob::SendIllusionPacket(uint16 in_race, uint8 in_gender, uint8 in_texture, /* Refresh armor and tints after send illusion packet */ this->SendArmorAppearance(); - Log(Logs::Detail, Logs::Spells, "Illusion: Race = %i, Gender = %i, Texture = %i, HelmTexture = %i, HairColor = %i, BeardColor = %i, EyeColor1 = %i, EyeColor2 = %i, HairStyle = %i, Face = %i, DrakkinHeritage = %i, DrakkinTattoo = %i, DrakkinDetails = %i, Size = %f", - race, gender, texture, helmtexture, haircolor, beardcolor, eyecolor1, eyecolor2, hairstyle, luclinface, drakkin_heritage, drakkin_tattoo, drakkin_details, size); + Log(Logs::Detail, + Logs::Spells, + "Illusion: Race = %i, Gender = %i, Texture = %i, HelmTexture = %i, HairColor = %i, BeardColor = %i, EyeColor1 = %i, EyeColor2 = %i, HairStyle = %i, Face = %i, DrakkinHeritage = %i, DrakkinTattoo = %i, DrakkinDetails = %i, Size = %f", + race, + gender, + texture, + helmtexture, + haircolor, + beardcolor, + eyecolor1, + eyecolor2, + hairstyle, + luclinface, + drakkin_heritage, + drakkin_tattoo, + drakkin_details, + size); } bool Mob::RandomizeFeatures(bool send_illusion, bool set_variables) @@ -2810,275 +2865,11 @@ uint32 Mob::RandomTimer(int min,int max) { return r; } -uint32 NPC::GetEquipment(uint8 material_slot) const -{ - if(material_slot > 8) - return 0; - int16 invslot = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot); - if (invslot == INVALID_INDEX) - return 0; - return equipment[invslot]; -} - -void Mob::SendArmorAppearance(Client *one_client) -{ - // one_client of 0 means sent to all clients - // - // Despite the fact that OP_NewSpawn and OP_ZoneSpawns include the - // armor being worn and its mats, the client doesn't update the display - // on arrival of these packets reliably. - // - // Send Wear changes if mob is a PC race and item is an armor slot. - // The other packets work for primary/secondary. - - if (IsPlayerRace(race)) - { - if (!IsClient()) - { - const EQEmu::ItemData *item = nullptr; - for (int i = 0; i < 7; ++i) - { - item = database.GetItem(GetEquipment(i)); - if (item != 0) - { - SendWearChange(i, one_client); - } - } - } - } -} - -void Mob::SendWearChange(uint8 material_slot, Client *one_client) -{ - auto outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct)); - WearChange_Struct* wc = (WearChange_Struct*)outapp->pBuffer; - - wc->spawn_id = GetID(); - wc->material = GetEquipmentMaterial(material_slot); - wc->elite_material = IsEliteMaterialItem(material_slot); - wc->hero_forge_model = GetHerosForgeModel(material_slot); - -#ifdef BOTS - if (IsBot()) { - auto item_inst = CastToBot()->GetBotItem(EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot)); - if (item_inst) - wc->color.Color = item_inst->GetColor(); - else - wc->color.Color = 0; - } - else { - wc->color.Color = GetEquipmentColor(material_slot); - } -#else - wc->color.Color = GetEquipmentColor(material_slot); -#endif - - wc->wear_slot_id = material_slot; - - if (!one_client) - { - entity_list.QueueClients(this, outapp); - } - else - { - one_client->QueuePacket(outapp, false, Client::CLIENT_CONNECTED); - } - - safe_delete(outapp); -} - -void Mob::SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model, uint32 elite_material, uint32 unknown06, uint32 unknown18) -{ - auto outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct)); - WearChange_Struct* wc = (WearChange_Struct*)outapp->pBuffer; - - wc->spawn_id = this->GetID(); - wc->material = texture; - if (this->IsClient()) - wc->color.Color = GetEquipmentColor(slot); - else - wc->color.Color = this->GetArmorTint(slot); - wc->wear_slot_id = slot; - - wc->unknown06 = unknown06; - wc->elite_material = elite_material; - wc->hero_forge_model = hero_forge_model; - wc->unknown18 = unknown18; - - - entity_list.QueueClients(this, outapp); - safe_delete(outapp); -} - -void Mob::SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint) -{ - uint32 color; - color = (red_tint & 0xFF) << 16; - color |= (green_tint & 0xFF) << 8; - color |= (blue_tint & 0xFF); - color |= (color) ? (0xFF << 24) : 0; - armor_tint.Slot[material_slot].Color = color; - - auto outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct)); - WearChange_Struct* wc = (WearChange_Struct*)outapp->pBuffer; - - wc->spawn_id = this->GetID(); - wc->material = GetEquipmentMaterial(material_slot); - wc->hero_forge_model = GetHerosForgeModel(material_slot); - wc->color.Color = color; - wc->wear_slot_id = material_slot; - - entity_list.QueueClients(this, outapp); - safe_delete(outapp); -} - -void Mob::WearChange(uint8 material_slot, uint16 texture, uint32 color, uint32 hero_forge_model) -{ - armor_tint.Slot[material_slot].Color = color; - - auto outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct)); - WearChange_Struct* wc = (WearChange_Struct*)outapp->pBuffer; - - wc->spawn_id = this->GetID(); - wc->material = texture; - wc->hero_forge_model = hero_forge_model; - wc->color.Color = color; - wc->wear_slot_id = material_slot; - - entity_list.QueueClients(this, outapp); - safe_delete(outapp); -} - -int32 Mob::GetEquipmentMaterial(uint8 material_slot) const -{ - uint32 equipmaterial = 0; - int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); - const EQEmu::ItemData *item = nullptr; - item = database.GetItem(GetEquipment(material_slot)); - - if (item != 0) - { - // For primary and secondary we need the model, not the material - if (material_slot == EQEmu::textures::weaponPrimary || material_slot == EQEmu::textures::weaponSecondary) - { - if (this->IsClient()) - { - int16 invslot = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot); - if (invslot == INVALID_INDEX) - { - return 0; - } - const EQEmu::ItemInstance* inst = CastToClient()->m_inv[invslot]; - if (inst) - { - if (inst->GetOrnamentationAug(ornamentationAugtype)) - { - item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem(); - if (item && strlen(item->IDFile) > 2) - { - equipmaterial = atoi(&item->IDFile[2]); - } - } - else if (inst->GetOrnamentationIDFile()) - { - equipmaterial = inst->GetOrnamentationIDFile(); - } - } - } - - if (equipmaterial == 0 && strlen(item->IDFile) > 2) - { - equipmaterial = atoi(&item->IDFile[2]); - } - } - else - { - equipmaterial = item->Material; - } - } - - return equipmaterial; -} - -int32 Mob::GetHerosForgeModel(uint8 material_slot) const -{ - uint32 HeroModel = 0; - if (material_slot >= 0 && material_slot < EQEmu::textures::weaponPrimary) - { - uint32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); - const EQEmu::ItemData *item = nullptr; - item = database.GetItem(GetEquipment(material_slot)); - int16 invslot = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot); - - if (item != 0 && invslot != INVALID_INDEX) - { - if (IsClient()) - { - const EQEmu::ItemInstance* inst = CastToClient()->m_inv[invslot]; - if (inst) - { - if (inst->GetOrnamentationAug(ornamentationAugtype)) - { - item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem(); - HeroModel = item->HerosForgeModel; - } - else if (inst->GetOrnamentHeroModel()) - { - HeroModel = inst->GetOrnamentHeroModel(); - } - } - } - - if (HeroModel == 0) - { - HeroModel = item->HerosForgeModel; - } - } - - if (IsNPC()) - { - HeroModel = CastToNPC()->GetHeroForgeModel(); - // Robes require full model number, and should only be sent to chest, arms, wrists, and legs slots - if (HeroModel > 1000 && material_slot != 1 && material_slot != 2 && material_slot != 3 && material_slot != 5) - { - HeroModel = 0; - } - } - } - - // Auto-Convert Hero Model to match the slot - // Otherwise, use the exact Model if model is > 999 - // Robes for example are 11607 to 12107 in RoF - if (HeroModel > 0 && HeroModel < 1000) - { - HeroModel *= 100; - HeroModel += material_slot; - } - - return HeroModel; -} - -uint32 Mob::GetEquipmentColor(uint8 material_slot) const -{ - const EQEmu::ItemData *item = nullptr; - - if (armor_tint.Slot[material_slot].Color) - { - return armor_tint.Slot[material_slot].Color; - } - - item = database.GetItem(GetEquipment(material_slot)); - if (item != 0) - return item->Color; - - return 0; -} - uint32 Mob::IsEliteMaterialItem(uint8 material_slot) const { const EQEmu::ItemData *item = nullptr; - item = database.GetItem(GetEquipment(material_slot)); + item = database.GetItem(GetEquippedItemFromTextureSlot(material_slot)); if(item != 0) { return item->EliteMaterial; @@ -3090,26 +2881,31 @@ uint32 Mob::IsEliteMaterialItem(uint8 material_slot) const // works just like a printf void Mob::Say(const char *format, ...) { - char buf[1000]; + char buf[1000]; va_list ap; va_start(ap, format); vsnprintf(buf, 1000, format, ap); va_end(ap); - Mob* talker = this; - if(spellbonuses.VoiceGraft != 0) { - if(spellbonuses.VoiceGraft == GetPetID()) + Mob *talker = this; + if (spellbonuses.VoiceGraft != 0) { + if (spellbonuses.VoiceGraft == GetPetID()) { talker = entity_list.GetMob(spellbonuses.VoiceGraft); - else + } + else { spellbonuses.VoiceGraft = 0; + } } - if(!talker) + if (!talker) { talker = this; + } - entity_list.MessageClose_StringID(talker, false, 200, 10, - GENERIC_SAY, GetCleanName(), buf); + entity_list.MessageClose_StringID( + talker, false, 200, 10, + GENERIC_SAY, GetCleanName(), buf + ); } // diff --git a/zone/mob.h b/zone/mob.h index 0fee32be4..56d6e5e4f 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -107,58 +107,59 @@ public: AuraMgr() : count(0) { } }; - Mob(const char* in_name, - const char* in_lastname, - int32 in_cur_hp, - int32 in_max_hp, - uint8 in_gender, - uint16 in_race, - uint8 in_class, - bodyType in_bodytype, - uint8 in_deity, - uint8 in_level, - uint32 in_npctype_id, - float in_size, - float in_runspeed, - const glm::vec4& position, - uint8 in_light, - uint8 in_texture, - uint8 in_helmtexture, - uint16 in_ac, - uint16 in_atk, - uint16 in_str, - uint16 in_sta, - uint16 in_dex, - uint16 in_agi, - uint16 in_int, - uint16 in_wis, - uint16 in_cha, - uint8 in_haircolor, - uint8 in_beardcolor, - uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye? - uint8 in_eyecolor2, - uint8 in_hairstyle, - uint8 in_luclinface, - uint8 in_beard, - uint32 in_drakkin_heritage, - uint32 in_drakkin_tattoo, - uint32 in_drakkin_details, - EQEmu::TintProfile in_armor_tint, - uint8 in_aa_title, - uint8 in_see_invis, // see through invis - uint8 in_see_invis_undead, // see through invis vs. undead - uint8 in_see_hide, - uint8 in_see_improved_hide, - int32 in_hp_regen, - int32 in_mana_regen, - uint8 in_qglobal, - uint8 in_maxlevel, - uint32 in_scalerate, - uint8 in_armtexture, - uint8 in_bracertexture, - uint8 in_handtexture, - uint8 in_legtexture, - uint8 in_feettexture + Mob( + const char *in_name, + const char *in_lastname, + int32 in_cur_hp, + int32 in_max_hp, + uint8 in_gender, + uint16 in_race, + uint8 in_class, + bodyType in_bodytype, + uint8 in_deity, + uint8 in_level, + uint32 in_npctype_id, + float in_size, + float in_runspeed, + const glm::vec4 &position, + uint8 in_light, + uint8 in_texture, + uint8 in_helmtexture, + uint16 in_ac, + uint16 in_atk, + uint16 in_str, + uint16 in_sta, + uint16 in_dex, + uint16 in_agi, + uint16 in_int, + uint16 in_wis, + uint16 in_cha, + uint8 in_haircolor, + uint8 in_beardcolor, + uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye? + uint8 in_eyecolor2, + uint8 in_hairstyle, + uint8 in_luclinface, + uint8 in_beard, + uint32 in_drakkin_heritage, + uint32 in_drakkin_tattoo, + uint32 in_drakkin_details, + EQEmu::TintProfile in_armor_tint, + uint8 in_aa_title, + uint8 in_see_invis, // see through invis + uint8 in_see_invis_undead, // see through invis vs. undead + uint8 in_see_hide, + uint8 in_see_improved_hide, + int32 in_hp_regen, + int32 in_mana_regen, + uint8 in_qglobal, + uint8 in_maxlevel, + uint32 in_scalerate, + uint8 in_armtexture, + uint8 in_bracertexture, + uint8 in_handtexture, + uint8 in_legtexture, + uint8 in_feettexture ); virtual ~Mob(); @@ -237,30 +238,43 @@ public: return; } - //Appearance - void SendLevelAppearance(); - void SendStunAppearance(); - void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5, - Client *specific_target=nullptr); - void SendTargetable(bool on, Client *specific_target = nullptr); - virtual void SendArmorAppearance(Client *one_client = nullptr); - virtual void SendWearChange(uint8 material_slot, Client *one_client = nullptr); - virtual void SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model = 0, uint32 elite_material = 0, - uint32 unknown06 = 0, uint32 unknown18 = 0); - virtual void SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint); - virtual void WearChange(uint8 material_slot, uint16 texture, uint32 color, uint32 hero_forge_model = 0); - void DoAnim(const int animnum, int type=0, bool ackreq = true, eqFilterType filter = FilterNone); - void ProjectileAnimation(Mob* to, int item_id, bool IsArrow = false, float speed = 0, - float angle = 0, float tilt = 0, float arc = 0, const char *IDFile = nullptr, EQEmu::skills::SkillType skillInUse = EQEmu::skills::SkillArchery); - void ChangeSize(float in_size, bool bNoRestriction = false); - inline uint8 SeeInvisible() const { return see_invis; } - inline bool SeeInvisibleUndead() const { return see_invis_undead; } + /** + ************************************************ + * Appearance + ************************************************ + */ + + EQEmu::InternalTextureProfile mob_texture_profile = {}; + + bool IsInvisible(Mob* other = 0) const; + + EQEmu::skills::SkillType AttackAnimation(int Hand, const EQEmu::ItemInstance* weapon, EQEmu::skills::SkillType skillinuse = EQEmu::skills::Skill1HBlunt); + + inline bool GetSeeInvisible(uint8 see_invis); inline bool SeeHide() const { return see_hide; } inline bool SeeImprovedHide() const { return see_improved_hide; } - inline bool GetSeeInvisible(uint8 see_invis); - bool IsInvisible(Mob* other = 0) const; + inline bool SeeInvisibleUndead() const { return see_invis_undead; } + inline uint8 SeeInvisible() const { return see_invis; } + + int32 GetTextureProfileMaterial(uint8 material_slot) const; + int32 GetTextureProfileColor(uint8 material_slot) const; + int32 GetTextureProfileHeroForgeModel(uint8 material_slot) const; + + virtual void SendArmorAppearance(Client *one_client = nullptr); + virtual void SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model = 0, uint32 elite_material = 0, uint32 unknown06 = 0, uint32 unknown18 = 0); + virtual void SendWearChange(uint8 material_slot, Client *one_client = nullptr); + virtual void SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint); + virtual void WearChange(uint8 material_slot, uint16 texture, uint32 color, uint32 hero_forge_model = 0); + + void ChangeSize(float in_size, bool bNoRestriction = false); + void DoAnim(const int animnum, int type=0, bool ackreq = true, eqFilterType filter = FilterNone); + void ProjectileAnimation(Mob* to, int item_id, bool IsArrow = false, float speed = 0, float angle = 0, float tilt = 0, float arc = 0, const char *IDFile = nullptr, EQEmu::skills::SkillType skillInUse = EQEmu::skills::SkillArchery); + void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5, Client *specific_target=nullptr); + void SendLevelAppearance(); + void SendStunAppearance(); + void SendTargetable(bool on, Client *specific_target = nullptr); void SetInvisible(uint8 state); - EQEmu::skills::SkillType AttackAnimation(int Hand, const EQEmu::ItemInstance* weapon, EQEmu::skills::SkillType skillinuse = EQEmu::skills::Skill1HBlunt); + void SetMobTextureProfile(uint8 material_slot, uint16 texture, uint32 color = 0, uint32 hero_forge_model = 0); //Song bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1); @@ -410,7 +424,7 @@ public: bool CanFacestab() { return can_facestab; } void SetFacestab(bool val) { can_facestab = val; } virtual uint16 GetSkill(EQEmu::skills::SkillType skill_num) const { return 0; } - virtual uint32 GetEquipment(uint8 material_slot) const { return(0); } + virtual uint32 GetEquippedItemFromTextureSlot(uint8 material_slot) const { return(0); } virtual int32 GetEquipmentMaterial(uint8 material_slot) const; virtual int32 GetHerosForgeModel(uint8 material_slot) const; virtual uint32 GetEquipmentColor(uint8 material_slot) const; @@ -420,12 +434,12 @@ public: virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) = 0; virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) = 0; - inline virtual void SetHP(int32 hp) { if (hp >= max_hp) cur_hp = max_hp; else cur_hp = hp;} + inline virtual void SetHP(int32 hp) { if (hp >= max_hp) current_hp = max_hp; else current_hp = hp;} bool ChangeHP(Mob* other, int32 amount, uint16 spell_id = 0, int8 buffslot = -1, bool iBuffTic = false); inline void SetOOCRegen(int32 newoocregen) {ooc_regen = newoocregen;} virtual void Heal(); virtual void HealDamage(uint32 ammount, Mob* caster = nullptr, uint16 spell_id = SPELL_UNKNOWN); - virtual void SetMaxHP() { cur_hp = max_hp; } + virtual void SetMaxHP() { current_hp = max_hp; } virtual inline uint16 GetBaseRace() const { return base_race; } virtual inline uint8 GetBaseGender() const { return base_gender; } virtual inline uint16 GetDeity() const { return deity; } @@ -471,8 +485,8 @@ public: inline Mob* GetTarget() const { return target; } virtual void SetTarget(Mob* mob); inline bool HasTargetReflection() const { return (target && target != this && target->target == this); } - virtual inline float GetHPRatio() const { return max_hp == 0 ? 0 : ((float)cur_hp/max_hp*100); } - virtual inline int GetIntHPRatio() const { return max_hp == 0 ? 0 : static_cast(cur_hp * 100 / max_hp); } + virtual inline float GetHPRatio() const { return max_hp == 0 ? 0 : ((float)current_hp/max_hp*100); } + virtual inline int GetIntHPRatio() const { return max_hp == 0 ? 0 : static_cast(current_hp * 100 / max_hp); } inline int32 GetAC() const { return AC; } inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK; } inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; } @@ -521,7 +535,7 @@ public: inline virtual int32 GetMaxCR() const { return 255; } inline virtual int32 GetMaxFR() const { return 255; } inline virtual int32 GetDelayDeath() const { return 0; } - inline int32 GetHP() const { return cur_hp; } + inline int32 GetHP() const { return current_hp; } inline int32 GetMaxHP() const { return max_hp; } virtual int32 CalcMaxHP(); inline int32 GetMaxMana() const { return max_mana; } @@ -1231,7 +1245,7 @@ protected: int targeted; bool findable; bool trackable; - int32 cur_hp; + int32 current_hp; int32 max_hp; int32 base_hp; int32 current_mana; diff --git a/zone/mob_appearance.cpp b/zone/mob_appearance.cpp new file mode 100644 index 000000000..85894994b --- /dev/null +++ b/zone/mob_appearance.cpp @@ -0,0 +1,544 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2018 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "../common/eqemu_logsys.h" + +#include "../common/misc_functions.h" +#include "../common/spdat.h" +#include "../common/string_util.h" + +#include "mob.h" +#include "quest_parser_collection.h" +#include "zonedb.h" + +/** + * Stores internal representation of mob texture by material slot + * + * @param material_slot + * @param texture + * @param color + * @param hero_forge_model + */ +void Mob::SetMobTextureProfile(uint8 material_slot, uint16 texture, uint32 color, uint32 hero_forge_model) +{ + Log(Logs::Detail, Logs::MobAppearance, + "Mob::SetMobTextureProfile [%s] material_slot: %u texture: %u color: %u hero_forge_model: %u", + this->GetCleanName(), + material_slot, + texture, + color, + hero_forge_model + ); + + switch (material_slot) { + case EQEmu::textures::armorHead: + mob_texture_profile.Head.Material = texture; + mob_texture_profile.Head.HerosForgeModel = hero_forge_model; + mob_texture_profile.Head.Color = color; + break; + case EQEmu::textures::armorChest: + mob_texture_profile.Chest.Material = texture; + mob_texture_profile.Chest.HerosForgeModel = hero_forge_model; + mob_texture_profile.Chest.Color = color; + break; + case EQEmu::textures::armorArms: + mob_texture_profile.Arms.Material = texture; + mob_texture_profile.Arms.HerosForgeModel = hero_forge_model; + mob_texture_profile.Arms.Color = color; + break; + case EQEmu::textures::armorWrist: + mob_texture_profile.Wrist.Material = texture; + mob_texture_profile.Wrist.HerosForgeModel = hero_forge_model; + mob_texture_profile.Wrist.Color = color; + break; + case EQEmu::textures::armorHands: + mob_texture_profile.Hands.Material = texture; + mob_texture_profile.Hands.HerosForgeModel = hero_forge_model; + mob_texture_profile.Hands.Color = color; + break; + case EQEmu::textures::armorLegs: + mob_texture_profile.Legs.Material = texture; + mob_texture_profile.Legs.HerosForgeModel = hero_forge_model; + mob_texture_profile.Legs.Color = color; + break; + case EQEmu::textures::armorFeet: + mob_texture_profile.Feet.Material = texture; + mob_texture_profile.Feet.HerosForgeModel = hero_forge_model; + mob_texture_profile.Feet.Color = color; + break; + case EQEmu::textures::weaponPrimary: + mob_texture_profile.Primary.Material = texture; + mob_texture_profile.Primary.HerosForgeModel = hero_forge_model; + mob_texture_profile.Primary.Color = color; + break; + case EQEmu::textures::weaponSecondary: + mob_texture_profile.Secondary.Material = texture; + mob_texture_profile.Secondary.HerosForgeModel = hero_forge_model; + mob_texture_profile.Secondary.Color = color; + break; + default: + return; + } +} + +/** + * Returns internal representation of mob texture by material + * + * @param material_slot + * @return + */ +int32 Mob::GetTextureProfileMaterial(uint8 material_slot) const +{ + switch (material_slot) { + case EQEmu::textures::armorHead: + return mob_texture_profile.Head.Material; + case EQEmu::textures::armorChest: + return mob_texture_profile.Chest.Material; + case EQEmu::textures::armorArms: + return mob_texture_profile.Arms.Material; + case EQEmu::textures::armorWrist: + return mob_texture_profile.Wrist.Material; + case EQEmu::textures::armorHands: + return mob_texture_profile.Hands.Material; + case EQEmu::textures::armorLegs: + return mob_texture_profile.Legs.Material; + case EQEmu::textures::armorFeet: + return mob_texture_profile.Feet.Material; + case EQEmu::textures::weaponPrimary: + return mob_texture_profile.Primary.Material; + case EQEmu::textures::weaponSecondary: + return mob_texture_profile.Secondary.Material; + default: + return 0; + } +} + +/** + * Returns internal representation of mob texture by color + * + * @param material_slot + * @return + */ +int32 Mob::GetTextureProfileColor(uint8 material_slot) const +{ + switch (material_slot) { + case EQEmu::textures::armorHead: + return mob_texture_profile.Head.Color; + case EQEmu::textures::armorChest: + return mob_texture_profile.Chest.Color; + case EQEmu::textures::armorArms: + return mob_texture_profile.Arms.Color; + case EQEmu::textures::armorWrist: + return mob_texture_profile.Wrist.Color; + case EQEmu::textures::armorHands: + return mob_texture_profile.Hands.Color; + case EQEmu::textures::armorLegs: + return mob_texture_profile.Legs.Color; + case EQEmu::textures::armorFeet: + return mob_texture_profile.Feet.Color; + case EQEmu::textures::weaponPrimary: + return mob_texture_profile.Primary.Color; + case EQEmu::textures::weaponSecondary: + return mob_texture_profile.Secondary.Color; + default: + return 0; + } +} + +/** + * Returns internal representation of mob texture by HerosForgeModel + * + * @param material_slot + * @return + */ +int32 Mob::GetTextureProfileHeroForgeModel(uint8 material_slot) const +{ + switch (material_slot) { + case EQEmu::textures::armorHead: + return mob_texture_profile.Head.HerosForgeModel; + case EQEmu::textures::armorChest: + return mob_texture_profile.Chest.HerosForgeModel; + case EQEmu::textures::armorArms: + return mob_texture_profile.Arms.HerosForgeModel; + case EQEmu::textures::armorWrist: + return mob_texture_profile.Wrist.HerosForgeModel; + case EQEmu::textures::armorHands: + return mob_texture_profile.Hands.HerosForgeModel; + case EQEmu::textures::armorLegs: + return mob_texture_profile.Legs.HerosForgeModel; + case EQEmu::textures::armorFeet: + return mob_texture_profile.Feet.HerosForgeModel; + case EQEmu::textures::weaponPrimary: + return mob_texture_profile.Primary.HerosForgeModel; + case EQEmu::textures::weaponSecondary: + return mob_texture_profile.Secondary.HerosForgeModel; + default: + return 0; + } +} + +/** + * Gets the material or texture for a slot (leather / plate etc.) + * + * @param material_slot + * @return + */ +int32 Mob::GetEquipmentMaterial(uint8 material_slot) const +{ + uint32 equipment_material = 0; + int32 ornamentation_augment_type = RuleI(Character, OrnamentationAugmentType); + + int32 texture_profile_material = GetTextureProfileMaterial(material_slot); + + Log(Logs::Detail, Logs::MobAppearance, + "Mob::GetEquipmentMaterial [%s] material_slot: %u texture_profile_material: %i", + this->clean_name, + material_slot, + texture_profile_material + ); + + if (texture_profile_material > 0) { + return texture_profile_material; + } + + auto item = database.GetItem(GetEquippedItemFromTextureSlot(material_slot)); + + if (item != nullptr) { + + /** + * Handle primary / secondary texture + */ + bool is_primary_or_secondary_weapon = + material_slot == EQEmu::textures::weaponPrimary || + material_slot == EQEmu::textures::weaponSecondary; + + if (is_primary_or_secondary_weapon) { + if (this->IsClient()) { + + int16 inventory_slot = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot); + if (inventory_slot == INVALID_INDEX) { + return 0; + } + + const EQEmu::ItemInstance *item_instance = CastToClient()->m_inv[inventory_slot]; + if (item_instance) { + if (item_instance->GetOrnamentationAug(ornamentation_augment_type)) { + item = item_instance->GetOrnamentationAug(ornamentation_augment_type)->GetItem(); + if (item && strlen(item->IDFile) > 2) { + equipment_material = atoi(&item->IDFile[2]); + } + } + else if (item_instance->GetOrnamentationIDFile()) { + equipment_material = item_instance->GetOrnamentationIDFile(); + } + } + } + + if (equipment_material == 0 && strlen(item->IDFile) > 2) { + equipment_material = atoi(&item->IDFile[2]); + } + } + else { + equipment_material = item->Material; + } + } + + return equipment_material; +} + +/** + * @param material_slot + * @return + */ +uint32 Mob::GetEquipmentColor(uint8 material_slot) const +{ + const EQEmu::ItemData *item = nullptr; + + if (armor_tint.Slot[material_slot].Color) { + return armor_tint.Slot[material_slot].Color; + } + + item = database.GetItem(GetEquippedItemFromTextureSlot(material_slot)); + if (item != nullptr) { + return item->Color; + } + + return 0; +} + +/** + * @param material_slot + * @return + */ +int32 Mob::GetHerosForgeModel(uint8 material_slot) const +{ + uint32 hero_model = 0; + if (material_slot >= 0 && material_slot < EQEmu::textures::weaponPrimary) { + uint32 ornamentation_aug_type = RuleI(Character, OrnamentationAugmentType); + + const EQEmu::ItemData *item = database.GetItem(GetEquippedItemFromTextureSlot(material_slot)); + int16 invslot = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot); + + if (item != nullptr && invslot != INVALID_INDEX) { + if (IsClient()) { + const EQEmu::ItemInstance *inst = CastToClient()->m_inv[invslot]; + if (inst) { + if (inst->GetOrnamentationAug(ornamentation_aug_type)) { + item = inst->GetOrnamentationAug(ornamentation_aug_type)->GetItem(); + hero_model = item->HerosForgeModel; + } + else if (inst->GetOrnamentHeroModel()) { + hero_model = inst->GetOrnamentHeroModel(); + } + } + } + + if (hero_model == 0) { + hero_model = item->HerosForgeModel; + } + } + + if (IsNPC()) { + hero_model = CastToNPC()->GetHeroForgeModel(); + + /** + * Robes require full model number, and should only be sent to chest, arms, wrists, and legs slots + */ + if (hero_model > 1000 && material_slot != 1 && material_slot != 2 && material_slot != 3 && + material_slot != 5) { + hero_model = 0; + } + } + } + + /** + * Auto-Convert Hero Model to match the slot + * + * Otherwise, use the exact Model if model is > 999 + * Robes for example are 11607 to 12107 in RoF + */ + if (hero_model > 0 && hero_model < 1000) { + hero_model *= 100; + hero_model += material_slot; + } + + return hero_model; +} + +uint32 NPC::GetEquippedItemFromTextureSlot(uint8 material_slot) const +{ + if (material_slot > 8) { + return 0; + } + + int16 inventory_slot = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot); + if (inventory_slot == INVALID_INDEX) { + return 0; + } + + return equipment[inventory_slot]; +} + +/** + * NPCs typically use this function for sending appearance + * @param one_client + */ +void Mob::SendArmorAppearance(Client *one_client) +{ + /** + * one_client of 0 means sent to all clients + * + * Despite the fact that OP_NewSpawn and OP_ZoneSpawns include the + * armor being worn and its mats, the client doesn't update the display + * on arrival of these packets reliably. + * + * Send Wear changes if mob is a PC race and item is an armor slot. + * The other packets work for primary/secondary. + */ + + Log(Logs::Detail, Logs::MobAppearance, "Mob::SendArmorAppearance [%s]", + this->GetCleanName() + ); + + if (IsPlayerRace(race)) { + if (!IsClient()) { + for (uint8 i = 0; i <= EQEmu::textures::materialCount; ++i) { + const EQEmu::ItemData *item = database.GetItem(GetEquippedItemFromTextureSlot(i)); + if (item != nullptr) { + SendWearChange(i, one_client); + } + } + } + } + + for (uint8 i = 0; i <= EQEmu::textures::materialCount; ++i) { + if (GetTextureProfileMaterial(i)) { + SendWearChange(i, one_client); + } + } +} + +/** + * @param material_slot + * @param one_client + */ +void Mob::SendWearChange(uint8 material_slot, Client *one_client) +{ + auto packet = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct)); + auto *wear_change = (WearChange_Struct *) packet->pBuffer; + + Log(Logs::Detail, Logs::MobAppearance, "Mob::SendWearChange [%s]", + this->GetCleanName() + ); + + wear_change->spawn_id = GetID(); + wear_change->material = static_cast(GetEquipmentMaterial(material_slot)); + wear_change->elite_material = IsEliteMaterialItem(material_slot); + wear_change->hero_forge_model = static_cast(GetHerosForgeModel(material_slot)); + +#ifdef BOTS + if (IsBot()) { + auto item_inst = CastToBot()->GetBotItem(EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot)); + if (item_inst) + wear_change->color.Color = item_inst->GetColor(); + else + wear_change->color.Color = 0; + } + else { + wear_change->color.Color = GetEquipmentColor(material_slot); + } +#else + wear_change->color.Color = GetEquipmentColor(material_slot); +#endif + + wear_change->wear_slot_id = material_slot; + + if (!one_client) { + entity_list.QueueClients(this, packet); + } + else { + one_client->QueuePacket(packet, false, Client::CLIENT_CONNECTED); + } + + safe_delete(packet); +} + +/** + * + * @param slot + * @param texture + * @param hero_forge_model + * @param elite_material + * @param unknown06 + * @param unknown18 + */ +void Mob::SendTextureWC( + uint8 slot, + uint16 texture, + uint32 hero_forge_model, + uint32 elite_material, + uint32 unknown06, + uint32 unknown18 +) +{ + auto outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct)); + auto *wear_change = (WearChange_Struct *) outapp->pBuffer; + + if (this->IsClient()) { + wear_change->color.Color = GetEquipmentColor(slot); + } + else { + wear_change->color.Color = this->GetArmorTint(slot); + } + + wear_change->spawn_id = this->GetID(); + wear_change->material = texture; + wear_change->wear_slot_id = slot; + wear_change->unknown06 = unknown06; + wear_change->elite_material = elite_material; + wear_change->hero_forge_model = hero_forge_model; + wear_change->unknown18 = unknown18; + + SetMobTextureProfile(slot, texture, wear_change->color.Color, hero_forge_model); + + entity_list.QueueClients(this, outapp); + safe_delete(outapp); +} + +/** + * @param material_slot + * @param red_tint + * @param green_tint + * @param blue_tint + */ +void Mob::SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint) +{ + uint32 color; + color = (red_tint & 0xFF) << 16; + color |= (green_tint & 0xFF) << 8; + color |= (blue_tint & 0xFF); + color |= (color) ? (0xFF << 24) : 0; + armor_tint.Slot[material_slot].Color = color; + + auto outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct)); + auto *wc = (WearChange_Struct *) outapp->pBuffer; + + wc->spawn_id = this->GetID(); + wc->material = GetEquipmentMaterial(material_slot); + wc->hero_forge_model = GetHerosForgeModel(material_slot); + wc->color.Color = color; + wc->wear_slot_id = material_slot; + + SetMobTextureProfile(material_slot, texture, color); + + entity_list.QueueClients(this, outapp); + safe_delete(outapp); +} + +/** + * @param material_slot + * @param texture + * @param color + * @param hero_forge_model + */ +void Mob::WearChange(uint8 material_slot, uint16 texture, uint32 color, uint32 hero_forge_model) +{ + armor_tint.Slot[material_slot].Color = color; + + /** + * Change internal values + */ + SetMobTextureProfile(material_slot, texture, color, hero_forge_model); + + /** + * Packet update + */ + auto outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct)); + auto *wear_change = (WearChange_Struct *) outapp->pBuffer; + + wear_change->spawn_id = this->GetID(); + wear_change->material = texture; + wear_change->hero_forge_model = hero_forge_model; + wear_change->color.Color = color; + wear_change->wear_slot_id = material_slot; + + entity_list.QueueClients(this, outapp); + safe_delete(outapp); +} \ No newline at end of file diff --git a/zone/npc.cpp b/zone/npc.cpp index 31a8b9445..6f047169a 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -973,7 +973,7 @@ bool NPC::SpawnZoneController() memset(npc_type, 0, sizeof(NPCType)); strncpy(npc_type->name, "zone_controller", 60); - npc_type->cur_hp = 2000000000; + npc_type->current_hp = 2000000000; npc_type->max_hp = 2000000000; npc_type->hp_regen = 100000000; npc_type->race = 240; @@ -1024,7 +1024,7 @@ NPC * NPC::SpawnGridNodeNPC(std::string name, const glm::vec4 &position, uint32 sprintf(npc_type->name, "%u_%u", grid_id, grid_number); sprintf(npc_type->lastname, "Number: %u Grid: %u Pause: %u", grid_number, grid_id, pause); - npc_type->cur_hp = 4000000; + npc_type->current_hp = 4000000; npc_type->max_hp = 4000000; npc_type->race = 2254; npc_type->gender = 2; @@ -1058,7 +1058,7 @@ NPC * NPC::SpawnNodeNPC(std::string name, std::string last_name, const glm::vec4 sprintf(npc_type->name, "%s", name.c_str()); sprintf(npc_type->lastname, "%s", last_name.c_str()); - npc_type->cur_hp = 4000000; + npc_type->current_hp = 4000000; npc_type->max_hp = 4000000; npc_type->race = 2254; npc_type->gender = 2; @@ -1095,33 +1095,45 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* else { Seperator sep(spawncommand); //Lets see if someone didn't fill out the whole #spawn function properly - if (!sep.IsNumber(1)) - sprintf(sep.arg[1],"1"); - if (!sep.IsNumber(2)) - sprintf(sep.arg[2],"1"); - if (!sep.IsNumber(3)) - sprintf(sep.arg[3],"0"); - if (atoi(sep.arg[4]) > 2100000000 || atoi(sep.arg[4]) <= 0) - sprintf(sep.arg[4]," "); - if (!strcmp(sep.arg[5],"-")) - sprintf(sep.arg[5]," "); - if (!sep.IsNumber(5)) - sprintf(sep.arg[5]," "); - if (!sep.IsNumber(6)) - sprintf(sep.arg[6],"1"); - if (!sep.IsNumber(8)) - sprintf(sep.arg[8],"0"); - if (!sep.IsNumber(9)) + if (!sep.IsNumber(1)) { + sprintf(sep.arg[1], "1"); + } + if (!sep.IsNumber(2)) { + sprintf(sep.arg[2], "1"); + } + if (!sep.IsNumber(3)) { + sprintf(sep.arg[3], "0"); + } + if (atoi(sep.arg[4]) > 2100000000 || atoi(sep.arg[4]) <= 0) { + sprintf(sep.arg[4], " "); + } + if (!strcmp(sep.arg[5], "-")) { + sprintf(sep.arg[5], " "); + } + if (!sep.IsNumber(5)) { + sprintf(sep.arg[5], " "); + } + if (!sep.IsNumber(6)) { + sprintf(sep.arg[6], "1"); + } + if (!sep.IsNumber(8)) { + sprintf(sep.arg[8], "0"); + } + if (!sep.IsNumber(9)) { sprintf(sep.arg[9], "0"); - if (!sep.IsNumber(7)) - sprintf(sep.arg[7],"0"); - if (!strcmp(sep.arg[4],"-")) - sprintf(sep.arg[4]," "); - if (!sep.IsNumber(10)) // bodytype + } + if (!sep.IsNumber(7)) { + sprintf(sep.arg[7], "0"); + } + if (!strcmp(sep.arg[4], "-")) { + sprintf(sep.arg[4], " "); + } + if (!sep.IsNumber(10)) { // bodytype sprintf(sep.arg[10], "0"); + } //Calc MaxHP if client neglected to enter it... - if (!sep.IsNumber(4)) { - sep.arg[4] = 0; + if (sep.arg[4] && !sep.IsNumber(4)) { + sprintf(sep.arg[4], "0"); } // Autoselect NPC Gender @@ -1134,7 +1146,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* memset(npc_type, 0, sizeof(NPCType)); strncpy(npc_type->name, sep.arg[0], 60); - npc_type->cur_hp = atoi(sep.arg[4]); + npc_type->current_hp = atoi(sep.arg[4]); npc_type->max_hp = atoi(sep.arg[4]); npc_type->race = atoi(sep.arg[1]); npc_type->gender = atoi(sep.arg[5]); @@ -1487,38 +1499,49 @@ uint32 ZoneDatabase::NPCSpawnDB(uint8 command, const char* zone, uint32 zone_ver int32 NPC::GetEquipmentMaterial(uint8 material_slot) const { - if (material_slot >= EQEmu::textures::materialCount) + int32 texture_profile_material = GetTextureProfileMaterial(material_slot); + + Log(Logs::Detail, Logs::MobAppearance, "NPC::GetEquipmentMaterial [%s] material_slot: %u", + this->clean_name, + material_slot + ); + + if (texture_profile_material > 0) { + return texture_profile_material; + } + + if (material_slot >= EQEmu::textures::materialCount) { return 0; + } int16 invslot = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot); - if (invslot == INVALID_INDEX) + if (invslot == INVALID_INDEX) { return 0; + } - if (equipment[invslot] == 0) - { - switch(material_slot) - { - case EQEmu::textures::armorHead: - return helmtexture; - case EQEmu::textures::armorChest: - return texture; - case EQEmu::textures::armorArms: - return armtexture; - case EQEmu::textures::armorWrist: - return bracertexture; - case EQEmu::textures::armorHands: - return handtexture; - case EQEmu::textures::armorLegs: - return legtexture; - case EQEmu::textures::armorFeet: - return feettexture; - case EQEmu::textures::weaponPrimary: - return d_melee_texture1; - case EQEmu::textures::weaponSecondary: - return d_melee_texture2; - default: - //they have nothing in the slot, and its not a special slot... they get nothing. - return(0); + if (equipment[invslot] == 0) { + switch (material_slot) { + case EQEmu::textures::armorHead: + return helmtexture; + case EQEmu::textures::armorChest: + return texture; + case EQEmu::textures::armorArms: + return armtexture; + case EQEmu::textures::armorWrist: + return bracertexture; + case EQEmu::textures::armorHands: + return handtexture; + case EQEmu::textures::armorLegs: + return legtexture; + case EQEmu::textures::armorFeet: + return feettexture; + case EQEmu::textures::weaponPrimary: + return d_melee_texture1; + case EQEmu::textures::weaponSecondary: + return d_melee_texture2; + default: + //they have nothing in the slot, and its not a special slot... they get nothing. + return (0); } } @@ -2164,8 +2187,8 @@ void NPC::ModifyNPCStat(const char *identifier, const char *new_value) base_hp = atoi(val.c_str()); CalcMaxHP(); - if (cur_hp > max_hp) { - cur_hp = max_hp; + if (current_hp > max_hp) { + current_hp = max_hp; } return; @@ -2346,14 +2369,14 @@ void NPC::LevelScale() { base_hp += (random_level - level) * 100; } - cur_hp = max_hp; + current_hp = max_hp; max_dmg += (random_level - level) * 2; } else { uint8 scale_adjust = 1; base_hp += (int)(base_hp * scaling); max_hp += (int)(max_hp * scaling); - cur_hp = max_hp; + current_hp = max_hp; if (max_dmg) { max_dmg += (int)(max_dmg * scaling / scale_adjust); @@ -2394,7 +2417,7 @@ void NPC::LevelScale() { ATK += (int)(ATK * scaling); base_hp += (int)(base_hp * scaling); max_hp += (int)(max_hp * scaling); - cur_hp = max_hp; + current_hp = max_hp; STR += (int)(STR * scaling / scale_adjust); STA += (int)(STA * scaling / scale_adjust); AGI += (int)(AGI * scaling / scale_adjust); diff --git a/zone/npc.h b/zone/npc.h index 7ad1fccd0..b9e0458e6 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -311,7 +311,7 @@ public: void MoveTo(const glm::vec4& position, bool saveguardspot); void GetClosestWaypoint(std::list &wp_list, int count, const glm::vec3& location); - uint32 GetEquipment(uint8 material_slot) const; // returns item id + uint32 GetEquippedItemFromTextureSlot(uint8 material_slot) const; // returns item id int32 GetEquipmentMaterial(uint8 material_slot) const; void NextGuardPosition(); @@ -468,6 +468,7 @@ public: virtual int GetStuckBehavior() const { return NPCTypedata_ours ? NPCTypedata_ours->stuck_behavior : NPCTypedata->stuck_behavior; } + protected: const NPCType* NPCTypedata; diff --git a/zone/pathfinder_waypoint.cpp b/zone/pathfinder_waypoint.cpp index 3d3f0162d..58ad5afea 100644 --- a/zone/pathfinder_waypoint.cpp +++ b/zone/pathfinder_waypoint.cpp @@ -529,7 +529,7 @@ void PathfinderWaypoint::ShowNode(const Node &n) { sprintf(npc_type->name, "%s", DigitToWord(n.id).c_str()); sprintf(npc_type->lastname, "%i", n.id); - npc_type->cur_hp = 4000000; + npc_type->current_hp = 4000000; npc_type->max_hp = 4000000; npc_type->race = 2254; npc_type->gender = 2; diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 6177961f4..b9884b2a0 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -639,7 +639,7 @@ XS(XS_Mob_GetEquipment) { if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetEquipment(material_slot); + RETVAL = THIS->GetEquippedItemFromTextureSlot(material_slot); XSprePUSH; PUSHi((IV) RETVAL); } diff --git a/zone/pets.cpp b/zone/pets.cpp index ad88f7a60..ab1f13bce 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -240,7 +240,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, if(scale_power > 0) { npc_type->max_hp *= (1 + scale_power); - npc_type->cur_hp = npc_type->max_hp; + npc_type->current_hp = npc_type->max_hp; npc_type->AC *= (1 + scale_power); npc_type->level += 1 + ((int)act_power / 25) > npc_type->level + RuleR(Pets, PetPowerLevelCap) ? RuleR(Pets, PetPowerLevelCap) : 1 + ((int)act_power / 25); // gains an additional level for every 25 pet power npc_type->min_dmg = (npc_type->min_dmg * (1 + (scale_power / 2))); @@ -255,7 +255,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, if (MaxHP){ npc_type->max_hp += (npc_type->max_hp*MaxHP)/100; - npc_type->cur_hp = npc_type->max_hp; + npc_type->current_hp = npc_type->max_hp; } //TODO: think about regen (engaged vs. not engaged) diff --git a/zone/trap.cpp b/zone/trap.cpp index 191d80fce..5e4198e5b 100644 --- a/zone/trap.cpp +++ b/zone/trap.cpp @@ -456,7 +456,7 @@ void Trap::CreateHiddenTrigger() auto make_npc = new NPCType; memcpy(make_npc, base_type, sizeof(NPCType)); make_npc->max_hp = 100000; - make_npc->cur_hp = 100000; + make_npc->current_hp = 100000; strcpy(make_npc->name, "a_trap"); make_npc->runspeed = 0.0f; make_npc->bodytype = BT_Special; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index d721edba4..b30c037b7 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -2495,7 +2495,7 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load temp_npctype_data->race = atoi(row[3]); temp_npctype_data->class_ = atoi(row[4]); temp_npctype_data->max_hp = atoi(row[5]); - temp_npctype_data->cur_hp = temp_npctype_data->max_hp; + temp_npctype_data->current_hp = temp_npctype_data->max_hp; temp_npctype_data->Mana = atoi(row[6]); temp_npctype_data->gender = atoi(row[7]); temp_npctype_data->texture = atoi(row[8]); @@ -2777,7 +2777,7 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client tmpNPCType->race = atoi(row[3]); tmpNPCType->class_ = atoi(row[4]); tmpNPCType->max_hp = atoi(row[5]); - tmpNPCType->cur_hp = tmpNPCType->max_hp; + tmpNPCType->current_hp = tmpNPCType->max_hp; tmpNPCType->Mana = atoi(row[6]); tmpNPCType->gender = atoi(row[7]); tmpNPCType->texture = atoi(row[8]); diff --git a/zone/zonedump.h b/zone/zonedump.h index 6636bfa1e..b75057a16 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -36,7 +36,7 @@ struct NPCType { char name[64]; char lastname[70]; - int32 cur_hp; + int32 current_hp; int32 max_hp; float size; float runspeed; From 2c8ed1074a904d157c4112a6dc5ea25a71f54ec2 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 31 Dec 2018 23:19:48 -0600 Subject: [PATCH 02/11] Fix bots build --- zone/bot.cpp | 26 +++++++++++++------------- zone/inventory.cpp | 2 +- zone/mob_appearance.cpp | 4 ++++ zone/npc.cpp | 2 +- zone/perl_mob.cpp | 2 +- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index f78363649..5876ebed3 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -89,7 +89,7 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm GenerateAppearance(); GenerateBaseStats(); // Calculate HitPoints Last As It Uses Base Stats - cur_hp = GenerateBaseHitPoints(); + current_hp = GenerateBaseHitPoints(); current_mana = GenerateBaseManaPoints(); cur_end = CalcBaseEndurance(); hp_regen = CalcHPRegen(); @@ -137,7 +137,7 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to _baseATK = npcTypeData.ATK; _baseRace = npcTypeData.race; _baseGender = npcTypeData.gender; - cur_hp = npcTypeData.cur_hp; + current_hp = npcTypeData.current_hp; current_mana = npcTypeData.Mana; RestRegenHP = 0; RestRegenMana = 0; @@ -209,10 +209,10 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to hp_regen = CalcHPRegen(); mana_regen = CalcManaRegen(); end_regen = CalcEnduranceRegen(); - if(cur_hp > max_hp) - cur_hp = max_hp; + if(current_hp > max_hp) + current_hp = max_hp; - if(cur_hp <= 0) { + if(current_hp <= 0) { SetHP(max_hp/5); SetMana(0); BuffFadeAll(); @@ -336,7 +336,7 @@ NPCType Bot::FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::str BotNPCType.drakkin_heritage = drakkinHeritage; BotNPCType.drakkin_tattoo = drakkinTattoo; BotNPCType.drakkin_details = drakkinDetails; - BotNPCType.cur_hp = hp; + BotNPCType.current_hp = hp; BotNPCType.Mana = mana; BotNPCType.MR = mr; BotNPCType.CR = cr; @@ -386,7 +386,7 @@ NPCType Bot::CreateDefaultNPCTypeStructForBot(std::string botName, std::string b Result.maxlevel = botLevel; Result.size = 6.0; Result.npc_id = 0; - Result.cur_hp = 0; + Result.current_hp = 0; Result.drakkin_details = 0; Result.drakkin_heritage = 0; Result.drakkin_tattoo = 0; @@ -5147,7 +5147,7 @@ int Bot::GetHandToHandDamage(void) { // everyone uses this in the revamp! int skill = GetSkill(EQEmu::skills::SkillHandtoHand); int epic = 0; - if (CastToNPC()->GetEquipment(EQEmu::textures::armorHands) == 10652 && GetLevel() > 46) + if (CastToNPC()->GetEquippedItemFromTextureSlot(EQEmu::textures::armorHands) == 10652 && GetLevel() > 46) epic = 280; if (epic > skill) skill = epic; @@ -5169,7 +5169,7 @@ int Bot::GetHandToHandDamage(void) { 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, // 31-40 10, 11, 11, 11, 11, 11, 11, 12, 12}; // 41-49 if (GetClass() == MONK) { - if (CastToNPC()->GetEquipment(EQEmu::textures::armorHands) == 10652 && GetLevel() > 50) + if (CastToNPC()->GetEquippedItemFromTextureSlot(EQEmu::textures::armorHands) == 10652 && GetLevel() > 50) return 9; if (level > 62) return 15; @@ -7159,14 +7159,14 @@ int32 Bot::CalcMaxHP() { bot_hp += GroupLeadershipAAHealthEnhancement(); bot_hp += (bot_hp * ((spellbonuses.MaxHPChange + itembonuses.MaxHPChange) / 10000.0f)); max_hp = bot_hp; - if (cur_hp > max_hp) - cur_hp = max_hp; + if (current_hp > max_hp) + current_hp = max_hp; int hp_perc_cap = spellbonuses.HPPercCap[0]; if(hp_perc_cap) { int curHP_cap = ((max_hp * hp_perc_cap) / 100); - if (cur_hp > curHP_cap || (spellbonuses.HPPercCap[1] && cur_hp > spellbonuses.HPPercCap[1])) - cur_hp = curHP_cap; + if (current_hp > curHP_cap || (spellbonuses.HPPercCap[1] && current_hp > spellbonuses.HPPercCap[1])) + current_hp = curHP_cap; } return max_hp; } diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 7e9f2d9a1..3ceefc33b 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -2887,7 +2887,7 @@ int32 Client::GetEquipmentMaterial(uint8 material_slot) { const ItemData *item; - item = database.GetItem(GetEquipment(material_slot)); + item = database.GetItem(GetEquippedItemFromTextureSlot(material_slot)); if(item != 0) { return item->Material; diff --git a/zone/mob_appearance.cpp b/zone/mob_appearance.cpp index 85894994b..fe4e07eee 100644 --- a/zone/mob_appearance.cpp +++ b/zone/mob_appearance.cpp @@ -28,6 +28,10 @@ #include "quest_parser_collection.h" #include "zonedb.h" +#ifdef BOTS +#include "bot.h" +#endif + /** * Stores internal representation of mob texture by material slot * diff --git a/zone/npc.cpp b/zone/npc.cpp index 6f047169a..01339fde9 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -1058,7 +1058,7 @@ NPC * NPC::SpawnNodeNPC(std::string name, std::string last_name, const glm::vec4 sprintf(npc_type->name, "%s", name.c_str()); sprintf(npc_type->lastname, "%s", last_name.c_str()); - npc_type->current_hp = 4000000; + npc_type->current_hp = 4000000; npc_type->max_hp = 4000000; npc_type->race = 2254; npc_type->gender = 2; diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index b9884b2a0..268c5a60f 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -624,7 +624,7 @@ XS(XS_Mob_GetEquipment); /* prototype to pass -Wmissing-prototypes */ XS(XS_Mob_GetEquipment) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetEquipment(THIS, uint8 material_slot)"); + Perl_croak(aTHX_ "Usage: Mob::GetEquippedItemFromTextureSlot(THIS, uint8 material_slot)"); { Mob *THIS; int32 RETVAL; From c1a02e8244d55c8ad9ce774212e2667c1c9d43a9 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 31 Dec 2018 23:20:04 -0600 Subject: [PATCH 03/11] Add path finder wrapper around devtools proximity show --- zone/command.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/zone/command.cpp b/zone/command.cpp index 681c22a7e..f6e40e7e7 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -4969,6 +4969,10 @@ void command_proximity(Client *c, const Seperator *sep) NPC *npc = c->GetTarget()->CastToNPC(); + std::vector points; + + FindPerson_Point p{}; + if (npc->IsProximitySet()) { glm::vec4 position; position.w = npc->GetHeading(); @@ -4991,7 +4995,30 @@ void command_proximity(Client *c, const Seperator *sep) position.x = npc->GetProximityMaxX(); position.y = npc->GetProximityMaxY(); NPC::SpawnNodeNPC("Proximity", "", position); + + p.x = npc->GetProximityMinX(); + p.y = npc->GetProximityMinY(); + p.z = npc->GetZ(); + points.push_back(p); + + p.x = npc->GetProximityMinX(); + p.y = npc->GetProximityMaxY(); + points.push_back(p); + + p.x = npc->GetProximityMaxX(); + p.y = npc->GetProximityMaxY(); + points.push_back(p); + + p.x = npc->GetProximityMaxX(); + p.y = npc->GetProximityMinY(); + points.push_back(p); + + p.x = npc->GetProximityMinX(); + p.y = npc->GetProximityMinY(); + points.push_back(p); } + + c->SendPathPacket(points); } void command_pvp(Client *c, const Seperator *sep) From 7a56ffc380834ffbd0ecbdaaa651a715f9294789 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 31 Dec 2018 23:20:55 -0600 Subject: [PATCH 04/11] Comment change [skip ci] --- zone/perl_mob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 268c5a60f..b9884b2a0 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -624,7 +624,7 @@ XS(XS_Mob_GetEquipment); /* prototype to pass -Wmissing-prototypes */ XS(XS_Mob_GetEquipment) { dXSARGS; if (items != 2) - Perl_croak(aTHX_ "Usage: Mob::GetEquippedItemFromTextureSlot(THIS, uint8 material_slot)"); + Perl_croak(aTHX_ "Usage: Mob::GetEquipment(THIS, uint8 material_slot)"); { Mob *THIS; int32 RETVAL; From df68ad63582eaf29644359f298be9c6076e41282 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 1 Jan 2019 04:22:31 -0600 Subject: [PATCH 05/11] More texture / ornamentation work - export SetPrimaryWeaponOrnamentation and SetSecondaryWeaponOrnamentation to Perl / Lua --- common/patches/rof.cpp | 23 +- common/patches/rof2.cpp | 23 +- zone/client.cpp | 41 ++++ zone/client.h | 3 + zone/command.cpp | 15 +- zone/lua_client.cpp | 12 + zone/lua_client.h | 4 + zone/perl_client.cpp | 476 ++++++++++++++++++++++------------------ zone/zonedb.h | 80 +++---- 9 files changed, 398 insertions(+), 279 deletions(-) diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index cb8eddced..d0fa44773 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -5146,16 +5146,19 @@ namespace RoF ob.write((const char*)&evotop, sizeof(RoF::structs::EvolvingItem)); } - //ORNAMENT IDFILE / ICON - int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); - uint32 ornaIcon = 0; - uint32 heroModel = 0; + /** + * Ornamentation + */ + int ornamentation_augment_type = RuleI(Character, OrnamentationAugmentType); + uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0); + uint32 hero_model = 0; - if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) { - ornaIcon = inst->GetOrnamentationIcon(); - heroModel = inst->GetOrnamentHeroModel(EQEmu::InventoryProfile::CalcMaterialFromSlot(slot_id_in)); + if (inst->GetOrnamentationIDFile()) { + hero_model = inst->GetOrnamentHeroModel(EQEmu::InventoryProfile::CalcMaterialFromSlot(slot_id_in)); - char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); + char tmp[30]; + memset(tmp, 0x0, 30); + sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); //Mainhand ob.write(tmp, strlen(tmp)); @@ -5172,9 +5175,9 @@ namespace RoF RoF::structs::ItemSerializationHeaderFinish hdrf; - hdrf.ornamentIcon = ornaIcon; + hdrf.ornamentIcon = ornamentation_icon; hdrf.unknowna1 = 0xffffffff; - hdrf.ornamentHeroModel = heroModel; + hdrf.ornamentHeroModel = hero_model; hdrf.unknown063 = 0; hdrf.unknowna3 = 0; hdrf.unknowna4 = 0xffffffff; diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index cb9e468fb..949cd1db3 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -5443,16 +5443,19 @@ namespace RoF2 ob.write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem)); } - //ORNAMENT IDFILE / ICON - int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); - uint32 ornaIcon = 0; - uint32 heroModel = 0; + /** + * Ornamentation + */ + int ornamentation_augment_type = RuleI(Character, OrnamentationAugmentType); + uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0); + uint32 hero_model = 0; - if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) { - ornaIcon = inst->GetOrnamentationIcon(); - heroModel = inst->GetOrnamentHeroModel(EQEmu::InventoryProfile::CalcMaterialFromSlot(slot_id_in)); + if (inst->GetOrnamentationIDFile()) { + hero_model = inst->GetOrnamentHeroModel(EQEmu::InventoryProfile::CalcMaterialFromSlot(slot_id_in)); - char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); + char tmp[30]; + memset(tmp, 0x0, 30); + sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); //Mainhand ob.write(tmp, strlen(tmp)); @@ -5469,9 +5472,9 @@ namespace RoF2 RoF2::structs::ItemSerializationHeaderFinish hdrf; - hdrf.ornamentIcon = ornaIcon; + hdrf.ornamentIcon = ornamentation_icon; hdrf.unknowna1 = 0xffffffff; - hdrf.ornamentHeroModel = heroModel; + hdrf.ornamentHeroModel = hero_model; hdrf.unknown063 = 0; hdrf.Copied = 0; hdrf.unknowna4 = 0xffffffff; diff --git a/zone/client.cpp b/zone/client.cpp index bb43a3e4f..e4b81cdf7 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -9021,7 +9021,48 @@ bool Client::IsDevToolsWindowEnabled() const return dev_tools_window_enabled; } +/** + * @param in_dev_tools_window_enabled + */ void Client::SetDevToolsWindowEnabled(bool in_dev_tools_window_enabled) { Client::dev_tools_window_enabled = in_dev_tools_window_enabled; +} + +/** + * @param model_id + */ +void Client::SetPrimaryWeaponOrnamentation(uint32 model_id) +{ + if (GetItemIDAt(EQEmu::invslot::slotPrimary) > 0) { + database.QueryDatabase( + StringFormat( + "UPDATE `inventory` SET `ornamentidfile` = %i WHERE `charid` = %i AND `slotid` = %i", + model_id, + character_id, + EQEmu::invslot::slotPrimary + )); + + WearChange(EQEmu::textures::weaponPrimary, static_cast(model_id), 0); + Message(15, "Your primary weapon appearance has been modified, changes will fully take affect next time you zone"); + } +} + +/** + * @param model_id + */ +void Client::SetSecondaryWeaponOrnamentation(uint32 model_id) +{ + if (GetItemIDAt(EQEmu::invslot::slotSecondary) > 0) { + database.QueryDatabase( + StringFormat( + "UPDATE `inventory` SET `ornamentidfile` = %i WHERE `charid` = %i AND `slotid` = %i", + model_id, + character_id, + EQEmu::invslot::slotSecondary + )); + + WearChange(EQEmu::textures::weaponSecondary, static_cast(model_id), 0); + Message(15, "Your secondary weapon appearance has been modified, changes will fully take affect next time you zone"); + } } \ No newline at end of file diff --git a/zone/client.h b/zone/client.h index 48efba685..96b386a85 100644 --- a/zone/client.h +++ b/zone/client.h @@ -252,6 +252,9 @@ public: bool IsDevToolsWindowEnabled() const; void SetDevToolsWindowEnabled(bool dev_tools_window_enabled); + void SetPrimaryWeaponOrnamentation(uint32 model_id); + void SetSecondaryWeaponOrnamentation(uint32 model_id); + //abstract virtual function implementations required by base abstract class virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill); virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None); diff --git a/zone/command.cpp b/zone/command.cpp index f6e40e7e7..2645e7ece 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -2826,15 +2826,12 @@ void command_test(Client *c, const Seperator *sep) { c->Message(15, "Triggering test command"); - // EQEmu::ItemInstance* fake_weapon_secondary = database.CreateItem(static_cast(c->GetItemIDAt(EQEmu::invslot::slotSecondary))); - // fake_weapon_secondary->SetNewIDFile(c->GetEquipmentMaterial(EQEmu::textures::weaponSecondary)); - // c->SendItemPacket(EQEmu::invslot::slotSecondary, fake_weapon_secondary, ItemPacketTrade); - // safe_delete(fake_weapon_secondary); - - EQEmu::ItemInstance* fake_weapon = database.CreateItem(static_cast(c->GetItemIDAt(EQEmu::invslot::slotPrimary))); - fake_weapon->SetNewIDFile(c->GetEquipmentMaterial(EQEmu::textures::weaponPrimary)); - c->SendItemPacket(EQEmu::invslot::slotPrimary, fake_weapon, ItemPacketTrade); - safe_delete(fake_weapon); + if (sep->arg[1]) { + c->SetPrimaryWeaponOrnamentation(atoi(sep->arg[1])); + } + if (sep->arg[2]) { + c->SetSecondaryWeaponOrnamentation(atoi(sep->arg[2])); + } } void command_texture(Client *c, const Seperator *sep) diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 7a8d954d8..a8991f97a 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -1486,6 +1486,16 @@ void Lua_Client::DisableAreaRegens() self->DisableAreaRegens(); } +void Lua_Client::SetPrimaryWeaponOrnamentation(uint32 model_id) { + Lua_Safe_Call_Void(); + self->SetPrimaryWeaponOrnamentation(model_id); +} + +void Lua_Client::SetSecondaryWeaponOrnamentation(uint32 model_id) { + Lua_Safe_Call_Void(); + self->SetSecondaryWeaponOrnamentation(model_id); +} + luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()) @@ -1548,6 +1558,8 @@ luabind::scope lua_register_client() { .def("GetBindHeading", (float(Lua_Client::*)(int))&Lua_Client::GetBindHeading) .def("GetBindZoneID", (uint32(Lua_Client::*)(void))&Lua_Client::GetBindZoneID) .def("GetBindZoneID", (uint32(Lua_Client::*)(int))&Lua_Client::GetBindZoneID) + .def("SetPrimaryWeaponOrnamentation", (void(Lua_Client::*)(uint32))&Lua_Client::SetPrimaryWeaponOrnamentation) + .def("SetSecondaryWeaponOrnamentation", (void(Lua_Client::*)(uint32))&Lua_Client::SetSecondaryWeaponOrnamentation) .def("MovePC", (void(Lua_Client::*)(int,float,float,float,float))&Lua_Client::MovePC) .def("MovePCInstance", (void(Lua_Client::*)(int,int,float,float,float,float))&Lua_Client::MovePCInstance) .def("ChangeLastName", (void(Lua_Client::*)(const char *in))&Lua_Client::ChangeLastName) diff --git a/zone/lua_client.h b/zone/lua_client.h index 10e766b5c..715ea141d 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -309,6 +309,10 @@ public: void DisableAreaEndRegen(); void EnableAreaRegens(int value); void DisableAreaRegens(); + + + void SetPrimaryWeaponOrnamentation(uint32 model_id); + void SetSecondaryWeaponOrnamentation(uint32 model_id); }; #endif diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 74c95f5d2..fcdeca352 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -6126,6 +6126,59 @@ XS(XS_Client_Popup2) { XSRETURN_EMPTY; } +XS(XS_Client_SetPrimaryWeaponOrnamentation); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_SetPrimaryWeaponOrnamentation) +{ + dXSARGS; + if (items != 2) { + Perl_croak(aTHX_ "Usage: Client::SetPrimaryWeaponOrnamentation(THIS, model_id)"); + } + { + Client *THIS; + uint32 model_id = (uint32) SvUV(ST(1)); + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } + else { + Perl_croak(aTHX_ "THIS is not of type Client"); + } + if (THIS == nullptr) { + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + } + + THIS->SetPrimaryWeaponOrnamentation(model_id); + } + XSRETURN_EMPTY; +} + +XS(XS_Client_SetSecondaryWeaponOrnamentation); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_SetSecondaryWeaponOrnamentation) +{ + dXSARGS; + if (items != 2) { + Perl_croak(aTHX_ "Usage: Client::SetSecondaryWeaponOrnamentation(THIS, model_id)"); + } + { + Client *THIS; + uint32 model_id = (uint32) SvUV(ST(1)); + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } + else { + Perl_croak(aTHX_ "THIS is not of type Client"); + } + if (THIS == nullptr) { + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + } + + THIS->SetSecondaryWeaponOrnamentation(model_id); + } + XSRETURN_EMPTY; +} #ifdef __cplusplus extern "C" @@ -6147,240 +6200,241 @@ XS(boot_Client) { XS_VERSION_BOOTCHECK; - newXSproto(strcpy(buf, "SendSound"), XS_Client_SendSound, file, "$"); - newXSproto(strcpy(buf, "Save"), XS_Client_Save, file, "$$"); - newXSproto(strcpy(buf, "SaveBackup"), XS_Client_SaveBackup, file, "$"); + newXSproto(strcpy(buf, "AccountID"), XS_Client_AccountID, file, "$"); + newXSproto(strcpy(buf, "AccountName"), XS_Client_AccountName, file, "$"); + newXSproto(strcpy(buf, "AddAAPoints"), XS_Client_AddAAPoints, file, "$$"); + newXSproto(strcpy(buf, "AddAlternateCurrencyValue"), XS_Client_AddAlternateCurrencyValue, file, "$$$"); + newXSproto(strcpy(buf, "AddCrystals"), XS_Client_AddCrystals, file, "$$"); + newXSproto(strcpy(buf, "AddEXP"), XS_Client_AddEXP, file, "$$;$$"); + newXSproto(strcpy(buf, "AddLevelBasedExp"), XS_Client_AddLevelBasedExp, file, "$$;$"); + newXSproto(strcpy(buf, "AddMoneyToPP"), XS_Client_AddMoneyToPP, file, "$$$$$$"); + newXSproto(strcpy(buf, "AddPVPPoints"), XS_Client_AddPVPPoints, file, "$$"); + newXSproto(strcpy(buf, "AddSkill"), XS_Client_AddSkill, file, "$$$"); + newXSproto(strcpy(buf, "Admin"), XS_Client_Admin, file, "$"); + newXSproto(strcpy(buf, "AssignTask"), XS_Client_AssignTask, file, "$$$;$"); + newXSproto(strcpy(buf, "AssignToInstance"), XS_Client_AssignToInstance, file, "$$"); + newXSproto(strcpy(buf, "AutoSplitEnabled"), XS_Client_AutoSplitEnabled, file, "$"); + newXSproto(strcpy(buf, "BreakInvis"), XS_Client_BreakInvis, file, "$"); + newXSproto(strcpy(buf, "CalcEXP"), XS_Client_CalcEXP, file, "$"); + newXSproto(strcpy(buf, "CalcPriceMod"), XS_Client_CalcPriceMod, file, "$;$$"); + newXSproto(strcpy(buf, "CanHaveSkill"), XS_Client_CanHaveSkill, file, "$$"); + newXSproto(strcpy(buf, "ChangeLastName"), XS_Client_ChangeLastName, file, "$$"); + newXSproto(strcpy(buf, "CharacterID"), XS_Client_CharacterID, file, "$"); + newXSproto(strcpy(buf, "CheckIncreaseSkill"), XS_Client_CheckIncreaseSkill, file, "$$;$"); + newXSproto(strcpy(buf, "CheckSpecializeIncrease"), XS_Client_CheckSpecializeIncrease, file, "$$"); + newXSproto(strcpy(buf, "ClearCompassMark"), XS_Client_ClearCompassMark, file, "$"); + newXSproto(strcpy(buf, "ClearZoneFlag"), XS_Client_ClearZoneFlag, file, "$$"); newXSproto(strcpy(buf, "Connected"), XS_Client_Connected, file, "$"); - newXSproto(strcpy(buf, "InZone"), XS_Client_InZone, file, "$"); - newXSproto(strcpy(buf, "Kick"), XS_Client_Kick, file, "$"); + newXSproto(strcpy(buf, "DecreaseByID"), XS_Client_DecreaseByID, file, "$$$"); + newXSproto(strcpy(buf, "DeleteItemInInventory"), XS_Client_DeleteItemInInventory, file, "$$;$$"); newXSproto(strcpy(buf, "Disconnect"), XS_Client_Disconnect, file, "$"); - newXSproto(strcpy(buf, "IsLD"), XS_Client_IsLD, file, "$"); - newXSproto(strcpy(buf, "WorldKick"), XS_Client_WorldKick, file, "$"); - newXSproto(strcpy(buf, "GetAnon"), XS_Client_GetAnon, file, "$"); + newXSproto(strcpy(buf, "DropItem"), XS_Client_DropItem, file, "$$"); newXSproto(strcpy(buf, "Duck"), XS_Client_Duck, file, "$"); - newXSproto(strcpy(buf, "Stand"), XS_Client_Stand, file, "$"); - newXSproto(strcpy(buf, "SetGM"), XS_Client_SetGM, file, "$$"); - newXSproto(strcpy(buf, "SetPVP"), XS_Client_SetPVP, file, "$$"); - newXSproto(strcpy(buf, "GetPVP"), XS_Client_GetPVP, file, "$"); - newXSproto(strcpy(buf, "GetGM"), XS_Client_GetGM, file, "$"); - newXSproto(strcpy(buf, "SetBaseClass"), XS_Client_SetBaseClass, file, "$$"); - newXSproto(strcpy(buf, "SetBaseRace"), XS_Client_SetBaseRace, file, "$$"); - newXSproto(strcpy(buf, "SetBaseGender"), XS_Client_SetBaseGender, file, "$$"); - newXSproto(strcpy(buf, "GetBaseFace"), XS_Client_GetBaseFace, file, "$"); - newXSproto(strcpy(buf, "GetLanguageSkill"), XS_Client_GetLanguageSkill, file, "$$"); - newXSproto(strcpy(buf, "GetLastName"), XS_Client_GetLastName, file, "$"); - newXSproto(strcpy(buf, "GetLDoNPointsTheme"), XS_Client_GetLDoNPointsTheme, file, "$"); - newXSproto(strcpy(buf, "GetBaseSTR"), XS_Client_GetBaseSTR, file, "$"); - newXSproto(strcpy(buf, "GetBaseSTA"), XS_Client_GetBaseSTA, file, "$"); + newXSproto(strcpy(buf, "Escape"), XS_Client_Escape, file, "$"); + newXSproto(strcpy(buf, "ExpeditionMessage"), XS_Client_ExpeditionMessage, file, "$$$"); + newXSproto(strcpy(buf, "FailTask"), XS_Client_FailTask, file, "$$"); + newXSproto(strcpy(buf, "ForageItem"), XS_Client_ForageItem, file, "$"); + newXSproto(strcpy(buf, "Freeze"), XS_Client_Freeze, file, "$"); + newXSproto(strcpy(buf, "GetAAExp"), XS_Client_GetAAExp, file, "$"); + newXSproto(strcpy(buf, "GetAALevel"), XS_Client_GetAALevel, file, "$$"); + newXSproto(strcpy(buf, "GetAAPercent"), XS_Client_GetAAPercent, file, "$"); + newXSproto(strcpy(buf, "GetAAPoints"), XS_Client_GetAAPoints, file, "$$"); + newXSproto(strcpy(buf, "GetAccountAge"), XS_Client_GetAccountAge, file, "$"); + newXSproto(strcpy(buf, "GetAccountFlag"), XS_Client_GetAccountFlag, file, "$$"); + newXSproto(strcpy(buf, "GetAggroCount"), XS_Client_GetAggroCount, file, "$"); + newXSproto(strcpy(buf, "GetAllMoney"), XS_Client_GetAllMoney, file, "$"); + newXSproto(strcpy(buf, "GetAnon"), XS_Client_GetAnon, file, "$"); + newXSproto(strcpy(buf, "GetAugmentAt"), XS_Client_GetAugmentAt, file, "$$$"); + newXSproto(strcpy(buf, "GetAugmentIDAt"), XS_Client_GetAugmentIDAt, file, "$$$"); + newXSproto(strcpy(buf, "GetBaseAGI"), XS_Client_GetBaseAGI, file, "$"); newXSproto(strcpy(buf, "GetBaseCHA"), XS_Client_GetBaseCHA, file, "$"); newXSproto(strcpy(buf, "GetBaseDEX"), XS_Client_GetBaseDEX, file, "$"); + newXSproto(strcpy(buf, "GetBaseFace"), XS_Client_GetBaseFace, file, "$"); newXSproto(strcpy(buf, "GetBaseINT"), XS_Client_GetBaseINT, file, "$"); - newXSproto(strcpy(buf, "GetBaseAGI"), XS_Client_GetBaseAGI, file, "$"); + newXSproto(strcpy(buf, "GetBaseSTA"), XS_Client_GetBaseSTA, file, "$"); + newXSproto(strcpy(buf, "GetBaseSTR"), XS_Client_GetBaseSTR, file, "$"); newXSproto(strcpy(buf, "GetBaseWIS"), XS_Client_GetBaseWIS, file, "$"); - newXSproto(strcpy(buf, "GetWeight"), XS_Client_GetWeight, file, "$"); - newXSproto(strcpy(buf, "GetEXP"), XS_Client_GetEXP, file, "$"); - newXSproto(strcpy(buf, "GetAAExp"), XS_Client_GetAAExp, file, "$"); - newXSproto(strcpy(buf, "GetAAPercent"), XS_Client_GetAAPercent, file, "$"); - newXSproto(strcpy(buf, "GetTotalSecondsPlayed"), XS_Client_GetTotalSecondsPlayed, file, "$"); - newXSproto(strcpy(buf, "UpdateLDoNPoints"), XS_Client_UpdateLDoNPoints, file, "$$$"); - newXSproto(strcpy(buf, "SetDeity"), XS_Client_SetDeity, file, "$$"); - newXSproto(strcpy(buf, "AddEXP"), XS_Client_AddEXP, file, "$$;$$"); - newXSproto(strcpy(buf, "SetEXP"), XS_Client_SetEXP, file, "$$$;$"); - newXSproto(strcpy(buf, "SetBindPoint"), XS_Client_SetBindPoint, file, "$;$$$$$"); + newXSproto(strcpy(buf, "GetBecomeNPCLevel"), XS_Client_GetBecomeNPCLevel, file, "$"); + newXSproto(strcpy(buf, "GetBindHeading"), XS_Client_GetBindHeading, file, "$$"); newXSproto(strcpy(buf, "GetBindX"), XS_Client_GetBindX, file, "$$"); newXSproto(strcpy(buf, "GetBindY"), XS_Client_GetBindY, file, "$$"); newXSproto(strcpy(buf, "GetBindZ"), XS_Client_GetBindZ, file, "$$"); - newXSproto(strcpy(buf, "GetBindHeading"), XS_Client_GetBindHeading, file, "$$"); newXSproto(strcpy(buf, "GetBindZoneID"), XS_Client_GetBindZoneID, file, "$$"); - newXSproto(strcpy(buf, "MovePC"), XS_Client_MovePC, file, "$$$$$$"); - newXSproto(strcpy(buf, "MovePCInstance"), XS_Client_MovePCInstance, file, "$$$$$$$"); - newXSproto(strcpy(buf, "ChangeLastName"), XS_Client_ChangeLastName, file, "$$"); - newXSproto(strcpy(buf, "GetFactionLevel"), XS_Client_GetFactionLevel, file, "$$$$$$$$"); - newXSproto(strcpy(buf, "SetFactionLevel"), XS_Client_SetFactionLevel, file, "$$$$$$"); - newXSproto(strcpy(buf, "SetFactionLevel2"), XS_Client_SetFactionLevel2, file, "$$$$$$$"); - newXSproto(strcpy(buf, "GetRawItemAC"), XS_Client_GetRawItemAC, file, "$"); - newXSproto(strcpy(buf, "AccountID"), XS_Client_AccountID, file, "$"); - newXSproto(strcpy(buf, "AccountName"), XS_Client_AccountName, file, "$"); - newXSproto(strcpy(buf, "Admin"), XS_Client_Admin, file, "$"); - newXSproto(strcpy(buf, "CharacterID"), XS_Client_CharacterID, file, "$"); - newXSproto(strcpy(buf, "UpdateAdmin"), XS_Client_UpdateAdmin, file, "$;$"); - newXSproto(strcpy(buf, "UpdateWho"), XS_Client_UpdateWho, file, "$;$"); - newXSproto(strcpy(buf, "GuildRank"), XS_Client_GuildRank, file, "$"); - newXSproto(strcpy(buf, "GuildID"), XS_Client_GuildID, file, "$"); - newXSproto(strcpy(buf, "GetFace"), XS_Client_GetFace, file, "$"); - newXSproto(strcpy(buf, "TakeMoneyFromPP"), XS_Client_TakeMoneyFromPP, file, "$$;$"); - newXSproto(strcpy(buf, "AddMoneyToPP"), XS_Client_AddMoneyToPP, file, "$$$$$$"); - newXSproto(strcpy(buf, "TGB"), XS_Client_TGB, file, "$"); - newXSproto(strcpy(buf, "GetSkillPoints"), XS_Client_GetSkillPoints, file, "$"); - newXSproto(strcpy(buf, "SetSkillPoints"), XS_Client_SetSkillPoints, file, "$$"); - newXSproto(strcpy(buf, "IncreaseSkill"), XS_Client_IncreaseSkill, file, "$$;$"); - newXSproto(strcpy(buf, "IncreaseLanguageSkill"), XS_Client_IncreaseLanguageSkill, file, "$$;$"); - newXSproto(strcpy(buf, "GetSkill"), XS_Client_GetSkill, file, "$$"); - newXSproto(strcpy(buf, "GetRawSkill"), XS_Client_GetRawSkill, file, "$$"); - newXSproto(strcpy(buf, "HasSkill"), XS_Client_HasSkill, file, "$$"); - newXSproto(strcpy(buf, "CanHaveSkill"), XS_Client_CanHaveSkill, file, "$$"); - newXSproto(strcpy(buf, "SetSkill"), XS_Client_SetSkill, file, "$$$"); - newXSproto(strcpy(buf, "AddSkill"), XS_Client_AddSkill, file, "$$$"); - newXSproto(strcpy(buf, "CheckSpecializeIncrease"), XS_Client_CheckSpecializeIncrease, file, "$$"); - newXSproto(strcpy(buf, "CheckIncreaseSkill"), XS_Client_CheckIncreaseSkill, file, "$$;$"); - newXSproto(strcpy(buf, "SetLanguageSkill"), XS_Client_SetLanguageSkill, file, "$$$"); - newXSproto(strcpy(buf, "MaxSkill"), XS_Client_MaxSkill, file, "$$;$$"); - newXSproto(strcpy(buf, "GMKill"), XS_Client_GMKill, file, "$"); - newXSproto(strcpy(buf, "IsMedding"), XS_Client_IsMedding, file, "$"); - newXSproto(strcpy(buf, "GetDuelTarget"), XS_Client_GetDuelTarget, file, "$"); - newXSproto(strcpy(buf, "IsDueling"), XS_Client_IsDueling, file, "$"); - newXSproto(strcpy(buf, "SetDuelTarget"), XS_Client_SetDuelTarget, file, "$$"); - newXSproto(strcpy(buf, "SetDueling"), XS_Client_SetDueling, file, "$$"); - newXSproto(strcpy(buf, "ResetAA"), XS_Client_ResetAA, file, "$"); - newXSproto(strcpy(buf, "MemSpell"), XS_Client_MemSpell, file, "$$$;$"); - newXSproto(strcpy(buf, "UnmemSpell"), XS_Client_UnmemSpell, file, "$$;$"); - newXSproto(strcpy(buf, "UnmemSpellBySpellID"), XS_Client_UnmemSpellBySpellID, file, "$$"); - newXSproto(strcpy(buf, "UnmemSpellAll"), XS_Client_UnmemSpellAll, file, "$;$"); - newXSproto(strcpy(buf, "ScribeSpell"), XS_Client_ScribeSpell, file, "$$$;$"); - newXSproto(strcpy(buf, "UnscribeSpell"), XS_Client_UnscribeSpell, file, "$$;$"); - newXSproto(strcpy(buf, "UnscribeSpellAll"), XS_Client_UnscribeSpellAll, file, "$;$"); - newXSproto(strcpy(buf, "TrainDiscBySpellID"), XS_Client_TrainDiscBySpellID, file, "$$"); - newXSproto(strcpy(buf, "GetDiscSlotBySpellID"), XS_Client_GetDiscSlotBySpellID, file, "$$"); - newXSproto(strcpy(buf, "UntrainDisc"), XS_Client_UntrainDisc, file, "$$;$"); - newXSproto(strcpy(buf, "UntrainDiscAll"), XS_Client_UntrainDiscAll, file, "$;$"); - newXSproto(strcpy(buf, "IsSitting"), XS_Client_IsSitting, file, "$"); - newXSproto(strcpy(buf, "IsBecomeNPC"), XS_Client_IsBecomeNPC, file, "$"); - newXSproto(strcpy(buf, "GetBecomeNPCLevel"), XS_Client_GetBecomeNPCLevel, file, "$"); - newXSproto(strcpy(buf, "SetBecomeNPC"), XS_Client_SetBecomeNPC, file, "$$"); - newXSproto(strcpy(buf, "SetBecomeNPCLevel"), XS_Client_SetBecomeNPCLevel, file, "$$"); - newXSproto(strcpy(buf, "SetFeigned"), XS_Client_SetFeigned, file, "$$"); - newXSproto(strcpy(buf, "GetFeigned"), XS_Client_GetFeigned, file, "$"); - newXSproto(strcpy(buf, "AutoSplitEnabled"), XS_Client_AutoSplitEnabled, file, "$"); - newXSproto(strcpy(buf, "SetHorseId"), XS_Client_SetHorseId, file, "$$"); - newXSproto(strcpy(buf, "GetHorseId"), XS_Client_GetHorseId, file, "$"); - newXSproto(strcpy(buf, "NukeItem"), XS_Client_NukeItem, file, "$$;$"); - newXSproto(strcpy(buf, "SetTint"), XS_Client_SetTint, file, "$$$"); - newXSproto(strcpy(buf, "SetMaterial"), XS_Client_SetMaterial, file, "$$$"); - newXSproto(strcpy(buf, "Undye"), XS_Client_Undye, file, "$"); - newXSproto(strcpy(buf, "GetItemIDAt"), XS_Client_GetItemIDAt, file, "$$"); - newXSproto(strcpy(buf, "GetAugmentIDAt"), XS_Client_GetAugmentIDAt, file, "$$$"); - newXSproto(strcpy(buf, "DeleteItemInInventory"), XS_Client_DeleteItemInInventory, file, "$$;$$"); - newXSproto(strcpy(buf, "SummonItem"), XS_Client_SummonItem, file, "$$;$$$$$$$$"); - newXSproto(strcpy(buf, "SetStats"), XS_Client_SetStats, file, "$$$"); - newXSproto(strcpy(buf, "IncStats"), XS_Client_IncStats, file, "$$$"); - newXSproto(strcpy(buf, "DropItem"), XS_Client_DropItem, file, "$$"); - newXSproto(strcpy(buf, "BreakInvis"), XS_Client_BreakInvis, file, "$"); - newXSproto(strcpy(buf, "GetGroup"), XS_Client_GetGroup, file, "$"); - newXSproto(strcpy(buf, "LeaveGroup"), XS_Client_LeaveGroup, file, "$"); - newXSproto(strcpy(buf, "GetRaid"), XS_Client_GetRaid, file, "$"); - newXSproto(strcpy(buf, "IsGrouped"), XS_Client_IsGrouped, file, "$"); - newXSproto(strcpy(buf, "IsRaidGrouped"), XS_Client_IsRaidGrouped, file, "$"); - newXSproto(strcpy(buf, "Hungry"), XS_Client_Hungry, file, "$"); - newXSproto(strcpy(buf, "Thirsty"), XS_Client_Thirsty, file, "$"); - newXSproto(strcpy(buf, "GetInstrumentMod"), XS_Client_GetInstrumentMod, file, "$$"); - newXSproto(strcpy(buf, "DecreaseByID"), XS_Client_DecreaseByID, file, "$$$"); - newXSproto(strcpy(buf, "SlotConvert2"), XS_Client_SlotConvert2, file, "$$"); - newXSproto(strcpy(buf, "Escape"), XS_Client_Escape, file, "$"); - newXSproto(strcpy(buf, "RemoveNoRent"), XS_Client_RemoveNoRent, file, "$"); - newXSproto(strcpy(buf, "GoFish"), XS_Client_GoFish, file, "$"); - newXSproto(strcpy(buf, "ForageItem"), XS_Client_ForageItem, file, "$"); - newXSproto(strcpy(buf, "CalcPriceMod"), XS_Client_CalcPriceMod, file, "$;$$"); - newXSproto(strcpy(buf, "ResetTrade"), XS_Client_ResetTrade, file, "$"); - newXSproto(strcpy(buf, "UseDiscipline"), XS_Client_UseDiscipline, file, "$$$"); + newXSproto(strcpy(buf, "GetCarriedMoney"), XS_Client_GetCarriedMoney, file, "$"); newXSproto(strcpy(buf, "GetCharacterFactionLevel"), XS_Client_GetCharacterFactionLevel, file, "$$"); - newXSproto(strcpy(buf, "SetZoneFlag"), XS_Client_SetZoneFlag, file, "$$"); - newXSproto(strcpy(buf, "ClearZoneFlag"), XS_Client_ClearZoneFlag, file, "$$"); - newXSproto(strcpy(buf, "HasZoneFlag"), XS_Client_HasZoneFlag, file, "$$"); - newXSproto(strcpy(buf, "SendZoneFlagInfo"), XS_Client_SendZoneFlagInfo, file, "$$"); - newXSproto(strcpy(buf, "LoadZoneFlags"), XS_Client_LoadZoneFlags, file, "$"); - newXSproto(strcpy(buf, "SetAATitle"), XS_Client_SetAATitle, file, "$$;$"); newXSproto(strcpy(buf, "GetClientVersion"), XS_Client_GetClientVersion, file, "$"); newXSproto(strcpy(buf, "GetClientVersionBit"), XS_Client_GetClientVersionBit, file, "$"); - newXSproto(strcpy(buf, "SetTitleSuffix"), XS_Client_SetTitleSuffix, file, "$$;$"); - newXSproto(strcpy(buf, "SetAAPoints"), XS_Client_SetAAPoints, file, "$$"); - newXSproto(strcpy(buf, "GetAAPoints"), XS_Client_GetAAPoints, file, "$$"); - newXSproto(strcpy(buf, "GetSpentAA"), XS_Client_GetSpentAA, file, "$$"); - newXSproto(strcpy(buf, "AddAAPoints"), XS_Client_AddAAPoints, file, "$$"); - newXSproto(strcpy(buf, "RefundAA"), XS_Client_RefundAA, file, "$$"); - newXSproto(strcpy(buf, "GetModCharacterFactionLevel"), XS_Client_GetModCharacterFactionLevel, file, "$$"); - newXSproto(strcpy(buf, "GetLDoNWins"), XS_Client_GetLDoNWins, file, "$"); - newXSproto(strcpy(buf, "GetLDoNLosses"), XS_Client_GetLDoNLosses, file, "$"); - newXSproto(strcpy(buf, "GetLDoNWinsTheme"), XS_Client_GetLDoNWinsTheme, file, "$$"); - newXSproto(strcpy(buf, "GetLDoNLossesTheme"), XS_Client_GetLDoNLossesTheme, file, "$$"); - newXSproto(strcpy(buf, "GetItemAt"), XS_Client_GetItemAt, file, "$$"); - newXSproto(strcpy(buf, "GetAugmentAt"), XS_Client_GetAugmentAt, file, "$$$"); - newXSproto(strcpy(buf, "GetStartZone"), XS_Client_GetStartZone, file, "$"); - newXSproto(strcpy(buf, "SetStartZone"), XS_Client_SetStartZone, file, "$$"); - newXSproto(strcpy(buf, "KeyRingAdd"), XS_Client_KeyRingAdd, file, "$$"); - newXSproto(strcpy(buf, "KeyRingCheck"), XS_Client_KeyRingCheck, file, "$$"); - newXSproto(strcpy(buf, "AddPVPPoints"), XS_Client_AddPVPPoints, file, "$$"); - newXSproto(strcpy(buf, "AddCrystals"), XS_Client_AddCrystals, file, "$$"); - newXSproto(strcpy(buf, "GetPVPPoints"), XS_Client_GetPVPPoints, file, "$"); - newXSproto(strcpy(buf, "GetRadiantCrystals"), XS_Client_GetRadiantCrystals, file, "$"); - newXSproto(strcpy(buf, "GetEbonCrystals"), XS_Client_GetEbonCrystals, file, "$"); - newXSproto(strcpy(buf, "ReadBook"), XS_Client_ReadBook, file, "$$$"); - newXSproto(strcpy(buf, "UpdateGroupAAs"), XS_Client_UpdateGroupAAs, file, "$$$"); - newXSproto(strcpy(buf, "GetGroupPoints"), XS_Client_GetGroupPoints, file, "$"); - newXSproto(strcpy(buf, "GetRaidPoints"), XS_Client_GetRaidPoints, file, "$"); - newXSproto(strcpy(buf, "LearnRecipe"), XS_Client_LearnRecipe, file, "$$"); - newXSproto(strcpy(buf, "GetEndurance"), XS_Client_GetEndurance, file, "$"); - newXSproto(strcpy(buf, "GetMaxEndurance"), XS_Client_GetMaxEndurance, file, "$"); - newXSproto(strcpy(buf, "GetEnduranceRatio"), XS_Client_GetEnduranceRatio, file, "$"); - newXSproto(strcpy(buf, "SetEndurance"), XS_Client_SetEndurance, file, "$$"); - newXSproto(strcpy(buf, "SendOPTranslocateConfirm"), XS_Client_SendOPTranslocateConfirm, file, "$$$"); - newXSproto(strcpy(buf, "NPCSpawn"), XS_Client_NPCSpawn, file, "$$$;$"); - newXSproto(strcpy(buf, "GetIP"), XS_Client_GetIP, file, "$"); - newXSproto(strcpy(buf, "AddLevelBasedExp"), XS_Client_AddLevelBasedExp, file, "$$;$"); - newXSproto(strcpy(buf, "IncrementAA"), XS_Client_IncrementAA, file, "$$"); - newXSproto(strcpy(buf, "GrantAlternateAdvancementAbility"), XS_Client_GrantAlternateAdvancementAbility, file, - "$$$;$"); - newXSproto(strcpy(buf, "GetAALevel"), XS_Client_GetAALevel, file, "$$"); - newXSproto(strcpy(buf, "MarkCompassLoc"), XS_Client_MarkCompassLoc, file, "$$$$"); - newXSproto(strcpy(buf, "ClearCompassMark"), XS_Client_ClearCompassMark, file, "$"); - newXSproto(strcpy(buf, "GetFreeSpellBookSlot"), XS_Client_GetFreeSpellBookSlot, file, "$;$"); - newXSproto(strcpy(buf, "GetSpellBookSlotBySpellID"), XS_Client_GetSpellBookSlotBySpellID, file, "$$"); - newXSproto(strcpy(buf, "UpdateTaskActivity"), XS_Client_UpdateTaskActivity, file, "$$$$;$"); - newXSproto(strcpy(buf, "AssignTask"), XS_Client_AssignTask, file, "$$$;$"); - newXSproto(strcpy(buf, "FailTask"), XS_Client_FailTask, file, "$$"); - newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$"); - newXSproto(strcpy(buf, "IsTaskActive"), XS_Client_IsTaskActive, file, "$$"); - newXSproto(strcpy(buf, "IsTaskActivityActive"), XS_Client_IsTaskActivityActive, file, "$$$"); - newXSproto(strcpy(buf, "GetTaskActivityDoneCount"), XS_Client_GetTaskActivityDoneCount, file, "$$$"); newXSproto(strcpy(buf, "GetCorpseCount"), XS_Client_GetCorpseCount, file, "$"); newXSproto(strcpy(buf, "GetCorpseID"), XS_Client_GetCorpseID, file, "$$"); newXSproto(strcpy(buf, "GetCorpseItemAt"), XS_Client_GetCorpseItemAt, file, "$$$"); - newXSproto(strcpy(buf, "AssignToInstance"), XS_Client_AssignToInstance, file, "$$"); - newXSproto(strcpy(buf, "Freeze"), XS_Client_Freeze, file, "$"); - newXSproto(strcpy(buf, "UnFreeze"), XS_Client_UnFreeze, file, "$"); - newXSproto(strcpy(buf, "GetAggroCount"), XS_Client_GetAggroCount, file, "$"); - newXSproto(strcpy(buf, "GetCarriedMoney"), XS_Client_GetCarriedMoney, file, "$"); - newXSproto(strcpy(buf, "GetAllMoney"), XS_Client_GetAllMoney, file, "$"); - newXSproto(strcpy(buf, "GetItemInInventory"), XS_Client_GetItemInInventory, file, "$$"); - newXSproto(strcpy(buf, "SetCustomItemData"), XS_Client_SetCustomItemData, file, "$$$$"); newXSproto(strcpy(buf, "GetCustomItemData"), XS_Client_GetCustomItemData, file, "$$$"); - newXSproto(strcpy(buf, "OpenLFGuildWindow"), XS_Client_OpenLFGuildWindow, file, "$"); - newXSproto(strcpy(buf, "SignalClient"), XS_Client_SignalClient, file, "$"); - newXSproto(strcpy(buf, "AddAlternateCurrencyValue"), XS_Client_AddAlternateCurrencyValue, file, "$$$"); - newXSproto(strcpy(buf, "SendWebLink"), XS_Client_SendWebLink, file, "$:$"); - newXSproto(strcpy(buf, "GetInstanceID"), XS_Client_GetInstanceID, file, "$$"); - newXSproto(strcpy(buf, "HasSpellScribed"), XS_Client_HasSkill, file, "$$"); - newXSproto(strcpy(buf, "SetAccountFlag"), XS_Client_SetAccountFlag, file, "$$"); - newXSproto(strcpy(buf, "GetAccountFlag"), XS_Client_GetAccountFlag, file, "$$"); + newXSproto(strcpy(buf, "GetDiscSlotBySpellID"), XS_Client_GetDiscSlotBySpellID, file, "$$"); + newXSproto(strcpy(buf, "GetDuelTarget"), XS_Client_GetDuelTarget, file, "$"); + newXSproto(strcpy(buf, "GetEbonCrystals"), XS_Client_GetEbonCrystals, file, "$"); + newXSproto(strcpy(buf, "GetEndurance"), XS_Client_GetEndurance, file, "$"); + newXSproto(strcpy(buf, "GetEnduranceRatio"), XS_Client_GetEnduranceRatio, file, "$"); + newXSproto(strcpy(buf, "GetEXP"), XS_Client_GetEXP, file, "$"); + newXSproto(strcpy(buf, "GetFace"), XS_Client_GetFace, file, "$"); + newXSproto(strcpy(buf, "GetFactionLevel"), XS_Client_GetFactionLevel, file, "$$$$$$$$"); + newXSproto(strcpy(buf, "GetFeigned"), XS_Client_GetFeigned, file, "$"); + newXSproto(strcpy(buf, "GetFreeSpellBookSlot"), XS_Client_GetFreeSpellBookSlot, file, "$;$"); + newXSproto(strcpy(buf, "GetGM"), XS_Client_GetGM, file, "$"); + newXSproto(strcpy(buf, "GetGroup"), XS_Client_GetGroup, file, "$"); + newXSproto(strcpy(buf, "GetGroupPoints"), XS_Client_GetGroupPoints, file, "$"); + newXSproto(strcpy(buf, "GetHorseId"), XS_Client_GetHorseId, file, "$"); newXSproto(strcpy(buf, "GetHunger"), XS_Client_GetHunger, file, "$$"); - newXSproto(strcpy(buf, "GetThirst"), XS_Client_GetThirst, file, "$$"); - newXSproto(strcpy(buf, "SetHunger"), XS_Client_SetHunger, file, "$$"); - newXSproto(strcpy(buf, "SetThirst"), XS_Client_SetThirst, file, "$$"); - newXSproto(strcpy(buf, "SetConsumption"), XS_Client_SetConsumption, file, "$$$"); - newXSproto(strcpy(buf, "SilentMessage"), XS_Client_SilentMessage, file, "$$"); - newXSproto(strcpy(buf, "PlayMP3"), XS_Client_PlayMP3, file, "$;$"); - newXSproto(strcpy(buf, "SendTargetCommand"), XS_Client_SendTargetCommand, file, "$$"); - newXSproto(strcpy(buf, "ExpeditionMessage"), XS_Client_ExpeditionMessage, file, "$$$"); - newXSproto(strcpy(buf, "SendMarqueeMessage"), XS_Client_SendMarqueeMessage, file, "$$$$$$$"); - newXSproto(strcpy(buf, "SendColoredText"), XS_Client_SendColoredText, file, "$$$"); - newXSproto(strcpy(buf, "SendSpellAnim"), XS_Client_SendSpellAnim, file, "$$$"); + newXSproto(strcpy(buf, "GetInstanceID"), XS_Client_GetInstanceID, file, "$$"); + newXSproto(strcpy(buf, "GetInstrumentMod"), XS_Client_GetInstrumentMod, file, "$$"); + newXSproto(strcpy(buf, "GetIP"), XS_Client_GetIP, file, "$"); + newXSproto(strcpy(buf, "GetItemAt"), XS_Client_GetItemAt, file, "$$"); + newXSproto(strcpy(buf, "GetItemIDAt"), XS_Client_GetItemIDAt, file, "$$"); + newXSproto(strcpy(buf, "GetItemInInventory"), XS_Client_GetItemInInventory, file, "$$"); + newXSproto(strcpy(buf, "GetLanguageSkill"), XS_Client_GetLanguageSkill, file, "$$"); + newXSproto(strcpy(buf, "GetLastName"), XS_Client_GetLastName, file, "$"); + newXSproto(strcpy(buf, "GetLDoNLosses"), XS_Client_GetLDoNLosses, file, "$"); + newXSproto(strcpy(buf, "GetLDoNLossesTheme"), XS_Client_GetLDoNLossesTheme, file, "$$"); + newXSproto(strcpy(buf, "GetLDoNPointsTheme"), XS_Client_GetLDoNPointsTheme, file, "$"); + newXSproto(strcpy(buf, "GetLDoNWins"), XS_Client_GetLDoNWins, file, "$"); + newXSproto(strcpy(buf, "GetLDoNWinsTheme"), XS_Client_GetLDoNWinsTheme, file, "$$"); + newXSproto(strcpy(buf, "GetMaxEndurance"), XS_Client_GetMaxEndurance, file, "$"); + newXSproto(strcpy(buf, "GetModCharacterFactionLevel"), XS_Client_GetModCharacterFactionLevel, file, "$$"); + newXSproto(strcpy(buf, "GetMoney"), XS_Client_GetMoney, file, "$$$"); + newXSproto(strcpy(buf, "GetPVP"), XS_Client_GetPVP, file, "$"); + newXSproto(strcpy(buf, "GetPVPPoints"), XS_Client_GetPVPPoints, file, "$"); + newXSproto(strcpy(buf, "GetRadiantCrystals"), XS_Client_GetRadiantCrystals, file, "$"); + newXSproto(strcpy(buf, "GetRaid"), XS_Client_GetRaid, file, "$"); + newXSproto(strcpy(buf, "GetRaidPoints"), XS_Client_GetRaidPoints, file, "$"); + newXSproto(strcpy(buf, "GetRawItemAC"), XS_Client_GetRawItemAC, file, "$"); + newXSproto(strcpy(buf, "GetRawSkill"), XS_Client_GetRawSkill, file, "$$"); + newXSproto(strcpy(buf, "GetSkill"), XS_Client_GetSkill, file, "$$"); + newXSproto(strcpy(buf, "GetSkillPoints"), XS_Client_GetSkillPoints, file, "$"); + newXSproto(strcpy(buf, "GetSpellBookSlotBySpellID"), XS_Client_GetSpellBookSlotBySpellID, file, "$$"); + newXSproto(strcpy(buf, "GetSpentAA"), XS_Client_GetSpentAA, file, "$$"); + newXSproto(strcpy(buf, "GetStartZone"), XS_Client_GetStartZone, file, "$"); newXSproto(strcpy(buf, "GetTargetRingX"), XS_Client_GetTargetRingX, file, "$$"); newXSproto(strcpy(buf, "GetTargetRingY"), XS_Client_GetTargetRingY, file, "$$"); newXSproto(strcpy(buf, "GetTargetRingZ"), XS_Client_GetTargetRingZ, file, "$$"); - newXSproto(strcpy(buf, "QuestReward"), XS_Client_QuestReward, file, "$$;$$$$$$$"); - newXSproto(strcpy(buf, "CalcEXP"), XS_Client_CalcEXP, file, "$"); - newXSproto(strcpy(buf, "GetMoney"), XS_Client_GetMoney, file, "$$$"); - newXSproto(strcpy(buf, "GetAccountAge"), XS_Client_GetAccountAge, file, "$"); + newXSproto(strcpy(buf, "GetTaskActivityDoneCount"), XS_Client_GetTaskActivityDoneCount, file, "$$$"); + newXSproto(strcpy(buf, "GetThirst"), XS_Client_GetThirst, file, "$$"); + newXSproto(strcpy(buf, "GetTotalSecondsPlayed"), XS_Client_GetTotalSecondsPlayed, file, "$"); + newXSproto(strcpy(buf, "GetWeight"), XS_Client_GetWeight, file, "$"); + newXSproto(strcpy(buf, "GMKill"), XS_Client_GMKill, file, "$"); + newXSproto(strcpy(buf, "GoFish"), XS_Client_GoFish, file, "$"); + newXSproto(strcpy(buf, "GrantAlternateAdvancementAbility"), XS_Client_GrantAlternateAdvancementAbility, file, "$$$;$"); + newXSproto(strcpy(buf, "GuildID"), XS_Client_GuildID, file, "$"); + newXSproto(strcpy(buf, "GuildRank"), XS_Client_GuildRank, file, "$"); + newXSproto(strcpy(buf, "HasSkill"), XS_Client_HasSkill, file, "$$"); + newXSproto(strcpy(buf, "HasSpellScribed"), XS_Client_HasSkill, file, "$$"); + newXSproto(strcpy(buf, "HasZoneFlag"), XS_Client_HasZoneFlag, file, "$$"); + newXSproto(strcpy(buf, "Hungry"), XS_Client_Hungry, file, "$"); + newXSproto(strcpy(buf, "IncreaseLanguageSkill"), XS_Client_IncreaseLanguageSkill, file, "$$;$"); + newXSproto(strcpy(buf, "IncreaseSkill"), XS_Client_IncreaseSkill, file, "$$;$"); + newXSproto(strcpy(buf, "IncrementAA"), XS_Client_IncrementAA, file, "$$"); + newXSproto(strcpy(buf, "IncStats"), XS_Client_IncStats, file, "$$$"); + newXSproto(strcpy(buf, "InZone"), XS_Client_InZone, file, "$"); + newXSproto(strcpy(buf, "IsBecomeNPC"), XS_Client_IsBecomeNPC, file, "$"); + newXSproto(strcpy(buf, "IsDueling"), XS_Client_IsDueling, file, "$"); + newXSproto(strcpy(buf, "IsGrouped"), XS_Client_IsGrouped, file, "$"); + newXSproto(strcpy(buf, "IsLD"), XS_Client_IsLD, file, "$"); + newXSproto(strcpy(buf, "IsMedding"), XS_Client_IsMedding, file, "$"); + newXSproto(strcpy(buf, "IsRaidGrouped"), XS_Client_IsRaidGrouped, file, "$"); + newXSproto(strcpy(buf, "IsSitting"), XS_Client_IsSitting, file, "$"); + newXSproto(strcpy(buf, "IsTaskActive"), XS_Client_IsTaskActive, file, "$$"); + newXSproto(strcpy(buf, "IsTaskActivityActive"), XS_Client_IsTaskActivityActive, file, "$$$"); + newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$"); + newXSproto(strcpy(buf, "KeyRingAdd"), XS_Client_KeyRingAdd, file, "$$"); + newXSproto(strcpy(buf, "KeyRingCheck"), XS_Client_KeyRingCheck, file, "$$"); + newXSproto(strcpy(buf, "Kick"), XS_Client_Kick, file, "$"); + newXSproto(strcpy(buf, "LearnRecipe"), XS_Client_LearnRecipe, file, "$$"); + newXSproto(strcpy(buf, "LeaveGroup"), XS_Client_LeaveGroup, file, "$"); + newXSproto(strcpy(buf, "LoadZoneFlags"), XS_Client_LoadZoneFlags, file, "$"); + newXSproto(strcpy(buf, "MarkCompassLoc"), XS_Client_MarkCompassLoc, file, "$$$$"); + newXSproto(strcpy(buf, "MaxSkill"), XS_Client_MaxSkill, file, "$$;$$"); + newXSproto(strcpy(buf, "MemSpell"), XS_Client_MemSpell, file, "$$$;$"); + newXSproto(strcpy(buf, "MovePC"), XS_Client_MovePC, file, "$$$$$$"); + newXSproto(strcpy(buf, "MovePCInstance"), XS_Client_MovePCInstance, file, "$$$$$$$"); + newXSproto(strcpy(buf, "NPCSpawn"), XS_Client_NPCSpawn, file, "$$$;$"); + newXSproto(strcpy(buf, "NukeItem"), XS_Client_NukeItem, file, "$$;$"); + newXSproto(strcpy(buf, "OpenLFGuildWindow"), XS_Client_OpenLFGuildWindow, file, "$"); + newXSproto(strcpy(buf, "PlayMP3"), XS_Client_PlayMP3, file, "$;$"); newXSproto(strcpy(buf, "Popup2"), XS_Client_Popup2, file, "$$$;$$$$$$$"); + newXSproto(strcpy(buf, "QuestReward"), XS_Client_QuestReward, file, "$$;$$$$$$$"); + newXSproto(strcpy(buf, "ReadBook"), XS_Client_ReadBook, file, "$$$"); + newXSproto(strcpy(buf, "RefundAA"), XS_Client_RefundAA, file, "$$"); + newXSproto(strcpy(buf, "RemoveNoRent"), XS_Client_RemoveNoRent, file, "$"); + newXSproto(strcpy(buf, "ResetAA"), XS_Client_ResetAA, file, "$"); + newXSproto(strcpy(buf, "ResetTrade"), XS_Client_ResetTrade, file, "$"); + newXSproto(strcpy(buf, "Save"), XS_Client_Save, file, "$$"); + newXSproto(strcpy(buf, "SaveBackup"), XS_Client_SaveBackup, file, "$"); + newXSproto(strcpy(buf, "ScribeSpell"), XS_Client_ScribeSpell, file, "$$$;$"); + newXSproto(strcpy(buf, "SendColoredText"), XS_Client_SendColoredText, file, "$$$"); + newXSproto(strcpy(buf, "SendMarqueeMessage"), XS_Client_SendMarqueeMessage, file, "$$$$$$$"); + newXSproto(strcpy(buf, "SendOPTranslocateConfirm"), XS_Client_SendOPTranslocateConfirm, file, "$$$"); + newXSproto(strcpy(buf, "SendSound"), XS_Client_SendSound, file, "$"); + newXSproto(strcpy(buf, "SendSpellAnim"), XS_Client_SendSpellAnim, file, "$$$"); + newXSproto(strcpy(buf, "SendTargetCommand"), XS_Client_SendTargetCommand, file, "$$"); + newXSproto(strcpy(buf, "SendWebLink"), XS_Client_SendWebLink, file, "$:$"); + newXSproto(strcpy(buf, "SendZoneFlagInfo"), XS_Client_SendZoneFlagInfo, file, "$$"); + newXSproto(strcpy(buf, "SetAAPoints"), XS_Client_SetAAPoints, file, "$$"); + newXSproto(strcpy(buf, "SetAATitle"), XS_Client_SetAATitle, file, "$$;$"); + newXSproto(strcpy(buf, "SetAccountFlag"), XS_Client_SetAccountFlag, file, "$$"); + newXSproto(strcpy(buf, "SetBaseClass"), XS_Client_SetBaseClass, file, "$$"); + newXSproto(strcpy(buf, "SetBaseGender"), XS_Client_SetBaseGender, file, "$$"); + newXSproto(strcpy(buf, "SetBaseRace"), XS_Client_SetBaseRace, file, "$$"); + newXSproto(strcpy(buf, "SetBecomeNPC"), XS_Client_SetBecomeNPC, file, "$$"); + newXSproto(strcpy(buf, "SetBecomeNPCLevel"), XS_Client_SetBecomeNPCLevel, file, "$$"); + newXSproto(strcpy(buf, "SetBindPoint"), XS_Client_SetBindPoint, file, "$;$$$$$"); + newXSproto(strcpy(buf, "SetConsumption"), XS_Client_SetConsumption, file, "$$$"); + newXSproto(strcpy(buf, "SetCustomItemData"), XS_Client_SetCustomItemData, file, "$$$$"); + newXSproto(strcpy(buf, "SetDeity"), XS_Client_SetDeity, file, "$$"); + newXSproto(strcpy(buf, "SetDueling"), XS_Client_SetDueling, file, "$$"); + newXSproto(strcpy(buf, "SetDuelTarget"), XS_Client_SetDuelTarget, file, "$$"); + newXSproto(strcpy(buf, "SetEndurance"), XS_Client_SetEndurance, file, "$$"); + newXSproto(strcpy(buf, "SetEXP"), XS_Client_SetEXP, file, "$$$;$"); + newXSproto(strcpy(buf, "SetFactionLevel"), XS_Client_SetFactionLevel, file, "$$$$$$"); + newXSproto(strcpy(buf, "SetFactionLevel2"), XS_Client_SetFactionLevel2, file, "$$$$$$$"); + newXSproto(strcpy(buf, "SetFeigned"), XS_Client_SetFeigned, file, "$$"); + newXSproto(strcpy(buf, "SetGM"), XS_Client_SetGM, file, "$$"); + newXSproto(strcpy(buf, "SetHorseId"), XS_Client_SetHorseId, file, "$$"); + newXSproto(strcpy(buf, "SetHunger"), XS_Client_SetHunger, file, "$$"); + newXSproto(strcpy(buf, "SetLanguageSkill"), XS_Client_SetLanguageSkill, file, "$$$"); + newXSproto(strcpy(buf, "SetMaterial"), XS_Client_SetMaterial, file, "$$$"); + newXSproto(strcpy(buf, "SetPrimaryWeaponOrnamentation"), XS_Client_SetPrimaryWeaponOrnamentation, file, "$$"); + newXSproto(strcpy(buf, "SetPVP"), XS_Client_SetPVP, file, "$$"); + newXSproto(strcpy(buf, "SetSecondaryWeaponOrnamentation"), XS_Client_SetSecondaryWeaponOrnamentation, file, "$$"); + newXSproto(strcpy(buf, "SetSkill"), XS_Client_SetSkill, file, "$$$"); + newXSproto(strcpy(buf, "SetSkillPoints"), XS_Client_SetSkillPoints, file, "$$"); + newXSproto(strcpy(buf, "SetStartZone"), XS_Client_SetStartZone, file, "$$"); + newXSproto(strcpy(buf, "SetStats"), XS_Client_SetStats, file, "$$$"); + newXSproto(strcpy(buf, "SetThirst"), XS_Client_SetThirst, file, "$$"); + newXSproto(strcpy(buf, "SetTint"), XS_Client_SetTint, file, "$$$"); + newXSproto(strcpy(buf, "SetTitleSuffix"), XS_Client_SetTitleSuffix, file, "$$;$"); + newXSproto(strcpy(buf, "SetZoneFlag"), XS_Client_SetZoneFlag, file, "$$"); + newXSproto(strcpy(buf, "SignalClient"), XS_Client_SignalClient, file, "$"); + newXSproto(strcpy(buf, "SilentMessage"), XS_Client_SilentMessage, file, "$$"); + newXSproto(strcpy(buf, "SlotConvert2"), XS_Client_SlotConvert2, file, "$$"); + newXSproto(strcpy(buf, "Stand"), XS_Client_Stand, file, "$"); + newXSproto(strcpy(buf, "SummonItem"), XS_Client_SummonItem, file, "$$;$$$$$$$$"); + newXSproto(strcpy(buf, "TakeMoneyFromPP"), XS_Client_TakeMoneyFromPP, file, "$$;$"); + newXSproto(strcpy(buf, "TGB"), XS_Client_TGB, file, "$"); + newXSproto(strcpy(buf, "Thirsty"), XS_Client_Thirsty, file, "$"); + newXSproto(strcpy(buf, "TrainDiscBySpellID"), XS_Client_TrainDiscBySpellID, file, "$$"); + newXSproto(strcpy(buf, "Undye"), XS_Client_Undye, file, "$"); + newXSproto(strcpy(buf, "UnFreeze"), XS_Client_UnFreeze, file, "$"); + newXSproto(strcpy(buf, "UnmemSpell"), XS_Client_UnmemSpell, file, "$$;$"); + newXSproto(strcpy(buf, "UnmemSpellAll"), XS_Client_UnmemSpellAll, file, "$;$"); + newXSproto(strcpy(buf, "UnmemSpellBySpellID"), XS_Client_UnmemSpellBySpellID, file, "$$"); + newXSproto(strcpy(buf, "UnscribeSpell"), XS_Client_UnscribeSpell, file, "$$;$"); + newXSproto(strcpy(buf, "UnscribeSpellAll"), XS_Client_UnscribeSpellAll, file, "$;$"); + newXSproto(strcpy(buf, "UntrainDisc"), XS_Client_UntrainDisc, file, "$$;$"); + newXSproto(strcpy(buf, "UntrainDiscAll"), XS_Client_UntrainDiscAll, file, "$;$"); + newXSproto(strcpy(buf, "UpdateAdmin"), XS_Client_UpdateAdmin, file, "$;$"); + newXSproto(strcpy(buf, "UpdateGroupAAs"), XS_Client_UpdateGroupAAs, file, "$$$"); + newXSproto(strcpy(buf, "UpdateLDoNPoints"), XS_Client_UpdateLDoNPoints, file, "$$$"); + newXSproto(strcpy(buf, "UpdateTaskActivity"), XS_Client_UpdateTaskActivity, file, "$$$$;$"); + newXSproto(strcpy(buf, "UpdateWho"), XS_Client_UpdateWho, file, "$;$"); + newXSproto(strcpy(buf, "UseDiscipline"), XS_Client_UseDiscipline, file, "$$$"); + newXSproto(strcpy(buf, "WorldKick"), XS_Client_WorldKick, file, "$"); XSRETURN_YES; } diff --git a/zone/zonedb.h b/zone/zonedb.h index 78f78ab83..843bdace5 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -271,7 +271,12 @@ public: void DeleteBuyLines(uint32 CharID); void UpdateBuyLine(uint32 CharID, uint32 BuySlot, uint32 Quantity); - /* General Character Related Stuff */ + /** + ************************************************ + * Character + ************************************************ + */ + bool SetServerFilters(char* name, ServerSideFilters_Struct *ssfs); uint32 GetServerFilters(char* name, ServerSideFilters_Struct *ssfs); @@ -284,46 +289,43 @@ public: void RemoveTempFactions(Client *c); void UpdateItemRecastTimestamps(uint32 char_id, uint32 recast_type, uint32 timestamp); - /* Character Data Loaders */ - bool LoadCharacterFactionValues(uint32 character_id, faction_map & val_list); - bool LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Struct* pp); - bool LoadCharacterMemmedSpells(uint32 character_id, PlayerProfile_Struct* pp); - bool LoadCharacterLanguages(uint32 character_id, PlayerProfile_Struct* pp); - bool LoadCharacterDisciplines(uint32 character_id, PlayerProfile_Struct* pp); - bool LoadCharacterSkills(uint32 character_id, PlayerProfile_Struct* pp); - bool LoadCharacterData(uint32 character_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp); - bool LoadCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp); - bool LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct* pp); - bool LoadCharacterMaterialColor(uint32 character_id, PlayerProfile_Struct* pp); - bool LoadCharacterBandolier(uint32 character_id, PlayerProfile_Struct* pp); - bool LoadCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp); - bool LoadCharacterPotions(uint32 character_id, PlayerProfile_Struct* pp); - bool LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp); + bool DeleteCharacterAAs(uint32 character_id); + bool DeleteCharacterBandolier(uint32 character_id, uint32 band_id); + bool DeleteCharacterDisc(uint32 character_id, uint32 slot_id); + bool DeleteCharacterDye(uint32 character_id); + bool DeleteCharacterLeadershipAAs(uint32 character_id); + bool DeleteCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); + bool DeleteCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); - /* Character Data Saves */ - bool SaveCharacterBindPoint(uint32 character_id, const BindStruct &bind, uint32 bind_num); - bool SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp); - bool SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp); - bool SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level, uint32 charges); - bool SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); - bool SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); - bool SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color); - bool SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint32 value); - bool SaveCharacterLanguage(uint32 character_id, uint32 lang_id, uint32 value); - bool SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 disc_id); - bool SaveCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp); - bool SaveCharacterBandolier(uint32 character_id, uint8 bandolier_id, uint8 bandolier_slot, uint32 item_id, uint32 icon, const char* bandolier_name); - bool SaveCharacterPotionBelt(uint32 character_id, uint8 potion_id, uint32 item_id, uint32 icon); - bool SaveCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterBandolier(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterData(uint32 character_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp); + bool LoadCharacterDisciplines(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterFactionValues(uint32 character_id, faction_map & val_list); + bool LoadCharacterLanguages(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterMaterialColor(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterMemmedSpells(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterPotions(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterSkills(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Struct* pp); + bool LoadCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp); - /* Character Data Deletes */ - bool DeleteCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); - bool DeleteCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); - bool DeleteCharacterDisc(uint32 character_id, uint32 slot_id); - bool DeleteCharacterBandolier(uint32 character_id, uint32 band_id); - bool DeleteCharacterLeadershipAAs(uint32 character_id); - bool DeleteCharacterAAs(uint32 character_id); - bool DeleteCharacterDye(uint32 character_id); + bool SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level, uint32 charges); + bool SaveCharacterBandolier(uint32 character_id, uint8 bandolier_id, uint8 bandolier_slot, uint32 item_id, uint32 icon, const char* bandolier_name); + bool SaveCharacterBindPoint(uint32 character_id, const BindStruct &bind, uint32 bind_num); + bool SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp); + bool SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp); + bool SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 disc_id); + bool SaveCharacterLanguage(uint32 character_id, uint32 lang_id, uint32 value); + bool SaveCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp); + bool SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color); + bool SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); + bool SaveCharacterPotionBelt(uint32 character_id, uint8 potion_id, uint32 item_id, uint32 icon); + bool SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint32 value); + bool SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); + bool SaveCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp); /* Character Inventory */ bool NoRentExpired(const char* name); From 4ba5ef91708eaed63fdc89fcb02935382dc45701 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 2 Jan 2019 02:36:12 -0600 Subject: [PATCH 06/11] Reload scaling data on repop --- common/database.cpp | 34 ++++++++++++++++++++++++---------- zone/zone.cpp | 14 +++++++++----- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 8ff79a44c..0af9169e5 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -1408,25 +1408,39 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 return base_cap; } -uint32 Database::GetCharacterInfo(const char* iName, uint32* oAccID, uint32* oZoneID, uint32* oInstanceID, float* oX, float* oY, float* oZ) { - std::string query = StringFormat("SELECT `id`, `account_id`, `zone_id`, `zone_instance`, `x`, `y`, `z` FROM `character_data` WHERE `name` = '%s'", iName); +uint32 Database::GetCharacterInfo( + const char *iName, + uint32 *oAccID, + uint32 *oZoneID, + uint32 *oInstanceID, + float *oX, + float *oY, + float *oZ +) +{ + std::string query = StringFormat( + "SELECT `id`, `account_id`, `zone_id`, `zone_instance`, `x`, `y`, `z` FROM `character_data` WHERE `name` = '%s'", + EscapeString(iName).c_str() + ); + auto results = QueryDatabase(query); if (!results.Success()) { return 0; } - if (results.RowCount() != 1) + if (results.RowCount() != 1) { return 0; + } - auto row = results.begin(); + auto row = results.begin(); uint32 charid = atoi(row[0]); - if (oAccID){ *oAccID = atoi(row[1]); } - if (oZoneID){ *oZoneID = atoi(row[2]); } - if (oInstanceID){ *oInstanceID = atoi(row[3]); } - if (oX){ *oX = atof(row[4]); } - if (oY){ *oY = atof(row[5]); } - if (oZ){ *oZ = atof(row[6]); } + if (oAccID) { *oAccID = atoi(row[1]); } + if (oZoneID) { *oZoneID = atoi(row[2]); } + if (oInstanceID) { *oInstanceID = atoi(row[3]); } + if (oX) { *oX = atof(row[4]); } + if (oY) { *oY = atof(row[5]); } + if (oZ) { *oZ = atof(row[6]); } return charid; } diff --git a/zone/zone.cpp b/zone/zone.cpp index c6f5c8ac5..3fa3e5370 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -54,6 +54,7 @@ #include "zone.h" #include "zone_config.h" #include "mob_movement_manager.h" +#include "npc_scale_manager.h" #include #include @@ -65,8 +66,6 @@ #define strcasecmp _stricmp #endif - - extern bool staticzone; extern NetConnection net; extern PetitionList petition_list; @@ -74,6 +73,7 @@ extern QuestParserCollection* parse; extern uint32 numclients; extern WorldServer worldserver; extern Zone* zone; +extern NpcScaleManager* npc_scale_manager; Mutex MZoneShutdown; @@ -1509,18 +1509,22 @@ void Zone::RepopClose(const glm::vec4& client_position, uint32 repop_distance) mod_repop(); } -void Zone::Repop(uint32 delay) { +void Zone::Repop(uint32 delay) +{ - if(!Depop()) + if (!Depop()) { return; + } - LinkedListIterator iterator(spawn2_list); + LinkedListIterator iterator(spawn2_list); iterator.Reset(); while (iterator.MoreElements()) { iterator.RemoveCurrent(); } + npc_scale_manager->LoadScaleData(); + entity_list.ClearTrapPointers(); quest_manager.ClearAllTimers(); From b870873ffe8b44011654bc21cfd289a0846631d5 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 2 Jan 2019 02:57:47 -0600 Subject: [PATCH 07/11] Changelog [skip ci] --- changelog.txt | 22 ++++++++++++++++++++++ zone/command.cpp | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index b0df4474f..43bc26bfa 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,28 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 1/1/2019 == +Akkadius: + - [Logging] Added new logging category "MobAppearance" + - [DevTools] Proximity show of NPC now shows a "Path finding" circle around the proximity nodes to more clearly display + - [Scaling] Global base scaling data now refreshes from the database on #repop + - [Commands] Implemented command #killallnpcs [npc_name] for testing, leave blank for all attackable NPC's + - NPC and Player Textures + - Textures that have been changed with #wearchange / #wc or any wearchange quest script call will now stick + for new clients entering a zone + - Weapon models for NPCs changed using wearchange will stick as well during combat and when new clients enter the zone + - The above changes allow for customization of a zone and NPC's without needing static data configured on npc_types + table data and allows for much more customization options + - Implemented Quest API Calls + Perl + $client->SetPrimaryWeaponOrnamentation(uint32 model_id); + $client->SetSecondaryWeaponOrnamentation(uint32 model_id); + Lua + client:SetPrimaryWeaponOrnamentation(uint32 model_id); + client:SetSecondaryWeaponOrnamentation(uint32 model_id); + - Both of these API calls persist an ornamentation to the weapon in the inventory table and will load both + in character select and cross zone + == 12/30/2018 == Akkadius (KLS): diff --git a/zone/command.cpp b/zone/command.cpp index 2645e7ece..6362337a2 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -249,7 +249,7 @@ int command_init(void) command_add("itemsearch", "[search criteria] - Search for an item", 10, command_itemsearch) || command_add("kick", "[charname] - Disconnect charname", 150, command_kick) || command_add("kill", "- Kill your target", 100, command_kill) || - command_add("killallnpcs", "- Kills all npcs, also takes an optional npc name as parameter", 200, command_killallnpcs) || + command_add("killallnpcs", " [npc_name] Kills all npcs by search name, leave blank for all attackable NPC's", 200, command_killallnpcs) || command_add("lastname", "[new lastname] - Set your or your player target's lastname", 50, command_lastname) || command_add("level", "[level] - Set your or your target's level", 10, command_level) || command_add("listnpcs", "[name/range] - Search NPCs", 20, command_listnpcs) || From f39244acca8c233d70d3557189ef65f3607b1cc8 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Wed, 2 Jan 2019 17:09:36 -0500 Subject: [PATCH 08/11] Comment out some IsBardOnlyStackEffect stuff --- common/spdat.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/spdat.cpp b/common/spdat.cpp index cb41c5158..8006e377d 100644 --- a/common/spdat.cpp +++ b/common/spdat.cpp @@ -1125,10 +1125,10 @@ bool IsStackableDot(uint16 spell_id) bool IsBardOnlyStackEffect(int effect) { switch(effect) { - case SE_CurrentMana: + /*case SE_CurrentMana: case SE_ManaRegen_v2: case SE_CurrentHP: - case SE_HealOverTime: + case SE_HealOverTime:*/ case SE_BardAEDot: return true; default: From 55e856d5fe056f46677c14a880c914eb39a92d51 Mon Sep 17 00:00:00 2001 From: Uleat Date: Wed, 2 Jan 2019 19:41:48 -0500 Subject: [PATCH 09/11] Update for a couple of things... - secondary material slot on self spawn (inc. pet) - instant update of prim/sec weapon ornamentations --- common/patches/rof2.cpp | 10 +--------- zone/client.cpp | 18 +++++++++++++----- zone/client_packet.cpp | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 949cd1db3..a062033fc 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -5491,16 +5491,8 @@ namespace RoF2 ob.write(item->Lore, strlen(item->Lore)); ob.write("\0", 1); - if (inst->GetNewIDFile() > 0) { - char new_id_file[30]; - memset(new_id_file, 0x0, 30); - sprintf(new_id_file, "IT%d", inst->GetNewIDFile()); - ob.write(new_id_file, strlen(new_id_file)); - } - else if (strlen(item->IDFile) > 0) { + if (strlen(item->IDFile) > 0) ob.write(item->IDFile, strlen(item->IDFile)); - } - ob.write("\0", 1); ob.write("\0", 1); diff --git a/zone/client.cpp b/zone/client.cpp index e4b81cdf7..12555cc75 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -9034,7 +9034,8 @@ void Client::SetDevToolsWindowEnabled(bool in_dev_tools_window_enabled) */ void Client::SetPrimaryWeaponOrnamentation(uint32 model_id) { - if (GetItemIDAt(EQEmu::invslot::slotPrimary) > 0) { + auto primary_item = m_inv.GetItem(EQEmu::invslot::slotPrimary); + if (primary_item) { database.QueryDatabase( StringFormat( "UPDATE `inventory` SET `ornamentidfile` = %i WHERE `charid` = %i AND `slotid` = %i", @@ -9043,8 +9044,11 @@ void Client::SetPrimaryWeaponOrnamentation(uint32 model_id) EQEmu::invslot::slotPrimary )); + primary_item->SetOrnamentationIDFile(model_id); + SendItemPacket(EQEmu::invslot::slotPrimary, primary_item, ItemPacketTrade); WearChange(EQEmu::textures::weaponPrimary, static_cast(model_id), 0); - Message(15, "Your primary weapon appearance has been modified, changes will fully take affect next time you zone"); + + Message(15, "Your primary weapon appearance has been modified"); } } @@ -9053,7 +9057,8 @@ void Client::SetPrimaryWeaponOrnamentation(uint32 model_id) */ void Client::SetSecondaryWeaponOrnamentation(uint32 model_id) { - if (GetItemIDAt(EQEmu::invslot::slotSecondary) > 0) { + auto secondary_item = m_inv.GetItem(EQEmu::invslot::slotSecondary); + if (secondary_item) { database.QueryDatabase( StringFormat( "UPDATE `inventory` SET `ornamentidfile` = %i WHERE `charid` = %i AND `slotid` = %i", @@ -9062,7 +9067,10 @@ void Client::SetSecondaryWeaponOrnamentation(uint32 model_id) EQEmu::invslot::slotSecondary )); + secondary_item->SetOrnamentationIDFile(model_id); + SendItemPacket(EQEmu::invslot::slotSecondary, secondary_item, ItemPacketTrade); WearChange(EQEmu::textures::weaponSecondary, static_cast(model_id), 0); - Message(15, "Your secondary weapon appearance has been modified, changes will fully take affect next time you zone"); + + Message(15, "Your secondary weapon appearance has been modified"); } -} \ No newline at end of file +} diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index efaa05e0a..eca721031 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -753,7 +753,7 @@ void Client::CompleteConnect() entity_list.SendUntargetable(this); int x; - for (x = 0; x < 8; x++) { + for (x = EQEmu::textures::textureBegin; x <= EQEmu::textures::LastTexture; x++) { SendWearChange(x); } // added due to wear change above @@ -762,7 +762,7 @@ void Client::CompleteConnect() Mob *pet = GetPet(); if (pet != nullptr) { - for (x = 0; x < 8; x++) { + for (x = EQEmu::textures::textureBegin; x <= EQEmu::textures::LastTexture; x++) { pet->SendWearChange(x); } // added due to wear change above From 4a099ca0ef4e1edf05fbeea6f327d615d26e4e29 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Thu, 3 Jan 2019 19:45:16 -0600 Subject: [PATCH 10/11] Update maintenance script with new appveyor windows CI build artifact [skip ci] --- utils/scripts/eqemu_server.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index 29a8142a6..6cacc5108 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -1257,8 +1257,8 @@ sub copy_file { sub fetch_latest_windows_appveyor { print "[Update] Fetching Latest Windows Binaries (unstable) from Appveyor... \n"; - get_remote_file("https://ci.appveyor.com/api/projects/KimLS/server/artifacts/build_x86_pdb.zip", "updates_staged/master_windows_build_pdb.zip", 1); - get_remote_file("https://ci.appveyor.com/api/projects/KimLS/server/artifacts/build_x86.zip", "updates_staged/master_windows_build.zip", 1); + get_remote_file("https://ci.appveyor.com/api/projects/KimLS/server/artifacts/eqemu-x86-no-bots.zip", "updates_staged/master_windows_build_pdb.zip", 1); + print "[Update] Fetched Latest Windows Binaries (unstable) from Appveyor... \n"; print "[Update] Extracting... --- \n"; unzip('updates_staged/master_windows_build.zip', 'updates_staged/binaries/'); From 85ebda1b5acfb3cb0df39d38d095d547520217c7 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 3 Jan 2019 18:33:22 -0800 Subject: [PATCH 11/11] GMMove minor logic change so clients who are not LD/Charmed will be affected --- zone/mob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/mob.cpp b/zone/mob.cpp index d38121b06..89d2ff1de 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1665,7 +1665,7 @@ void Mob::ShowBuffList(Client* client) { } void Mob::GMMove(float x, float y, float z, float heading, bool SendUpdate) { - if (IsCorpse()) { + if (IsCorpse() || (IsClient() && !IsAIControlled())) { m_Position.x = x; m_Position.y = y; m_Position.z = z;