diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index 69e006ec8..8df5f77cc 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -16,7 +16,7 @@ SET(zone_sources command.cpp corpse.cpp doors.cpp - effects.cpp + effects.cpp embparser.cpp embparser_api.cpp embperl.cpp @@ -92,6 +92,7 @@ SET(zone_sources perlpacket.cpp petitions.cpp pets.cpp + position.cpp qglobals.cpp queryserv.cpp questmgr.cpp @@ -183,6 +184,7 @@ SET(zone_headers perlpacket.h petitions.h pets.h + position.h qglobals.h quest_interface.h queryserv.h diff --git a/zone/aa.cpp b/zone/aa.cpp index 9aba83bbd..0f94b8c72 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -268,10 +268,10 @@ void Client::ActivateAA(aaID activate){ } // Check if AA is expendable if (aas_send[activate - activate_val]->special_category == 7) { - + // Add the AA cost to the extended profile to track overall total m_epp.expended_aa += aas_send[activate]->cost; - + SetAA(activate, 0); SaveAA(); /* Save Character AA */ @@ -546,12 +546,12 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u if(summon_count > MAX_SWARM_PETS) summon_count = MAX_SWARM_PETS; - static const float swarm_pet_x[MAX_SWARM_PETS] = { 5, -5, 5, -5, - 10, -10, 10, -10, - 8, -8, 8, -8 }; - static const float swarm_pet_y[MAX_SWARM_PETS] = { 5, 5, -5, -5, - 10, 10, -10, -10, - 8, 8, -8, -8 }; + static const xy_location swarmPetLocations[MAX_SWARM_PETS] = { + {5, 5}, {-5, 5}, {5, -5}, {-5, -5}, + {10, 10}, {-10, 10}, {10, -10}, {-10, -10}, + {8, 8}, {-8, 8}, {8, -8}, {-8, -8} + }; + while(summon_count > 0) { int pet_duration = pet.duration; if(duration_override > 0) @@ -568,8 +568,8 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u NPC* npca = new NPC( (npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer 0, - GetX()+swarm_pet_x[summon_count], GetY()+swarm_pet_y[summon_count], - GetZ(), GetHeading(), FlyMode3); + GetPosition() + swarmPetLocations[summon_count], + FlyMode3); if (followme) npca->SetFollowID(GetID()); @@ -643,12 +643,11 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid if(summon_count > MAX_SWARM_PETS) summon_count = MAX_SWARM_PETS; - static const float swarm_pet_x[MAX_SWARM_PETS] = { 5, -5, 5, -5, - 10, -10, 10, -10, - 8, -8, 8, -8 }; - static const float swarm_pet_y[MAX_SWARM_PETS] = { 5, 5, -5, -5, - 10, 10, -10, -10, - 8, 8, -8, -8 }; + static const xy_location swarmPetLocations[MAX_SWARM_PETS] = { + {5, 5}, {-5, 5}, {5, -5}, {-5, -5}, + {10, 10}, {-10, 10}, {10, -10}, {-10, -10}, + {8, 8}, {-8, 8}, {8, -8}, {-8, -8} + }; while(summon_count > 0) { int pet_duration = pet.duration; @@ -666,8 +665,8 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid NPC* npca = new NPC( (npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer 0, - GetX()+swarm_pet_x[summon_count], GetY()+swarm_pet_y[summon_count], - GetZ(), GetHeading(), FlyMode3); + GetPosition()+swarmPetLocations[summon_count], + FlyMode3); if (followme) npca->SetFollowID(GetID()); @@ -853,7 +852,7 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration) make_npc->d_melee_texture1 = 0; make_npc->d_melee_texture2 = 0; - NPC* npca = new NPC(make_npc, 0, GetX(), GetY(), GetZ(), GetHeading(), FlyMode3); + NPC* npca = new NPC(make_npc, 0, GetPosition(), FlyMode3); if(!npca->GetSwarmInfo()){ AA_SwarmPetInfo* nSI = new AA_SwarmPetInfo; @@ -1017,7 +1016,7 @@ void Client::BuyAA(AA_Action* action) /* Do Player Profile rank calculations and set player profile */ SaveAA(); /* Save to Database to avoid having to write the whole AA array to the profile, only write changes*/ - // database.SaveCharacterAA(this->CharacterID(), aa2->id, (cur_level + 1)); + // database.SaveCharacterAA(this->CharacterID(), aa2->id, (cur_level + 1)); if ((RuleB(AA, Stacking) && (GetClientVersionBit() >= 4) && (aa2->hotkey_sid == 4294967295u)) && ((aa2->max_level == (cur_level + 1)) && aa2->sof_next_id)){ @@ -1038,7 +1037,7 @@ void Client::BuyAA(AA_Action* action) if (cur_level < 1){ Message(15, "You have gained the ability \"%s\" at a cost of %d ability %s.", aa2->name, real_cost, (real_cost>1) ? "points" : "point"); - /* QS: Player_Log_AA_Purchases */ + /* QS: Player_Log_AA_Purchases */ if (RuleB(QueryServ, PlayerLogAAPurchases)){ std::string event_desc = StringFormat("Initial AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID()); QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc); diff --git a/zone/attack.cpp b/zone/attack.cpp index 9f6011c52..8d36c16ed 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2471,7 +2471,7 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b } if(IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { - if(!zone->watermap->InLiquid(other->GetX(), other->GetY(), other->GetZ())) { + if(!zone->watermap->InLiquid(other->GetPosition())) { return; } } diff --git a/zone/beacon.cpp b/zone/beacon.cpp index f21a3b512..c3988e866 100644 --- a/zone/beacon.cpp +++ b/zone/beacon.cpp @@ -53,7 +53,7 @@ extern Zone* zone; Beacon::Beacon(Mob *at_mob, int lifetime) :Mob ( - nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, at_mob->GetPosition(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ), remove_timer(lifetime), @@ -67,12 +67,6 @@ Beacon::Beacon(Mob *at_mob, int lifetime) spell_iterations = 0; caster_id = 0; - // copy location - x_pos = at_mob->GetX(); - y_pos = at_mob->GetY(); - z_pos = at_mob->GetZ(); - heading = at_mob->GetHeading(); - if(lifetime) { remove_timer.Start(); diff --git a/zone/bot.cpp b/zone/bot.cpp index eb919272a..e9d708d80 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -9,7 +9,7 @@ extern volatile bool ZoneLoaded; // This constructor is used during the bot create command -Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, 0, 0, 0, 0, 0, 0, false), rest_timer(1) { +Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, xyz_heading::Origin(), 0, false), rest_timer(1) { if(botOwner) { this->SetBotOwner(botOwner); this->_botOwnerCharacterID = botOwner->CharacterID(); @@ -99,7 +99,7 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, 0, 0, 0, 0, } // This constructor is used when the bot is loaded out of the database -Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType npcTypeData) : NPC(&npcTypeData, 0, 0, 0, 0, 0, 0, false), rest_timer(1) { +Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType npcTypeData) : NPC(&npcTypeData, nullptr, xyz_heading::Origin(), 0, false), rest_timer(1) { this->_botOwnerCharacterID = botOwnerCharacterID; if(this->_botOwnerCharacterID > 0) { @@ -3354,7 +3354,7 @@ void Bot::AI_Process() { if(GetHasBeenSummoned()) { if(IsBotCaster() || IsBotArcher()) { if (AImovement_timer->Check()) { - if(!GetTarget() || (IsBotCaster() && !IsBotCasterCombatRange(GetTarget())) || (IsBotArcher() && IsArcheryRange(GetTarget())) || (DistNoRootNoZ(GetPreSummonX(), GetPreSummonY()) < 10)) { + if(!GetTarget() || (IsBotCaster() && !IsBotCasterCombatRange(GetTarget())) || (IsBotArcher() && IsArcheryRange(GetTarget())) || (DistNoRootNoZ(m_PreSummonLocation.m_X, m_PreSummonLocation.m_Y) < 10)) { if(GetTarget()) FaceTarget(GetTarget()); SetHasBeenSummoned(false); @@ -3363,8 +3363,8 @@ void Bot::AI_Process() { if(GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this) { mlog(AI__WAYPOINTS, "Returning to location prior to being summoned."); - CalculateNewPosition2(GetPreSummonX(), GetPreSummonY(), GetPreSummonZ(), GetRunspeed()); - SetHeading(CalculateHeadingToTarget(GetPreSummonX(), GetPreSummonY())); + CalculateNewPosition2(m_PreSummonLocation.m_X, m_PreSummonLocation.m_Y, m_PreSummonLocation.m_Z, GetRunspeed()); + SetHeading(CalculateHeadingToTarget(m_PreSummonLocation.m_X, m_PreSummonLocation.m_Y)); return; } } @@ -4105,9 +4105,9 @@ void Bot::Spawn(Client* botCharacterOwner, std::string* errorMessage) { this->GetBotOwner()->CastToClient()->Message(13, "%s save failed!", this->GetCleanName()); // Spawn the bot at the bow owner's loc - this->x_pos = botCharacterOwner->GetX(); - this->y_pos = botCharacterOwner->GetY(); - this->z_pos = botCharacterOwner->GetZ(); + this->m_Position.m_X = botCharacterOwner->GetX(); + this->m_Position.m_Y = botCharacterOwner->GetY(); + this->m_Position.m_Z = botCharacterOwner->GetZ(); // Make the bot look at the bot owner FaceTarget(botCharacterOwner); @@ -9076,7 +9076,7 @@ void Bot::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, int16 *resist_adjust) { bool Result = false; - if(zone && !zone->IsSpellBlocked(spell_id, GetX(), GetY(), GetZ())) { + if(zone && !zone->IsSpellBlocked(spell_id, GetPosition())) { mlog(SPELLS__CASTING, "CastSpell called for spell %s (%d) on entity %d, slot %d, time %d, mana %d, from item slot %d", spells[spell_id].name, spell_id, target_id, slot, cast_time, mana_cost, (item_slot==0xFFFFFFFF)?999:item_slot); @@ -10663,12 +10663,12 @@ void Bot::BotGroupSummon(Group* group, Client* client) { if(botMember->GetBotOwnerCharacterID() == client->CharacterID()) { botMember->SetTarget(botMember->GetBotOwner()); botMember->WipeHateList(); - botMember->Warp(botMember->GetBotOwner()->GetX(), botMember->GetBotOwner()->GetY(), botMember->GetBotOwner()->GetZ()); + botMember->Warp(botMember->GetBotOwner()->GetPosition()); if(botMember->HasPet() && botMember->GetPet()) { botMember->GetPet()->SetTarget(botMember); botMember->GetPet()->WipeHateList(); - botMember->GetPet()->Warp(botMember->GetBotOwner()->GetX(), botMember->GetBotOwner()->GetY(), botMember->GetBotOwner()->GetZ()); + botMember->GetPet()->Warp(botMember->GetBotOwner()->GetPosition()); } } } @@ -11677,7 +11677,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { else { b->SetTarget(c->CastToMob()); - b->Warp(c->GetX(), c->GetY(), c->GetZ()); + b->Warp(c->GetPosition()); } } } @@ -15741,47 +15741,39 @@ std::list EntityList::GetBotsByBotOwnerCharacterID(uint32 botOwnerCharacte void EntityList::BotPickLock(Bot* rogue) { - auto it = door_list.begin(); for (auto it = door_list.begin(); it != door_list.end(); ++it) { Doors *cdoor = it->second; - if(cdoor && !cdoor->IsDoorOpen()) { - float zdiff = rogue->GetZ() - cdoor->GetZ(); - if(zdiff < 0) - zdiff = 0 - zdiff; - float curdist = 0; - float tmp = rogue->GetX() - cdoor->GetX(); - curdist += (tmp * tmp); - tmp = rogue->GetY() - cdoor->GetY(); - curdist += (tmp * tmp); - if((zdiff < 10) && (curdist <= 130)) { - // All rogue items with lock pick bonuses are hands or primary - const ItemInst* item1 = rogue->GetBotItem(MainHands); - const ItemInst* item2 = rogue->GetBotItem(MainPrimary); + if(!cdoor || cdoor->IsDoorOpen()) + continue; - float bonus1 = 0.0f; - float bonus2 = 0.0f; - float skill = rogue->GetSkill(SkillPickLock); + auto diff = rogue->GetPosition() - cdoor->GetPosition(); + diff.ABS_XYZ(); - if(item1) { // Hand slot item - if(item1->GetItem()->SkillModType == SkillPickLock) { - bonus1 = skill * (((float)item1->GetItem()->SkillModValue) / 100.0f); - } - } + float curdist = diff.m_X * diff.m_X + diff.m_Y * diff.m_Y; - if(item2) { // Primary slot item - if(item2->GetItem()->SkillModType == SkillPickLock) { - bonus2 = skill * (((float)item2->GetItem()->SkillModValue) / 100.0f); - } - } + if((diff.m_Z * diff.m_Z >= 10) || (curdist > 130)) + continue; - if((skill+bonus1+bonus2) >= cdoor->GetLockpick()) { - cdoor->ForceOpen(rogue); - } - else { - rogue->Say("I am not skilled enough for this lock."); - } - } - } + // All rogue items with lock pick bonuses are hands or primary + const ItemInst* item1 = rogue->GetBotItem(MainHands); + const ItemInst* item2 = rogue->GetBotItem(MainPrimary); + + float bonus1 = 0.0f; + float bonus2 = 0.0f; + float skill = rogue->GetSkill(SkillPickLock); + + if(item1) // Hand slot item + if(item1->GetItem()->SkillModType == SkillPickLock) + bonus1 = skill * (((float)item1->GetItem()->SkillModValue) / 100.0f); + + if(item2) // Primary slot item + if(item2->GetItem()->SkillModType == SkillPickLock) + bonus2 = skill * (((float)item2->GetItem()->SkillModValue) / 100.0f); + + if((skill+bonus1+bonus2) >= cdoor->GetLockpick()) + cdoor->ForceOpen(rogue); + else + rogue->Say("I am not skilled enough for this lock."); } } @@ -16168,11 +16160,9 @@ bool Bot::HasOrMayGetAggro() { void Bot::SetHasBeenSummoned(bool wasSummoned) { _hasBeenSummoned = wasSummoned; - if(!wasSummoned) { - _preSummonX = 0; - _preSummonY = 0; - _preSummonZ = 0; - } + if(!wasSummoned) + m_PreSummonLocation = xyz_location::Origin(); + } void Bot::SetDefaultBotStance() { diff --git a/zone/bot.h b/zone/bot.h index 40b505c84..b783c150a 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -448,9 +448,7 @@ public: uint32 GetAA(uint32 aa_id); void ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon); bool GetHasBeenSummoned() { return _hasBeenSummoned; } - float GetPreSummonX() { return _preSummonX; } - float GetPreSummonY() { return _preSummonY; } - float GetPreSummonZ() { return _preSummonZ; } + const xyz_location GetPreSummonLocation() const { return m_PreSummonLocation; } bool GetGroupMessagesOn() { return _groupMessagesOn; } bool GetInHealRotation() { return _isInHealRotation; } bool GetHealRotationActive() { return (GetInHealRotation() && _isHealRotationActive); } @@ -535,9 +533,7 @@ public: void SetSpellRecastTimer(int timer_index, int32 recast_delay); void SetDisciplineRecastTimer(int timer_index, int32 recast_delay); void SetHasBeenSummoned(bool s); - void SetPreSummonX(float x) { _preSummonX = x; } - void SetPreSummonY(float y) { _preSummonY = y; } - void SetPreSummonZ(float z) { _preSummonZ = z; } + void SetPreSummonLocation(const xyz_location& location) { m_PreSummonLocation = location; } void SetGroupMessagesOn(bool groupMessagesOn) { _groupMessagesOn = groupMessagesOn; } void SetInHealRotation( bool inRotation ) { _isInHealRotation = inRotation; } void SetHealRotationActive( bool isActive ) { _isHealRotationActive = isActive; } @@ -604,9 +600,7 @@ private: int32 end_regen; uint32 timers[MaxTimer]; bool _hasBeenSummoned; - float _preSummonX; - float _preSummonY; - float _preSummonZ; + xyz_location m_PreSummonLocation; uint8 _spellCastingChances[MaxStances][MaxSpellTypes]; bool _groupMessagesOn; bool _isInHealRotation; diff --git a/zone/client.cpp b/zone/client.cpp index 52bced4f4..a988c04a6 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -75,10 +75,7 @@ Client::Client(EQStreamInterface* ieqs) 0, // npctypeid 0, // size 0.7, // runspeed - 0, // heading - 0, // x - 0, // y - 0, // z + xyz_heading::Origin(), 0, // light 0xFF, // texture 0xFF, // helmtexture @@ -144,7 +141,11 @@ Client::Client(EQStreamInterface* ieqs) RespawnFromHoverTimer(0), merc_timer(RuleI(Mercs, UpkeepIntervalMS)), ItemTickTimer(10000), - ItemQuestTimer(500) + ItemQuestTimer(500), + m_Proximity(FLT_MAX, FLT_MAX, FLT_MAX), //arbitrary large number + m_ZoneSummonLocation(-2.0f,-2.0f,-2.0f), + m_AutoAttackPosition(0.0f, 0.0f, 0.0f, 0.0f), + m_AutoAttackTargetLocation(0.0f, 0.0f, 0.0f) { for(int cf=0; cf < _FilterCount; cf++) ClientFilters[cf] = FilterShow; @@ -190,16 +191,10 @@ Client::Client(EQStreamInterface* ieqs) auto_attack = false; auto_fire = false; linkdead_timer.Disable(); - zonesummon_x = -2; - zonesummon_y = -2; - zonesummon_z = -2; zonesummon_id = 0; zonesummon_ignorerestrictions = 0; zoning = false; zone_mode = ZoneUnsolicited; - proximity_x = FLT_MAX; //arbitrary large number - proximity_y = FLT_MAX; - proximity_z = FLT_MAX; casting_spell_id = 0; npcflag = false; npclevel = 0; @@ -268,13 +263,6 @@ Client::Client(EQStreamInterface* ieqs) m_AssistExemption = 0; m_CheatDetectMoved = false; CanUseReport = true; - aa_los_me.x = 0; - aa_los_me.y = 0; - aa_los_me.z = 0; - aa_los_me_heading = 0; - aa_los_them.x = 0; - aa_los_them.y = 0; - aa_los_them.z = 0; aa_los_them_mob = nullptr; los_status = false; los_status_facing = false; @@ -385,9 +373,9 @@ Client::~Client() { { m_pp.zone_id = m_pp.binds[0].zoneId; m_pp.zoneInstance = m_pp.binds[0].instance_id; - x_pos = m_pp.binds[0].x; - y_pos = m_pp.binds[0].y; - z_pos = m_pp.binds[0].z; + m_Position.m_X = m_pp.binds[0].x; + m_Position.m_Y = m_pp.binds[0].y; + m_Position.m_Z = m_pp.binds[0].z; } // we save right now, because the client might be zoning and the world @@ -511,11 +499,11 @@ bool Client::Save(uint8 iCommitNow) { return false; /* Wrote current basics to PP for saves */ - m_pp.x = x_pos; - m_pp.y = y_pos; - m_pp.z = z_pos; + m_pp.x = m_Position.m_X; + m_pp.y = m_Position.m_Y; + m_pp.z = m_Position.m_Z; m_pp.guildrank = guildrank; - m_pp.heading = heading; + m_pp.heading = m_Position.m_Heading; /* Mana and HP */ if (GetHP() <= 0) { @@ -532,8 +520,10 @@ bool Client::Save(uint8 iCommitNow) { database.SaveCharacterCurrency(CharacterID(), &m_pp); /* Save Current Bind Points */ - database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[0].zoneId, m_pp.binds[0].instance_id, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0, 0); /* Regular bind */ - database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[4].zoneId, m_pp.binds[4].instance_id, m_pp.binds[4].x, m_pp.binds[4].y, m_pp.binds[4].z, 0, 1); /* Home Bind */ + auto regularBindPosition = xyz_heading(m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0.0f); + auto homeBindPosition = xyz_heading(m_pp.binds[4].x, m_pp.binds[4].y, m_pp.binds[4].z, 0.0f); + database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[0].zoneId, m_pp.binds[0].instance_id, regularBindPosition, 0); /* Regular bind */ + database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[4].zoneId, m_pp.binds[4].instance_id, homeBindPosition, 1); /* Home Bind */ /* Save Character Buffs */ database.SaveBuffs(this); @@ -3683,7 +3673,7 @@ void Client::Sacrifice(Client *caster) void Client::SendOPTranslocateConfirm(Mob *Caster, uint16 SpellID) { - if(!Caster || PendingTranslocate) + if(!Caster || PendingTranslocate) return; const SPDat_Spell_Struct &Spell = spells[SpellID]; @@ -4136,7 +4126,7 @@ bool Client::GroupFollow(Client* inviter) { { GetMerc()->MercJoinClientGroup(); } - + if (inviter->IsLFP()) { // If the player who invited us to a group is LFP, have them update world now that we have joined their group. @@ -4800,8 +4790,7 @@ void Client::SummonAndRezzAllCorpses() entity_list.RemoveAllCorpsesByCharID(CharacterID()); - int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), - GetX(), GetY(), GetZ(), GetHeading()); + int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), GetPosition()); if(CorpseCount <= 0) { Message(clientMessageYellow, "You have no corpses to summnon."); @@ -4816,13 +4805,11 @@ void Client::SummonAndRezzAllCorpses() Message(clientMessageYellow, "All your corpses have been summoned to your feet and have received a 100% resurrection."); } -void Client::SummonAllCorpses(float dest_x, float dest_y, float dest_z, float dest_heading) +void Client::SummonAllCorpses(const xyz_heading& position) { - - if(dest_x == 0 && dest_y == 0 && dest_z == 0 && dest_heading == 0) - { - dest_x = GetX(); dest_y = GetY(); dest_z = GetZ(); dest_heading = GetHeading(); - } + auto summonLocation = position; + if(position.isOrigin() && position.m_Heading == 0.0f) + summonLocation = GetPosition(); ServerPacket *Pack = new ServerPacket(ServerOP_DepopAllPlayersCorpses, sizeof(ServerDepopAllPlayersCorpses_Struct)); @@ -4838,12 +4825,7 @@ void Client::SummonAllCorpses(float dest_x, float dest_y, float dest_z, float de entity_list.RemoveAllCorpsesByCharID(CharacterID()); - int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), - dest_x, dest_y, dest_z, dest_heading); - if(CorpseCount <= 0) - { - return; - } + database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), summonLocation); } void Client::DepopAllCorpses() @@ -6291,8 +6273,11 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid if(summon_count > MAX_SWARM_PETS) summon_count = MAX_SWARM_PETS; - static const float swarm_pet_x[MAX_SWARM_PETS] = { 5, -5, 5, -5, 10, -10, 10, -10, 8, -8, 8, -8 }; - static const float swarm_pet_y[MAX_SWARM_PETS] = { 5, 5, -5, -5, 10, 10, -10, -10, 8, 8, -8, -8 }; + static const xy_location swarmPetLocations[MAX_SWARM_PETS] = { + {5, 5}, {-5, 5}, {5, -5}, {-5, -5}, + {10, 10}, {-10, 10}, {10, -10}, {-10, -10}, + {8, 8}, {-8, 8}, {8, -8}, {-8, -8} + }; while(summon_count > 0) { NPCType *npc_dup = nullptr; @@ -6304,8 +6289,8 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid NPC* npca = new NPC( (npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer 0, - GetX()+swarm_pet_x[summon_count], GetY()+swarm_pet_y[summon_count], - GetZ(), GetHeading(), FlyMode3); + GetPosition()+swarmPetLocations[summon_count], + FlyMode3); if(!npca->GetSwarmInfo()){ AA_SwarmPetInfo* nSI = new AA_SwarmPetInfo; @@ -7333,7 +7318,7 @@ void Client::SendMercPersonalInfo() uint32 altCurrentType = 19; //TODO: Implement alternate currency purchases involving mercs! MercTemplate *mercData = &zone->merc_templates[GetMercInfo().MercTemplateID]; - + int stancecount = 0; stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size(); if(stancecount > MAX_MERC_STANCES || mercCount > MAX_MERC || mercTypeCount > MAX_MERC_GRADES) @@ -7435,7 +7420,7 @@ void Client::SendMercPersonalInfo() } if (MERC_DEBUG > 0) Message(7, "Mercenary Debug: SendMercPersonalInfo Send Successful"); - + SendMercMerchantResponsePacket(0); } else diff --git a/zone/client.h b/zone/client.h index 288eb2afb..8dd343c80 100644 --- a/zone/client.h +++ b/zone/client.h @@ -398,10 +398,10 @@ public: inline const char* GetLastName() const { return lastname; } - inline float ProximityX() const { return(proximity_x); } - inline float ProximityY() const { return(proximity_y); } - inline float ProximityZ() const { return(proximity_z); } - inline void ClearAllProximities() { entity_list.ProcessMove(this, FLT_MAX, FLT_MAX, FLT_MAX); proximity_x = FLT_MAX; proximity_y = FLT_MAX; proximity_z = FLT_MAX; } + inline float ProximityX() const { return m_Proximity.m_X; } + inline float ProximityY() const { return m_Proximity.m_Y; } + inline float ProximityZ() const { return m_Proximity.m_Z; } + inline void ClearAllProximities() { entity_list.ProcessMove(this, xyz_location(FLT_MAX, FLT_MAX, FLT_MAX)); m_Proximity = xyz_location(FLT_MAX,FLT_MAX,FLT_MAX); } /* Begin client modifiers @@ -580,7 +580,7 @@ public: void GoToBind(uint8 bindnum = 0); void GoToSafeCoords(uint16 zone_id, uint16 instance_id); void Gate(); - void SetBindPoint(int to_zone = -1, int to_instance = 0, float new_x = 0.0f, float new_y = 0.0f, float new_z = 0.0f); + void SetBindPoint(int to_zone = -1, int to_instance = 0, const xyz_location& location = xyz_location::Origin()); void SetStartZone(uint32 zoneid, float x = 0.0f, float y =0.0f, float z = 0.0f); uint32 GetStartZone(void); void MovePC(const char* zonename, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); @@ -1078,7 +1078,7 @@ public: void DoItemEnterZone(); bool DoItemEnterZone(uint32 slot_x, uint32 slot_y); // behavior change: 'slot_y' is now [RANGE]_END and not [RANGE]_END + 1 void SummonAndRezzAllCorpses(); - void SummonAllCorpses(float dest_x, float dest_y, float dest_z, float dest_heading); + void SummonAllCorpses(const xyz_heading& position); void DepopAllCorpses(); void DepopPlayerCorpse(uint32 dbid); void BuryPlayerCorpses(); @@ -1267,11 +1267,10 @@ protected: Mob* bind_sight_target; - Map::Vertex aa_los_me; - Map::Vertex aa_los_them; + xyz_heading m_AutoAttackPosition; + xyz_location m_AutoAttackTargetLocation; Mob *aa_los_them_mob; bool los_status; - float aa_los_me_heading; bool los_status_facing; QGlobalCache *qGlobals; @@ -1424,9 +1423,8 @@ private: void DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instance_id, float dest_x, float dest_y, float dest_z, float dest_h, int8 ignore_r); void ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm); void ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); - float zonesummon_x; - float zonesummon_y; - float zonesummon_z; + + xyz_location m_ZoneSummonLocation; uint16 zonesummon_id; uint8 zonesummon_ignorerestrictions; ZoneMode zone_mode; @@ -1465,10 +1463,7 @@ private: Timer RespawnFromHoverTimer; Timer merc_timer; - float proximity_x; - float proximity_y; - float proximity_z; - + xyz_location m_Proximity; void BulkSendInventoryItems(); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 1fa18051f..5cc3da16d 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1455,9 +1455,10 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) strcpy(lastname, m_pp.last_name); /* If PP is set to weird coordinates */ if ((m_pp.x == -1 && m_pp.y == -1 && m_pp.z == -1) || (m_pp.x == -2 && m_pp.y == -2 && m_pp.z == -2)) { - m_pp.x = zone->safe_x(); - m_pp.y = zone->safe_y(); - m_pp.z = zone->safe_z(); + auto safePoint = zone->GetSafePoint(); + m_pp.x = safePoint.m_X; + m_pp.y = safePoint.m_Y; + m_pp.z = safePoint.m_Z; } /* If too far below ground, then fix */ // float ground_z = GetGroundZ(m_pp.x, m_pp.y, m_pp.z); @@ -1467,10 +1468,10 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) /* Set Mob variables for spawn */ class_ = m_pp.class_; level = m_pp.level; - x_pos = m_pp.x; - y_pos = m_pp.y; - z_pos = m_pp.z; - heading = m_pp.heading; + m_Position.m_X = m_pp.x; + m_Position.m_Y = m_pp.y; + m_Position.m_Z = m_pp.z; + m_Position.m_Heading = m_pp.heading; race = m_pp.race; base_race = m_pp.race; gender = m_pp.gender; @@ -3240,13 +3241,8 @@ void Client::Handle_OP_AutoAttack(const EQApplicationPacket *app) ranged_timer.Disable(); attack_dw_timer.Disable(); - aa_los_me.x = 0; - aa_los_me.y = 0; - aa_los_me.z = 0; - aa_los_me_heading = 0; - aa_los_them.x = 0; - aa_los_them.y = 0; - aa_los_them.z = 0; + m_AutoAttackPosition = xyz_heading::Origin(); + m_AutoAttackTargetLocation = xyz_location::Origin(); aa_los_them_mob = nullptr; } else if (app->pBuffer[0] == 1) @@ -3260,25 +3256,15 @@ void Client::Handle_OP_AutoAttack(const EQApplicationPacket *app) if (GetTarget()) { aa_los_them_mob = GetTarget(); - aa_los_me.x = GetX(); - aa_los_me.y = GetY(); - aa_los_me.z = GetZ(); - aa_los_me_heading = GetHeading(); - aa_los_them.x = aa_los_them_mob->GetX(); - aa_los_them.y = aa_los_them_mob->GetY(); - aa_los_them.z = aa_los_them_mob->GetZ(); + m_AutoAttackPosition = GetPosition(); + m_AutoAttackTargetLocation = aa_los_them_mob->GetPosition(); los_status = CheckLosFN(aa_los_them_mob); los_status_facing = IsFacingMob(aa_los_them_mob); } else { - aa_los_me.x = GetX(); - aa_los_me.y = GetY(); - aa_los_me.z = GetZ(); - aa_los_me_heading = GetHeading(); - aa_los_them.x = 0; - aa_los_them.y = 0; - aa_los_them.z = 0; + m_AutoAttackPosition = GetPosition(); + m_AutoAttackTargetLocation = xyz_location::Origin(); aa_los_them_mob = nullptr; los_status = false; los_status_facing = false; @@ -4000,9 +3986,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) CastSpell_Struct* castspell = (CastSpell_Struct*)app->pBuffer; - targetring_x = castspell->x_pos; - targetring_y = castspell->y_pos; - targetring_z = castspell->z_pos; + m_TargetRing = xyz_location(castspell->x_pos, castspell->y_pos, castspell->z_pos); #ifdef _EQDEBUG LogFile->write(EQEmuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[0], castspell->cs_unknown[0]); @@ -4034,9 +4018,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) return; } - targetring_x = castspell->x_pos; - targetring_y = castspell->y_pos; - targetring_z = castspell->z_pos; + m_TargetRing = xyz_location(castspell->x_pos, castspell->y_pos, castspell->z_pos); CastSpell(spell_to_cast, castspell->target_id, castspell->slot); } @@ -4380,7 +4362,8 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) } // set the boat's position deltas - boat->SetDeltas(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading); + auto boatDelta = xyz_heading(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading); + boat->SetDelta(boatDelta); // send an update to everyone nearby except the client controlling the boat EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); PlayerPositionUpdateServer_Struct* ppus = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer; @@ -4396,9 +4379,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) float dist = 0; float tmp; - tmp = x_pos - ppu->x_pos; + tmp = m_Position.m_X - ppu->x_pos; dist += tmp*tmp; - tmp = y_pos - ppu->y_pos; + tmp = m_Position.m_Y - ppu->y_pos; dist += tmp*tmp; dist = sqrt(dist); @@ -4541,51 +4524,41 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) float rewind_x_diff = 0; float rewind_y_diff = 0; - rewind_x_diff = ppu->x_pos - rewind_x; + rewind_x_diff = ppu->x_pos - m_RewindLocation.m_X; rewind_x_diff *= rewind_x_diff; - rewind_y_diff = ppu->y_pos - rewind_y; + rewind_y_diff = ppu->y_pos - m_RewindLocation.m_Y; rewind_y_diff *= rewind_y_diff; //We only need to store updated values if the player has moved. //If the player has moved more than units for x or y, then we'll store //his pre-PPU x and y for /rewind, in case he gets stuck. - if ((rewind_x_diff > 750) || (rewind_y_diff > 750)) { - rewind_x = x_pos; - rewind_y = y_pos; - rewind_z = z_pos; - } + if ((rewind_x_diff > 750) || (rewind_y_diff > 750)) + m_RewindLocation = m_Position; //If the PPU was a large jump, such as a cross zone gate or Call of Hero, //just update rewind coords to the new ppu coords. This will prevent exploitation. - if ((rewind_x_diff > 5000) || (rewind_y_diff > 5000)) { - rewind_x = ppu->x_pos; - rewind_y = ppu->y_pos; - rewind_z = ppu->z_pos; - } + if ((rewind_x_diff > 5000) || (rewind_y_diff > 5000)) + m_RewindLocation = xyz_location(ppu->x_pos, ppu->y_pos, ppu->z_pos); if(proximity_timer.Check()) { - entity_list.ProcessMove(this, ppu->x_pos, ppu->y_pos, ppu->z_pos); + entity_list.ProcessMove(this, xyz_location(ppu->x_pos, ppu->y_pos, ppu->z_pos)); if(RuleB(TaskSystem, EnableTaskSystem) && RuleB(TaskSystem,EnableTaskProximity)) ProcessTaskProximities(ppu->x_pos, ppu->y_pos, ppu->z_pos); - proximity_x = ppu->x_pos; - proximity_y = ppu->y_pos; - proximity_z = ppu->z_pos; + + m_Proximity = xyz_location(ppu->x_pos, ppu->y_pos, ppu->z_pos); } // Update internal state - delta_x = ppu->delta_x; - delta_y = ppu->delta_y; - delta_z = ppu->delta_z; - delta_heading = ppu->delta_heading; + m_Delta = xyz_heading(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading); - if(IsTracking() && ((x_pos!=ppu->x_pos) || (y_pos!=ppu->y_pos))){ + if(IsTracking() && ((m_Position.m_X!=ppu->x_pos) || (m_Position.m_Y!=ppu->y_pos))){ if(zone->random.Real(0, 100) < 70)//should be good CheckIncreaseSkill(SkillTracking, nullptr, -20); } // Break Hide if moving without sneaking and set rewind timer if moved - if(ppu->y_pos != y_pos || ppu->x_pos != x_pos){ + if(ppu->y_pos != m_Position.m_Y || ppu->x_pos != m_Position.m_X){ if((hidden || improved_hidden) && !sneaking){ hidden = false; improved_hidden = false; @@ -4605,13 +4578,14 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) // Outgoing client packet float tmpheading = EQ19toFloat(ppu->heading); - if (!FCMP(ppu->y_pos, y_pos) || !FCMP(ppu->x_pos, x_pos) || !FCMP(tmpheading, heading) || ppu->animation != animation) + if (!FCMP(ppu->y_pos, m_Position.m_Y) || !FCMP(ppu->x_pos, m_Position.m_X) || !FCMP(tmpheading, m_Position.m_Heading) || ppu->animation != animation) { - x_pos = ppu->x_pos; - y_pos = ppu->y_pos; - z_pos = ppu->z_pos; - animation = ppu->animation; - heading = tmpheading; + m_Position.m_X = ppu->x_pos; + m_Position.m_Y = ppu->y_pos; + m_Position.m_Z = ppu->z_pos; + m_Position.m_Heading = tmpheading; + animation = ppu->animation; + EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); PlayerPositionUpdateServer_Struct* ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer; @@ -4623,13 +4597,8 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) safe_delete(outapp); } - if(zone->watermap) - { - if(zone->watermap->InLiquid(x_pos, y_pos, z_pos)) - { - CheckIncreaseSkill(SkillSwimming, nullptr, -17); - } - } + if(zone->watermap && zone->watermap->InLiquid(m_Position)) + CheckIncreaseSkill(SkillSwimming, nullptr, -17); return; } @@ -6623,7 +6592,7 @@ void Client::Handle_OP_GroupFollow2(const EQApplicationPacket *app) GroupGeneric_Struct* gf = (GroupGeneric_Struct*)app->pBuffer; Mob* inviter = entity_list.GetClientByName(gf->name1); - + // Inviter and Invitee are in the same zone if (inviter != nullptr && inviter->IsClient()) { @@ -6638,7 +6607,7 @@ void Client::Handle_OP_GroupFollow2(const EQApplicationPacket *app) { // Inviter is in another zone - Remove merc from group now if any LeaveGroup(); - + ServerPacket* pack = new ServerPacket(ServerOP_GroupFollow, sizeof(ServerGroupFollow_Struct)); ServerGroupFollow_Struct *sgfs = (ServerGroupFollow_Struct *)pack->pBuffer; sgfs->CharacterID = CharacterID(); @@ -8029,7 +7998,7 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app) InspectResponse_Struct* insr = (InspectResponse_Struct*)outapp->pBuffer; Mob* tmp = entity_list.GetMob(insr->TargetID); const Item_Struct* item = nullptr; - + int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); for (int16 L = EmuConstants::EQUIPMENT_BEGIN; L <= MainWaist; L++) { const ItemInst* inst = GetInv().GetItem(L); @@ -11706,7 +11675,7 @@ void Client::Handle_OP_Rewind(const EQApplicationPacket *app) Message_StringID(MT_System, REWIND_WAIT); } else { - CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), rewind_x, rewind_y, rewind_z, 0, 2, Rewind); + CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_RewindLocation.m_X, m_RewindLocation.m_Y, m_RewindLocation.m_Z, 0, 2, Rewind); rewind_timer.Start(30000, true); } } @@ -11830,29 +11799,29 @@ void Client::Handle_OP_SenseTraps(const EQApplicationPacket *app) int uskill = GetSkill(SkillSenseTraps); if ((zone->random.Int(0, 99) + uskill) >= (zone->random.Int(0, 99) + trap->skill*0.75)) { - float xdif = trap->x - GetX(); - float ydif = trap->y - GetY(); - if (xdif == 0 && ydif == 0) + auto diff = trap->m_Position - GetPosition(); + + if (diff.m_X == 0 && diff.m_Y == 0) Message(MT_Skills, "You sense a trap right under your feet!"); - else if (xdif > 10 && ydif > 10) + else if (diff.m_X > 10 && diff.m_Y > 10) Message(MT_Skills, "You sense a trap to the NorthWest."); - else if (xdif < -10 && ydif > 10) + else if (diff.m_X < -10 && diff.m_Y > 10) Message(MT_Skills, "You sense a trap to the NorthEast."); - else if (ydif > 10) + else if (diff.m_Y > 10) Message(MT_Skills, "You sense a trap to the North."); - else if (xdif > 10 && ydif < -10) + else if (diff.m_X > 10 && diff.m_Y < -10) Message(MT_Skills, "You sense a trap to the SouthWest."); - else if (xdif < -10 && ydif < -10) + else if (diff.m_X < -10 && diff.m_Y < -10) Message(MT_Skills, "You sense a trap to the SouthEast."); - else if (ydif < -10) + else if (diff.m_Y < -10) Message(MT_Skills, "You sense a trap to the South."); - else if (xdif > 10) + else if (diff.m_X > 10) Message(MT_Skills, "You sense a trap to the West."); else Message(MT_Skills, "You sense a trap to the East."); trap->detected = true; - float angle = CalculateHeadingToTarget(trap->x, trap->y); + float angle = CalculateHeadingToTarget(trap->m_Position.m_X, trap->m_Position.m_Y); if (angle < 0) angle = (256 + angle); @@ -12930,9 +12899,9 @@ void Client::Handle_OP_SwapSpell(const EQApplicationPacket *app) m_pp.spell_book[swapspell->from_slot] = m_pp.spell_book[swapspell->to_slot]; m_pp.spell_book[swapspell->to_slot] = swapspelltemp; - /* Save Spell Swaps */ + /* Save Spell Swaps */ if (!database.SaveCharacterSpell(this->CharacterID(), m_pp.spell_book[swapspell->from_slot], swapspell->from_slot)){ - database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[swapspell->from_slot], swapspell->from_slot); + database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[swapspell->from_slot], swapspell->from_slot); } if (!database.SaveCharacterSpell(this->CharacterID(), swapspelltemp, swapspell->to_slot)){ database.DeleteCharacterSpell(this->CharacterID(), swapspelltemp, swapspell->to_slot); @@ -13718,7 +13687,7 @@ void Client::Handle_OP_Translocate(const EQApplicationPacket *app) } Translocate_Struct *its = (Translocate_Struct*)app->pBuffer; - if (!PendingTranslocate) + if (!PendingTranslocate) return; if ((RuleI(Spells, TranslocateTimeLimit) > 0) && (time(nullptr) > (TranslocateTime + RuleI(Spells, TranslocateTimeLimit)))) { @@ -13739,7 +13708,7 @@ void Client::Handle_OP_Translocate(const EQApplicationPacket *app) // to the bind coords it has from the PlayerProfile, but with the X and Y reversed. I suspect they are // reversed in the pp, and since spells like Gate are handled serverside, this has not mattered before. if (((SpellID == 1422) || (SpellID == 1334) || (SpellID == 3243)) && - (zone->GetZoneID() == PendingTranslocateData.zone_id && + (zone->GetZoneID() == PendingTranslocateData.zone_id && zone->GetInstanceID() == PendingTranslocateData.instance_id)) { PendingTranslocate = false; @@ -13750,7 +13719,7 @@ void Client::Handle_OP_Translocate(const EQApplicationPacket *app) ////Was sending the packet back to initiate client zone... ////but that could be abusable, so lets go through proper channels MovePC(PendingTranslocateData.zone_id, PendingTranslocateData.instance_id, - PendingTranslocateData.x, PendingTranslocateData.y, + PendingTranslocateData.x, PendingTranslocateData.y, PendingTranslocateData.z, PendingTranslocateData.heading, 0, ZoneSolicited); } } diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 6e21ecd36..542390da9 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -174,7 +174,7 @@ bool Client::Process() { GetMerc()->Save(); GetMerc()->Depop(); } - + Raid *myraid = entity_list.GetRaidByClient(this); if (myraid) { @@ -340,41 +340,31 @@ bool Client::Process() { if(aa_los_them_mob) { if(auto_attack_target != aa_los_them_mob || - aa_los_me.x != GetX() || - aa_los_me.y != GetY() || - aa_los_me.z != GetZ() || - aa_los_them.x != aa_los_them_mob->GetX() || - aa_los_them.y != aa_los_them_mob->GetY() || - aa_los_them.z != aa_los_them_mob->GetZ()) + m_AutoAttackPosition.m_X != GetX() || + m_AutoAttackPosition.m_Y != GetY() || + m_AutoAttackPosition.m_Z != GetZ() || + m_AutoAttackTargetLocation.m_X != aa_los_them_mob->GetX() || + m_AutoAttackTargetLocation.m_Y != aa_los_them_mob->GetY() || + m_AutoAttackTargetLocation.m_Z != aa_los_them_mob->GetZ()) { aa_los_them_mob = auto_attack_target; - aa_los_me.x = GetX(); - aa_los_me.y = GetY(); - aa_los_me.z = GetZ(); - aa_los_them.x = aa_los_them_mob->GetX(); - aa_los_them.y = aa_los_them_mob->GetY(); - aa_los_them.z = aa_los_them_mob->GetZ(); + m_AutoAttackPosition = GetPosition(); + m_AutoAttackTargetLocation = aa_los_them_mob->GetPosition(); los_status = CheckLosFN(auto_attack_target); - aa_los_me_heading = GetHeading(); 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 - if (aa_los_me_heading != GetHeading()) { - aa_los_me_heading = GetHeading(); + if (m_AutoAttackPosition.m_Heading != GetHeading()) { + m_AutoAttackPosition.m_Heading = GetHeading(); los_status_facing = IsFacingMob(aa_los_them_mob); } } else { aa_los_them_mob = auto_attack_target; - aa_los_me.x = GetX(); - aa_los_me.y = GetY(); - aa_los_me.z = GetZ(); - aa_los_me_heading = GetHeading(); - aa_los_them.x = aa_los_them_mob->GetX(); - aa_los_them.y = aa_los_them_mob->GetY(); - aa_los_them.z = aa_los_them_mob->GetZ(); + m_AutoAttackPosition = GetPosition(); + m_AutoAttackTargetLocation = aa_los_them_mob->GetPosition(); los_status = CheckLosFN(auto_attack_target); los_status_facing = IsFacingMob(aa_los_them_mob); } @@ -529,9 +519,7 @@ bool Client::Process() { else { animation = 0; - delta_x = 0; - delta_y = 0; - delta_z = 0; + m_Delta = xyz_heading(0.0f, 0.0f, 0.0f, m_Delta.m_Heading); SendPosUpdate(2); } } @@ -785,32 +773,32 @@ void Client::OnDisconnect(bool hard_disconnect) { if (MyRaid) MyRaid->MemberZoned(this); - parse->EventPlayer(EVENT_DISCONNECT, this, "", 0); + parse->EventPlayer(EVENT_DISCONNECT, this, "", 0); /* QS: PlayerLogConnectDisconnect */ if (RuleB(QueryServ, PlayerLogConnectDisconnect)){ std::string event_desc = StringFormat("Disconnect :: in zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID()); QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc); - } + } } - Mob *Other = trade->With(); + Mob *Other = trade->With(); if(Other) { - mlog(TRADING__CLIENT, "Client disconnected during a trade. Returning their items."); + mlog(TRADING__CLIENT, "Client disconnected during a trade. Returning their items."); FinishTrade(this); if(Other->IsClient()) Other->CastToClient()->FinishTrade(Other); /* Reset both sides of the trade */ - trade->Reset(); + trade->Reset(); Other->trade->Reset(); } database.SetFirstLogon(CharacterID(), 0); //We change firstlogon status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world. - /* Remove ourself from all proximities */ + /* Remove ourself from all proximities */ ClearAllProximities(); EQApplicationPacket *outapp = new EQApplicationPacket(OP_LogoutReply); @@ -1555,7 +1543,7 @@ void Client::OPMoveCoin(const EQApplicationPacket* app) if (from_bucket == &m_pp.platinum_shared) amount_to_add = 0 - amount_to_take; - database.SetSharedPlatinum(AccountID(),amount_to_add); + database.SetSharedPlatinum(AccountID(),amount_to_add); } } else{ @@ -1741,7 +1729,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app) } SetSkill(skill, t_level); - } else { + } else { switch(skill) { case SkillBrewing: case SkillMakePoison: @@ -1943,7 +1931,7 @@ void Client::DoEnduranceUpkeep() { int upkeep_sum = 0; int cost_redux = spellbonuses.EnduranceReduction + itembonuses.EnduranceReduction + aabonuses.EnduranceReduction; - + bool has_effect = false; uint32 buffs_i; uint32 buff_count = GetMaxTotalSlots(); @@ -2129,9 +2117,9 @@ void Client::HandleRespawnFromHover(uint32 Option) if (corpse) { - x_pos = corpse->GetX(); - y_pos = corpse->GetY(); - z_pos = corpse->GetZ(); + m_Position.m_X = corpse->GetX(); + m_Position.m_Y = corpse->GetY(); + m_Position.m_Z = corpse->GetZ(); } EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) + 10); @@ -2184,10 +2172,10 @@ void Client::HandleRespawnFromHover(uint32 Option) SetMana(GetMaxMana()); SetEndurance(GetMaxEndurance()); - x_pos = chosen->x; - y_pos = chosen->y; - z_pos = chosen->z; - heading = chosen->heading; + m_Position.m_X = chosen->x; + m_Position.m_Y = chosen->y; + m_Position.m_Z = chosen->z; + m_Position.m_Heading = chosen->heading; ClearHover(); entity_list.RefreshClientXTargets(this); @@ -2197,7 +2185,7 @@ void Client::HandleRespawnFromHover(uint32 Option) //After they've respawned into the same zone, trigger EVENT_RESPAWN parse->EventPlayer(EVENT_RESPAWN, this, static_cast(itoa(Option)), is_rez ? 1 : 0); - //Pop Rez option from the respawn options list; + //Pop Rez option from the respawn options list; //easiest way to make sure it stays at the end and //doesn't disrupt adding/removing scripted options respawn_options.pop_back(); diff --git a/zone/command.cpp b/zone/command.cpp index 140427520..ea527cbe8 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -1839,14 +1839,7 @@ void command_itemtest(Client *c, const Seperator *sep) void command_gassign(Client *c, const Seperator *sep) { if (sep->IsNumber(1) && c->GetTarget() && c->GetTarget()->IsNPC()) - { - database.AssignGrid( - c, - (c->GetTarget()->CastToNPC()->org_x), - (c->GetTarget()->CastToNPC()->org_y), - atoi(sep->arg[1]) - ); - } + database.AssignGrid(c, c->GetTarget()->CastToNPC()->m_SpawnPoint, atoi(sep->arg[1])); else c->Message(0,"Usage: #gassign [num] - must have an npc target!"); } @@ -2019,7 +2012,7 @@ void command_dbspawn2(Client *c, const Seperator *sep) if(sep->IsNumber(5)) cond_min = atoi(sep->arg[5]); } - database.CreateSpawn2(c, atoi(sep->arg[1]), zone->GetShortName(), c->GetHeading(), c->GetX(), c->GetY(), c->GetZ(), atoi(sep->arg[2]), atoi(sep->arg[3]), cond, cond_min); + database.CreateSpawn2(c, atoi(sep->arg[1]), zone->GetShortName(), c->GetPosition(), atoi(sep->arg[2]), atoi(sep->arg[3]), cond, cond_min); } else { c->Message(0, "Usage: #dbspawn2 spawngroup respawn variance [condition_id] [condition_min]"); @@ -2098,10 +2091,12 @@ void command_wp(Client *c, const Seperator *sep) if (wp == 0) //default to highest if it's left blank, or we enter 0 wp = database.GetHighestWaypoint(zone->GetZoneID(), atoi(sep->arg[2])) + 1; if (strcasecmp("-h",sep->arg[5]) == 0) { - database.AddWP(c, atoi(sep->arg[2]),wp, c->GetX(), c->GetY(), c->GetZ(), atoi(sep->arg[3]),zone->GetZoneID(), c->GetHeading()); + database.AddWP(c, atoi(sep->arg[2]),wp, c->GetPosition(), atoi(sep->arg[3]),zone->GetZoneID()); } else { - database.AddWP(c, atoi(sep->arg[2]),wp, c->GetX(), c->GetY(), c->GetZ(), atoi(sep->arg[3]),zone->GetZoneID(), -1); + auto position = c->GetPosition(); + position.m_Heading = -1; + database.AddWP(c, atoi(sep->arg[2]),wp, position, atoi(sep->arg[3]),zone->GetZoneID()); } } else if (strcasecmp("delete",sep->arg[1]) == 0) @@ -2469,7 +2464,7 @@ void command_spawn(Client *c, const Seperator *sep) LogFile->write(EQEmuLog::Debug,"#spawn Spawning:"); #endif - NPC* npc = NPC::SpawnNPC(sep->argplus[1], c->GetX(), c->GetY(), c->GetZ(), c->GetHeading(), c); + NPC* npc = NPC::SpawnNPC(sep->argplus[1], c->GetPosition(), c); if (!npc) { c->Message(0, "Format: #spawn name race level material hp gender class priweapon secweapon merchantid bodytype - spawns a npc those parameters."); c->Message(0, "Name Format: NPCFirstname_NPCLastname - All numbers in a name are stripped and \"_\" characters become a space."); @@ -2528,7 +2523,7 @@ void command_npctypespawn(Client *c, const Seperator *sep) const NPCType* tmp = 0; if ((tmp = database.GetNPCType(atoi(sep->arg[1])))) { //tmp->fixedZ = 1; - NPC* npc = new NPC(tmp, 0, c->GetX(), c->GetY(), c->GetZ(), c->GetHeading(), FlyMode3); + NPC* npc = new NPC(tmp, 0, c->GetPosition(), FlyMode3); if (npc && sep->IsNumber(2)) npc->SetNPCFactionID(atoi(sep->arg[2])); @@ -2591,7 +2586,7 @@ void command_peekinv(Client *c, const Seperator *sep) peekTrade = 0x20, peekWorld = 0x40 } ; - + if (!c->GetTarget() || !c->GetTarget()->IsClient()) { c->Message(0, "You must have a PC target selected for this command"); return; @@ -5420,8 +5415,7 @@ void command_wpadd(Client *c, const Seperator *sep) { int type1=0, type2=0, - pause=0, - heading=-1; // Defaults for a new grid + pause=0; // Defaults for a new grid Mob *t=c->GetTarget(); if (t && t->IsNPC()) @@ -5444,9 +5438,11 @@ void command_wpadd(Client *c, const Seperator *sep) return; } } - if (strcmp("-h",sep->arg[2]) == 0) - heading = c->GetHeading(); - uint32 tmp_grid = database.AddWPForSpawn(c, s2info->GetID(), c->GetX(),c->GetY(),c->GetZ(), pause, type1, type2, zone->GetZoneID(), heading); + auto position = c->GetPosition(); + if (strcmp("-h",sep->arg[2]) != 0) + position.m_Heading = -1; + + uint32 tmp_grid = database.AddWPForSpawn(c, s2info->GetID(), position, pause, type1, type2, zone->GetZoneID()); if (tmp_grid) t->CastToNPC()->SetGrid(tmp_grid); @@ -5563,9 +5559,8 @@ void command_givemoney(Client *c, const Seperator *sep) void command_itemsearch(Client *c, const Seperator *sep) { - if (sep->arg[1][0] == 0) { + if (sep->arg[1][0] == 0) c->Message(0, "Usage: #itemsearch [search string]"); - } else { const char *search_criteria=sep->argplus[1]; @@ -5620,6 +5615,7 @@ void command_itemsearch(Client *c, const Seperator *sep) c->Message(0, "50 items shown...too many results."); else c->Message(0, "%i items found", count); + } } @@ -7334,7 +7330,7 @@ void command_pf(Client *c, const Seperator *sep) { Mob *who = c->GetTarget(); c->Message(0, "POS: (%.2f, %.2f, %.2f)", who->GetX(), who->GetY(), who->GetZ()); - c->Message(0, "WP: (%.2f, %.2f, %.2f) (%d/%d)", who->GetCWPX(), who->GetCWPY(), who->GetCWPZ(), who->GetCWP(), who->IsNPC()?who->CastToNPC()->GetMaxWp():-1); + c->Message(0, "WP: %s (%d/%d)", to_string(who->GetCurrentWayPoint()).c_str(), who->IsNPC()?who->CastToNPC()->GetMaxWp():-1); c->Message(0, "TAR: (%.2f, %.2f, %.2f)", who->GetTarX(), who->GetTarY(), who->GetTarZ()); c->Message(0, "TARV: (%.2f, %.2f, %.2f)", who->GetTarVX(), who->GetTarVY(), who->GetTarVZ()); c->Message(0, "|TV|=%.2f index=%d", who->GetTarVector(), who->GetTarNDX()); @@ -7376,16 +7372,18 @@ void command_bestz(Client *c, const Seperator *sep) { if(c->GetTarget()) { z=c->GetTarget()->GetZ(); - RegionType = zone->watermap->ReturnRegionType(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z); - c->Message(0,"InWater returns %d", zone->watermap->InWater(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z)); - c->Message(0,"InLava returns %d", zone->watermap->InLava(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z)); + auto position = xyz_location(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z); + RegionType = zone->watermap->ReturnRegionType(position); + c->Message(0,"InWater returns %d", zone->watermap->InWater(position)); + c->Message(0,"InLava returns %d", zone->watermap->InLava(position)); } else { z=c->GetZ(); - RegionType = zone->watermap->ReturnRegionType(c->GetX(), c->GetY(), z); - c->Message(0,"InWater returns %d", zone->watermap->InWater(c->GetX(), c->GetY(), z)); - c->Message(0,"InLava returns %d", zone->watermap->InLava(c->GetX(), c->GetY(), z)); + auto position = xyz_location(c->GetX(), c->GetY(), z); + RegionType = zone->watermap->ReturnRegionType(position); + c->Message(0,"InWater returns %d", zone->watermap->InWater(position)); + c->Message(0,"InLava returns %d", zone->watermap->InLava(position)); } @@ -8200,7 +8198,7 @@ void command_setgraveyard(Client *c, const Seperator *sep) zoneid = database.GetZoneID(sep->arg[1]); if(zoneid > 0) { - graveyard_id = database.CreateGraveyardRecord(zoneid, t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); + graveyard_id = database.CreateGraveyardRecord(zoneid, t->GetPosition()); if(graveyard_id > 0) { c->Message(0, "Successfuly added a new record for this graveyard!"); @@ -8263,7 +8261,7 @@ void command_summonburriedplayercorpse(Client *c, const Seperator *sep) return; } - Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(t->CharacterID(), t->GetZoneID(), zone->GetInstanceID(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); + Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(t->CharacterID(), t->GetZoneID(), zone->GetInstanceID(), t->GetPosition()); if(!PlayerCorpse) c->Message(0, "Your target doesn't have any burried corpses."); diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 0f0a04c28..e1c519e89 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -70,13 +70,13 @@ void Corpse::SendLootReqErrorPacket(Client* client, uint8 response) { safe_delete(outapp); } -Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, float in_x, float in_y, float in_z, float in_heading, std::string time_of_death, bool rezzed, bool was_at_graveyard){ +Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const xyz_heading& position, std::string time_of_death, bool rezzed, bool was_at_graveyard) { uint32 item_count = database.GetCharacterCorpseItemCount(in_dbid); char *buffer = new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))]; PlayerCorpse_Struct *pcs = (PlayerCorpse_Struct*)buffer; database.LoadCharacterCorpseData(in_dbid, pcs); - /* Load Items */ + /* Load Items */ ItemList itemlist; ServerLootItem_Struct* tmp = 0; for (unsigned int i = 0; i < pcs->itemcount; i++) { @@ -95,10 +95,7 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std: pcs->silver, // uint32 in_silver pcs->gold, // uint32 in_gold pcs->plat, // uint32 in_plat - in_x, // float in_x - in_y, // float in_y - in_z, // float in_z - in_heading, // float in_heading + position, pcs->size, // float in_size pcs->gender, // uint8 in_gender pcs->race, // uint16 in_race @@ -110,9 +107,9 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std: pcs->exp, // uint32 in_rezexp was_at_graveyard // bool wasAtGraveyard ); - if (pcs->locked){ + + if (pcs->locked) pc->Lock(); - } /* Load Item Tints */ pc->item_tint[0].color = pcs->item_tint[0].color; @@ -123,7 +120,7 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std: pc->item_tint[5].color = pcs->item_tint[5].color; pc->item_tint[6].color = pcs->item_tint[6].color; pc->item_tint[7].color = pcs->item_tint[7].color; - pc->item_tint[8].color = pcs->item_tint[8].color; + pc->item_tint[8].color = pcs->item_tint[8].color; /* Load Physical Appearance */ pc->haircolor = pcs->haircolor; @@ -145,57 +142,12 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std: } Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime) - : Mob("Unnamed_Corpse", // const char* in_name, - "", // const char* in_lastname, - 0, // int32 in_cur_hp, - 0, // int32 in_max_hp, - in_npc->GetGender(), // uint8 in_gender, - in_npc->GetRace(), // uint16 in_race, - in_npc->GetClass(), // uint8 in_class, - BT_Humanoid, // bodyType in_bodytype, - in_npc->GetDeity(), // uint8 in_deity, - in_npc->GetLevel(), // uint8 in_level, - in_npc->GetNPCTypeID(), // uint32 in_npctype_id, - in_npc->GetSize(), // float in_size, - 0, // float in_runspeed, - in_npc->GetHeading(), // float in_heading, - in_npc->GetX(), // float in_x_pos, - in_npc->GetY(), // float in_y_pos, - in_npc->GetZ(), // float in_z_pos, - 0, // uint8 in_light, - in_npc->GetTexture(), // uint8 in_texture, - in_npc->GetHelmTexture(), // uint8 in_helmtexture, - 0, // uint16 in_ac, - 0, // uint16 in_atk, - 0, // uint16 in_str, - 0, // uint16 in_sta, - 0, // uint16 in_dex, - 0, // uint16 in_agi, - 0, // uint16 in_int, - 0, // uint16 in_wis, - 0, // uint16 in_cha, - 0, // uint8 in_haircolor, - 0, // uint8 in_beardcolor, - 0, // uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye? - 0, // uint8 in_eyecolor2, - 0, // uint8 in_hairstyle, - 0, // uint8 in_luclinface, - 0, // uint8 in_beard, - 0, // uint32 in_drakkin_heritage, - 0, // uint32 in_drakkin_tattoo, - 0, // uint32 in_drakkin_details, - 0, // uint32 in_armor_tint[_MaterialCount], - 0xff, // uint8 in_aa_title, - 0, // uint8 in_see_invis, // see through invis/ivu - 0, // uint8 in_see_invis_undead, - 0, // uint8 in_see_hide, - 0, // uint8 in_see_improved_hide, - 0, // int32 in_hp_regen, - 0, // int32 in_mana_regen, - 0, // uint8 in_qglobal, - 0, // uint8 in_maxlevel, - 0 // uint32 in_scalerate -), +// vesuvias - appearence fix +: Mob("Unnamed_Corpse","",0,0,in_npc->GetGender(),in_npc->GetRace(),in_npc->GetClass(),BT_Humanoid,//bodytype added + in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0, + in_npc->GetPosition(), 0, in_npc->GetTexture(),in_npc->GetHelmTexture(), + 0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0xff,0,0,0,0,0,0,0,0,0), corpse_decay_timer(in_decaytime), corpse_rez_timer(0), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), @@ -224,7 +176,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP player_corpse_depop = false; strcpy(corpse_name, in_npc->GetName()); strcpy(name, in_npc->GetName()); - + for(int count = 0; count < 100; count++) { if ((level >= npcCorpseDecayTimes[count].minlvl) && (level <= npcCorpseDecayTimes[count].maxlvl)) { corpse_decay_timer.SetTimer(npcCorpseDecayTimes[count].seconds*1000); @@ -235,7 +187,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP corpse_decay_timer.SetTimer(RuleI(NPC,EmptyNPCCorpseDecayTimeMS)+1000); } - + if(in_npc->HasPrivateCorpse()) { corpse_delay_timer.SetTimer(corpse_decay_timer.GetRemainingTime() + 1000); } @@ -260,10 +212,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( 0, // uint32 in_npctype_id, client->GetSize(), // float in_size, 0, // float in_runspeed, - client->GetHeading(), // float in_heading, - client->GetX(), // float in_x_pos, - client->GetY(), // float in_y_pos, - client->GetZ(), // float in_z_pos, + client->GetPosition(), 0, // uint8 in_light, client->GetTexture(), // uint8 in_texture, client->GetHelmTexture(), // uint8 in_helmtexture, @@ -297,15 +246,15 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( 0, // uint8 in_qglobal, 0, // uint8 in_maxlevel, 0 // uint32 in_scalerate - ), + ), corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), corpse_rez_timer(RuleI(Character, CorpseResTimeMS)), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), corpse_graveyard_timer(RuleI(Zone, GraveyardTimeMS)), - loot_cooldown_timer(10) + loot_cooldown_timer(10) { int i; - + PlayerProfile_Struct *pp = &client->GetPP(); ItemInst *item; @@ -335,7 +284,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( platinum = 0; strcpy(corpse_name, pp->name); - strcpy(name, pp->name); + strcpy(name, pp->name); /* become_npc was not being initialized which led to some pretty funky things with newly created corpses */ become_npc = false; @@ -343,8 +292,8 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( SetPlayerKillItemID(0); /* Check Rule to see if we can leave corpses */ - if(!RuleB(Character, LeaveNakedCorpses) || - RuleB(Character, LeaveCorpses) && + if(!RuleB(Character, LeaveNakedCorpses) || + RuleB(Character, LeaveCorpses) && GetLevel() >= RuleI(Character, DeathItemLossLevel)) { // cash // Let's not move the cash when 'RespawnFromHover = true' && 'client->GetClientVersion() < EQClientSoF' since the client doesn't. @@ -485,59 +434,55 @@ std::list Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16 return returnlist; } -/* Called from Database Load */ - -Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, float in_x, float in_y, float in_z, float in_heading, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard) - : Mob("Unnamed_Corpse", // const char* in_name, - "", // const char* in_lastname, - 0, // int32 in_cur_hp, - 0, // int32 in_max_hp, - in_gender, // uint8 in_gender, - in_race, // uint16 in_race, - in_class, // uint8 in_class, - BT_Humanoid, // bodyType in_bodytype, - in_deity, // uint8 in_deity, - in_level, // uint8 in_level, - 0, // uint32 in_npctype_id, - in_size, // float in_size, - 0, // float in_runspeed, - in_heading, // float in_heading, - in_x, // float in_x_pos, - in_y, // float in_y_pos, - in_z, // float in_z_pos, - 0, // uint8 in_light, - in_texture, // uint8 in_texture, - in_helmtexture, // uint8 in_helmtexture, - 0, // uint16 in_ac, - 0, // uint16 in_atk, - 0, // uint16 in_str, - 0, // uint16 in_sta, - 0, // uint16 in_dex, - 0, // uint16 in_agi, - 0, // uint16 in_int, - 0, // uint16 in_wis, - 0, // uint16 in_cha, - 0, // uint8 in_haircolor, - 0, // uint8 in_beardcolor, - 0, // uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye? - 0, // uint8 in_eyecolor2, - 0, // uint8 in_hairstyle, - 0, // uint8 in_luclinface, - 0, // uint8 in_beard, - 0, // uint32 in_drakkin_heritage, - 0, // uint32 in_drakkin_tattoo, - 0, // uint32 in_drakkin_details, - 0, // uint32 in_armor_tint[_MaterialCount], - 0xff, // uint8 in_aa_title, - 0, // uint8 in_see_invis, // see through invis/ivu - 0, // uint8 in_see_invis_undead, - 0, // uint8 in_see_hide, - 0, // uint8 in_see_improved_hide, - 0, // int32 in_hp_regen, - 0, // int32 in_mana_regen, - 0, // uint8 in_qglobal, - 0, // uint8 in_maxlevel, - 0), // uint32 in_scalerate +// To be called from LoadFromDBData +Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, const xyz_heading& position, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard) +: Mob("Unnamed_Corpse", +"", +0, +0, +in_gender, +in_race, +in_class, +BT_Humanoid, +in_deity, +in_level, +0, +in_size, +0, +position, +0, +in_texture, +in_helmtexture, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0xff, +0, +0, +0, +0, +0, +0, +0, +0, +0), corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), corpse_rez_timer(RuleI(Character, CorpseResTimeMS)), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), @@ -547,9 +492,8 @@ Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemLi LoadPlayerCorpseDecayTime(in_dbid); - if (!zone->HasGraveyard() || wasAtGraveyard){ + if (!zone->HasGraveyard() || wasAtGraveyard) corpse_graveyard_timer.Disable(); - } memset(item_tint, 0, sizeof(item_tint)); @@ -652,18 +596,18 @@ bool Corpse::Save() { ItemList::iterator cur, end; cur = itemlist.begin(); end = itemlist.end(); - for (; cur != end; ++cur) { + for (; cur != end; ++cur) { ServerLootItem_Struct* item = *cur; memcpy((char*)&dbpc->items[x++], (char*)item, sizeof(ServerLootItem_Struct)); } /* Create New Corpse*/ if (corpse_db_id == 0) { - corpse_db_id = database.SaveCharacterCorpse(char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading); + corpse_db_id = database.SaveCharacterCorpse(char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, m_Position); } /* Update Corpse Data */ else{ - corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading, IsRezzed()); + corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, m_Position, IsRezzed()); } safe_delete_array(dbpc); @@ -673,16 +617,15 @@ bool Corpse::Save() { void Corpse::Delete() { if (IsPlayerCorpse() && corpse_db_id != 0) - database.DeleteCharacterCorpse(corpse_db_id); - + database.DeleteCharacterCorpse(corpse_db_id); + corpse_db_id = 0; player_corpse_depop = true; } void Corpse::Bury() { - if (IsPlayerCorpse() && corpse_db_id != 0){ + if (IsPlayerCorpse() && corpse_db_id != 0) database.BuryCharacterCorpse(corpse_db_id); - } corpse_db_id = 0; player_corpse_depop = true; } @@ -707,7 +650,7 @@ void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, ui is_corpse_changed = true; ServerLootItem_Struct* item = new ServerLootItem_Struct; - + memset(item, 0, sizeof(ServerLootItem_Struct)); item->item_id = itemnum; item->charges = charges; @@ -782,7 +725,7 @@ void Corpse::RemoveItem(uint16 lootslot) { } void Corpse::RemoveItem(ServerLootItem_Struct* item_data){ - uint8 material; + uint8 material; ItemList::iterator cur,end; cur = itemlist.begin(); end = itemlist.end(); @@ -827,14 +770,12 @@ bool Corpse::IsEmpty() const { } bool Corpse::Process() { - if (player_corpse_depop){ + if (player_corpse_depop) return false; - } if (corpse_delay_timer.Check()) { - for (int i = 0; i < MAX_LOOTERS; i++){ + for (int i = 0; i < MAX_LOOTERS; i++) allowed_looters[i] = 0; - } corpse_delay_timer.Disable(); return true; } @@ -844,8 +785,7 @@ bool Corpse::Process() { Save(); player_corpse_depop = true; database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(), - (zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->graveyard_x(), - zone->graveyard_y(), zone->graveyard_z(), zone->graveyard_heading()); + (zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->GetGraveyardPoint()); corpse_graveyard_timer.Disable(); ServerPacket* pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct)); SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer; @@ -911,15 +851,11 @@ bool Corpse::CanPlayerLoot(int charid) { looters++; } - if (allowed_looters[i] == charid){ + if (allowed_looters[i] == charid) return true; - } } /* If we have no looters, obviously client can loot */ - if (looters == 0){ - return true; - } - return false; + return looters == 0; } void Corpse::AllowPlayerLoot(Mob *them, uint8 slot) { @@ -952,21 +888,20 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a return; } - if(being_looted_by == 0) { - being_looted_by = 0xFFFFFFFF; - } + if(being_looted_by == 0) + being_looted_by = 0xFFFFFFFF; if(this->being_looted_by != 0xFFFFFFFF) { // lets double check.... Entity* looter = entity_list.GetID(this->being_looted_by); - if(looter == 0) { - this->being_looted_by = 0xFFFFFFFF; - } + if(looter == 0) + this->being_looted_by = 0xFFFFFFFF; } uint8 Loot_Request_Type = 1; bool loot_coin = false; - if(database.GetVariable("LootCoin", tmp, 9)) { loot_coin = (atoi(tmp) == 1); } + if(database.GetVariable("LootCoin", tmp, 9)) + loot_coin = (atoi(tmp) == 1); if (this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) { SendLootReqErrorPacket(client, 0); @@ -1004,7 +939,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a d->unknown2 = 0xef; /* Dont take the coin off if it's a gm peeking at the corpse */ - if(Loot_Request_Type == 2 || (Loot_Request_Type >= 3 && loot_coin)) { + if(Loot_Request_Type == 2 || (Loot_Request_Type >= 3 && loot_coin)) { if(!IsPlayerCorpse() && client->IsGrouped() && client->AutoSplitEnabled() && client->GetGroup()) { d->copper = 0; d->silver = 0; @@ -1022,7 +957,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a } RemoveCash(); - Save(); + Save(); } outapp->priority = 6; @@ -1251,7 +1186,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) { /* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */ database.DeleteItemOffCharacterCorpse(this->corpse_db_id, item_data->equip_slot, item_data->item_id); /* Delete Item Instance */ - RemoveItem(item_data->lootslot); + RemoveItem(item_data->lootslot); } /* Remove Bag Contents */ @@ -1259,9 +1194,9 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) { for (int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) { if (bag_item_data[i]) { /* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */ - database.DeleteItemOffCharacterCorpse(this->corpse_db_id, bag_item_data[i]->equip_slot, bag_item_data[i]->item_id); + database.DeleteItemOffCharacterCorpse(this->corpse_db_id, bag_item_data[i]->equip_slot, bag_item_data[i]->item_id); /* Delete Item Instance */ - RemoveItem(bag_item_data[i]); + RemoveItem(bag_item_data[i]); } } } @@ -1333,7 +1268,7 @@ void Corpse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) { ns->spawn.NPC = 2; } -void Corpse::QueryLoot(Client* to) { +void Corpse::QueryLoot(Client* to) { int x = 0, y = 0; // x = visible items, y = total items to->Message(0, "Coin: %ip, %ig, %is, %ic", platinum, gold, silver, copper); diff --git a/zone/corpse.h b/zone/corpse.h index 9c898976c..4357d6694 100644 --- a/zone/corpse.h +++ b/zone/corpse.h @@ -37,22 +37,19 @@ class Corpse : public Mob { public: static void SendEndLootErrorPacket(Client* client); - static void SendLootReqErrorPacket(Client* client, uint8 response = 2); - + static void SendLootReqErrorPacket(Client* client, uint8 response = 2); + Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime = 600000); Corpse(Client* client, int32 in_rezexp); - Corpse(uint32 in_corpseid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, float in_x, float in_y, float in_z, float in_heading, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture, uint32 in_rezexp, bool wasAtGraveyard = false); - - ~Corpse(); - static Corpse* LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, float in_x, float in_y, float in_z, float in_heading, std::string time_of_death, bool rezzed, bool was_at_graveyard); + Corpse(uint32 in_corpseid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, const xyz_heading& position, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture, uint32 in_rezexp, bool wasAtGraveyard = false); + + ~Corpse(); + static Corpse* LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const xyz_heading& position, std::string time_of_death, bool rezzed, bool was_at_graveyard); /* Corpse: General */ virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; } virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; } - virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, - bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { - return false; - } + virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; } virtual bool HasRaid() { return false; } virtual bool HasGroup() { return false; } virtual Raid* GetRaid() { return 0; } @@ -73,7 +70,7 @@ class Corpse : public Mob { uint32 GetDecayTime() { if (!corpse_decay_timer.Enabled()) return 0xFFFFFFFF; else return corpse_decay_timer.GetRemainingTime(); } uint32 GetRezTime() { if (!corpse_rez_timer.Enabled()) return 0; else return corpse_rez_timer.GetRemainingTime(); } void SetDecayTimer(uint32 decay_time); - + void Delete(); void Bury(); void CalcCorpseName(); @@ -81,9 +78,9 @@ class Corpse : public Mob { /* Corpse: Items */ uint32 GetWornItem(int16 equipSlot) const; - ServerLootItem_Struct* GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data = 0); + ServerLootItem_Struct* GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data = 0); void SetPlayerKillItemID(int32 pk_item_id) { player_kill_item = pk_item_id; } - int32 GetPlayerKillItem() { return player_kill_item; } + int32 GetPlayerKillItem() { return player_kill_item; } void RemoveItem(uint16 lootslot); void RemoveItem(ServerLootItem_Struct* item_data); void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); @@ -123,10 +120,10 @@ class Corpse : public Mob { bool Summon(Client* client, bool spell, bool CheckDistance); void Spawn(); - char corpse_name[64]; + char corpse_name[64]; uint32 GetEquipment(uint8 material_slot) const; uint32 GetEquipmentColor(uint8 material_slot) const; - inline int GetRezExp() { return rez_experience; } + inline int GetRezExp() { return rez_experience; } protected: std::list MoveItemToCorpse(Client *client, ItemInst *item, int16 equipslot); @@ -139,7 +136,7 @@ private: uint32 corpse_db_id; /* Corpse Database ID (Player Corpse) */ uint32 char_id; /* Character ID */ ItemList itemlist; /* Internal Item list used for corpses */ - uint32 copper; + uint32 copper; uint32 silver; uint32 gold; uint32 platinum; @@ -152,7 +149,7 @@ private: int allowed_looters[MAX_LOOTERS]; /* People allowed to loot the corpse, character id */ Timer corpse_decay_timer; /* The amount of time in millseconds in which a corpse will take to decay (Depop/Poof) */ Timer corpse_rez_timer; /* The amount of time in millseconds in which a corpse can be rezzed */ - Timer corpse_delay_timer; + Timer corpse_delay_timer; Timer corpse_graveyard_timer; Timer loot_cooldown_timer; /* Delay between loot actions on the corpse entity */ Color_Struct item_tint[9]; diff --git a/zone/doors.cpp b/zone/doors.cpp index a745265cf..152712c15 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -39,17 +39,15 @@ extern EntityList entity_list; extern WorldServer worldserver; -Doors::Doors(const Door* door) -: close_timer(5000) +Doors::Doors(const Door* door) : + close_timer(5000), + m_Position(door->pos_x, door->pos_y, door->pos_z, door->heading), + m_Destination(door->dest_x, door->dest_y, door->dest_z, door->dest_heading) { db_id = door->db_id; door_id = door->door_id; strn0cpy(zone_name,door->zone_name,32); strn0cpy(door_name,door->door_name,32); - pos_x = door->pos_x; - pos_y = door->pos_y; - pos_z = door->pos_z; - heading = door->heading; incline = door->incline; opentype = door->opentype; guild_id = door->guild_id; @@ -66,28 +64,22 @@ Doors::Doors(const Door* door) close_timer.Disable(); - strn0cpy(dest_zone,door->dest_zone,32); + strn0cpy(dest_zone,door->dest_zone,16); dest_instance_id = door->dest_instance_id; - dest_x = door->dest_x; - dest_y = door->dest_y; - dest_z = door->dest_z; - dest_heading = door->dest_heading; is_ldon_door = door->is_ldon_door; client_version_mask = door->client_version_mask; } -Doors::Doors(const char *dmodel, float dx, float dy, float dz, float dheading, uint8 dopentype, uint16 dsize) -: close_timer(5000) +Doors::Doors(const char *dmodel, const xyz_heading& position, uint8 dopentype, uint16 dsize) : + close_timer(5000), + m_Position(position), + m_Destination(xyz_heading::Origin()) { db_id = database.GetDoorsCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); door_id = database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); strn0cpy(zone_name,zone->GetShortName(),32); strn0cpy(door_name,dmodel,32); - pos_x = dx; - pos_y = dy; - pos_z = dz; - heading = dheading; incline = 0; opentype = dopentype; guild_id = 0; @@ -106,10 +98,6 @@ Doors::Doors(const char *dmodel, float dx, float dy, float dz, float dheading, u strn0cpy(dest_zone,"NONE",32); dest_instance_id = 0; - dest_x = 0; - dest_y = 0; - dest_z = 0; - dest_heading = 0; is_ldon_door = 0; client_version_mask = 4294967295u; @@ -144,9 +132,9 @@ bool Doors::Process() void Doors::HandleClick(Client* sender, uint8 trigger) { //door debugging info dump - _log(DOORS__INFO, "%s clicked door %s (dbid %d, eqid %d) at (%.4f,%.4f,%.4f @%.4f)", sender->GetName(), door_name, db_id, door_id, pos_x, pos_y, pos_z, heading); + _log(DOORS__INFO, "%s clicked door %s (dbid %d, eqid %d) at %s", sender->GetName(), door_name, db_id, door_id, to_string(m_Position).c_str()); _log(DOORS__INFO, " incline %d, opentype %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", incline, opentype, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param); - _log(DOORS__INFO, " size %d, invert %d, dest: %s (%.4f,%.4f,%.4f @%.4f)", size, invert_state, dest_zone, dest_x, dest_y, dest_z, dest_heading); + _log(DOORS__INFO, " size %d, invert %d, dest: %s %s", size, invert_state, dest_zone, to_string(m_Destination).c_str()); EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct)); MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; @@ -422,7 +410,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger) { sender->KeyRingAdd(playerkey); } - sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); + sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.m_X, m_Destination.m_Y, m_Destination.m_Z, m_Destination.m_Heading); } else if (( !IsDoorOpen() || opentype == 58 ) && (keyneeded && ((keyneeded == playerkey) || sender->GetGM()))) { @@ -432,22 +420,22 @@ void Doors::HandleClick(Client* sender, uint8 trigger) } if(database.GetZoneID(dest_zone) == zone->GetZoneID()) { - sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); + sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.m_X, m_Destination.m_Y, m_Destination.m_Z, m_Destination.m_Heading); } else { - sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, dest_x, dest_y, dest_z, dest_heading); + sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.m_X, m_Destination.m_Y, m_Destination.m_Z, m_Destination.m_Heading); } } if (( !IsDoorOpen() || opentype == 58 ) && (!keyneeded)) { if(database.GetZoneID(dest_zone) == zone->GetZoneID()) { - sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); + sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.m_X, m_Destination.m_Y, m_Destination.m_Z, m_Destination.m_Heading); } else { - sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, dest_x, dest_y, dest_z, dest_heading); + sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.m_X, m_Destination.m_Y, m_Destination.m_Z, m_Destination.m_Heading); } } } @@ -560,14 +548,14 @@ void Doors::ToggleState(Mob *sender) void Doors::DumpDoor(){ LogFile->write(EQEmuLog::Debug, - "db_id:%i door_id:%i zone_name:%s door_name:%s pos_x:%f pos_y:%f pos_z:%f heading:%f", - db_id, door_id, zone_name, door_name, pos_x, pos_y, pos_z, heading); + "db_id:%i door_id:%i zone_name:%s door_name:%s %s", + db_id, door_id, zone_name, door_name, to_string(m_Position).c_str()); LogFile->write(EQEmuLog::Debug, "opentype:%i guild_id:%i lockpick:%i keyitem:%i nokeyring:%i trigger_door:%i trigger_type:%i door_param:%i open:%s", opentype, guild_id, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param, (isopen) ? "open":"closed"); LogFile->write(EQEmuLog::Debug, - "dest_zone:%s dest_x:%f dest_y:%f dest_z:%f dest_heading:%f", - dest_zone, dest_x, dest_y, dest_z, dest_heading); + "dest_zone:%s destination:%s ", + dest_zone, to_string(m_Destination).c_str()); } int32 ZoneDatabase::GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version) { @@ -709,30 +697,13 @@ bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name void Doors::SetLocation(float x, float y, float z) { entity_list.DespawnAllDoors(); - pos_x = x; - pos_y = y; - pos_z = z; + m_Position = xyz_location(x, y, z); entity_list.RespawnAllDoors(); } -void Doors::SetX(float in) { +void Doors::SetPosition(const xyz_heading& position) { entity_list.DespawnAllDoors(); - pos_x = in; - entity_list.RespawnAllDoors(); -} -void Doors::SetY(float in) { - entity_list.DespawnAllDoors(); - pos_y = in; - entity_list.RespawnAllDoors(); -} -void Doors::SetZ(float in) { - entity_list.DespawnAllDoors(); - pos_z = in; - entity_list.RespawnAllDoors(); -} -void Doors::SetHeading(float in) { - entity_list.DespawnAllDoors(); - heading = in; + m_Position = position; entity_list.RespawnAllDoors(); } @@ -767,6 +738,6 @@ void Doors::CreateDatabaseEntry() { return; } - database.InsertDoor(GetDoorDBID(), GetDoorID(), GetDoorName(), GetX(), GetY(), GetZ(), GetHeading(), GetOpenType(), GetGuildID(), GetLockpick(), GetKeyItem(), GetDoorParam(), GetInvertState(), GetIncline(), GetSize()); + database.InsertDoor(GetDoorDBID(), GetDoorID(), GetDoorName(), m_Position, GetOpenType(), GetGuildID(), GetLockpick(), GetKeyItem(), GetDoorParam(), GetInvertState(), GetIncline(), GetSize()); } diff --git a/zone/doors.h b/zone/doors.h index 545834d88..9f842bb7c 100644 --- a/zone/doors.h +++ b/zone/doors.h @@ -17,7 +17,7 @@ class Doors : public Entity { public: Doors(const Door* door); - Doors(const char *dmodel, float dx, float dy, float dz, float dheading, uint8 dopentype = 58, uint16 dsize = 100); + Doors(const char *dmodel, const xyz_heading& position, uint8 dopentype = 58, uint16 dsize = 100); ~Doors(); bool IsDoor() const { return true; } void HandleClick(Client* sender, uint8 trigger); @@ -29,10 +29,7 @@ public: char* GetDoorName() { return door_name; } uint32 GetDoorParam() { return door_param; } int GetInvertState() { return invert_state; } - float GetX() { return pos_x; } - float GetY() { return pos_y; } - float GetZ() { return pos_z; } - float GetHeading() { return heading; } + const xyz_heading GetPosition() const{ return m_Position; } int GetIncline() { return incline; } bool triggered; void SetOpenState(bool st) { isopen = st; } @@ -54,10 +51,7 @@ public: void SetEntityID(uint32 entity) { entity_id = entity; } void DumpDoor(); - float GetDestX() { return dest_x; } - float GetDestY() { return dest_y; } - float GetDestZ() { return dest_z; } - float GetDestHeading() { return dest_heading; } + const xyz_heading GetDestination() const { return m_Destination; } uint8 IsLDoNDoor() { return is_ldon_door; } uint32 GetClientVersionMask() { return client_version_mask; } @@ -67,14 +61,11 @@ public: void ForceClose(Mob *sender, bool alt_mode=false); void ToggleState(Mob *sender); - void SetX(float in); - void SetY(float in); - void SetZ(float in); - void SetHeading(float in); + void SetPosition(const xyz_heading& position); + void SetLocation(float x, float y, float z); void SetIncline(int in); void SetDoorName(const char* name); void SetOpenType(uint8 in); - void SetLocation(float x, float y, float z); void SetSize(uint16 size); void CreateDatabaseEntry(); @@ -84,10 +75,7 @@ private: uint8 door_id; char zone_name[32]; char door_name[32]; - float pos_x; - float pos_y; - float pos_z; - float heading; + xyz_heading m_Position; int incline; uint8 opentype; uint32 guild_id; @@ -106,10 +94,7 @@ private: char dest_zone[16]; int dest_instance_id; - float dest_x; - float dest_y; - float dest_z; - float dest_heading; + xyz_heading m_Destination; uint8 is_ldon_door; uint32 client_version_mask; diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index e75575b7c..435dd6eea 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -32,7 +32,7 @@ #include "zone.h" extern Zone* zone; -extern QueryServ* QServ; +extern QueryServ* QServ; /* @@ -219,11 +219,9 @@ XS(XS__spawn) int npc_type = (int)SvIV(ST(0)); int grid = (int)SvIV(ST(1)); int unused = (int)SvIV(ST(2)); - float x = (float)SvNV(ST(3)); - float y = (float)SvNV(ST(4)); - float z = (float)SvNV(ST(5)); + auto position = xyz_heading((float)SvNV(ST(3)), (float)SvNV(ST(4)), (float)SvNV(ST(5)), 0.0f); - Mob *r = quest_manager.spawn2(npc_type, grid, unused, x, y, z, 0); + Mob *r = quest_manager.spawn2(npc_type, grid, unused, position); RETVAL = (r != nullptr) ? r->GetID() : 0; XSprePUSH; PUSHu((UV)RETVAL); @@ -243,12 +241,9 @@ XS(XS__spawn2) int npc_type = (int)SvIV(ST(0)); int grid = (int)SvIV(ST(1)); int unused = (int)SvIV(ST(2)); - float x = (float)SvNV(ST(3)); - float y = (float)SvNV(ST(4)); - float z = (float)SvNV(ST(5)); - float heading = (float)SvNV(ST(6)); + auto position = xyz_heading((float)SvNV(ST(3)), (float)SvNV(ST(4)), (float)SvNV(ST(5)), (float)SvNV(ST(6))); - Mob *r = quest_manager.spawn2(npc_type, grid, unused, x, y, z, heading); + Mob *r = quest_manager.spawn2(npc_type, grid, unused, position); RETVAL = (r != nullptr) ? r->GetID() : 0; XSprePUSH; PUSHu((UV)RETVAL); @@ -275,7 +270,7 @@ XS(XS__unique_spawn) if(items == 7) heading = (float)SvNV(ST(6)); - Mob *r = quest_manager.unique_spawn(npc_type, grid, unused, x, y, z, heading); + Mob *r = quest_manager.unique_spawn(npc_type, grid, unused, xyz_heading(x, y, z, heading)); RETVAL = (r != nullptr) ? r->GetID() : 0; XSprePUSH; PUSHu((UV)RETVAL); @@ -1175,7 +1170,7 @@ XS(XS__createguild) Perl_croak(aTHX_ "Usage: createguild(guild_name, leader)"); char * guild_name = (char *)SvPV_nolen(ST(0)); - char * leader = (char *)SvPV_nolen(ST(1)); + char * leader = (char *)SvPV_nolen(ST(1)); quest_manager.CreateGuild(guild_name, leader); @@ -1322,11 +1317,9 @@ XS(XS__rebind) Perl_croak(aTHX_ "Usage: rebind(zoneid, x, y, z)"); int zoneid = (int)SvIV(ST(0)); - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); + auto location = xyz_location((float)SvNV(ST(1)),(float)SvNV(ST(2)),(float)SvNV(ST(3))); - quest_manager.rebind(zoneid, x, y, z); + quest_manager.rebind(zoneid, location); XSRETURN_EMPTY; } @@ -1395,7 +1388,7 @@ XS(XS__moveto) else saveguard = false; - quest_manager.moveto(x, y, z, h, saveguard); + quest_manager.moveto(xyz_heading(x, y, z, h), saveguard); XSRETURN_EMPTY; } @@ -1750,12 +1743,9 @@ XS(XS__summonburriedplayercorpse) bool RETVAL; uint32 char_id = (int)SvIV(ST(0)); - float dest_x = (float)SvIV(ST(1)); - float dest_y = (float)SvIV(ST(2)); - float dest_z = (float)SvIV(ST(3)); - float dest_heading = (float)SvIV(ST(4)); + auto position = xyz_heading((float)SvIV(ST(1)), (float)SvIV(ST(2)), (float)SvIV(ST(3)),(float)SvIV(ST(4))); - RETVAL = quest_manager.summonburriedplayercorpse(char_id, dest_x, dest_y, dest_z, dest_heading); + RETVAL = quest_manager.summonburriedplayercorpse(char_id, position); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -1771,12 +1761,9 @@ XS(XS__summonallplayercorpses) bool RETVAL; uint32 char_id = (int)SvIV(ST(0)); - float dest_x = (float)SvIV(ST(1)); - float dest_y = (float)SvIV(ST(2)); - float dest_z = (float)SvIV(ST(3)); - float dest_heading = (float)SvIV(ST(4)); + auto position = xyz_heading((float)SvIV(ST(1)),(float)SvIV(ST(2)),(float)SvIV(ST(3)),(float)SvIV(ST(4))); - RETVAL = quest_manager.summonallplayercorpses(char_id, dest_x, dest_y, dest_z, dest_heading); + RETVAL = quest_manager.summonallplayercorpses(char_id, position); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); @@ -2673,10 +2660,10 @@ XS(XS__CreateGroundObject) uint16 id = 0; if(items == 5) - id = quest_manager.CreateGroundObject(itemid, x, y, z, heading); + id = quest_manager.CreateGroundObject(itemid, xyz_heading(x, y, z, heading)); else{ uint32 decay_time = (uint32)SvIV(ST(5)); - id = quest_manager.CreateGroundObject(itemid, x, y, z, heading, decay_time); + id = quest_manager.CreateGroundObject(itemid, xyz_heading(x, y, z, heading), decay_time); } XSRETURN_IV(id); @@ -2704,7 +2691,7 @@ XS(XS__CreateGroundObjectFromModel) if (items > 6) decay_time = (uint32)SvIV(ST(6)); - id = quest_manager.CreateGroundObjectFromModel(modelname, x, y, z, heading, type, decay_time); + id = quest_manager.CreateGroundObjectFromModel(modelname, xyz_heading(x, y, z, heading), type, decay_time); XSRETURN_IV(id); } @@ -2979,12 +2966,12 @@ XS(XS__MovePCInstance) if (items == 4) { - quest_manager.MovePCInstance(zoneid, instanceid, x, y, z, 0.0f); + quest_manager.MovePCInstance(zoneid, instanceid, xyz_heading(x, y, z, 0.0f)); } else { float heading = (float)SvNV(ST(5)); - quest_manager.MovePCInstance(zoneid, instanceid, x, y, z, heading); + quest_manager.MovePCInstance(zoneid, instanceid, xyz_heading(x, y, z, heading)); } XSRETURN_EMPTY; @@ -3294,7 +3281,7 @@ XS(XS__GetZoneID) char *zone = (char *)SvPV_nolen(ST(0)); int32 id = quest_manager.GetZoneID(zone); - + XSRETURN_IV(id); } @@ -3307,7 +3294,7 @@ XS(XS__GetZoneLongName) dXSTARG; char *zone = (char *)SvPV_nolen(ST(0)); Const_char* RETVAL = quest_manager.GetZoneLongName(zone); - + sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; XSRETURN(1); } @@ -3437,7 +3424,7 @@ XS(XS__clear_npctype_cache) int32 npctype_id = (int32)SvIV(ST(0)); quest_manager.ClearNPCTypeCache(npctype_id); } - + XSRETURN_EMPTY; } @@ -3460,11 +3447,11 @@ XS(XS__qs_player_event); XS(XS__qs_player_event) { dXSARGS; - if (items != 2){ + if (items != 2){ Perl_croak(aTHX_ "Usage: qs_player_event(char_id, event_desc)"); } else{ - int char_id = (int)SvIV(ST(0)); + int char_id = (int)SvIV(ST(0)); std::string event_desc = (std::string)SvPV_nolen(ST(1)); QServ->PlayerLogEvent(Player_Log_Quest, char_id, event_desc); } @@ -3499,7 +3486,7 @@ XS(XS__crosszonesignalnpcbynpctypeid) if (items == 2) { uint32 npctype_id = (uint32)SvIV(ST(0)); - uint32 data = (uint32)SvIV(ST(1)); + uint32 data = (uint32)SvIV(ST(1)); quest_manager.CrossZoneSignalNPCByNPCTypeID(npctype_id, data); } diff --git a/zone/entity.cpp b/zone/entity.cpp index eaed09570..6eb32b684 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -68,7 +68,7 @@ Entity::Entity() Entity::~Entity() { - + } Client *Entity::CastToClient() @@ -484,14 +484,14 @@ void EntityList::MobProcess() while (it != mob_list.end()) { uint16 id = it->first; Mob *mob = it->second; - + size_t sz = mob_list.size(); bool p_val = mob->Process(); size_t a_sz = mob_list.size(); - + if(a_sz > sz) { //increased size can potentially screw with iterators so reset it to current value - //if buckets are re-orderered we may skip a process here and there but since + //if buckets are re-orderered we may skip a process here and there but since //process happens so often it shouldn't matter much it = mob_list.find(id); ++it; @@ -846,10 +846,11 @@ bool EntityList::MakeDoorSpawnPacket(EQApplicationPacket *app, Client *client) strlen(door->GetDoorName()) > 3) { memset(&nd, 0, sizeof(nd)); memcpy(nd.name, door->GetDoorName(), 32); - nd.xPos = door->GetX(); - nd.yPos = door->GetY(); - nd.zPos = door->GetZ(); - nd.heading = door->GetHeading(); + auto position = door->GetPosition(); + nd.xPos = position.m_X; + nd.yPos = position.m_Y; + nd.zPos = position.m_Z; + nd.heading = position.m_Heading; nd.incline = door->GetIncline(); nd.size = door->GetSize(); nd.doorId = door->GetDoorID(); @@ -1551,16 +1552,14 @@ Client *EntityList::GetClientByWID(uint32 iWID) return nullptr; } -Client *EntityList::GetRandomClient(float x, float y, float z, float Distance, Client *ExcludeClient) +Client *EntityList::GetRandomClient(const xyz_location& location, float Distance, Client *ExcludeClient) { std::vector ClientsInRange; - auto it = client_list.begin(); - while (it != client_list.end()) { - if ((it->second != ExcludeClient) && (it->second->DistNoRoot(x, y, z) <= Distance)) + + for (auto it = client_list.begin();it != client_list.end(); ++it) + if ((it->second != ExcludeClient) && (it->second->DistNoRoot(location.m_X, location.m_Y, location.m_Z) <= Distance)) ClientsInRange.push_back(it->second); - ++it; - } if (ClientsInRange.empty()) return nullptr; @@ -3065,54 +3064,43 @@ void EntityList::AddHealAggro(Mob *target, Mob *caster, uint16 thedam) void EntityList::OpenDoorsNear(NPC *who) { - auto it = door_list.begin(); - while (it != door_list.end()) { + + for (auto it = door_list.begin();it != door_list.end(); ++it) { Doors *cdoor = it->second; - if (cdoor && !cdoor->IsDoorOpen()) { - float zdiff = who->GetZ() - cdoor->GetZ(); - if (zdiff < 0) - zdiff = 0 - zdiff; - float curdist = 0; - float tmp = who->GetX() - cdoor->GetX(); - curdist += tmp * tmp; - tmp = who->GetY() - cdoor->GetY(); - curdist += tmp * tmp; - if (zdiff < 10 && curdist <= 100) - cdoor->NPCOpen(who); - } - ++it; + if (!cdoor || cdoor->IsDoorOpen()) + continue; + + auto diff = who->GetPosition() - cdoor->GetPosition(); + diff.ABS_XYZ(); + + float curdist = diff.m_X * diff.m_X + diff.m_Y * diff.m_Y; + + if (diff.m_Z * diff.m_Z < 10 && curdist <= 100) + cdoor->NPCOpen(who); } } void EntityList::SendAlarm(Trap *trap, Mob *currenttarget, uint8 kos) { - float val2 = trap->effectvalue * trap->effectvalue; + float preSquareDistance = trap->effectvalue * trap->effectvalue; - auto it = npc_list.begin(); - while (it != npc_list.end()) { + for (auto it = npc_list.begin();it != npc_list.end(); ++it) { NPC *cur = it->second; - float curdist = 0; - float tmp = cur->GetX() - trap->x; - curdist += tmp*tmp; - tmp = cur->GetY() - trap->y; - curdist += tmp*tmp; - tmp = cur->GetZ() - trap->z; - curdist += tmp*tmp; - if (!cur->GetOwner() && - /*!cur->CastToMob()->dead && */ - !cur->IsEngaged() && - curdist <= val2 ) - { - if (kos) { - uint8 factioncon = currenttarget->GetReverseFactionCon(cur); - if (factioncon == FACTION_THREATENLY || factioncon == FACTION_SCOWLS) { - cur->AddToHateList(currenttarget,1); - } - } else { + + auto diff = cur->GetPosition() - trap->m_Position; + float curdist = diff.m_X * diff.m_X + diff.m_Y * diff.m_Y + diff.m_Z * diff.m_Z; + + if (cur->GetOwner() || cur->IsEngaged() || curdist > preSquareDistance ) + continue; + + if (kos) { + uint8 factioncon = currenttarget->GetReverseFactionCon(cur); + if (factioncon == FACTION_THREATENLY || factioncon == FACTION_SCOWLS) { cur->AddToHateList(currenttarget,1); } - } - ++it; + } + else + cur->AddToHateList(currenttarget,1); } } @@ -3149,7 +3137,7 @@ struct quest_proximity_event { int area_type; }; -void EntityList::ProcessMove(Client *c, float x, float y, float z) +void EntityList::ProcessMove(Client *c, const xyz_location& location) { float last_x = c->ProximityX(); float last_y = c->ProximityY(); @@ -3171,9 +3159,9 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z) last_z < l->min_z || last_z > l->max_z) { old_in = false; } - if (x < l->min_x || x > l->max_x || - y < l->min_y || y > l->max_y || - z < l->min_z || z > l->max_z) { + if (location.m_X < l->min_x || location.m_X > l->max_x || + location.m_Y < l->min_y || location.m_Y > l->max_y || + location.m_Z < l->min_z || location.m_Z > l->max_z) { new_in = false; } @@ -3206,9 +3194,9 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z) old_in = false; } - if (x < a.min_x || x > a.max_x || - y < a.min_y || y > a.max_y || - z < a.min_z || z > a.max_z ) { + if (location.m_X < a.min_x || location.m_X > a.max_x || + location.m_Y < a.min_y || location.m_Y > a.max_y || + location.m_Z < a.min_z || location.m_Z > a.max_z ) { new_in = false; } @@ -3611,7 +3599,7 @@ int16 EntityList::CountTempPets(Mob *owner) } ++it; } - + owner->SetTempPetCount(count); return count; @@ -3802,51 +3790,54 @@ void EntityList::GroupMessage(uint32 gid, const char *from, const char *message) } } -uint16 EntityList::CreateGroundObject(uint32 itemid, float x, float y, float z, - float heading, uint32 decay_time) +uint16 EntityList::CreateGroundObject(uint32 itemid, const xyz_heading& position, uint32 decay_time) { const Item_Struct *is = database.GetItem(itemid); - if (is) { - ItemInst *i = new ItemInst(is, is->MaxCharges); - if (i) { - Object *object = new Object(i, x, y, z, heading,decay_time); - entity_list.AddObject(object, true); + if (!is) + return 0; - safe_delete(i); - if (object) - return object->GetID(); - } - return 0; // fell through itemstruct - } - return 0; // fell through everything, this is bad/incomplete from perl + ItemInst *i = new ItemInst(is, is->MaxCharges); + if (!i) + return 0; + + Object *object = new Object(i, position.m_X, position.m_Y, position.m_Z, position.m_Heading,decay_time); + entity_list.AddObject(object, true); + + safe_delete(i); + if (!object) + return 0; + + return object->GetID(); } -uint16 EntityList::CreateGroundObjectFromModel(const char *model, float x, - float y, float z, float heading, uint8 type, uint32 decay_time) +uint16 EntityList::CreateGroundObjectFromModel(const char *model, const xyz_heading& position, uint8 type, uint32 decay_time) { - if (model) { - Object *object = new Object(model, x, y, z, heading, type); - entity_list.AddObject(object, true); + if (!model) + return 0; - if (object) - return object->GetID(); - } - return 0; // fell through everything, this is bad/incomplete from perl + Object *object = new Object(model, position.m_X, position.m_Y, position.m_Z, position.m_Heading, type); + entity_list.AddObject(object, true); + + if (!object) + return 0; + + return object->GetID(); } -uint16 EntityList::CreateDoor(const char *model, float x, float y, float z, - float heading, uint8 opentype, uint16 size) +uint16 EntityList::CreateDoor(const char *model, const xyz_heading& position, uint8 opentype, uint16 size) { - if (model) { - Doors *door = new Doors(model, x, y, z, heading, opentype, size); - RemoveAllDoors(); - zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion()); - entity_list.AddDoor(door); - entity_list.RespawnAllDoors(); + if (!model) + return 0; // fell through everything, this is bad/incomplete from perl + + Doors *door = new Doors(model, position, opentype, size); + RemoveAllDoors(); + zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion()); + entity_list.AddDoor(door); + entity_list.RespawnAllDoors(); + + if (door) + return door->GetEntityID(); - if (door) - return door->GetEntityID(); - } return 0; // fell through everything, this is bad/incomplete from perl } diff --git a/zone/entity.h b/zone/entity.h index 2b1678740..c94ce03b8 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -27,6 +27,7 @@ #include "../common/bodytypes.h" #include "../common/eq_constants.h" +#include "position.h" #include "zonedump.h" class Beacon; @@ -57,7 +58,7 @@ class Bot; class BotRaids; #endif -extern EntityList entity_list; +extern EntityList entity_list; class Entity { @@ -154,7 +155,7 @@ public: Client *GetClientByCharID(uint32 iCharID); Client *GetClientByWID(uint32 iWID); Client *GetClient(uint32 ip, uint16 port); - Client *GetRandomClient(float x, float y, float z, float Distance, Client *ExcludeClient = nullptr); + Client *GetRandomClient(const xyz_location& location, float Distance, Client *ExcludeClient = nullptr); Group *GetGroupByMob(Mob* mob); Group *GetGroupByClient(Client* client); Group *GetGroupByID(uint32 id); @@ -202,7 +203,7 @@ public: void MobProcess(); void TrapProcess(); void BeaconProcess(); - void ProcessMove(Client *c, float x, float y, float z); + void ProcessMove(Client *c, const xyz_location& location); void ProcessMove(NPC *n, float x, float y, float z); void AddArea(int id, int type, float min_x, float max_x, float min_y, float max_y, float min_z, float max_z); void RemoveArea(int id); @@ -393,9 +394,9 @@ public: void SaveAllClientsTaskState(); void ReloadAllClientsTaskState(int TaskID=0); - uint16 CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time = 300000); - uint16 CreateGroundObjectFromModel(const char *model, float x, float y, float z, float heading, uint8 type = 0x00, uint32 decay_time = 0); - uint16 CreateDoor(const char *model, float x, float y, float z, float heading, uint8 type = 0, uint16 size = 100); + uint16 CreateGroundObject(uint32 itemid, const xyz_heading& position, uint32 decay_time = 300000); + uint16 CreateGroundObjectFromModel(const char *model, const xyz_heading& position, uint8 type = 0x00, uint32 decay_time = 0); + uint16 CreateDoor(const char *model, const xyz_heading& position, uint8 type = 0, uint16 size = 100); void ZoneWho(Client *c, Who_All_Struct* Who); void UnMarkNPC(uint16 ID); diff --git a/zone/fearpath.cpp b/zone/fearpath.cpp index f4354e709..ea32e2f95 100644 --- a/zone/fearpath.cpp +++ b/zone/fearpath.cpp @@ -162,9 +162,7 @@ void Mob::CalculateNewFearpoint() if(Route.size() > 0) { - fear_walkto_x = Loc.x; - fear_walkto_y = Loc.y; - fear_walkto_z = Loc.z; + m_FearWalkTarget = xyz_location(Loc.x, Loc.y, Loc.z); curfp = true; mlog(PATHING__DEBUG, "Feared to node %i (%8.3f, %8.3f, %8.3f)", Node, Loc.x, Loc.y, Loc.z); @@ -194,14 +192,8 @@ void Mob::CalculateNewFearpoint() } } if (curfp) - { - fear_walkto_x = ranx; - fear_walkto_y = rany; - fear_walkto_z = ranz; - } + m_FearWalkTarget = xyz_location(ranx, rany, ranz); else //Break fear - { BuffFadeByEffect(SE_Fear); - } } diff --git a/zone/forage.cpp b/zone/forage.cpp index 6704e9b45..24c621c52 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -174,7 +174,8 @@ bool Client::CanFish() { } if(zone->zonemap != nullptr && zone->watermap != nullptr && RuleB(Watermap, CheckForWaterWhenFishing)) { - float RodX, RodY, RodZ; + + xyz_location rodPosition; // Tweak Rod and LineLength if required const float RodLength = RuleR(Watermap, FishingRodLength); const float LineLength = RuleR(Watermap, FishingLineLength); @@ -183,25 +184,25 @@ bool Client::CanFish() { HeadingDegrees = (int) ((GetHeading()*360)/256); HeadingDegrees = HeadingDegrees % 360; - RodX = x_pos + RodLength * sin(HeadingDegrees * M_PI/180.0f); - RodY = y_pos + RodLength * cos(HeadingDegrees * M_PI/180.0f); + rodPosition.m_X = m_Position.m_X + RodLength * sin(HeadingDegrees * M_PI/180.0f); + rodPosition.m_Y = m_Position.m_Y + RodLength * cos(HeadingDegrees * M_PI/180.0f); // Do BestZ to find where the line hanging from the rod intersects the water (if it is water). // and go 1 unit into the water. Map::Vertex dest; - dest.x = RodX; - dest.y = RodY; - dest.z = z_pos+10; + dest.x = rodPosition.m_X; + dest.y = rodPosition.m_Y; + dest.z = m_Position.m_Z+10; - RodZ = zone->zonemap->FindBestZ(dest, nullptr) + 4; - bool in_lava = zone->watermap->InLava(RodX, RodY, RodZ); - bool in_water = zone->watermap->InWater(RodX, RodY, RodZ) || zone->watermap->InVWater(RodX, RodY, RodZ); + rodPosition.m_Z = zone->zonemap->FindBestZ(dest, nullptr) + 4; + bool in_lava = zone->watermap->InLava(rodPosition); + bool in_water = zone->watermap->InWater(rodPosition) || zone->watermap->InVWater(rodPosition); //Message(0, "Rod is at %4.3f, %4.3f, %4.3f, InWater says %d, InLava says %d", RodX, RodY, RodZ, in_water, in_lava); if (in_lava) { Message_StringID(MT_Skills, FISHING_LAVA); //Trying to catch a fire elemental or something? return false; } - if((!in_water) || (z_pos-RodZ)>LineLength) { //Didn't hit the water OR the water is too far below us + if((!in_water) || (m_Position.m_Z-rodPosition.m_Z)>LineLength) { //Didn't hit the water OR the water is too far below us Message_StringID(MT_Skills, FISHING_LAND); //Trying to catch land sharks perhaps? return false; } @@ -272,7 +273,9 @@ void Client::GoFish() if(npc_chance < zone->random.Int(0, 99)) { const NPCType* tmp = database.GetNPCType(npc_id); if(tmp != nullptr) { - NPC* npc = new NPC(tmp, nullptr, GetX()+3, GetY(), GetZ(), GetHeading(), FlyMode3); + auto positionNPC = GetPosition(); + positionNPC.m_X = positionNPC.m_X + 3; + NPC* npc = new NPC(tmp, nullptr, positionNPC, FlyMode3); npc->AddLootTable(); npc->AddToHateList(this, 1, 0, false); //no help yelling diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index c62dbdab1..b37b07f59 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -308,8 +308,9 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center) continue; } + auto hateEntryPosition = xyz_location(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ()); if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { - if (!zone->watermap->InLiquid(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ())) { + if (!zone->watermap->InLiquid(hateEntryPosition)) { skipped_count++; ++iterator; continue; @@ -434,7 +435,7 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center) { struct_HateList *cur = (*iterator); if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { - if (!zone->watermap->InLiquid(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ())) { + if (!zone->watermap->InLiquid(cur->entity_on_hatelist->GetPosition())) { skipped_count++; ++iterator; continue; diff --git a/zone/horse.cpp b/zone/horse.cpp index 044c64e15..8c7bc23ba 100644 --- a/zone/horse.cpp +++ b/zone/horse.cpp @@ -28,8 +28,8 @@ std::map Horse::horse_types; LinkedList horses_auto_delete; -Horse::Horse(Client *_owner, uint16 spell_id, float x, float y, float z, float heading) - : NPC(GetHorseType(spell_id), nullptr, x, y, z, heading, FlyMode3) +Horse::Horse(Client *_owner, uint16 spell_id, const xyz_heading& position) + : NPC(GetHorseType(spell_id), nullptr, position, FlyMode3) { //give the horse its proper name. strn0cpy(name, _owner->GetCleanName(), 55); @@ -126,7 +126,7 @@ void Client::SummonHorse(uint16 spell_id) { // No Horse, lets get them one. - Horse* horse = new Horse(this, spell_id, GetX(), GetY(), GetZ(), GetHeading()); + Horse* horse = new Horse(this, spell_id, GetPosition()); //we want to manage the spawn packet ourself. //another reason is we dont want quests executing on it. diff --git a/zone/horse.h b/zone/horse.h index 0965a2b69..28ca19356 100644 --- a/zone/horse.h +++ b/zone/horse.h @@ -29,7 +29,7 @@ struct NewSpawn_Struct; class Horse : public NPC { public: - Horse(Client *owner, uint16 spell_id, float x, float y, float z, float heading); + Horse(Client *owner, uint16 spell_id, const xyz_heading& position); virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 0f560d1bd..5678bd24a 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -242,17 +242,17 @@ void Lua_Client::SetBindPoint(int to_zone, int to_instance) { void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x) { Lua_Safe_Call_Void(); - self->SetBindPoint(to_zone, to_instance, new_x); + self->SetBindPoint(to_zone, to_instance, xyz_location(new_x,0.0f,0.0f)); } void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y) { Lua_Safe_Call_Void(); - self->SetBindPoint(to_zone, to_instance, new_x, new_y); + self->SetBindPoint(to_zone, to_instance, xyz_location(new_x, new_y, 0.0f)); } void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y, float new_z) { Lua_Safe_Call_Void(); - self->SetBindPoint(to_zone, to_instance, new_x, new_y, new_z); + self->SetBindPoint(to_zone, to_instance, xyz_location(new_x, new_y, new_z)); } float Lua_Client::GetBindX() { @@ -700,13 +700,13 @@ void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5); } -void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, +void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned) { Lua_Safe_Call_Void(); self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned); } -void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, +void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned, int to_slot) { Lua_Safe_Call_Void(); self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned, to_slot); @@ -1396,7 +1396,7 @@ luabind::scope lua_register_client() { .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem) .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem) .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool))&Lua_Client::SummonItem) - .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool,int))&Lua_Client::SummonItem) + .def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool,int))&Lua_Client::SummonItem) .def("SetStats", (void(Lua_Client::*)(int,int))&Lua_Client::SetStats) .def("IncStats", (void(Lua_Client::*)(int,int))&Lua_Client::IncStats) .def("DropItem", (void(Lua_Client::*)(int))&Lua_Client::DropItem) diff --git a/zone/lua_door.cpp b/zone/lua_door.cpp index 091cd0c0e..bcd0ca284 100644 --- a/zone/lua_door.cpp +++ b/zone/lua_door.cpp @@ -20,42 +20,50 @@ const char *Lua_Door::GetDoorName() { float Lua_Door::GetX() { Lua_Safe_Call_Real(); - return self->GetX(); + return self->GetPosition().m_X; } float Lua_Door::GetY() { Lua_Safe_Call_Real(); - return self->GetY(); + return self->GetPosition().m_Y; } float Lua_Door::GetZ() { Lua_Safe_Call_Real(); - return self->GetZ(); + return self->GetPosition().m_Z; } float Lua_Door::GetHeading() { Lua_Safe_Call_Real(); - return self->GetHeading(); + return self->GetPosition().m_Heading; } void Lua_Door::SetX(float x) { Lua_Safe_Call_Void(); - self->SetX(x); + auto position = self->GetPosition(); + position.m_X = x; + self->SetPosition(position); } void Lua_Door::SetY(float y) { Lua_Safe_Call_Void(); - self->SetY(y); + auto position = self->GetPosition(); + position.m_Y = y; + self->SetPosition(position); } void Lua_Door::SetZ(float z) { Lua_Safe_Call_Void(); - self->SetZ(z); + auto position = self->GetPosition(); + position.m_Z = z; + self->SetPosition(position); } void Lua_Door::SetHeading(float h) { Lua_Safe_Call_Void(); - self->SetHeading(h); + auto position = self->GetPosition(); + position.m_Heading = h; + self->SetPosition(position); } void Lua_Door::SetLocation(float x, float y, float z) { diff --git a/zone/lua_entity_list.cpp b/zone/lua_entity_list.cpp index eace84a69..9632b6624 100644 --- a/zone/lua_entity_list.cpp +++ b/zone/lua_entity_list.cpp @@ -298,12 +298,12 @@ void Lua_EntityList::MessageGroup(Lua_Mob who, bool skip_close, uint32 type, con Lua_Client Lua_EntityList::GetRandomClient(float x, float y, float z, float dist) { Lua_Safe_Call_Class(Lua_Client); - return self->GetRandomClient(x, y, z, dist); + return self->GetRandomClient(xyz_location(x, y, z), dist); } Lua_Client Lua_EntityList::GetRandomClient(float x, float y, float z, float dist, Lua_Client exclude) { Lua_Safe_Call_Class(Lua_Client); - return self->GetRandomClient(x, y, z, dist, exclude); + return self->GetRandomClient(xyz_location(x, y, z), dist, exclude); } Lua_Mob_List Lua_EntityList::GetMobList() { diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 9975995d9..b0127137f 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -124,7 +124,7 @@ void register_event(std::string package_name, std::string name, int evt, luabind e.encounter_name = name; e.lua_reference = func; e.event_id = static_cast(evt); - + auto liter = lua_encounter_events_registered.find(package_name); if(liter == lua_encounter_events_registered.end()) { std::list elist; @@ -201,7 +201,7 @@ void unregister_player_event(int evt) { void register_item_event(std::string name, int evt, int item_id, luabind::adl::object func) { std::string package_name = "item_"; package_name += std::to_string(static_cast(item_id)); - + if(luabind::type(func) == LUA_TFUNCTION) { register_event(package_name, name, evt, func); } @@ -251,13 +251,13 @@ void unregister_spell_event(int evt, int spell_id) { } Lua_Mob lua_spawn2(int npc_type, int grid, int unused, double x, double y, double z, double heading) { - return Lua_Mob(quest_manager.spawn2(npc_type, grid, unused, - static_cast(x), static_cast(y), static_cast(z), static_cast(heading))); + auto position = xyz_heading(x, y, z, heading); + return Lua_Mob(quest_manager.spawn2(npc_type, grid, unused, position)); } Lua_Mob lua_unique_spawn(int npc_type, int grid, int unused, double x, double y, double z, double heading = 0.0) { - return Lua_Mob(quest_manager.unique_spawn(npc_type, grid, unused, - static_cast(x), static_cast(y), static_cast(z), static_cast(heading))); + auto position = xyz_heading(x,y,z,heading); + return Lua_Mob(quest_manager.unique_spawn(npc_type, grid, unused, position)); } Lua_Mob lua_spawn_from_spawn2(uint32 spawn2_id) { @@ -421,15 +421,15 @@ void lua_pause(int duration) { } void lua_move_to(float x, float y, float z) { - quest_manager.moveto(x, y, z, 0, false); + quest_manager.moveto(xyz_heading(x, y, z, 0.0f), false); } void lua_move_to(float x, float y, float z, float h) { - quest_manager.moveto(x, y, z, h, false); + quest_manager.moveto(xyz_heading(x, y, z, h), false); } void lua_move_to(float x, float y, float z, float h, bool save_guard_spot) { - quest_manager.moveto(x, y, z, h, save_guard_spot); + quest_manager.moveto(xyz_heading(x, y, z, h), save_guard_spot); } void lua_path_resume() { @@ -485,11 +485,11 @@ void lua_toggle_spawn_event(int event_id, bool enable, bool strict, bool reset) } void lua_summon_burried_player_corpse(uint32 char_id, float x, float y, float z, float h) { - quest_manager.summonburriedplayercorpse(char_id, x, y, z, h); + quest_manager.summonburriedplayercorpse(char_id, xyz_heading(x, y, z, h)); } void lua_summon_all_player_corpses(uint32 char_id, float x, float y, float z, float h) { - quest_manager.summonallplayercorpses(char_id, x, y, z, h); + quest_manager.summonallplayercorpses(char_id, xyz_heading(x, y, z, h)); } int lua_get_player_burried_corpse_count(uint32 char_id) { @@ -685,23 +685,23 @@ int lua_get_level(int type) { } void lua_create_ground_object(uint32 item_id, float x, float y, float z, float h) { - quest_manager.CreateGroundObject(item_id, x, y, z, h); + quest_manager.CreateGroundObject(item_id, xyz_heading(x, y, z, h)); } void lua_create_ground_object(uint32 item_id, float x, float y, float z, float h, uint32 decay_time) { - quest_manager.CreateGroundObject(item_id, x, y, z, h, decay_time); + quest_manager.CreateGroundObject(item_id, xyz_heading(x, y, z, h), decay_time); } void lua_create_ground_object_from_model(const char *model, float x, float y, float z, float h) { - quest_manager.CreateGroundObjectFromModel(model, x, y, z, h); + quest_manager.CreateGroundObjectFromModel(model, xyz_heading(x, y, z, h)); } void lua_create_ground_object_from_model(const char *model, float x, float y, float z, float h, int type) { - quest_manager.CreateGroundObjectFromModel(model, x, y, z, h, type); + quest_manager.CreateGroundObjectFromModel(model, xyz_heading(x, y, z, h), type); } void lua_create_ground_object_from_model(const char *model, float x, float y, float z, float h, int type, uint32 decay_time) { - quest_manager.CreateGroundObjectFromModel(model, x, y, z, h, type, decay_time); + quest_manager.CreateGroundObjectFromModel(model, xyz_heading(x, y, z, h), type, decay_time); } void lua_create_door(const char *model, float x, float y, float z, float h, int open_type, int size) { @@ -1036,7 +1036,7 @@ void lua_add_spawn_point(luabind::adl::object table) { int condition_min_value = 0; bool enabled = true; int animation = 0; - + auto cur = table["spawn2_id"]; if(luabind::type(cur) != LUA_TNIL) { try { @@ -1284,7 +1284,7 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float if(luabind::type(table) != LUA_TTABLE) { return; } - + NPCType* npc_type = new NPCType; memset(npc_type, 0, sizeof(NPCType)); @@ -1391,7 +1391,7 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float LuaCreateNPCParse(raid_target, bool, false); LuaCreateNPCParse(probability, uint8, 0); - NPC* npc = new NPC(npc_type, nullptr, x, y, z, heading, FlyMode3); + NPC* npc = new NPC(npc_type, nullptr, xyz_heading(x, y, z, heading), FlyMode3); npc->GiveNPCTypeData(npc_type); entity_list.AddNPC(npc); } diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 26bb08f0a..054bb7728 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -631,7 +631,7 @@ double Lua_Mob::ResistSpell(int resist_type, int spell_id, Lua_Mob caster, bool return self->ResistSpell(resist_type, spell_id, caster, use_resist_override, resist_override); } -double Lua_Mob::ResistSpell(int resist_type, int spell_id, Lua_Mob caster, bool use_resist_override, int resist_override, +double Lua_Mob::ResistSpell(int resist_type, int spell_id, Lua_Mob caster, bool use_resist_override, int resist_override, bool charisma_check) { Lua_Safe_Call_Real(); return self->ResistSpell(resist_type, spell_id, caster, use_resist_override, resist_override, charisma_check); @@ -674,22 +674,22 @@ double Lua_Mob::GetHeading() { double Lua_Mob::GetWaypointX() { Lua_Safe_Call_Real(); - return self->GetCWPX(); + return self->GetCurrentWayPoint().m_X; } double Lua_Mob::GetWaypointY() { Lua_Safe_Call_Real(); - return self->GetCWPY(); + return self->GetCurrentWayPoint().m_Y; } double Lua_Mob::GetWaypointZ() { Lua_Safe_Call_Real(); - return self->GetCWPZ(); + return self->GetCurrentWayPoint().m_Z; } double Lua_Mob::GetWaypointH() { Lua_Safe_Call_Real(); - return self->GetCWPH(); + return self->GetCurrentWayPoint().m_Heading; } double Lua_Mob::GetWaypointPause() { @@ -777,19 +777,19 @@ bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, in return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast(item_slot)); } -bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer, +bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer, int timer_duration) { Lua_Safe_Call_Bool(); - return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast(item_slot), + return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast(item_slot), static_cast(timer), static_cast(timer_duration)); } -bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer, +bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer, int timer_duration, int resist_adjust) { Lua_Safe_Call_Bool(); int16 res = resist_adjust; - return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast(item_slot), + return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast(item_slot), static_cast(timer), static_cast(timer_duration), 0, &res); } @@ -841,7 +841,7 @@ Lua_Mob Lua_Mob::GetOwner() { Lua_HateList Lua_Mob::GetHateList() { Lua_Safe_Call_Class(Lua_HateList); Lua_HateList ret; - + auto h_list = self->GetHateList(); auto iter = h_list.begin(); while(iter != h_list.end()) { @@ -1222,7 +1222,7 @@ bool Lua_Mob::EntityVariableExists(const char *name) { void Lua_Mob::Signal(uint32 id) { Lua_Safe_Call_Void(); - + if(self->IsClient()) { self->CastToClient()->Signal(id); } else if(self->IsNPC()) { @@ -1255,7 +1255,7 @@ void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, in self->DoSpecialAttackDamage(other, static_cast(skill), max_damage, min_damage, hate_override, reuse_time); } -void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time, +void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time, bool hit_chance) { Lua_Safe_Call_Void(); self->DoSpecialAttackDamage(other, static_cast(skill), max_damage, min_damage, hate_override, reuse_time, hit_chance); @@ -1286,7 +1286,7 @@ void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_ self->DoThrowingAttackDmg(other, range_weapon, item, weapon_damage, chance_mod); } -void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_Item item, int weapon_damage, int chance_mod, +void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_Item item, int weapon_damage, int chance_mod, int focus) { Lua_Safe_Call_Void(); self->DoThrowingAttackDmg(other, range_weapon, item, weapon_damage, chance_mod, focus); @@ -1337,7 +1337,7 @@ void Lua_Mob::DoArcheryAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_I self->DoArcheryAttackDmg(other, range_weapon, ammo, weapon_damage, chance_mod); } -void Lua_Mob::DoArcheryAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_ItemInst ammo, int weapon_damage, int chance_mod, +void Lua_Mob::DoArcheryAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_ItemInst ammo, int weapon_damage, int chance_mod, int focus) { Lua_Safe_Call_Void(); self->DoArcheryAttackDmg(other, range_weapon, ammo, weapon_damage, chance_mod, focus); @@ -1395,7 +1395,7 @@ void Lua_Mob::ProjectileAnimation(Lua_Mob to, int item_id, bool is_arrow, double void Lua_Mob::ProjectileAnimation(Lua_Mob to, int item_id, bool is_arrow, double speed, double angle, double tilt, double arc) { Lua_Safe_Call_Void(); - self->ProjectileAnimation(to, item_id, is_arrow, static_cast(speed), static_cast(angle), static_cast(tilt), + self->ProjectileAnimation(to, item_id, is_arrow, static_cast(speed), static_cast(angle), static_cast(tilt), static_cast(arc)); } @@ -1635,7 +1635,7 @@ void Lua_Mob::SendSpellEffect(uint32 effect_id, uint32 duration, uint32 finish_d self->SendSpellEffect(effect_id, duration, finish_delay, zone_wide, unk020, perm_effect); } -void Lua_Mob::SendSpellEffect(uint32 effect_id, uint32 duration, uint32 finish_delay, bool zone_wide, uint32 unk020, bool perm_effect, +void Lua_Mob::SendSpellEffect(uint32 effect_id, uint32 duration, uint32 finish_delay, bool zone_wide, uint32 unk020, bool perm_effect, Lua_Client c) { Lua_Safe_Call_Void(); self->SendSpellEffect(effect_id, duration, finish_delay, zone_wide, unk020, perm_effect, c); diff --git a/zone/lua_npc.cpp b/zone/lua_npc.cpp index 869efb019..95ae4c5c9 100644 --- a/zone/lua_npc.cpp +++ b/zone/lua_npc.cpp @@ -269,7 +269,8 @@ void Lua_NPC::PauseWandering(int pause_time) { void Lua_NPC::MoveTo(float x, float y, float z, float h, bool save) { Lua_Safe_Call_Void(); - self->MoveTo(x, y, z, h, save); + auto position = xyz_heading(x, y, z, h); + self->MoveTo(position, save); } void Lua_NPC::NextGuardPosition() { @@ -314,37 +315,37 @@ int Lua_NPC::GetSpawnPointID() { float Lua_NPC::GetSpawnPointX() { Lua_Safe_Call_Real(); - return self->GetSpawnPointX(); + return self->GetSpawnPoint().m_X; } float Lua_NPC::GetSpawnPointY() { Lua_Safe_Call_Real(); - return self->GetSpawnPointY(); + return self->GetSpawnPoint().m_Y; } float Lua_NPC::GetSpawnPointZ() { Lua_Safe_Call_Real(); - return self->GetSpawnPointZ(); + return self->GetSpawnPoint().m_Z; } float Lua_NPC::GetSpawnPointH() { Lua_Safe_Call_Real(); - return self->GetSpawnPointH(); + return self->GetSpawnPoint().m_Heading; } float Lua_NPC::GetGuardPointX() { Lua_Safe_Call_Real(); - return self->GetGuardPointX(); + return self->GetGuardPoint().m_X; } float Lua_NPC::GetGuardPointY() { Lua_Safe_Call_Real(); - return self->GetGuardPointY(); + return self->GetGuardPoint().m_Y; } float Lua_NPC::GetGuardPointZ() { Lua_Safe_Call_Real(); - return self->GetGuardPointZ(); + return self->GetGuardPoint().m_Z; } void Lua_NPC::SetPrimSkill(int skill_id) { diff --git a/zone/map.h b/zone/map.h index dc03d8ac0..cec2adb8a 100644 --- a/zone/map.h +++ b/zone/map.h @@ -22,6 +22,7 @@ #ifndef ZONE_MAP_H #define ZONE_MAP_H +#include "position.h" #include #define BEST_Z_INVALID -99999 @@ -35,10 +36,14 @@ public: Vertex() : x(0.0f), y(0.0f), z(0.0f) { } Vertex(float _x, float _y, float _z) : x(_x), y(_y), z(_z) { } ~Vertex() { } - bool operator==(const Vertex &v) const + bool operator==(const Vertex &v) const { return((v.x == x) && (v.y == y) && (v.z == z)); } + operator xyz_location() const + { + return xyz_location(x,y,z); + } float x; float y; @@ -48,7 +53,7 @@ public: Map(); ~Map(); - + float FindBestZ(Vertex &start, Vertex *result) const; bool LineIntersectsZone(Vertex start, Vertex end, float step, Vertex *result) const; bool LineIntersectsZoneNoZLeaps(Vertex start, Vertex end, float step_mag, Vertex *result) const; @@ -61,7 +66,7 @@ private: void TranslateVertex(Vertex &v, float tx, float ty, float tz); bool LoadV1(FILE *f); bool LoadV2(FILE *f); - + struct impl; impl *imp; }; diff --git a/zone/merc.cpp b/zone/merc.cpp index b73c4fa0e..e50cb04c5 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -20,7 +20,7 @@ extern volatile bool ZoneLoaded; Merc::Merc(const NPCType* d, float x, float y, float z, float heading) -: NPC(d, 0, x, y, z, heading, 0, false), endupkeep_timer(1000), rest_timer(1), confidence_timer(6000), check_target_timer(2000) +: NPC(d, nullptr, xyz_heading(x, y, z, heading), 0, false), endupkeep_timer(1000), rest_timer(1), confidence_timer(6000), check_target_timer(2000) { base_hp = d->max_hp; base_mana = d->Mana; @@ -4722,11 +4722,11 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, if(merc_template) { //TODO: Maybe add a way of updating client merc stats in a seperate function? like, for example, on leveling up. - const NPCType* npc_type_to_copy = database.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel()); + const NPCType* npc_type_to_copy = database.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel()); if(npc_type_to_copy != nullptr) { //This is actually a very terrible method of assigning stats, and should be changed at some point. See the comment in merc's deconstructor. - NPCType* npc_type = new NPCType; + NPCType* npc_type = new NPCType; memset(npc_type, 0, sizeof(NPCType)); memcpy(npc_type, npc_type_to_copy, sizeof(NPCType)); if(c && !updateFromDB) @@ -4919,7 +4919,7 @@ bool Merc::Spawn(Client *owner) { entity_list.AddMerc(this, true, true); SendPosition(); - + if (MERC_DEBUG > 0) owner->Message(7, "Mercenary Debug: Spawn."); @@ -4945,7 +4945,7 @@ void Client::SendMercResponsePackets(uint32 ResponseType) break; case 3: //Mercenary failed to spawn! SendMercMerchantResponsePacket(3); - break; + break; case 4: //Mercenaries are not allowed in raids! SendMercMerchantResponsePacket(4); break; @@ -5109,7 +5109,7 @@ void Client::UpdateMercTimer() { SendMercResponsePackets(16); } - + if (MERC_DEBUG > 0) Message(7, "Mercenary Debug: UpdateMercTimer Complete."); @@ -5132,7 +5132,7 @@ bool Client::CheckCanHireMerc(Mob* merchant, uint32 template_id) { MercTemplate* mercTemplate = zone->GetMercTemplate(template_id); //check for suspended merc - if(GetMercInfo().mercid != 0 && GetMercInfo().IsSuspended) { + if(GetMercInfo().mercid != 0 && GetMercInfo().IsSuspended) { SendMercResponsePackets(6); return false; } @@ -5163,7 +5163,7 @@ bool Client::CheckCanHireMerc(Mob* merchant, uint32 template_id) { return false; } } - + if (MERC_DEBUG > 0) Message(7, "Mercenary Debug: CheckCanHireMerc True."); @@ -5237,7 +5237,7 @@ bool Client::CheckCanSpawnMerc(uint32 template_id) { SendMercResponsePackets(9); return false; } - + if (MERC_DEBUG > 0) Message(7, "Mercenary Debug: CheckCanSpawnMerc True."); @@ -5260,7 +5260,7 @@ bool Client::CheckCanUnsuspendMerc() { Message(0, "You must wait %i seconds before unsuspending your mercenary.", GetPTimers().GetRemainingTime(pTimerMercSuspend)); return false; } - + if (MERC_DEBUG > 0) Message(7, "Mercenary Debug: CheckCanUnsuspendMerc True."); @@ -5413,7 +5413,7 @@ void Client::SendMercTimer(Merc* merc) { } -void Client::SpawnMerc(Merc* merc, bool setMaxStats) { +void Client::SpawnMerc(Merc* merc, bool setMaxStats) { if (!merc || !CheckCanSpawnMerc(merc->GetMercTemplateID())) { @@ -5454,12 +5454,12 @@ bool Merc::Suspend() { mercOwner->GetMercTimer()->Disable(); mercOwner->SendMercSuspendResponsePacket(mercOwner->GetMercInfo().SuspendedTime); mercOwner->SendMercTimer(this); - + Depop(); // Start the timer to send the packet that refreshes the Unsuspend Button mercOwner->GetPTimers().Start(pTimerMercSuspend, RuleI(Mercs, SuspendIntervalS)); - + if (MERC_DEBUG > 0) mercOwner->Message(7, "Mercenary Debug: Suspend Complete."); @@ -5556,7 +5556,7 @@ bool Client::DismissMerc(uint32 MercID) { if (MERC_DEBUG > 0) Message(7, "Mercenary Debug: Dismiss Successful."); } - + if (GetMerc()) { GetMerc()->Depop(); @@ -5724,7 +5724,7 @@ bool Merc::MercJoinClientGroup() { if(MERC_DEBUG > 0) mercOwner->Message(7, "Mercenary Debug: Mercenary disbanded new group."); } - + } else if (AddMercToGroup(this, mercOwner->GetGroup())) { diff --git a/zone/mob.cpp b/zone/mob.cpp index 3c7243e03..1d2d7053e 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -49,11 +49,7 @@ Mob::Mob(const char* in_name, uint32 in_npctype_id, float in_size, float in_runspeed, - float in_heading, - float in_x_pos, - float in_y_pos, - float in_z_pos, - + const xyz_heading& position, uint8 in_light, uint8 in_texture, uint8 in_helmtexture, @@ -102,29 +98,21 @@ Mob::Mob(const char* in_name, bardsong_timer(6000), gravity_timer(1000), viral_timer(0), - flee_timer(FLEE_CHECK_TIMER) - + m_FearWalkTarget(-999999.0f,-999999.0f,-999999.0f), + m_TargetLocation(xyz_location::Origin()), + m_TargetV(xyz_location::Origin()), + flee_timer(FLEE_CHECK_TIMER), + m_Position(position) { targeted = 0; tar_ndx=0; tar_vector=0; - tar_vx=0; - tar_vy=0; - tar_vz=0; - tarx=0; - tary=0; - tarz=0; - fear_walkto_x = -999999; - fear_walkto_y = -999999; - fear_walkto_z = -999999; curfp = false; AI_Init(); SetMoving(false); moved=false; - rewind_x = 0; //Stored x_pos for /rewind - rewind_y = 0; //Stored y_pos for /rewind - rewind_z = 0; //Stored z_pos for /rewind + m_RewindLocation = xyz_location::Origin(); move_tic_count = 0; _egnode = nullptr; @@ -161,10 +149,6 @@ Mob::Mob(const char* in_name, if (runspeed < 0 || runspeed > 20) runspeed = 1.25f; - heading = in_heading; - x_pos = in_x_pos; - y_pos = in_y_pos; - z_pos = in_z_pos; light = in_light; texture = in_texture; helmtexture = in_helmtexture; @@ -259,10 +243,7 @@ Mob::Mob(const char* in_name, } } - delta_heading = 0; - delta_x = 0; - delta_y = 0; - delta_z = 0; + m_Delta = xyz_heading::Origin(); animation = 0; logging_enabled = false; @@ -335,17 +316,12 @@ Mob::Mob(const char* in_name, wandertype=0; pausetype=0; cur_wp = 0; - cur_wp_x = 0; - cur_wp_y = 0; - cur_wp_z = 0; + m_CurrentWayPoint = xyz_heading::Origin(); cur_wp_pause = 0; patrol=0; follow=0; follow_dist = 100; // Default Distance for Follow flee_mode = false; - fear_walkto_x = -999999; - fear_walkto_y = -999999; - fear_walkto_z = -999999; curfp = false; flee_timer.Start(); @@ -387,9 +363,7 @@ Mob::Mob(const char* in_name, nimbus_effect3 = 0; m_targetable = true; - targetring_x = 0.0f; - targetring_y = 0.0f; - targetring_z = 0.0f; + m_TargetRing = xyz_location::Origin(); flymode = FlyMode3; // Pathing @@ -908,10 +882,10 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName)); } - ns->spawn.heading = FloatToEQ19(heading); - ns->spawn.x = FloatToEQ19(x_pos);//((int32)x_pos)<<3; - ns->spawn.y = FloatToEQ19(y_pos);//((int32)y_pos)<<3; - ns->spawn.z = FloatToEQ19(z_pos);//((int32)z_pos)<<3; + ns->spawn.heading = FloatToEQ19(m_Position.m_Heading); + ns->spawn.x = FloatToEQ19(m_Position.m_X);//((int32)x_pos)<<3; + ns->spawn.y = FloatToEQ19(m_Position.m_Y);//((int32)y_pos)<<3; + ns->spawn.z = FloatToEQ19(m_Position.m_Z);//((int32)z_pos)<<3; ns->spawn.spawnId = GetID(); ns->spawn.curHp = static_cast(GetHPRatio()); ns->spawn.max_hp = 100; //this field needs a better name @@ -966,13 +940,9 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) // 3 - Mobs in water do not sink. A value of 3 in this field appears to be the default setting for all mobs // (in water or not) according to 6.2 era packet collects. if(IsClient()) - { ns->spawn.flymode = FindType(SE_Levitate) ? 2 : 0; - } else - { ns->spawn.flymode = flymode; - } ns->spawn.lastName[0] = '\0'; @@ -1240,13 +1210,13 @@ void Mob::SendPosUpdate(uint8 iSendToSelf) { void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu){ memset(spu,0xff,sizeof(PlayerPositionUpdateServer_Struct)); spu->spawn_id = GetID(); - spu->x_pos = FloatToEQ19(x_pos); - spu->y_pos = FloatToEQ19(y_pos); - spu->z_pos = FloatToEQ19(z_pos); + spu->x_pos = FloatToEQ19(m_Position.m_X); + spu->y_pos = FloatToEQ19(m_Position.m_Y); + spu->z_pos = FloatToEQ19(m_Position.m_Z); spu->delta_x = NewFloatToEQ13(0); spu->delta_y = NewFloatToEQ13(0); spu->delta_z = NewFloatToEQ13(0); - spu->heading = FloatToEQ19(heading); + spu->heading = FloatToEQ19(m_Position.m_Heading); spu->animation = 0; spu->delta_heading = NewFloatToEQ13(0); spu->padding0002 =0; @@ -1259,13 +1229,13 @@ void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu){ // this is for SendPosUpdate() void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) { spu->spawn_id = GetID(); - spu->x_pos = FloatToEQ19(x_pos); - spu->y_pos = FloatToEQ19(y_pos); - spu->z_pos = FloatToEQ19(z_pos); - spu->delta_x = NewFloatToEQ13(delta_x); - spu->delta_y = NewFloatToEQ13(delta_y); - spu->delta_z = NewFloatToEQ13(delta_z); - spu->heading = FloatToEQ19(heading); + spu->x_pos = FloatToEQ19(m_Position.m_X); + spu->y_pos = FloatToEQ19(m_Position.m_Y); + spu->z_pos = FloatToEQ19(m_Position.m_Z); + spu->delta_x = NewFloatToEQ13(m_Delta.m_X); + spu->delta_y = NewFloatToEQ13(m_Delta.m_Y); + spu->delta_z = NewFloatToEQ13(m_Delta.m_Z); + spu->heading = FloatToEQ19(m_Position.m_Heading); spu->padding0002 =0; spu->padding0006 =7; spu->padding0014 =0x7f; @@ -1274,7 +1244,7 @@ void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) { spu->animation = animation; else spu->animation = pRunAnimSpeed;//animation; - spu->delta_heading = NewFloatToEQ13(static_cast(delta_heading)); + spu->delta_heading = NewFloatToEQ13(m_Delta.m_Heading); } void Mob::ShowStats(Client* client) @@ -1390,11 +1360,11 @@ void Mob::GMMove(float x, float y, float z, float heading, bool SendUpdate) { entity_list.ProcessMove(CastToNPC(), x, y, z); } - x_pos = x; - y_pos = y; - z_pos = z; - if (heading != 0.01) - this->heading = heading; + m_Position.m_X = x; + m_Position.m_Y = y; + m_Position.m_Z = z; + if (m_Position.m_Heading != 0.01) + this->m_Position.m_Heading = heading; if(IsNPC()) CastToNPC()->SaveGuardSpot(true); if(SendUpdate) @@ -2305,9 +2275,9 @@ bool Mob::CanThisClassBlock(void) const } float Mob::Dist(const Mob &other) const { - float xDiff = other.x_pos - x_pos; - float yDiff = other.y_pos - y_pos; - float zDiff = other.z_pos - z_pos; + float xDiff = other.m_Position.m_X - m_Position.m_X; + float yDiff = other.m_Position.m_Y - m_Position.m_Y; + float zDiff = other.m_Position.m_Z - m_Position.m_Z; return sqrtf( (xDiff * xDiff) + (yDiff * yDiff) @@ -2315,17 +2285,17 @@ float Mob::Dist(const Mob &other) const { } float Mob::DistNoZ(const Mob &other) const { - float xDiff = other.x_pos - x_pos; - float yDiff = other.y_pos - y_pos; + float xDiff = other.m_Position.m_X - m_Position.m_X; + float yDiff = other.m_Position.m_Y - m_Position.m_Y; return sqrtf( (xDiff * xDiff) + (yDiff * yDiff) ); } float Mob::DistNoRoot(const Mob &other) const { - float xDiff = other.x_pos - x_pos; - float yDiff = other.y_pos - y_pos; - float zDiff = other.z_pos - z_pos; + float xDiff = other.m_Position.m_X - m_Position.m_X; + float yDiff = other.m_Position.m_Y - m_Position.m_Y; + float zDiff = other.m_Position.m_Z - m_Position.m_Z; return ( (xDiff * xDiff) + (yDiff * yDiff) @@ -2333,9 +2303,9 @@ float Mob::DistNoRoot(const Mob &other) const { } float Mob::DistNoRoot(float x, float y, float z) const { - float xDiff = x - x_pos; - float yDiff = y - y_pos; - float zDiff = z - z_pos; + float xDiff = x - m_Position.m_X; + float yDiff = y - m_Position.m_Y; + float zDiff = z - m_Position.m_Z; return ( (xDiff * xDiff) + (yDiff * yDiff) @@ -2343,15 +2313,15 @@ float Mob::DistNoRoot(float x, float y, float z) const { } float Mob::DistNoRootNoZ(float x, float y) const { - float xDiff = x - x_pos; - float yDiff = y - y_pos; + float xDiff = x - m_Position.m_X; + float yDiff = y - m_Position.m_Y; return ( (xDiff * xDiff) + (yDiff * yDiff) ); } float Mob::DistNoRootNoZ(const Mob &other) const { - float xDiff = other.x_pos - x_pos; - float yDiff = other.y_pos - y_pos; + float xDiff = other.m_Position.m_X - m_Position.m_X; + float yDiff = other.m_Position.m_Y - m_Position.m_Y; return ( (xDiff * xDiff) + (yDiff * yDiff) ); } @@ -2496,20 +2466,18 @@ bool Mob::HateSummon() { entity_list.MessageClose(this, true, 500, MT_Say, "%s says,'You will not evade me, %s!' ", GetCleanName(), target->GetCleanName() ); if (target->IsClient()) { - target->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x_pos, y_pos, z_pos, target->GetHeading(), 0, SummonPC); + target->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Position.m_X, m_Position.m_Y, m_Position.m_Z, target->GetHeading(), 0, SummonPC); } else { #ifdef BOTS if(target && target->IsBot()) { // set pre summoning info to return to (to get out of melee range for caster) target->CastToBot()->SetHasBeenSummoned(true); - target->CastToBot()->SetPreSummonX(target->GetX()); - target->CastToBot()->SetPreSummonY(target->GetY()); - target->CastToBot()->SetPreSummonZ(target->GetZ()); + target->CastToBot()->SetPreSummonLocation(target->GetPosition()); } #endif //BOTS - target->GMMove(x_pos, y_pos, z_pos, target->GetHeading()); + target->GMMove(m_Position.m_X, m_Position.m_Y, m_Position.m_Z, target->GetHeading()); } return true; @@ -2687,7 +2655,7 @@ int32 Mob::GetEquipmentMaterial(uint8 material_slot) const int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); const Item_Struct *item; item = database.GetItem(GetEquipment(material_slot)); - + if (item != 0) { // For primary and secondary we need the model, not the material @@ -2798,14 +2766,10 @@ uint32 Mob::GetEquipmentColor(uint8 material_slot) const { return armor_tint[material_slot]; } - else - { - item = database.GetItem(GetEquipment(material_slot)); - if (item != 0) - { - return item->Color; - } - } + + item = database.GetItem(GetEquipment(material_slot)); + if (item != 0) + return item->Color; return 0; } @@ -2927,20 +2891,16 @@ void Mob::SetNextIncHPEvent( int inchpevent ) nextinchpevent = inchpevent; } //warp for quest function,from sandy -void Mob::Warp( float x, float y, float z ) +void Mob::Warp(const xyz_location& location) { - if(IsNPC()) { - entity_list.ProcessMove(CastToNPC(), x, y, z); - } + if(IsNPC()) + entity_list.ProcessMove(CastToNPC(), location.m_X, location.m_Y, location.m_Z); - x_pos = x; - y_pos = y; - z_pos = z; + m_Position = location; Mob* target = GetTarget(); - if (target) { + if (target) FaceTarget( target ); - } SendPosition(); } @@ -3026,7 +2986,7 @@ int32 Mob::GetActSpellCasttime(uint16 spell_id, int32 casttime) { } casttime = (casttime*(100 - cast_reducer)/100); - return(casttime); + return casttime; } void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on) { @@ -3061,7 +3021,8 @@ void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on) { bool twinproc = false; int32 twinproc_chance = 0; - twinproc_chance = GetFocusEffect(focusTwincast, spell_id); + if(IsClient()) + twinproc_chance = CastToClient()->GetFocusEffect(focusTwincast, spell_id); if(twinproc_chance && zone->random.Roll(twinproc_chance)) twinproc = true; @@ -3153,9 +3114,9 @@ float Mob::FindGroundZ(float new_x, float new_y, float z_offset) if (zone->zonemap != nullptr) { Map::Vertex me; - me.x = new_x; - me.y = new_y; - me.z = z_pos+z_offset; + me.x = m_Position.m_X; + me.y = m_Position.m_Y; + me.z = m_Position.m_Z + z_offset; Map::Vertex hit; float best_z = zone->zonemap->FindBestZ(me, &hit); if (best_z != -999999) @@ -3173,9 +3134,9 @@ float Mob::GetGroundZ(float new_x, float new_y, float z_offset) if (zone->zonemap != 0) { Map::Vertex me; - me.x = new_x; - me.y = new_y; - me.z = z_pos+z_offset; + me.x = m_Position.m_X; + me.y = m_Position.m_Y; + me.z = m_Position.m_Z+z_offset; Map::Vertex hit; float best_z = zone->zonemap->FindBestZ(me, &hit); if (best_z != -999999) @@ -3270,11 +3231,8 @@ void Mob::TriggerDefensiveProcs(const ItemInst* weapon, Mob *on, uint16 hand, in } } -void Mob::SetDeltas(float dx, float dy, float dz, float dh) { - delta_x = dx; - delta_y = dy; - delta_z = dz; - delta_heading = static_cast(dh); +void Mob::SetDelta(const xyz_heading& delta) { + m_Delta = delta; } void Mob::SetEntityVariable(const char *id, const char *m_var) diff --git a/zone/mob.h b/zone/mob.h index 515f484e1..6e304c34a 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -22,6 +22,7 @@ #include "entity.h" #include "hate_list.h" #include "pathing.h" +#include "position.h" #include #include @@ -77,10 +78,7 @@ public: uint32 in_npctype_id, float in_size, float in_runspeed, - float in_heading, - float in_x_pos, - float in_y_pos, - float in_z_pos, + const xyz_heading& position, uint8 in_light, uint8 in_texture, uint8 in_helmtexture, @@ -183,7 +181,7 @@ public: bool IsInvisible(Mob* other = 0) const; void SetInvisible(uint8 state); bool AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* weapon); - + //Song bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1); bool ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, uint16 slot); @@ -296,9 +294,9 @@ public: inline virtual uint32 GetNimbusEffect2() const { return nimbus_effect2; } inline virtual uint32 GetNimbusEffect3() const { return nimbus_effect3; } void RemoveNimbusEffect(int effectid); - inline float GetTargetRingX() const { return targetring_x; } - inline float GetTargetRingY() const { return targetring_y; } - inline float GetTargetRingZ() const { return targetring_z; } + inline float GetTargetRingX() const { return m_TargetRing.m_X; } + inline float GetTargetRingY() const { return m_TargetRing.m_Y; } + inline float GetTargetRingZ() const { return m_TargetRing.m_Z; } inline bool HasEndurUpkeep() const { return endur_upkeep; } inline void SetEndurUpkeep(bool val) { endur_upkeep = val; } @@ -400,18 +398,19 @@ public: ((static_cast(cur_mana) / max_mana) * 100); } virtual int32 CalcMaxMana(); uint32 GetNPCTypeID() const { return npctype_id; } - inline const float GetX() const { return x_pos; } - inline const float GetY() const { return y_pos; } - inline const float GetZ() const { return z_pos; } - inline const float GetHeading() const { return heading; } + inline const xyz_heading GetPosition() const { return m_Position; } + inline const float GetX() const { return m_Position.m_X; } + inline const float GetY() const { return m_Position.m_Y; } + inline const float GetZ() const { return m_Position.m_Z; } + inline const float GetHeading() const { return m_Position.m_Heading; } inline const float GetSize() const { return size; } inline const float GetBaseSize() const { return base_size; } - inline const float GetTarX() const { return tarx; } - inline const float GetTarY() const { return tary; } - inline const float GetTarZ() const { return tarz; } - inline const float GetTarVX() const { return tar_vx; } - inline const float GetTarVY() const { return tar_vy; } - inline const float GetTarVZ() const { return tar_vz; } + inline const float GetTarX() const { return m_TargetLocation.m_X; } + inline const float GetTarY() const { return m_TargetLocation.m_Y; } + inline const float GetTarZ() const { return m_TargetLocation.m_Z; } + inline const float GetTarVX() const { return m_TargetV.m_X; } + inline const float GetTarVY() const { return m_TargetV.m_Y; } + inline const float GetTarVZ() const { return m_TargetV.m_Z; } inline const float GetTarVector() const { return tar_vector; } inline const uint8 GetTarNDX() const { return tar_ndx; } bool IsBoat() const; @@ -426,9 +425,9 @@ public: virtual inline int32 GetPrimaryFaction() const { return 0; } //Movement - void Warp( float x, float y, float z ); + void Warp(const xyz_location& location); inline bool IsMoving() const { return moving; } - virtual void SetMoving(bool move) { moving = move; delta_x = 0; delta_y = 0; delta_z = 0; delta_heading = 0; } + virtual void SetMoving(bool move) { moving = move; m_Delta = xyz_heading::Origin(); } virtual void GoToBind(uint8 bindnum = 0) { } virtual void Gate(); float GetWalkspeed() const { return(_GetMovementSpeed(-47)); } @@ -438,15 +437,15 @@ public: bool IsRunning() const { return m_is_running; } void SetRunning(bool val) { m_is_running = val; } virtual void GMMove(float x, float y, float z, float heading = 0.01, bool SendUpdate = true); - void SetDeltas(float delta_x, float delta_y, float delta_z, float delta_h); + void SetDelta(const xyz_heading& delta); void SetTargetDestSteps(uint8 target_steps) { tar_ndx = target_steps; } void SendPosUpdate(uint8 iSendToSelf = 0); void MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct* spu); void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu); void SendPosition(); void SetFlyMode(uint8 flymode); - inline void Teleport(Map::Vertex NewPosition) { x_pos = NewPosition.x; y_pos = NewPosition.y; - z_pos = NewPosition.z; }; + inline void Teleport(Map::Vertex NewPosition) { m_Position.m_X = NewPosition.x; m_Position.m_Y = NewPosition.y; + m_Position.m_Z = NewPosition.z; }; //AI static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel); @@ -467,8 +466,8 @@ public: bool IsEngaged() { return(!hate_list.IsHateListEmpty()); } bool HateSummon(); void FaceTarget(Mob* MobToFace = 0); - void SetHeading(float iHeading) { if(heading != iHeading) { pLastChange = Timer::GetCurrentTime(); - heading = iHeading; } } + void SetHeading(float iHeading) { if(m_Position.m_Heading != iHeading) { pLastChange = Timer::GetCurrentTime(); + m_Position.m_Heading = iHeading; } } void WipeHateList(); void AddFeignMemory(Client* attacker); void RemoveFromFeignMemory(Client* attacker); @@ -575,10 +574,10 @@ public: int16 CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus=false); uint8 IsFocusEffect(uint16 spellid, int effect_index, bool AA=false,uint32 aa_effect=0); - void SendIllusionPacket(uint16 in_race, uint8 in_gender = 0xFF, uint8 in_texture = 0xFF, uint8 in_helmtexture = 0xFF, - uint8 in_haircolor = 0xFF, uint8 in_beardcolor = 0xFF, uint8 in_eyecolor1 = 0xFF, uint8 in_eyecolor2 = 0xFF, - uint8 in_hairstyle = 0xFF, uint8 in_luclinface = 0xFF, uint8 in_beard = 0xFF, uint8 in_aa_title = 0xFF, - uint32 in_drakkin_heritage = 0xFFFFFFFF, uint32 in_drakkin_tattoo = 0xFFFFFFFF, + void SendIllusionPacket(uint16 in_race, uint8 in_gender = 0xFF, uint8 in_texture = 0xFF, uint8 in_helmtexture = 0xFF, + uint8 in_haircolor = 0xFF, uint8 in_beardcolor = 0xFF, uint8 in_eyecolor1 = 0xFF, uint8 in_eyecolor2 = 0xFF, + uint8 in_hairstyle = 0xFF, uint8 in_luclinface = 0xFF, uint8 in_beard = 0xFF, uint8 in_aa_title = 0xFF, + uint32 in_drakkin_heritage = 0xFFFFFFFF, uint32 in_drakkin_tattoo = 0xFFFFFFFF, uint32 in_drakkin_details = 0xFFFFFFFF, float in_size = -1.0f); bool RandomizeFeatures(bool send_illusion = true, bool set_variables = true); virtual void Stun(int duration); @@ -627,7 +626,7 @@ public: bool CanBlockSpell() const { return(spellbonuses.BlockNextSpell); } bool DoHPToManaCovert(uint16 mana_cost = 0); int32 ApplySpellEffectiveness(Mob* caster, int16 spell_id, int32 value, bool IsBard = false); - int8 GetDecayEffectValue(uint16 spell_id, uint16 spelleffect); + int8 GetDecayEffectValue(uint16 spell_id, uint16 spelleffect); int32 GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg); void MeleeLifeTap(int32 damage); bool PassCastRestriction(bool UseCastRestriction = true, int16 value = 0, bool IsDamage = true); @@ -688,9 +687,9 @@ public: inline int16 GetTempPetCount() const { return count_TempPet; } inline void SetTempPetCount(int16 i) { count_TempPet = i; } bool HasPetAffinity() { if (aabonuses.GivePetGroupTarget || itembonuses.GivePetGroupTarget || spellbonuses.GivePetGroupTarget) return true; return false; } - inline bool IsPetOwnerClient() const { return pet_owner_client; } + inline bool IsPetOwnerClient() const { return pet_owner_client; } inline void SetPetOwnerClient(bool value) { pet_owner_client = value; } - inline bool IsTempPet() const { return _IsTempPet; } + inline bool IsTempPet() const { return _IsTempPet; } inline void SetTempPet(bool value) { _IsTempPet = value; } inline const bodyType GetBodyType() const { return bodytype; } @@ -821,10 +820,10 @@ public: void SetDontCureMeBefore(uint32 time) { pDontCureMeBefore = time; } // calculate interruption of spell via movement of mob - void SaveSpellLoc() {spell_x = x_pos; spell_y = y_pos; spell_z = z_pos; } - inline float GetSpellX() const {return spell_x;} - inline float GetSpellY() const {return spell_y;} - inline float GetSpellZ() const {return spell_z;} + void SaveSpellLoc() {m_SpellLocation = m_Position; } + inline float GetSpellX() const {return m_SpellLocation.m_X;} + inline float GetSpellY() const {return m_SpellLocation.m_Y;} + inline float GetSpellZ() const {return m_SpellLocation.m_Z;} inline bool IsGrouped() const { return isgrouped; } void SetGrouped(bool v); inline bool IsRaidGrouped() const { return israidgrouped; } @@ -875,11 +874,8 @@ public: Shielders_Struct shielder[MAX_SHIELDERS]; Trade* trade; - - inline float GetCWPX() const { return(cur_wp_x); } - inline float GetCWPY() const { return(cur_wp_y); } - inline float GetCWPZ() const { return(cur_wp_z); } - inline float GetCWPH() const { return(cur_wp_heading); } + + inline xyz_heading GetCurrentWayPoint() const { return m_CurrentWayPoint; } inline float GetCWPP() const { return(static_cast(cur_wp_pause)); } inline int GetCWP() const { return(cur_wp); } void SetCurrentWP(uint16 waypoint) { cur_wp = waypoint; } @@ -1023,10 +1019,7 @@ protected: uint8 level; uint8 orig_level; uint32 npctype_id; - float x_pos; - float y_pos; - float z_pos; - float heading; + xyz_heading m_Position; uint16 animation; float base_size; float size; @@ -1075,10 +1068,7 @@ protected: char clean_name[64]; char lastname[64]; - int32 delta_heading; - float delta_x; - float delta_y; - float delta_z; + xyz_heading m_Delta; uint8 light; @@ -1087,7 +1077,6 @@ protected: uint8 pRunAnimSpeed; bool m_is_running; - Timer attack_timer; Timer attack_dw_timer; Timer ranged_timer; @@ -1100,7 +1089,7 @@ protected: //spell casting vars Timer spellend_timer; uint16 casting_spell_id; - float spell_x, spell_y, spell_z; + xyz_location m_SpellLocation; int attacked_count; bool delaytimer; uint16 casting_spell_targetid; @@ -1119,9 +1108,8 @@ protected: bool ActiveProjectileATK; tProjatk ProjectileAtk[MAX_SPELL_PROJECTILE]; - float rewind_x; - float rewind_y; - float rewind_z; + xyz_location m_RewindLocation; + Timer rewind_timer; // Currently 3 max nimbus particle effects at a time @@ -1217,16 +1205,12 @@ protected: int pausetype; int cur_wp; - float cur_wp_x; - float cur_wp_y; - float cur_wp_z; + xyz_heading m_CurrentWayPoint; int cur_wp_pause; - float cur_wp_heading; + int patrol; - float fear_walkto_x; - float fear_walkto_y; - float fear_walkto_z; + xyz_location m_FearWalkTarget; bool curfp; // Pathing @@ -1261,19 +1245,13 @@ protected: bool pet_owner_client; //Flags regular and pets as belonging to a client EGNode *_egnode; //the EG node we are in - float tarx; - float tary; - float tarz; + xyz_location m_TargetLocation; uint8 tar_ndx; float tar_vector; - float tar_vx; - float tar_vy; - float tar_vz; + xyz_location m_TargetV; float test_vector; - float targetring_x; - float targetring_y; - float targetring_z; + xyz_location m_TargetRing; uint32 m_spellHitsLeft[38]; // Used to track which spells will have their numhits incremented when spell finishes casting, 38 Buffslots int flymode; diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 5802bfd93..f6310801d 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -493,10 +493,7 @@ void Mob::AI_Start(uint32 iMoveDelay) { pAssistRange = 70; hate_list.WipeHateList(); - delta_heading = 0; - delta_x = 0; - delta_y = 0; - delta_z = 0; + m_Delta = xyz_heading::Origin(); pRunAnimSpeed = 0; pLastChange = Timer::GetCurrentTime(); } @@ -787,17 +784,17 @@ void Client::AI_Process() if(AImovement_timer->Check()) { animation = GetRunspeed() * 21; // Check if we have reached the last fear point - if((ABS(GetX()-fear_walkto_x) < 0.1) && (ABS(GetY()-fear_walkto_y) <0.1)) { + if((ABS(GetX()-m_FearWalkTarget.m_X) < 0.1) && (ABS(GetY()-m_FearWalkTarget.m_Y) <0.1)) { // Calculate a new point to run to CalculateNewFearpoint(); } if(!RuleB(Pathing, Fear) || !zone->pathing) - CalculateNewPosition2(fear_walkto_x, fear_walkto_y, fear_walkto_z, GetFearSpeed(), true); + CalculateNewPosition2(m_FearWalkTarget.m_X, m_FearWalkTarget.m_Y, m_FearWalkTarget.m_Z, GetFearSpeed(), true); else { bool WaypointChanged, NodeReached; - Map::Vertex Goal = UpdatePath(fear_walkto_x, fear_walkto_y, fear_walkto_z, + Map::Vertex Goal = UpdatePath(m_FearWalkTarget.m_X, m_FearWalkTarget.m_Y, m_FearWalkTarget.m_Z, GetFearSpeed(), WaypointChanged, NodeReached); if(WaypointChanged) @@ -1055,17 +1052,17 @@ void Mob::AI_Process() { } else { if(AImovement_timer->Check()) { // Check if we have reached the last fear point - if((ABS(GetX()-fear_walkto_x) < 0.1) && (ABS(GetY()-fear_walkto_y) <0.1)) { + if((ABS(GetX()-m_FearWalkTarget.m_X) < 0.1) && (ABS(GetY()-m_FearWalkTarget.m_Y) <0.1)) { // Calculate a new point to run to CalculateNewFearpoint(); } if(!RuleB(Pathing, Fear) || !zone->pathing) - CalculateNewPosition2(fear_walkto_x, fear_walkto_y, fear_walkto_z, GetFearSpeed(), true); + CalculateNewPosition2(m_FearWalkTarget.m_X, m_FearWalkTarget.m_Y, m_FearWalkTarget.m_Z, GetFearSpeed(), true); else { bool WaypointChanged, NodeReached; - Map::Vertex Goal = UpdatePath(fear_walkto_x, fear_walkto_y, fear_walkto_z, + Map::Vertex Goal = UpdatePath(m_FearWalkTarget.m_X, m_FearWalkTarget.m_Y, m_FearWalkTarget.m_Z, GetFearSpeed(), WaypointChanged, NodeReached); if(WaypointChanged) @@ -1127,19 +1124,20 @@ void Mob::AI_Process() { if(DivineAura()) return; + auto npcSpawnPoint = CastToNPC()->GetSpawnPoint(); if(GetSpecialAbility(TETHER)) { float tether_range = static_cast(GetSpecialAbilityParam(TETHER, 0)); tether_range = tether_range > 0.0f ? tether_range * tether_range : pAggroRange * pAggroRange; - if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > tether_range) { - GMMove(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY(), CastToNPC()->GetSpawnPointZ(), CastToNPC()->GetSpawnPointH()); + if(DistNoRootNoZ(npcSpawnPoint.m_X, npcSpawnPoint.m_Y) > tether_range) { + GMMove(npcSpawnPoint.m_X, npcSpawnPoint.m_Y, npcSpawnPoint.m_Z, npcSpawnPoint.m_Heading); } } else if(GetSpecialAbility(LEASH)) { float leash_range = static_cast(GetSpecialAbilityParam(LEASH, 0)); leash_range = leash_range > 0.0f ? leash_range * leash_range : pAggroRange * pAggroRange; - if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > leash_range) { - GMMove(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY(), CastToNPC()->GetSpawnPointZ(), CastToNPC()->GetSpawnPointH()); + if(DistNoRootNoZ(npcSpawnPoint.m_X, npcSpawnPoint.m_Y) > leash_range) { + GMMove(npcSpawnPoint.m_X, npcSpawnPoint.m_Y, npcSpawnPoint.m_Z, npcSpawnPoint.m_Heading); SetHP(GetMaxHP()); BuffFadeAll(); WipeHateList(); @@ -1373,7 +1371,8 @@ void Mob::AI_Process() { //we cannot reach our target... //underwater stuff only works with water maps in the zone! if(IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { - if(!zone->watermap->InLiquid(target->GetX(), target->GetY(), target->GetZ())) { + auto targetPosition = xyz_location(target->GetX(), target->GetY(), target->GetZ()); + if(!zone->watermap->InLiquid(targetPosition)) { Mob *tar = hate_list.GetEntWithMostHateOnList(this); if(tar == target) { WipeHateList(); @@ -1725,15 +1724,15 @@ void NPC::AI_DoMovement() { } // endif (movetimercompleted==true) else if (!(AIwalking_timer->Enabled())) { // currently moving - if (cur_wp_x == GetX() && cur_wp_y == GetY()) + if (m_CurrentWayPoint.m_X == GetX() && m_CurrentWayPoint.m_Y == GetY()) { // are we there yet? then stop mlog(AI__WAYPOINTS, "We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d", cur_wp, GetX(), GetY(), GetZ(), GetGrid()); SetWaypointPause(); if(GetAppearance() != eaStanding) SetAppearance(eaStanding, false); SetMoving(false); - if (cur_wp_heading >= 0.0) { - SetHeading(cur_wp_heading); + if (m_CurrentWayPoint.m_Heading >= 0.0) { + SetHeading(m_CurrentWayPoint.m_Heading); } SendPosition(); @@ -1749,12 +1748,12 @@ void NPC::AI_DoMovement() { else { // not at waypoint yet, so keep moving if(!RuleB(Pathing, AggroReturnToGrid) || !zone->pathing || (DistractedFromGrid == 0)) - CalculateNewPosition2(cur_wp_x, cur_wp_y, cur_wp_z, walksp, true); + CalculateNewPosition2(m_CurrentWayPoint.m_X, m_CurrentWayPoint.m_Y, m_CurrentWayPoint.m_Z, walksp, true); else { bool WaypointChanged; bool NodeReached; - Map::Vertex Goal = UpdatePath(cur_wp_x, cur_wp_y, cur_wp_z, walksp, WaypointChanged, NodeReached); + Map::Vertex Goal = UpdatePath(m_CurrentWayPoint.m_X, m_CurrentWayPoint.m_Y, m_CurrentWayPoint.m_Z, walksp, WaypointChanged, NodeReached); if(WaypointChanged) tar_ndx = 20; @@ -1787,13 +1786,13 @@ void NPC::AI_DoMovement() { { bool CP2Moved; if(!RuleB(Pathing, Guard) || !zone->pathing) - CP2Moved = CalculateNewPosition2(guard_x, guard_y, guard_z, walksp); + CP2Moved = CalculateNewPosition2(m_GuardPoint.m_X, m_GuardPoint.m_Y, m_GuardPoint.m_Z, walksp); else { - if(!((x_pos == guard_x) && (y_pos == guard_y) && (z_pos == guard_z))) + if(!((m_Position.m_X == m_GuardPoint.m_X) && (m_Position.m_Y == m_GuardPoint.m_Y) && (m_Position.m_Z == m_GuardPoint.m_Z))) { bool WaypointChanged, NodeReached; - Map::Vertex Goal = UpdatePath(guard_x, guard_y, guard_z, walksp, WaypointChanged, NodeReached); + Map::Vertex Goal = UpdatePath(m_GuardPoint.m_X, m_GuardPoint.m_Y, m_GuardPoint.m_Z, walksp, WaypointChanged, NodeReached); if(WaypointChanged) tar_ndx = 20; @@ -1809,13 +1808,13 @@ void NPC::AI_DoMovement() { if (!CP2Moved) { if(moved) { - mlog(AI__WAYPOINTS, "Reached guard point (%.3f,%.3f,%.3f)", guard_x, guard_y, guard_z); + mlog(AI__WAYPOINTS, "Reached guard point (%.3f,%.3f,%.3f)", m_GuardPoint.m_X, m_GuardPoint.m_Y, m_GuardPoint.m_Z); ClearFeignMemory(); moved=false; SetMoving(false); if (GetTarget() == nullptr || DistNoRoot(*GetTarget()) >= 5*5 ) { - SetHeading(guard_heading); + SetHeading(m_GuardPoint.m_Heading); } else { FaceTarget(GetTarget()); } diff --git a/zone/npc.cpp b/zone/npc.cpp index 479a3d5a7..c48254768 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -25,10 +25,10 @@ #include "../common/spdat.h" #include "../common/string_util.h" #include "../common/clientversions.h" -#include "../common/features.h" -#include "../common/item.h" -#include "../common/item_struct.h" -#include "../common/linked_list.h" +#include "../common/features.h" +#include "../common/item.h" +#include "../common/item_struct.h" +#include "../common/linked_list.h" #include "../common/servertalk.h" #include "aa.h" @@ -56,7 +56,7 @@ extern Zone* zone; extern volatile bool ZoneLoaded; extern EntityList entity_list; -NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float heading, int iflymode, bool IsCorpse) +NPC::NPC(const NPCType* d, Spawn2* in_respawn, const xyz_heading& position, int iflymode, bool IsCorpse) : Mob(d->name, d->lastname, d->max_hp, @@ -70,10 +70,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float d->npc_id, d->size, d->runspeed, - heading, - x, - y, - z, + position, d->light, d->texture, d->helmtexture, @@ -115,7 +112,10 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float qglobal_purge_timer(30000), sendhpupdate_timer(1000), enraged_timer(1000), - taunt_timer(TauntReuseTime * 1000) + taunt_timer(TauntReuseTime * 1000), + m_SpawnPoint(position), + m_GuardPoint(-1,-1,-1,0), + m_GuardPointSaved(0,0,0,0) { //What is the point of this, since the names get mangled.. Mob* mob = entity_list.GetMob(name); @@ -205,14 +205,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float MerchantType = d->merchanttype; merchant_open = GetClass() == MERCHANT; adventure_template_id = d->adventure_template; - org_x = x; - org_y = y; - org_z = z; flymode = iflymode; - guard_x = -1; //just some value we might be able to recongize as "unset" - guard_y = -1; - guard_z = -1; - guard_heading = 0; guard_anim = eaStanding; roambox_distance = 0; roambox_max_x = -2; @@ -223,7 +216,6 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float roambox_movingto_y = -2; roambox_min_delay = 1000; roambox_delay = 1000; - org_heading = heading; p_depop = false; loottable_id = d->loottable_id; @@ -356,10 +348,6 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float reface_timer = new Timer(15000); reface_timer->Disable(); qGlobals = nullptr; - guard_x_saved = 0; - guard_y_saved = 0; - guard_z_saved = 0; - guard_heading_saved = 0; SetEmoteID(d->emoteid); InitializeBuffSlots(); CalcBonuses(); @@ -674,8 +662,8 @@ bool NPC::Process() DoGravityEffect(); } - if(reface_timer->Check() && !IsEngaged() && (guard_x == GetX() && guard_y == GetY() && guard_z == GetZ())) { - SetHeading(guard_heading); + if(reface_timer->Check() && !IsEngaged() && (m_GuardPoint.m_X == GetX() && m_GuardPoint.m_Y == GetY() && m_GuardPoint.m_Z == GetZ())) { + SetHeading(m_GuardPoint.m_Heading); SendPosition(); reface_timer->Disable(); } @@ -780,7 +768,7 @@ bool NPC::DatabaseCastAccepted(int spell_id) { return false; } -NPC* NPC::SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z, float in_heading, Client* client) { +NPC* NPC::SpawnNPC(const char* spawncommand, const xyz_heading& position, Client* client) { if(spawncommand == 0 || spawncommand[0] == 0) { return 0; } @@ -939,7 +927,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z, npc_type->prim_melee_type = 28; npc_type->sec_melee_type = 28; - NPC* npc = new NPC(npc_type, 0, in_x, in_y, in_z, in_heading/8, FlyMode3); + NPC* npc = new NPC(npc_type, nullptr, position, FlyMode3); npc->GiveNPCTypeData(npc_type); entity_list.AddNPC(npc); @@ -2433,7 +2421,7 @@ void NPC::DepopSwarmPets() Mob* owner = entity_list.GetMobID(GetSwarmInfo()->owner_id); if (owner) owner->SetTempPetCount(owner->GetTempPetCount() - 1); - + Depop(); return; } diff --git a/zone/npc.h b/zone/npc.h index e7a72ff11..7e16c02f3 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -64,10 +64,10 @@ struct AISpells_Struct { }; struct AISpellsEffects_Struct { - uint16 spelleffectid; - int32 base; - int32 limit; - int32 max; + uint16 spelleffectid; + int32 base; + int32 limit; + int32 max; }; struct AISpellsVar_Struct { @@ -83,7 +83,7 @@ struct AISpellsVar_Struct { uint32 idle_no_sp_recast_min; uint32 idle_no_sp_recast_max; uint8 idle_beneficial_chance; -}; +}; class AA_SwarmPetInfo; class Client; @@ -95,10 +95,10 @@ struct Item_Struct; class NPC : public Mob { public: - static NPC* SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z, float in_heading = 0, Client* client = 0); + static NPC* SpawnNPC(const char* spawncommand, const xyz_heading& position, Client* client = nullptr); static int8 GetAILevel(bool iForceReRead = false); - NPC(const NPCType* data, Spawn2* respawn, float x, float y, float z, float heading, int iflymode, bool IsCorpse = false); + NPC(const NPCType* data, Spawn2* respawn, const xyz_heading& position, int iflymode, bool IsCorpse = false); virtual ~NPC(); @@ -162,7 +162,7 @@ public: FACTION_VALUE CheckNPCFactionAlly(int32 other_faction); virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther); - void GoToBind(uint8 bindnum = 0) { GMMove(org_x, org_y, org_z, org_heading); } + void GoToBind(uint8 bindnum = 0) { GMMove(m_SpawnPoint.m_X, m_SpawnPoint.m_Y, m_SpawnPoint.m_Z, m_SpawnPoint.m_Heading); } void Gate(); void GetPetState(SpellBuff_Struct *buffs, uint32 *items, char *name); @@ -210,14 +210,8 @@ public: uint32 GetSp2() const { return spawn_group; } uint32 GetSpawnPointID() const; - float GetSpawnPointX() const { return org_x; } - float GetSpawnPointY() const { return org_y; } - float GetSpawnPointZ() const { return org_z; } - float GetSpawnPointH() const { return org_heading; } - float GetGuardPointX() const { return guard_x; } - float GetGuardPointY() const { return guard_y; } - float GetGuardPointZ() const { return guard_z; } - float GetGuardPointH() const { return guard_heading; } + xyz_heading const GetSpawnPoint() const { return m_SpawnPoint; } + xyz_heading const GetGuardPoint() const { return m_GuardPoint; } EmuAppearance GetGuardPointAnim() const { return guard_anim; } void SaveGuardPointAnim(EmuAppearance anim) { guard_anim = anim; } @@ -254,7 +248,7 @@ public: void SetNPCFactionID(int32 in) { npc_faction_id = in; database.GetFactionIdsForNPC(npc_faction_id, &faction_list, &primary_faction); } - float org_x, org_y, org_z, org_heading; + xyz_heading m_SpawnPoint; uint32 GetMaxDMG() const {return max_dmg;} uint32 GetMinDMG() const {return min_dmg;} @@ -288,15 +282,15 @@ public: void StopWandering(); void ResumeWandering(); void PauseWandering(int pausetime); - void MoveTo(float mtx, float mty, float mtz, float mth, bool saveguardspot); - void GetClosestWaypoint(std::list &wp_list, int count, float m_x, float m_y, float m_z); + void MoveTo(const xyz_heading& position, bool saveguardspot); + void GetClosestWaypoint(std::list &wp_list, int count, const xyz_location& location); uint32 GetEquipment(uint8 material_slot) const; // returns item id int32 GetEquipmentMaterial(uint8 material_slot) const; void NextGuardPosition(); void SaveGuardSpot(bool iClearGuardSpot = false); - inline bool IsGuarding() const { return(guard_heading != 0); } + inline bool IsGuarding() const { return(m_GuardPoint.m_Heading != 0); } void SaveGuardSpotCharm(); void RestoreGuardSpotCharm(); void AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay = 2500, uint32 iMinDelay = 2500); @@ -387,7 +381,7 @@ public: inline void SetHealScale(float amt) { healscale = amt; } inline float GetHealScale() { return healscale; } - + inline void SetSpellFocusDMG(int32 NewSpellFocusDMG) {SpellFocusDMG = NewSpellFocusDMG;} inline int32 GetSpellFocusDMG() const { return SpellFocusDMG;} @@ -408,7 +402,7 @@ public: void SetHeroForgeModel(uint32 model) { herosforgemodel = model; } bool IsRaidTarget() const { return raid_target; }; - + protected: const NPCType* NPCTypedata; @@ -450,7 +444,6 @@ protected: AISpellsVar_Struct AISpellVar; int16 GetFocusEffect(focusType type, uint16 spell_id); - uint32 npc_spells_effects_id; std::vector AIspellsEffects; bool HasAISpellEffects; @@ -480,8 +473,8 @@ protected: void _ClearWaypints(); int max_wp; int save_wp; - float guard_x, guard_y, guard_z, guard_heading; - float guard_x_saved, guard_y_saved, guard_z_saved, guard_heading_saved; + xyz_heading m_GuardPoint; + xyz_heading m_GuardPointSaved; EmuAppearance guard_anim; float roambox_max_x; float roambox_max_y; @@ -519,7 +512,7 @@ protected: //mercenary stuff std::list mercTypeList; std::list mercDataList; - + bool raid_target; uint8 probability; diff --git a/zone/pathing.cpp b/zone/pathing.cpp index ed969b0ff..aba968f0b 100644 --- a/zone/pathing.cpp +++ b/zone/pathing.cpp @@ -587,8 +587,8 @@ void PathManager::SpawnPathNodes() npc_type->CHA = 150; npc_type->findable = 1; - - NPC* npc = new NPC(npc_type, 0, PathNodes[i].v.x, PathNodes[i].v.y, PathNodes[i].v.z, 0, FlyMode1); + auto position = xyz_heading(PathNodes[i].v.x, PathNodes[i].v.y, PathNodes[i].v.z, 0.0f); + NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1); npc->GiveNPCTypeData(npc_type); entity_list.AddNPC(npc, true, true); @@ -1197,12 +1197,14 @@ bool PathManager::NoHazardsAccurate(Map::Vertex From, Map::Vertex To) if (zone->watermap) { - if (zone->watermap->InLiquid(From.x, From.y, From.z) || zone->watermap->InLiquid(To.x, To.y, To.z)) + auto from = xyz_location(From.x, From.y, From.z); + auto to = xyz_location(To.x, To.y, To.z); + if (zone->watermap->InLiquid(from) || zone->watermap->InLiquid(to)) { break; } - - if (zone->watermap->InLiquid(TestPoint.x, TestPoint.y, NewZ)) + auto testPointNewZ = xyz_location(TestPoint.x, TestPoint.y, NewZ); + if (zone->watermap->InLiquid(testPointNewZ)) { Map::Vertex TestPointWater(TestPoint.x, TestPoint.y, NewZ - 0.5f); Map::Vertex TestPointWaterDest = TestPointWater; @@ -1574,7 +1576,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques npc_type->CHA = 150; npc_type->findable = 1; - NPC* npc = new NPC(npc_type, 0, new_node.v.x, new_node.v.y, new_node.v.z, 0, FlyMode1); + auto position = xyz_heading(new_node.v.x, new_node.v.y, new_node.v.z, 0.0f); + NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1); npc->GiveNPCTypeData(npc_type); entity_list.AddNPC(npc, true, true); @@ -1634,7 +1637,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques npc_type->CHA = 150; npc_type->findable = 1; - NPC* npc = new NPC(npc_type, 0, new_node.v.x, new_node.v.y, new_node.v.z, 0, FlyMode1); + auto position = xyz_heading(new_node.v.x, new_node.v.y, new_node.v.z, 0.0f); + NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1); npc->GiveNPCTypeData(npc_type); entity_list.AddNPC(npc, true, true); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index d3cec99e2..df0a48e69 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -1072,7 +1072,7 @@ XS(XS_Client_SetBindPoint) new_z = (float)SvNV(ST(5)); } - THIS->SetBindPoint(to_zone, to_instance, new_x, new_y, new_z); + THIS->SetBindPoint(to_zone, to_instance, xyz_location(new_x, new_y, new_z)); } XSRETURN_EMPTY; } @@ -1277,7 +1277,7 @@ XS(XS_Client_MovePC) #ifdef BOTS else if (THIS->IsBot()) _log(CLIENT__ERROR, "Perl(XS_Client_MovePC) attempted to process a type Bot reference"); - #endif + #endif else _log(CLIENT__ERROR, "Perl(XS_Client_MovePC) attempted to process an Unknown type reference"); @@ -1327,7 +1327,7 @@ XS(XS_Client_MovePCInstance) else _log(CLIENT__ERROR, "Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference"); - Perl_croak(aTHX_ "THIS is not of type Client"); + Perl_croak(aTHX_ "THIS is not of type Client"); Perl_croak(aTHX_ "THIS is not of type Client"); } @@ -5094,7 +5094,7 @@ XS(XS_Client_GetTaskActivityDoneCount) Perl_croak(aTHX_ "Usage: Client::GetTaskActivityDoneCount(THIS, TaskID, ActivityID)"); { Client * THIS; - int RETVAL; + int RETVAL; int TaskID = (int)SvIV(ST(1)); int ActivityID = (int)SvIV(ST(2)); dXSTARG; @@ -5108,7 +5108,7 @@ XS(XS_Client_GetTaskActivityDoneCount) if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - + RETVAL = THIS->GetTaskActivityDoneCountFromTaskID(TaskID, ActivityID); XSprePUSH; PUSHi((IV)RETVAL); } @@ -5952,7 +5952,7 @@ XS(XS_Client_SilentMessage) { Client * THIS; dXSTARG; - + if (sv_derived_from(ST(0), "Client")) { IV tmp = SvIV((SV*)SvRV(ST(0))); THIS = INT2PTR(Client *,tmp); @@ -6351,7 +6351,7 @@ XS(boot_Client) newXSproto(strcpy(buf, "SendMarqueeMessage"), XS_Client_SendMarqueeMessage, file, "$$$$$$$"); newXSproto(strcpy(buf, "SendColoredText"), XS_Client_SendColoredText, file, "$$$"); newXSproto(strcpy(buf, "SendSpellAnim"), XS_Client_SendSpellAnim, file, "$$$"); - + XSRETURN_YES; } diff --git a/zone/perl_doors.cpp b/zone/perl_doors.cpp index 77ad1902b..615cce6e9 100644 --- a/zone/perl_doors.cpp +++ b/zone/perl_doors.cpp @@ -138,7 +138,7 @@ XS(XS_Doors_GetX) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetX(); + RETVAL = THIS->GetPosition().m_X; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -164,7 +164,7 @@ XS(XS_Doors_GetY) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetY(); + RETVAL = THIS->GetPosition().m_Y; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -190,7 +190,7 @@ XS(XS_Doors_GetZ) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetZ(); + RETVAL = THIS->GetPosition().m_Z; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -216,7 +216,7 @@ XS(XS_Doors_GetHeading) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetHeading(); + RETVAL = THIS->GetPosition().m_Heading; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -556,7 +556,7 @@ XS(XS_Doors_SetX) Perl_croak(aTHX_ "Usage: Doors::SetX(THIS, XPos)"); { Doors * THIS; - float pos = (float)SvNV(ST(1)); + float x = (float)SvNV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { IV tmp = SvIV((SV*)SvRV(ST(0))); @@ -566,8 +566,9 @@ XS(XS_Doors_SetX) Perl_croak(aTHX_ "THIS is not of type Doors"); if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - - THIS->SetX(pos); + auto position = THIS->GetPosition(); + position.m_X = x; + THIS->SetPosition(position); } XSRETURN_EMPTY; } @@ -580,7 +581,7 @@ XS(XS_Doors_SetY) Perl_croak(aTHX_ "Usage: Doors::SetY(THIS, YPos)"); { Doors * THIS; - float pos = (float)SvNV(ST(1)); + float y = (float)SvNV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { IV tmp = SvIV((SV*)SvRV(ST(0))); @@ -591,7 +592,9 @@ XS(XS_Doors_SetY) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->SetY(pos); + auto position = THIS->GetPosition(); + position.m_Y = y; + THIS->SetPosition(position); } XSRETURN_EMPTY; } @@ -604,7 +607,7 @@ XS(XS_Doors_SetZ) Perl_croak(aTHX_ "Usage: Doors::SetZ(THIS, ZPos)"); { Doors * THIS; - float pos = (float)SvNV(ST(1)); + float z = (float)SvNV(ST(1)); if (sv_derived_from(ST(0), "Doors")) { IV tmp = SvIV((SV*)SvRV(ST(0))); @@ -615,7 +618,9 @@ XS(XS_Doors_SetZ) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->SetZ(pos); + auto position = THIS->GetPosition(); + position.m_Z = z; + THIS->SetPosition(position); } XSRETURN_EMPTY; } @@ -639,7 +644,9 @@ XS(XS_Doors_SetHeading) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->SetHeading(heading); + auto position = THIS->GetPosition(); + position.m_Heading = heading; + THIS->SetPosition(position); } XSRETURN_EMPTY; } diff --git a/zone/perl_entity.cpp b/zone/perl_entity.cpp index 3d685e011..a5ad00827 100644 --- a/zone/perl_entity.cpp +++ b/zone/perl_entity.cpp @@ -1875,7 +1875,7 @@ XS(XS_EntityList_GetRandomClient) c = INT2PTR(Client *,tmp); } } - RETVAL = entity_list.GetRandomClient(x, y, z, d * d, c); + RETVAL = entity_list.GetRandomClient(xyz_location(x, y, z), d * d, c); ST(0) = sv_newmortal(); sv_setref_pv(ST(0), "Client", (void*)RETVAL); } diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index af07cfcdf..790651459 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -1615,7 +1615,7 @@ XS(XS_Mob_TypesTempPet) else Perl_croak(aTHX_ "target is not of type Mob"); - + if (items < 7) sticktarg = false; else { @@ -3551,7 +3551,7 @@ XS(XS_Mob_GetWaypointX) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetCWPX(); + RETVAL = THIS->GetCurrentWayPoint().m_X; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -3577,7 +3577,7 @@ XS(XS_Mob_GetWaypointY) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetCWPY(); + RETVAL = THIS->GetCurrentWayPoint().m_Y; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -3603,7 +3603,7 @@ XS(XS_Mob_GetWaypointZ) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetCWPZ(); + RETVAL = THIS->GetCurrentWayPoint().m_Z; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -3629,7 +3629,7 @@ XS(XS_Mob_GetWaypointH) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetCWPH(); + RETVAL = THIS->GetCurrentWayPoint().m_Heading; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -7662,10 +7662,7 @@ XS(XS_Mob_SetDeltas) Perl_croak(aTHX_ "Usage: Mob::SetDeltas(THIS, delta_x, delta_y, delta_z, delta_h)"); { Mob * THIS; - float delta_x = (float)SvNV(ST(1)); - float delta_y = (float)SvNV(ST(2)); - float delta_z = (float)SvNV(ST(3)); - float delta_h = (float)SvNV(ST(4)); + auto delta = xyz_heading((float)SvNV(ST(1)), (float)SvNV(ST(2)), (float)SvNV(ST(3)), (float)SvNV(ST(4))); if (sv_derived_from(ST(0), "Mob")) { IV tmp = SvIV((SV*)SvRV(ST(0))); @@ -7676,7 +7673,7 @@ XS(XS_Mob_SetDeltas) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->SetDeltas(delta_x, delta_y, delta_z, delta_h); + THIS->SetDelta(delta); } XSRETURN_EMPTY; } diff --git a/zone/perl_npc.cpp b/zone/perl_npc.cpp index 279b64330..6fa2e256d 100644 --- a/zone/perl_npc.cpp +++ b/zone/perl_npc.cpp @@ -1345,7 +1345,8 @@ XS(XS_NPC_MoveTo) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->MoveTo(mtx, mty, mtz, mth, saveguard); + auto position = xyz_heading(mtx, mty, mtz, mth); + THIS->MoveTo(position, saveguard); } XSRETURN_EMPTY; } @@ -1545,7 +1546,7 @@ XS(XS_NPC_GetSpawnPointX) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetSpawnPointX(); + RETVAL = THIS->GetSpawnPoint().m_X; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -1572,7 +1573,7 @@ XS(XS_NPC_GetSpawnPointY) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetSpawnPointY(); + RETVAL = THIS->GetSpawnPoint().m_Y; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -1599,7 +1600,7 @@ XS(XS_NPC_GetSpawnPointZ) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetSpawnPointZ(); + RETVAL = THIS->GetSpawnPoint().m_Z; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -1626,7 +1627,7 @@ XS(XS_NPC_GetSpawnPointH) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetSpawnPointH(); + RETVAL = THIS->GetSpawnPoint().m_Heading; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -1653,7 +1654,7 @@ XS(XS_NPC_GetGuardPointX) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetGuardPointX(); + RETVAL = THIS->GetGuardPoint().m_X; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -1680,7 +1681,7 @@ XS(XS_NPC_GetGuardPointY) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetGuardPointY(); + RETVAL = THIS->GetGuardPoint().m_Y; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); @@ -1707,7 +1708,7 @@ XS(XS_NPC_GetGuardPointZ) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetGuardPointZ(); + RETVAL = THIS->GetGuardPoint().m_Z; XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); diff --git a/zone/pets.cpp b/zone/pets.cpp index eb120d619..051eb3253 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -430,7 +430,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, into walls or objects (+10), this sometimes creates the "ghost" effect. I changed to +2 (as close as I could get while it still looked good). I also noticed this can happen if an NPC is spawned on the same spot of another or in a related bad spot.*/ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 power) -: NPC(type_data, 0, owner->GetX()+2, owner->GetY()+2, owner->GetZ(), owner->GetHeading(), FlyMode3) +: NPC(type_data, 0, owner->GetPosition() + xy_location(2, 2), FlyMode3) { GiveNPCTypeData(type_data); typeofpet = type; diff --git a/zone/position.cpp b/zone/position.cpp new file mode 100644 index 000000000..ddbe429af --- /dev/null +++ b/zone/position.cpp @@ -0,0 +1,196 @@ +#include +#include + +#include "position.h" +#include "../common/string_util.h" + +xy_location::xy_location(float x, float y) : + m_X(x), + m_Y(y) { +} + +xy_location xy_location::operator -(const xy_location& rhs) const { + xy_location minus(m_X - rhs.m_X, m_Y - rhs.m_Y); + return minus; +} + +xy_location xy_location::operator +(const xy_location& rhs) const { + xy_location addition(m_X + rhs.m_X, m_Y + rhs.m_Y); + return addition; +} + +xyz_heading::xyz_heading(float x, float y, float z, float heading) : + m_X(x), + m_Y(y), + m_Z(z), + m_Heading(heading) { +} + +xyz_heading::xyz_heading(const xyz_heading& locationDir) : + m_X(locationDir.m_X), + m_Y(locationDir.m_Y), + m_Z(locationDir.m_Z), + m_Heading(locationDir.m_Heading) { +} + +xyz_heading::xyz_heading(const xyz_location& locationDir, float heading) : + m_X(locationDir.m_X), + m_Y(locationDir.m_Y), + m_Z(locationDir.m_Z), + m_Heading(heading) { +} + +xyz_heading::xyz_heading(const xy_location& locationDir, float z, float heading) : + m_X(locationDir.m_X), + m_Y(locationDir.m_Y), + m_Z(z), + m_Heading(heading) { +} + +xyz_heading::xyz_heading(const xy_location locationDir, float z, float heading) : + m_X(locationDir.m_X), + m_Y(locationDir.m_Y), + m_Z(z), + m_Heading(heading) { +} + +xyz_heading::operator xyz_location() const { + return xyz_location(m_X,m_Y,m_Z); +} + +xyz_heading::operator xy_location() const { + return xy_location(m_X,m_Y); +} + +const xyz_heading xyz_heading::operator +(const xyz_location& rhs) const{ + return xyz_heading(m_X + rhs.m_X, m_Y + rhs.m_Y, m_Z + rhs.m_Z, m_Heading); +} + +const xyz_heading xyz_heading::operator +(const xy_location& rhs) const{ + return xyz_heading(m_X + rhs.m_X, m_Y + rhs.m_Y, m_Z, m_Heading); +} + +const xyz_heading xyz_heading::operator -(const xyz_location& rhs) const{ + return xyz_heading(m_X - rhs.m_X, m_Y - rhs.m_Y, m_Z - rhs.m_Z, m_Heading); +} + +void xyz_heading::ABS_XYZ(void) { + m_X = abs(m_X); + m_Y = abs(m_Y); + m_Z = abs(m_Z); +} + +xyz_location::xyz_location(float x, float y, float z) : + m_X(x), + m_Y(y), + m_Z(z) { +} + +xyz_location::xyz_location(double x, double y, double z) : + m_X(static_cast(x)), + m_Y(static_cast(y)), + m_Z(static_cast(z)) { +} + +xyz_location::operator xy_location() const { + return xy_location(m_X, m_Y); +} + +xyz_location xyz_location::operator -(const xyz_location& rhs) const { + return xyz_location(m_X - rhs.m_X, m_Y - rhs.m_Y, m_Z - rhs.m_Z); +} + +xyz_location xyz_location::operator +(const xyz_location& rhs) const { + return xyz_location(m_X + rhs.m_X, m_Y + rhs.m_Y, m_Z + rhs.m_Z); +} + +void xyz_location::ABS_XYZ(void) { + m_X = abs(m_X); + m_Y = abs(m_Y); + m_Z = abs(m_Z); +} + +std::string to_string(const xyz_heading &position) { + return StringFormat("(%.3f, %.3f, %.3f, %.3f)", position.m_X,position.m_Y,position.m_Z,position.m_Heading); +} + +std::string to_string(const xyz_location &position){ + return StringFormat("(%.3f, %.3f, %.3f)", position.m_X,position.m_Y,position.m_Z); +} + +std::string to_string(const xy_location &position){ + return StringFormat("(%.3f, %.3f)", position.m_X,position.m_Y); +} + +/** +* Produces the non square root'ed distance between the two points within the XY plane. +*/ +float ComparativeDistance(const xy_location& point1, const xy_location& point2) { + auto diff = point1 - point2; + return diff.m_X * diff.m_X + diff.m_Y * diff.m_Y; +} + +/** +* Produces the distance between the two points on the XY plane. +*/ +float Distance(const xy_location& point1, const xy_location& point2) { + return sqrt(ComparativeDistance(point1, point2)); +} + +/** +* Produces the non square root'ed distance between the two points. +*/ +float ComparativeDistance(const xyz_location& point1, const xyz_location& point2) { + auto diff = point1 - point2; + return diff.m_X * diff.m_X + diff.m_Y * diff.m_Y + diff.m_Z * diff.m_Z; +} + +/** +* Produces the distance between the two points. +*/ +float Distance(const xyz_location& point1, const xyz_location& point2) { + return sqrt(ComparativeDistance(point1, point2)); +} + +/** +* Produces the distance between the two points within the XY plane. +*/ +float DistanceNoZ(const xyz_location& point1, const xyz_location& point2) { + return Distance(static_cast(point1),static_cast(point2)); +} + +/** +* Produces the non square root'ed distance between the two points within the XY plane. +*/ +float ComparativeDistanceNoZ(const xyz_location& point1, const xyz_location& point2) { + return ComparativeDistance(static_cast(point1),static_cast(point2)); +} + +/** +* Determines if 'position' is within (inclusive) the axis aligned +* box (3 dimensional) formed from the points minimum and maximum. +*/ +bool IsWithinAxisAlignedBox(const xyz_location &position, const xyz_location &minimum, const xyz_location &maximum) { + auto actualMinimum = xyz_location(std::min(minimum.m_X, maximum.m_X), std::min(minimum.m_Y, maximum.m_Y),std::min(minimum.m_Z, maximum.m_Z)); + auto actualMaximum = xyz_location(std::max(minimum.m_X, maximum.m_X), std::max(minimum.m_Y, maximum.m_Y),std::max(minimum.m_Z, maximum.m_Z)); + + bool xcheck = position.m_X >= actualMinimum.m_X && position.m_X <= actualMaximum.m_X; + bool ycheck = position.m_Y >= actualMinimum.m_Y && position.m_Y <= actualMaximum.m_Y; + bool zcheck = position.m_Z >= actualMinimum.m_Z && position.m_Z <= actualMaximum.m_Z; + + return xcheck && ycheck && zcheck; +} + +/** +* Determines if 'position' is within (inclusive) the axis aligned +* box (2 dimensional) formed from the points minimum and maximum. +*/ +bool IsWithinAxisAlignedBox(const xy_location &position, const xy_location &minimum, const xy_location &maximum) { + auto actualMinimum = xy_location(std::min(minimum.m_X, maximum.m_X), std::min(minimum.m_Y, maximum.m_Y)); + auto actualMaximum = xy_location(std::max(minimum.m_X, maximum.m_X), std::max(minimum.m_Y, maximum.m_Y)); + + bool xcheck = position.m_X >= actualMinimum.m_X && position.m_X <= actualMaximum.m_X; + bool ycheck = position.m_Y >= actualMinimum.m_Y && position.m_Y <= actualMaximum.m_Y; + + return xcheck && ycheck; +} diff --git a/zone/position.h b/zone/position.h new file mode 100644 index 000000000..fd66ede5f --- /dev/null +++ b/zone/position.h @@ -0,0 +1,97 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org) + + 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 +*/ +#ifndef POSITION_H +#define POSITION_H + +#include + +class xy_location { +public: + float m_X; + float m_Y; + + xy_location(float x = 0.0f, float y = 0.0f); + + xy_location operator -(const xy_location& rhs) const; + xy_location operator +(const xy_location& rhs) const; +}; + +class xyz_location { +public: + float m_X; + float m_Y; + float m_Z; + + static const xyz_location& Origin() {static xyz_location origin; return origin;} + + xyz_location(float x = 0.0f, float y = 0.0f, float z = 0.0f); + xyz_location(double x, double y, double z); + + operator xy_location() const; + + xyz_location operator -(const xyz_location& rhs) const; + xyz_location operator +(const xyz_location& rhs) const; + + void ABS_XYZ(); + bool isOrigin() const { return m_X == 0 && m_Y == 0 && m_Z == 0;} + +}; + +class xyz_heading { +public: + float m_X; + float m_Y; + float m_Z; + + float m_Heading; + + static const xyz_heading& Origin() {static xyz_heading origin; return origin;} + + xyz_heading(float x = 0.0f, float y = 0.0f, float z = 0.0f, float heading = 0.0f); + xyz_heading(const xyz_heading& locationDir); + xyz_heading(const xyz_location& locationDir, float heading = 0.0f); + explicit xyz_heading(const xy_location& locationDir, float z, float heading); + explicit xyz_heading(const xy_location locationDir, float z, float heading); + + operator xyz_location() const; + operator xy_location() const; + + const xyz_heading operator +(const xyz_location& rhs) const; + const xyz_heading operator +(const xy_location& rhs) const; + + const xyz_heading operator -(const xyz_location& rhs) const; + + void ABS_XYZ(); + bool isOrigin() const { return m_X == 0.0f && m_Y == 0.0f && m_Z == 0.0f;} +}; + +std::string to_string(const xyz_heading &position); +std::string to_string(const xyz_location &position); +std::string to_string(const xy_location &position); + +bool IsWithinAxisAlignedBox(const xyz_location &position, const xyz_location &minimum, const xyz_location &maximum); +bool IsWithinAxisAlignedBox(const xy_location &position, const xy_location &minimum, const xy_location &maximum); + +float ComparativeDistance(const xy_location& point1, const xy_location& point2); +float Distance(const xy_location& point1, const xy_location& point2); +float ComparativeDistance(const xyz_location& point1, const xyz_location& point2); +float Distance(const xyz_location& point1, const xyz_location& point2); +float DistanceNoZ(const xyz_location& point1, const xyz_location& point2); +float ComparativeDistanceNoZ(const xyz_location& point1, const xyz_location& point2); + +#endif diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 1dd219032..dd15c925d 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -201,11 +201,11 @@ void QuestManager::write(const char *file, const char *str) { fclose (pFile); } -Mob* QuestManager::spawn2(int npc_type, int grid, int unused, float x, float y, float z, float heading) { +Mob* QuestManager::spawn2(int npc_type, int grid, int unused, const xyz_heading& position) { const NPCType* tmp = 0; if (tmp = database.GetNPCType(npc_type)) { - NPC* npc = new NPC(tmp, 0, x, y, z, heading, FlyMode3); + NPC* npc = new NPC(tmp, nullptr, position, FlyMode3); npc->AddLootTable(); entity_list.AddNPC(npc,true,true); if(grid > 0) @@ -218,7 +218,7 @@ Mob* QuestManager::spawn2(int npc_type, int grid, int unused, float x, float y, return nullptr; } -Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading) { +Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, const xyz_heading& position) { Mob *other = entity_list.GetMobByNpcTypeID(npc_type); if(other != nullptr) { return other; @@ -227,7 +227,7 @@ Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, flo const NPCType* tmp = 0; if (tmp = database.GetNPCType(npc_type)) { - NPC* npc = new NPC(tmp, 0, x, y, z, heading, FlyMode3); + NPC* npc = new NPC(tmp, nullptr, position, FlyMode3); npc->AddLootTable(); entity_list.AddNPC(npc,true,true); if(grid > 0) @@ -300,8 +300,8 @@ Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id) database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0); found_spawn->SetCurrentNPCID(npcid); - NPC* npc = new NPC(tmp, found_spawn, found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(), - found_spawn->GetHeading(), FlyMode3); + auto position = xyz_heading(found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(), found_spawn->GetHeading()); + NPC* npc = new NPC(tmp, found_spawn, position, FlyMode3); found_spawn->SetNPCPointer(npc); npc->AddLootTable(); @@ -923,7 +923,7 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { spells[curspell].skill != 52 && ( !RuleB(Spells, UseCHAScribeHack) || spells[curspell].effectid[EFFECT_COUNT - 1] != 10 ) ) - { + { if(IsDiscipline(curspell)){ //we may want to come up with a function like Client::GetNextAvailableSpellBookSlot() to help speed this up a little for(uint32 r = 0; r < MAX_PP_DISCIPLINES; r++) { @@ -937,12 +937,12 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { SpellGlobalCheckResult = initiator->SpellGlobalCheck(curspell, Char_ID); if (SpellGlobalCheckResult) { initiator->GetPP().disciplines.values[r] = curspell; - database.SaveCharacterDisc(Char_ID, r, curspell); + database.SaveCharacterDisc(Char_ID, r, curspell); initiator->SendDisciplineUpdate(); initiator->Message(0, "You have learned a new discipline!"); count++; //success counter } - break; //continue the 1st loop + break; //continue the 1st loop } else { initiator->GetPP().disciplines.values[r] = curspell; @@ -1486,10 +1486,10 @@ void QuestManager::ding() { } -void QuestManager::rebind(int zoneid, float x, float y, float z) { +void QuestManager::rebind(int zoneid, const xyz_location& location) { QuestManagerCurrentQuestVars(); if(initiator && initiator->IsClient()) { - initiator->SetBindPoint(zoneid, x, y, z); + initiator->SetBindPoint(zoneid, 0, location); } } @@ -1517,12 +1517,12 @@ void QuestManager::pause(int duration) { owner->CastToNPC()->PauseWandering(duration); } -void QuestManager::moveto(float x, float y, float z, float h, bool saveguardspot) { +void QuestManager::moveto(const xyz_heading& position, bool saveguardspot) { QuestManagerCurrentQuestVars(); if (!owner || !owner->IsNPC()) return; - owner->CastToNPC()->MoveTo(x, y, z, h, saveguardspot); + owner->CastToNPC()->MoveTo(position, saveguardspot); } void QuestManager::resume() { @@ -1563,26 +1563,20 @@ void QuestManager::setnextinchpevent(int at) { owner->SetNextIncHPEvent(at); } -void QuestManager::respawn(int npc_type, int grid) { +void QuestManager::respawn(int npcTypeID, int grid) { QuestManagerCurrentQuestVars(); if (!owner || !owner->IsNPC()) return; - float x,y,z,h; - - x = owner->GetX(); - y = owner->GetY(); - z = owner->GetZ(); - h = owner->GetHeading(); running_quest e = quests_running_.top(); e.depop_npc = true; quests_running_.pop(); quests_running_.push(e); - const NPCType* tmp = 0; - if ((tmp = database.GetNPCType(npc_type))) + const NPCType* npcType = nullptr; + if ((npcType = database.GetNPCType(npcTypeID))) { - owner = new NPC(tmp, 0, x, y, z, h, FlyMode3); + owner = new NPC(npcType, nullptr, owner->GetPosition(), FlyMode3); owner->CastToNPC()->AddLootTable(); entity_list.AddNPC(owner->CastToNPC(),true,true); if(grid > 0) @@ -1704,27 +1698,28 @@ void QuestManager::sethp(int hpperc) { owner->Damage(owner, newhp, SPELL_UNKNOWN, SkillHandtoHand, false, 0, false); } -bool QuestManager::summonburriedplayercorpse(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading) { +bool QuestManager::summonburriedplayercorpse(uint32 char_id, const xyz_heading& position) { bool Result = false; - if(char_id > 0) { - Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(char_id, zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); - if(PlayerCorpse) { - Result = true; - } - } - return Result; + if(char_id <= 0) + return false; + + Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(char_id, zone->GetZoneID(), zone->GetInstanceID(), position); + if(!PlayerCorpse) + return false; + + return true; } -bool QuestManager::summonallplayercorpses(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading) { - bool Result = false; +bool QuestManager::summonallplayercorpses(uint32 char_id, const xyz_heading& position) { - if(char_id > 0) { - Client* c = entity_list.GetClientByCharID(char_id); - c->SummonAllCorpses(dest_x, dest_y, dest_z, dest_heading); - Result = true; - } - return Result; + if(char_id <= 0) + return false; + + Client* c = entity_list.GetClientByCharID(char_id); + c->SummonAllCorpses(position); + + return true; } uint32 QuestManager::getplayerburriedcorpsecount(uint32 char_id) { @@ -2312,17 +2307,17 @@ int QuestManager::getlevel(uint8 type) return 0; } -uint16 QuestManager::CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time) +uint16 QuestManager::CreateGroundObject(uint32 itemid, const xyz_heading& position, uint32 decay_time) { uint16 entid = 0; //safety check - entid = entity_list.CreateGroundObject(itemid, x, y, z, heading, decay_time); + entid = entity_list.CreateGroundObject(itemid, position, decay_time); return entid; } -uint16 QuestManager::CreateGroundObjectFromModel(const char *model, float x, float y, float z, float heading, uint8 type, uint32 decay_time) +uint16 QuestManager::CreateGroundObjectFromModel(const char *model, const xyz_heading& position, uint8 type, uint32 decay_time) { uint16 entid = 0; //safety check - entid = entity_list.CreateGroundObjectFromModel(model, x, y, z, heading, type, decay_time); + entid = entity_list.CreateGroundObjectFromModel(model, position, type, decay_time); return entid; } @@ -2587,12 +2582,12 @@ void QuestManager::RemoveAllFromInstance(uint16 instance_id) } } -void QuestManager::MovePCInstance(int zone_id, int instance_id, float x, float y, float z, float heading) +void QuestManager::MovePCInstance(int zone_id, int instance_id, const xyz_heading& position) { QuestManagerCurrentQuestVars(); if(initiator) { - initiator->MovePC(zone_id, instance_id, x, y, z, heading); + initiator->MovePC(zone_id, instance_id, position.m_X, position.m_Y, position.m_Z, position.m_Heading); } } @@ -2841,7 +2836,7 @@ void QuestManager::SendMail(const char *to, const char *from, const char *subjec uint16 QuestManager::CreateDoor(const char* model, float x, float y, float z, float heading, uint8 opentype, uint16 size) { uint16 entid = 0; //safety check - entid = entity_list.CreateDoor(model, x, y, z, heading, opentype, size); + entid = entity_list.CreateDoor(model, xyz_heading(x, y, z, heading), opentype, size); return entid; } @@ -2884,7 +2879,7 @@ void QuestManager::CrossZoneSignalPlayerByName(const char *CharName, uint32 data CZSC->data = data; worldserver.SendPacket(pack); safe_delete(pack); -} +} void QuestManager::CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message){ uint32 message_len = strlen(CharName) + 1; @@ -2894,7 +2889,7 @@ void QuestManager::CrossZoneMessagePlayerByName(uint32 Type, const char *CharNam CZSC->Type = Type; strn0cpy(CZSC->CharName, CharName, 64); strn0cpy(CZSC->Message, Message, 512); - worldserver.SendPacket(pack); + worldserver.SendPacket(pack); safe_delete(pack); } @@ -2904,7 +2899,7 @@ void QuestManager::CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, cons ServerPacket* pack = new ServerPacket(ServerOP_CZSetEntityVariableByNPCTypeID, sizeof(CZSetEntVarByNPCTypeID_Struct) + message_len + message_len2); CZSetEntVarByNPCTypeID_Struct* CZSNBYNID = (CZSetEntVarByNPCTypeID_Struct*)pack->pBuffer; CZSNBYNID->npctype_id = npctype_id; - strn0cpy(CZSNBYNID->id, id, 256); + strn0cpy(CZSNBYNID->id, id, 256); strn0cpy(CZSNBYNID->m_var, m_var, 256); worldserver.SendPacket(pack); safe_delete(pack); diff --git a/zone/questmgr.h b/zone/questmgr.h index 14a6c429c..522aef961 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -57,8 +57,8 @@ public: void me(const char *str); void summonitem(uint32 itemid, int16 charges = -1); void write(const char *file, const char *str); - Mob* spawn2(int npc_type, int grid, int unused, float x, float y, float z, float heading); - Mob* unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading = 0); + Mob* spawn2(int npc_type, int grid, int unused, const xyz_heading& position); + Mob* unique_spawn(int npc_type, int grid, int unused, const xyz_heading& position); Mob* spawn_from_spawn2(uint32 spawn2_id); void enable_spawn2(uint32 spawn2_id); void disable_spawn2(uint32 spawn2_id); @@ -132,11 +132,11 @@ public: void targlobal(const char *varname, const char *value, const char *duration, int npcid, int charid, int zoneid); void delglobal(const char *varname); void ding(); - void rebind(int zoneid, float x, float y, float z); + void rebind(int zoneid, const xyz_location& location); void start(int wp); void stop(); void pause(int duration); - void moveto(float x, float y, float z, float h, bool saveguardspot); + void moveto(const xyz_heading& position, bool saveguardspot); void resume(); void addldonpoints(int32 points, uint32 theme); void addldonwin(int32 wins, uint32 theme); @@ -157,8 +157,8 @@ public: void set_zone_flag(int zone_id); void clear_zone_flag(int zone_id); void sethp(int hpperc); - bool summonburriedplayercorpse(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading); - bool summonallplayercorpses(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading); + bool summonburriedplayercorpse(uint32 char_id, const xyz_heading& position); + bool summonallplayercorpses(uint32 char_id, const xyz_heading& position); uint32 getplayerburriedcorpsecount(uint32 char_id); bool buryplayercorpse(uint32 char_id); void forcedooropen(uint32 doorid, bool altmode); @@ -208,8 +208,8 @@ public: void enabletitle(int titleset); bool checktitle(int titlecheck); void removetitle(int titlecheck); - uint16 CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time = 300000); - uint16 CreateGroundObjectFromModel(const char* model, float x, float y, float z, float heading, uint8 type = 0x00, uint32 decay_time = 0); + uint16 CreateGroundObject(uint32 itemid, const xyz_heading& position, uint32 decay_time = 300000); + uint16 CreateGroundObjectFromModel(const char* model, const xyz_heading& position, uint8 type = 0x00, uint32 decay_time = 0); void ModifyNPCStat(const char *identifier, const char *newValue); void UpdateSpawnTimer(uint32 id, uint32 newTime); void MerchantSetItem(uint32 NPCid, uint32 itemid, uint32 quantity = 0); @@ -224,7 +224,7 @@ public: //void RemoveGroupFromInstance(uint16 instance_id); //potentially useful but not implmented at this time. //void RemoveRaidFromInstance(uint16 instance_id); //potentially useful but not implmented at this time. void RemoveAllFromInstance(uint16 instance_id); - void MovePCInstance(int zone_id, int instance_id, float x, float y, float z, float heading); + void MovePCInstance(int zone_id, int instance_id, const xyz_heading& position); void FlagInstanceByGroupLeader(uint32 zone, int16 version); void FlagInstanceByRaidLeader(uint32 zone, int16 version); const char* varlink(char* perltext, int item_id); @@ -241,7 +241,7 @@ public: uint16 CreateDoor( const char* model, float x, float y, float z, float heading, uint8 opentype, uint16 size); int32 GetZoneID(const char *zone); const char *GetZoneLongName(const char *zone); - void CrossZoneSignalPlayerByCharID(int charid, uint32 data); + void CrossZoneSignalPlayerByCharID(int charid, uint32 data); void CrossZoneSignalNPCByNPCTypeID(uint32 npctype_id, uint32 data); void CrossZoneSignalPlayerByName(const char *CharName, uint32 data); void CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, const char *id, const char *m_var); diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index f96c9872a..6be939e35 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -218,7 +218,7 @@ bool Spawn2::Process() { database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0); currentnpcid = npcid; - NPC* npc = new NPC(tmp, this, x, y, z, heading, FlyMode3); + NPC* npc = new NPC(tmp, this, xyz_heading(x, y, z, heading), FlyMode3); npc->mod_prespawn(this); @@ -414,13 +414,13 @@ Spawn2* ZoneDatabase::LoadSpawn2(LinkedList &spawn2_list, uint32 spawn2 return newSpawn; } -bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value) +bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* zone, const xyz_heading& position, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value) { std::string query = StringFormat("INSERT INTO spawn2 (spawngroupID, zone, x, y, z, heading, " "respawntime, variance, _condition, cond_value) " "VALUES (%i, '%s', %f, %f, %f, %f, %i, %i, %u, %i)", - spawngroup, zone, x, y, z, heading, + spawngroup, zone, position.m_X, position.m_Y, position.m_Z, position.m_Heading, respawn, variance, condition, cond_value); auto results = QueryDatabase(query); if (!results.Success()) { diff --git a/zone/spells.cpp b/zone/spells.cpp index ef5dd165a..a794d58a4 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -309,7 +309,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, sprintf(temp, "%d", spell_id); parse->EventNPC(EVENT_CAST_BEGIN, CastToNPC(), nullptr, temp, 0); } - + //To prevent NPC ghosting when spells are cast from scripts if (IsNPC() && IsMoving() && cast_time > 0) SendPosition(); @@ -362,7 +362,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot, casting_spell_type = type; SaveSpellLoc(); - mlog(SPELLS__CASTING, "Casting %d Started at (%.3f,%.3f,%.3f)", spell_id, spell_x, spell_y, spell_z); + mlog(SPELLS__CASTING, "Casting %d Started at (%.3f,%.3f,%.3f)", spell_id, m_SpellLocation.m_X, m_SpellLocation.m_Y, m_SpellLocation.m_Z); // if this spell doesn't require a target, or if it's an optional target // and a target wasn't provided, then it's us; unless TGB is on and this @@ -533,8 +533,8 @@ bool Mob::DoCastingChecks() return false; } - if (zone->IsSpellBlocked(spell_id, GetX(), GetY(), GetZ())) { - const char *msg = zone->GetSpellBlockedMessage(spell_id, GetX(), GetY(), GetZ()); + if (zone->IsSpellBlocked(spell_id, GetPosition())) { + const char *msg = zone->GetSpellBlockedMessage(spell_id, GetPosition()); if (msg) { Message(13, msg); return false; @@ -1626,7 +1626,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce { if(!spell_target) return false; - + ae_center = spell_target; CastAction = AETarget; } @@ -1645,7 +1645,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce { if(!spell_target) return false; - + ae_center = spell_target; CastAction = AETarget; } @@ -1918,8 +1918,8 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 if(IsClient() && !CastToClient()->GetGM()){ - if(zone->IsSpellBlocked(spell_id, GetX(), GetY(), GetZ())){ - const char *msg = zone->GetSpellBlockedMessage(spell_id, GetX(), GetY(), GetZ()); + if(zone->IsSpellBlocked(spell_id, GetPosition())){ + const char *msg = zone->GetSpellBlockedMessage(spell_id, GetPosition()); if(msg){ Message(13, msg); return false; @@ -2097,7 +2097,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 } else { // regular PB AE or targeted AE spell - spell_target is null if PB if(spell_target) // this must be an AETarget spell - { + { bool cast_on_target = true; if (spells[spell_id].targettype == ST_TargetAENoPlayersPets && spell_target->IsPetOwnerClient()) cast_on_target = false; @@ -2206,7 +2206,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 ConeDirectional(spell_id, resist_adjust); break; } - + case Beam: { BeamDirectional(spell_id, resist_adjust); @@ -3729,7 +3729,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r if (IsValidSpell(spells[spell_id].RecourseLink)) SpellFinished(spells[spell_id].RecourseLink, this, 10, 0, -1, spells[spells[spell_id].RecourseLink].ResistDiff); - + if (IsDetrimentalSpell(spell_id)) { CheckNumHitsRemaining(NumHit::OutgoingSpells); @@ -3856,9 +3856,9 @@ void Corpse::CastRezz(uint16 spellid, Mob* Caster) rezz->zone_id = zone->GetZoneID(); rezz->instance_id = zone->GetInstanceID(); rezz->spellid = spellid; - rezz->x = this->x_pos; - rezz->y = this->y_pos; - rezz->z = this->z_pos; + rezz->x = this->m_Position.m_X; + rezz->y = this->m_Position.m_Y; + rezz->z = this->m_Position.m_Z; rezz->unknown000 = 0x00000000; rezz->unknown020 = 0x00000000; rezz->unknown088 = 0x00000000; @@ -4522,7 +4522,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use if(partial_modifier <= 0) { return 100; - } + } else if(partial_modifier >= 100) { return 0; @@ -4840,7 +4840,7 @@ void Client::UnmemSpell(int slot, bool update_client) m_pp.mem_spells[slot] = 0xFFFFFFFF; database.DeleteCharacterMemorizedSpell(this->CharacterID(), m_pp.mem_spells[slot], slot); - + if(update_client) { MemorizeSpell(slot, m_pp.mem_spells[slot], memSpellForget); @@ -4884,8 +4884,8 @@ void Client::UnscribeSpell(int slot, bool update_client) mlog(CLIENT__SPELLS, "Spell %d erased from spell book slot %d", m_pp.spell_book[slot], slot); m_pp.spell_book[slot] = 0xFFFFFFFF; - - database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[slot], slot); + + database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[slot], slot); if(update_client) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_DeleteSpell, sizeof(DeleteSpell_Struct)); @@ -4913,7 +4913,7 @@ void Client::UntrainDisc(int slot, bool update_client) if(slot >= MAX_PP_DISCIPLINES || slot < 0) return; - mlog(CLIENT__SPELLS, "Discipline %d untrained from slot %d", m_pp.disciplines.values[slot], slot); + mlog(CLIENT__SPELLS, "Discipline %d untrained from slot %d", m_pp.disciplines.values[slot], slot); m_pp.disciplines.values[slot] = 0; database.DeleteCharacterDisc(this->CharacterID(), slot); @@ -5462,27 +5462,27 @@ void Mob::BeamDirectional(uint16 spell_id, int16 resist_adjust) if (IsBeneficialSpell(spell_id) && IsClient()) beneficial_targets = true; - + std::list targets_in_range; std::list::iterator iter; entity_list.GetTargetsForConeArea(this, spells[spell_id].min_range, spells[spell_id].range, spells[spell_id].range / 2, targets_in_range); iter = targets_in_range.begin(); - + float dX = 0; float dY = 0; float dZ = 0; - + CalcDestFromHeading(GetHeading(), spells[spell_id].range, 5, GetX(), GetY(), dX, dY, dZ); dZ = GetZ(); - + //FIND SLOPE: Put it into the form y = mx + b float m = (dY - GetY()) / (dX - GetX()); float b = (GetY() * dX - dY * GetX()) / (dX - GetX()); - + while(iter != targets_in_range.end()) { - if (!(*iter) || (beneficial_targets && ((*iter)->IsNPC() && !(*iter)->IsPetOwnerClient())) + if (!(*iter) || (beneficial_targets && ((*iter)->IsNPC() && !(*iter)->IsPetOwnerClient())) || (*iter)->BehindMob(this, (*iter)->GetX(),(*iter)->GetY())){ ++iter; continue; @@ -5490,7 +5490,7 @@ void Mob::BeamDirectional(uint16 spell_id, int16 resist_adjust) //# shortest distance from line to target point float d = abs( (*iter)->GetY() - m * (*iter)->GetX() - b) / sqrt(m * m + 1); - + if (d <= spells[spell_id].aoerange) { if(CheckLosFN((*iter)) || spells[spell_id].npc_no_los) { @@ -5537,7 +5537,7 @@ void Mob::ConeDirectional(uint16 spell_id, int16 resist_adjust) } float heading_to_target = (CalculateHeadingToTarget((*iter)->GetX(), (*iter)->GetY()) * 360.0f / 256.0f); - + while(heading_to_target < 0.0f) heading_to_target += 360.0f; diff --git a/zone/trap.cpp b/zone/trap.cpp index e48f9edf4..3cc684530 100644 --- a/zone/trap.cpp +++ b/zone/trap.cpp @@ -52,12 +52,10 @@ CREATE TABLE traps ( Trap::Trap() : Entity(), respawn_timer(600000), - chkarea_timer(500) + chkarea_timer(500), + m_Position(xyz_location::Origin()) { trap_id = 0; - x = 0; - y = 0; - z = 0; maxzdiff = 0; radius = 0; effect = 0; @@ -146,7 +144,9 @@ void Trap::Trigger(Mob* trigger) { if ((tmp = database.GetNPCType(effectvalue))) { - NPC* new_npc = new NPC(tmp, 0, x-5+zone->random.Int(0, 10), y-5+zone->random.Int(0, 10), z-5+zone->random.Int(0, 10), zone->random.Int(0, 249), FlyMode3); + auto randomOffset = xyz_heading(zone->random.Int(-5, 5),zone->random.Int(-5, 5),zone->random.Int(-5, 5), zone->random.Int(0, 249)); + auto spawnPosition = randomOffset + m_Position; + NPC* new_npc = new NPC(tmp, nullptr, spawnPosition, FlyMode3); new_npc->AddLootTable(); entity_list.AddNPC(new_npc); new_npc->AddToHateList(trigger,1); @@ -167,7 +167,9 @@ void Trap::Trigger(Mob* trigger) { if ((tmp = database.GetNPCType(effectvalue))) { - NPC* new_npc = new NPC(tmp, 0, x-2+zone->random.Int(0, 5), y-2+zone->random.Int(0, 5), z-2+zone->random.Int(0, 5), zone->random.Int(0, 249), FlyMode3); + auto randomOffset = xyz_heading(zone->random.Int(-2, 2), zone->random.Int(-2, 2), zone->random.Int(-2, 2), zone->random.Int(0, 249)); + auto spawnPosition = randomOffset + m_Position; + NPC* new_npc = new NPC(tmp, nullptr, spawnPosition, FlyMode3); new_npc->AddLootTable(); entity_list.AddNPC(new_npc); new_npc->AddToHateList(trigger,1); @@ -210,55 +212,47 @@ Trap* EntityList::FindNearbyTrap(Mob* searcher, float max_dist) { float max_dist2 = max_dist*max_dist; Trap *cur; - auto it = trap_list.begin(); - while (it != trap_list.end()) { - cur = it->second; - if(!cur->disarmed) { - float curdist = 0; - float tmp = searcher->GetX() - cur->x; - curdist += tmp*tmp; - tmp = searcher->GetY() - cur->y; - curdist += tmp*tmp; - tmp = searcher->GetZ() - cur->z; - curdist += tmp*tmp; - if (curdist < max_dist2 && curdist < dist) - { - dist = curdist; - current_trap = cur; - } - } - ++it; + for (auto it = trap_list.begin(); it != trap_list.end(); ++it) { + cur = it->second; + if(cur->disarmed) + continue; + + auto diff = searcher->GetPosition() - cur->m_Position; + float curdist = diff.m_X * diff.m_X + diff.m_Y * diff.m_Y + diff.m_Z * diff.m_Z; + + if (curdist < max_dist2 && curdist < dist) + { + dist = curdist; + current_trap = cur; + } } + return current_trap; } Mob* EntityList::GetTrapTrigger(Trap* trap) { Mob* savemob = 0; - float xdiff, ydiff, zdiff; - float maxdist = trap->radius * trap->radius; - auto it = client_list.begin(); - while (it != client_list.end()) { + for (auto it = client_list.begin(); it != client_list.end(); ++it) { Client* cur = it->second; - zdiff = cur->GetZ() - trap->z; - if(zdiff < 0) - zdiff = 0 - zdiff; - xdiff = cur->GetX() - trap->x; - ydiff = cur->GetY() - trap->y; - if ((xdiff*xdiff + ydiff*ydiff) <= maxdist - && zdiff < trap->maxzdiff) + auto diff = cur->GetPosition() - trap->m_Position; + diff.ABS_XYZ(); + + if ((diff.m_X*diff.m_X + diff.m_Y*diff.m_Y) <= maxdist + && diff.m_Z < trap->maxzdiff) { if (zone->random.Roll(trap->chance)) return(cur); else savemob = cur; } - ++it; + } + return savemob; } @@ -277,9 +271,7 @@ bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) { for (auto row = results.begin(); row != results.end(); ++row) { Trap* trap = new Trap(); trap->trap_id = atoi(row[0]); - trap->x = atof(row[1]); - trap->y = atof(row[2]); - trap->z = atof(row[3]); + trap->m_Position = xyz_location(atof(row[1]), atof(row[2]), atof(row[3])); trap->effect = atoi(row[4]); trap->effectvalue = atoi(row[5]); trap->effectvalue2 = atoi(row[6]); @@ -320,7 +312,7 @@ void Trap::CreateHiddenTrigger() make_npc->trackable = 0; make_npc->level = level; strcpy(make_npc->special_abilities, "19,1^20,1^24,1^25,1"); - NPC* npca = new NPC(make_npc, 0, x, y, z, 0, FlyMode3); + NPC* npca = new NPC(make_npc, nullptr, xyz_heading(m_Position, 0.0f), FlyMode3); npca->GiveNPCTypeData(make_npc); entity_list.AddNPC(npca); diff --git a/zone/trap.h b/zone/trap.h index 59a1a3685..e2dccd1ce 100644 --- a/zone/trap.h +++ b/zone/trap.h @@ -54,9 +54,7 @@ public: Timer respawn_timer; //Respawn Time when Trap's been disarmed Timer chkarea_timer; uint32 trap_id; //Database ID of trap - float x; //X position - float y; //Y position - float z; //Z position + xyz_location m_Position; float maxzdiff; //maximum z diff to be triggerable float radius; //radius around trap to be triggerable uint8 chance; //%chance that the trap is triggered each 'tick' diff --git a/zone/water_map.h b/zone/water_map.h index cc1887f10..32047378b 100644 --- a/zone/water_map.h +++ b/zone/water_map.h @@ -2,8 +2,10 @@ #define EQEMU_WATER_MAP_H #include "../common/types.h" +#include "position.h" #include + enum WaterRegionType { RegionTypeUnsupported = -2, RegionTypeUntagged = -1, @@ -24,11 +26,11 @@ public: virtual ~WaterMap() { } static WaterMap* LoadWaterMapfile(std::string zone_name); - virtual WaterRegionType ReturnRegionType(float y, float x, float z) const { return RegionTypeNormal; } - virtual bool InWater(float y, float x, float z) const { return false; } - virtual bool InVWater(float y, float x, float z) const { return false; } - virtual bool InLava(float y, float x, float z) const { return false; } - virtual bool InLiquid(float y, float x, float z) const { return false; } + virtual WaterRegionType ReturnRegionType(const xyz_location& location) const { return RegionTypeNormal; } + virtual bool InWater(const xyz_location& location) const { return false; } + virtual bool InVWater(const xyz_location& location) const { return false; } + virtual bool InLava(const xyz_location& location) const { return false; } + virtual bool InLiquid(const xyz_location& location) const { return false; } protected: virtual bool Load(FILE *fp) { return false; } diff --git a/zone/water_map_v2.cpp b/zone/water_map_v2.cpp index 29823b96c..9a8eb9564 100644 --- a/zone/water_map_v2.cpp +++ b/zone/water_map_v2.cpp @@ -6,31 +6,31 @@ WaterMapV2::WaterMapV2() { WaterMapV2::~WaterMapV2() { } -WaterRegionType WaterMapV2::ReturnRegionType(float y, float x, float z) const { +WaterRegionType WaterMapV2::ReturnRegionType(const xyz_location& location) const { size_t sz = regions.size(); for(size_t i = 0; i < sz; ++i) { auto const ®ion = regions[i]; - if (region.second.ContainsPoint(glm::vec3(x, y, z))) { + if (region.second.ContainsPoint(glm::vec3(location.m_X, location.m_Y, location.m_Z))) { return region.first; } } return RegionTypeNormal; } -bool WaterMapV2::InWater(float y, float x, float z) const { - return ReturnRegionType(y, x, z) == RegionTypeWater; +bool WaterMapV2::InWater(const xyz_location& location) const { + return ReturnRegionType(location) == RegionTypeWater; } -bool WaterMapV2::InVWater(float y, float x, float z) const { - return ReturnRegionType(y, x, z) == RegionTypeVWater; +bool WaterMapV2::InVWater(const xyz_location& location) const { + return ReturnRegionType(location) == RegionTypeVWater; } -bool WaterMapV2::InLava(float y, float x, float z) const { - return ReturnRegionType(y, x, z) == RegionTypeLava; +bool WaterMapV2::InLava(const xyz_location& location) const { + return ReturnRegionType(location) == RegionTypeLava; } -bool WaterMapV2::InLiquid(float y, float x, float z) const { - return InWater(y, x, z) || InLava(y, x, z); +bool WaterMapV2::InLiquid(const xyz_location& location) const { + return InWater(location) || InLava(location); } bool WaterMapV2::Load(FILE *fp) { @@ -106,7 +106,7 @@ bool WaterMapV2::Load(FILE *fp) { return false; } - regions.push_back(std::make_pair((WaterRegionType)region_type, + regions.push_back(std::make_pair((WaterRegionType)region_type, OrientedBoundingBox(glm::vec3(x, y, z), glm::vec3(x_rot, y_rot, z_rot), glm::vec3(x_scale, y_scale, z_scale), glm::vec3(x_extent, y_extent, z_extent)))); } diff --git a/zone/water_map_v2.h b/zone/water_map_v2.h index 726e6a798..a0adccc48 100644 --- a/zone/water_map_v2.h +++ b/zone/water_map_v2.h @@ -12,12 +12,12 @@ public: WaterMapV2(); ~WaterMapV2(); - virtual WaterRegionType ReturnRegionType(float y, float x, float z) const; - virtual bool InWater(float y, float x, float z) const; - virtual bool InVWater(float y, float x, float z) const; - virtual bool InLava(float y, float x, float z) const; - virtual bool InLiquid(float y, float x, float z) const; - + virtual WaterRegionType ReturnRegionType(const xyz_location& location) const; + virtual bool InWater(const xyz_location& location) const; + virtual bool InVWater(const xyz_location& location) const; + virtual bool InLava(const xyz_location& location) const; + virtual bool InLiquid(const xyz_location& location) const; + protected: virtual bool Load(FILE *fp); diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 9a9192397..5a315add0 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -120,7 +120,7 @@ void NPC::ResumeWandering() return; } - if (cur_wp_x == GetX() && cur_wp_y == GetY()) + if (m_CurrentWayPoint.m_X == GetX() && m_CurrentWayPoint.m_Y == GetY()) { // are we we at a waypoint? if so, trigger event and start to next char temp[100]; itoa(cur_wp,temp,10); //do this before updating to next waypoint @@ -159,7 +159,7 @@ void NPC::PauseWandering(int pausetime) return; } -void NPC::MoveTo(float mtx, float mty, float mtz, float mth, bool saveguardspot) +void NPC::MoveTo(const xyz_heading& position, bool saveguardspot) { // makes mob walk to specified location if (IsNPC() && GetGrid() != 0) { // he is on a grid @@ -174,36 +174,30 @@ void NPC::MoveTo(float mtx, float mty, float mtz, float mth, bool saveguardspot) save_wp=cur_wp; // save the current waypoint cur_wp=-1; // flag this move as quest controlled } - mlog(AI__WAYPOINTS, "MoveTo (%.3f, %.3f, %.3f), pausing regular grid wandering. Grid %d, save_wp %d", mtx, mty, mtz, -GetGrid(), save_wp); + mlog(AI__WAYPOINTS, "MoveTo %s, pausing regular grid wandering. Grid %d, save_wp %d",to_string(static_cast(position)).c_str(), -GetGrid(), save_wp); } else { // not on a grid roamer=true; save_wp=0; cur_wp=-2; // flag as quest controlled w/no grid - mlog(AI__WAYPOINTS, "MoveTo (%.3f, %.3f, %.3f) without a grid.", mtx, mty, mtz); + mlog(AI__WAYPOINTS, "MoveTo %s without a grid.", to_string(static_cast(position)).c_str()); } if (saveguardspot) { - guard_x = mtx; - guard_y = mty; - guard_z = mtz; - guard_heading = mth; + m_GuardPoint = position; - if(guard_heading == 0) - guard_heading = 0.0001; //hack to make IsGuarding simpler + if(m_GuardPoint.m_Heading == 0) + m_GuardPoint.m_Heading = 0.0001; //hack to make IsGuarding simpler - if(guard_heading == -1) - guard_heading = this->CalculateHeadingToTarget(mtx, mty); + if(m_GuardPoint.m_Heading == -1) + m_GuardPoint.m_Heading = this->CalculateHeadingToTarget(position.m_X, position.m_Y); - mlog(AI__WAYPOINTS, "Setting guard position to (%.3f, %.3f, %.3f)", guard_x, guard_y, guard_z); + mlog(AI__WAYPOINTS, "Setting guard position to %s", to_string(static_cast(m_GuardPoint)).c_str()); } - cur_wp_x = mtx; - cur_wp_y = mty; - cur_wp_z = mtz; + m_CurrentWayPoint = position; cur_wp_pause = 0; - cur_wp_heading = mth; pLastFightingDelayMoving = 0; if(AIwalking_timer->Enabled()) AIwalking_timer->Start(100); @@ -219,26 +213,23 @@ void NPC::UpdateWaypoint(int wp_index) cur = Waypoints.begin(); cur += wp_index; - cur_wp_x = cur->x; - cur_wp_y = cur->y; - cur_wp_z = cur->z; + m_CurrentWayPoint = xyz_heading(cur->x, cur->y, cur->z, cur->heading); cur_wp_pause = cur->pause; - cur_wp_heading = cur->heading; - mlog(AI__WAYPOINTS, "Next waypoint %d: (%.3f, %.3f, %.3f, %.3f)", wp_index, cur_wp_x, cur_wp_y, cur_wp_z, cur_wp_heading); + mlog(AI__WAYPOINTS, "Next waypoint %d: (%.3f, %.3f, %.3f, %.3f)", wp_index, m_CurrentWayPoint.m_X, m_CurrentWayPoint.m_Y, m_CurrentWayPoint.m_Z, m_CurrentWayPoint.m_Heading); //fix up pathing Z if(zone->HasMap() && RuleB(Map, FixPathingZAtWaypoints)) { if(!RuleB(Watermap, CheckForWaterAtWaypoints) || !zone->HasWaterMap() || - (zone->HasWaterMap() && !zone->watermap->InWater(cur_wp_x, cur_wp_y, cur_wp_z))) + (zone->HasWaterMap() && !zone->watermap->InWater(m_CurrentWayPoint))) { - Map::Vertex dest(cur_wp_x, cur_wp_y, cur_wp_z); + Map::Vertex dest(m_CurrentWayPoint.m_X, m_CurrentWayPoint.m_Y, m_CurrentWayPoint.m_Z); float newz = zone->zonemap->FindBestZ(dest, nullptr); if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaWaypoint)) - cur_wp_z = newz + 1; + m_CurrentWayPoint.m_Z = newz + 1; } } @@ -267,7 +258,7 @@ void NPC::CalculateNewWaypoint() case 1: //10 closest { std::list closest; - GetClosestWaypoint(closest, 10, GetX(), GetY(), GetZ()); + GetClosestWaypoint(closest, 10, GetPosition()); std::list::iterator iter = closest.begin(); if(closest.size() != 0) { @@ -323,7 +314,7 @@ void NPC::CalculateNewWaypoint() case 5: //pick random closest 5 and pick one that's in sight { std::list closest; - GetClosestWaypoint(closest, 5, GetX(), GetY(), GetZ()); + GetClosestWaypoint(closest, 5, GetPosition()); std::list::iterator iter = closest.begin(); while(iter != closest.end()) @@ -364,7 +355,7 @@ bool wp_distance_pred(const wp_distance& left, const wp_distance& right) return left.dist < right.dist; } -void NPC::GetClosestWaypoint(std::list &wp_list, int count, float m_x, float m_y, float m_z) +void NPC::GetClosestWaypoint(std::list &wp_list, int count, const xyz_location& location) { wp_list.clear(); if(Waypoints.size() <= count) @@ -379,11 +370,11 @@ void NPC::GetClosestWaypoint(std::list &wp_list, int count, float m_x, f std::list distances; for(int i = 0; i < Waypoints.size(); ++i) { - float cur_x = (Waypoints[i].x - m_x); + float cur_x = (Waypoints[i].x - location.m_X); cur_x *= cur_x; - float cur_y = (Waypoints[i].y - m_y); + float cur_y = (Waypoints[i].y - location.m_Y); cur_y *= cur_y; - float cur_z = (Waypoints[i].z - m_z); + float cur_z = (Waypoints[i].z - location.m_Z); cur_z *= cur_z; float cur_dist = cur_x + cur_y + cur_z; wp_distance w_dist; @@ -431,28 +422,23 @@ void NPC::SetWaypointPause() void NPC::SaveGuardSpot(bool iClearGuardSpot) { if (iClearGuardSpot) { mlog(AI__WAYPOINTS, "Clearing guard order."); - guard_x = 0; - guard_y = 0; - guard_z = 0; - guard_heading = 0; + m_GuardPoint = xyz_heading(0, 0, 0, 0); } else { - guard_x = x_pos; - guard_y = y_pos; - guard_z = z_pos; - guard_heading = heading; - if(guard_heading == 0) - guard_heading = 0.0001; //hack to make IsGuarding simpler - mlog(AI__WAYPOINTS, "Setting guard position to (%.3f, %.3f, %.3f)", guard_x, guard_y, guard_z); + m_GuardPoint = m_Position; + + if(m_GuardPoint.m_Heading == 0) + m_GuardPoint.m_Heading = 0.0001; //hack to make IsGuarding simpler + mlog(AI__WAYPOINTS, "Setting guard position to %s", to_string(static_cast(m_GuardPoint)).c_str()); } } void NPC::NextGuardPosition() { - if (!CalculateNewPosition2(guard_x, guard_y, guard_z, GetMovespeed())) { - SetHeading(guard_heading); + if (!CalculateNewPosition2(m_GuardPoint.m_X, m_GuardPoint.m_Y, m_GuardPoint.m_Z, GetMovespeed())) { + SetHeading(m_GuardPoint.m_Heading); mlog(AI__WAYPOINTS, "Unable to move to next guard position. Probably rooted."); } - else if((x_pos == guard_x) && (y_pos == guard_y) && (z_pos == guard_z)) + else if((m_Position.m_X == m_GuardPoint.m_X) && (m_Position.m_Y == m_GuardPoint.m_Y) && (m_Position.m_Z == m_GuardPoint.m_Z)) { if(moved) { @@ -480,7 +466,7 @@ void Mob::SaveSpawnSpot() { }*/ float Mob::CalculateDistance(float x, float y, float z) { - return (float)sqrtf( ((x_pos-x)*(x_pos-x)) + ((y_pos-y)*(y_pos-y)) + ((z_pos-z)*(z_pos-z)) ); + return (float)sqrtf( ((m_Position.m_X-x)*(m_Position.m_X-x)) + ((m_Position.m_Y-y)*(m_Position.m_Y-y)) + ((m_Position.m_Z-z)*(m_Position.m_Z-z)) ); } /* @@ -491,13 +477,13 @@ uint8 NPC::CalculateHeadingToNextWaypoint() { float Mob::CalculateHeadingToTarget(float in_x, float in_y) { float angle; - if (in_x-x_pos > 0) - angle = - 90 + atan((float)(in_y-y_pos) / (float)(in_x-x_pos)) * 180 / M_PI; - else if (in_x-x_pos < 0) - angle = + 90 + atan((float)(in_y-y_pos) / (float)(in_x-x_pos)) * 180 / M_PI; + if (in_x-m_Position.m_X > 0) + angle = - 90 + atan((float)(in_y-m_Position.m_Y) / (float)(in_x-m_Position.m_X)) * 180 / M_PI; + else if (in_x-m_Position.m_X < 0) + angle = + 90 + atan((float)(in_y-m_Position.m_Y) / (float)(in_x-m_Position.m_X)) * 180 / M_PI; else // Added? { - if (in_y-y_pos > 0) + if (in_y-m_Position.m_Y > 0) angle = 0; else angle = 180; @@ -513,16 +499,16 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b if(GetID()==0) return true; - if ((x_pos-x == 0) && (y_pos-y == 0)) {//spawn is at target coords - if(z_pos-z != 0) { - z_pos = z; + if ((m_Position.m_X-x == 0) && (m_Position.m_Y-y == 0)) {//spawn is at target coords + if(m_Position.m_Z-z != 0) { + m_Position.m_Z = z; mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z); return true; } mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater); return false; } - else if ((ABS(x_pos - x) < 0.1) && (ABS(y_pos - y) < 0.1)) + else if ((ABS(m_Position.m_X - x) < 0.1) && (ABS(m_Position.m_Y - y) < 0.1)) { mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f): X/Y difference <0.1, Jumping to target.", x, y, z); @@ -530,27 +516,27 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b entity_list.ProcessMove(CastToNPC(), x, y, z); } - x_pos = x; - y_pos = y; - z_pos = z; + m_Position.m_X = x; + m_Position.m_Y = y; + m_Position.m_Z = z; return true; } int compare_steps = IsBoat() ? 1 : 20; - if(tar_ndx < compare_steps && tarx==x && tary==y) { + if(tar_ndx < compare_steps && m_TargetLocation.m_X==x && m_TargetLocation.m_Y==y) { - float new_x = x_pos + tar_vx*tar_vector; - float new_y = y_pos + tar_vy*tar_vector; - float new_z = z_pos + tar_vz*tar_vector; + float new_x = m_Position.m_X + m_TargetV.m_X*tar_vector; + float new_y = m_Position.m_Y + m_TargetV.m_Y*tar_vector; + float new_z = m_Position.m_Z + m_TargetV.m_Z*tar_vector; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } - x_pos = new_x; - y_pos = new_y; - z_pos = new_z; + m_Position.m_X = new_x; + m_Position.m_Y = new_y; + m_Position.m_Z = new_z; - mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), old vector (%.3f, %.3f, %.3f)", x, y, z, tar_vx, tar_vy, tar_vz); + mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), old vector (%.3f, %.3f, %.3f)", x, y, z, m_TargetV.m_X, m_TargetV.m_Y, m_TargetV.m_Z); uint8 NPCFlyMode = 0; @@ -563,25 +549,25 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) { if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || - (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) + (zone->HasWaterMap() && !zone->watermap->InWater(m_Position.m_X))) { - Map::Vertex dest(x_pos, y_pos, z_pos); + Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z); float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f; - mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); + mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z); if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check. { - if((ABS(x - x_pos) < 0.5) && (ABS(y - y_pos) < 0.5)) + if((ABS(x - m_Position.m_X) < 0.5) && (ABS(y - m_Position.m_Y) < 0.5)) { - if(ABS(z-z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving)) - z_pos = z; + if(ABS(z-m_Position.m_Z) <= RuleR(Map, FixPathingZMaxDeltaMoving)) + m_Position.m_Z = z; else - z_pos = newz + 1; + m_Position.m_Z = newz + 1; } else - z_pos = newz + 1; + m_Position.m_Z = newz + 1; } } } @@ -596,28 +582,26 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b } else { tar_ndx=0; } - tarx=x; - tary=y; - tarz=z; + m_TargetLocation = xyz_location(x, y, z); - float nx = this->x_pos; - float ny = this->y_pos; - float nz = this->z_pos; + float nx = this->m_Position.m_X; + float ny = this->m_Position.m_Y; + float nz = this->m_Position.m_Z; // float nh = this->heading; - tar_vx = x - nx; - tar_vy = y - ny; - tar_vz = z - nz; + m_TargetV.m_X = x - nx; + m_TargetV.m_Y = y - ny; + m_TargetV.m_Z = z - nz; //pRunAnimSpeed = (int8)(speed*NPC_RUNANIM_RATIO); //speed *= NPC_SPEED_MULTIPLIER; - mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), new vector (%.3f, %.3f, %.3f) rate %.3f, RAS %d", x, y, z, tar_vx, tar_vy, tar_vz, speed, pRunAnimSpeed); + mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), new vector (%.3f, %.3f, %.3f) rate %.3f, RAS %d", x, y, z, m_TargetV.m_X, m_TargetV.m_Y, m_TargetV.m_Z, speed, pRunAnimSpeed); // -------------------------------------------------------------------------- // 2: get unit vector // -------------------------------------------------------------------------- - float mag = sqrtf (tar_vx*tar_vx + tar_vy*tar_vy + tar_vz*tar_vz); + float mag = sqrtf (m_TargetV.m_X*m_TargetV.m_X + m_TargetV.m_Y*m_TargetV.m_Y + m_TargetV.m_Z*m_TargetV.m_Z); tar_vector = speed / mag; // mob move fix @@ -630,24 +614,24 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b { if (numsteps>1) { - tar_vector=1.0f ; - tar_vx = tar_vx/numsteps; - tar_vy = tar_vy/numsteps; - tar_vz = tar_vz/numsteps; + tar_vector=1.0f ; + m_TargetV.m_X = m_TargetV.m_X/numsteps; + m_TargetV.m_Y = m_TargetV.m_Y/numsteps; + m_TargetV.m_Z = m_TargetV.m_Z/numsteps; - float new_x = x_pos + tar_vx; - float new_y = y_pos + tar_vy; - float new_z = z_pos + tar_vz; + float new_x = m_Position.m_X + m_TargetV.m_X; + float new_y = m_Position.m_Y + m_TargetV.m_Y; + float new_z = m_Position.m_Z + m_TargetV.m_Z; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } - x_pos = new_x; - y_pos = new_y; - z_pos = new_z; + m_Position.m_X = new_x; + m_Position.m_Y = new_y; + m_Position.m_Z = new_z; + m_Position.m_Heading = CalculateHeadingToTarget(x, y); tar_ndx=22-numsteps; - heading = CalculateHeadingToTarget(x, y); - mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", x_pos, y_pos, z_pos, numsteps); + mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.m_X, m_Position.m_Y, m_Position.m_Z, numsteps); } else { @@ -655,9 +639,9 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b entity_list.ProcessMove(CastToNPC(), x, y, z); } - x_pos = x; - y_pos = y; - z_pos = z; + m_Position.m_X = x; + m_Position.m_Y = y; + m_Position.m_Z = z; mlog(AI__WAYPOINTS, "Only a single step to get there... jumping."); @@ -667,18 +651,18 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b else { tar_vector/=20; - float new_x = x_pos + tar_vx*tar_vector; - float new_y = y_pos + tar_vy*tar_vector; - float new_z = z_pos + tar_vz*tar_vector; + float new_x = m_Position.m_X + m_TargetV.m_X*tar_vector; + float new_y = m_Position.m_Y + m_TargetV.m_Y*tar_vector; + float new_z = m_Position.m_Z + m_TargetV.m_Z*tar_vector; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } - x_pos = new_x; - y_pos = new_y; - z_pos = new_z; - heading = CalculateHeadingToTarget(x, y); - mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", x_pos, y_pos, z_pos, numsteps); + m_Position.m_X = new_x; + m_Position.m_Y = new_y; + m_Position.m_Z = new_z; + m_Position.m_Heading = CalculateHeadingToTarget(x, y); + mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.m_X, m_Position.m_Y, m_Position.m_Z, numsteps); } uint8 NPCFlyMode = 0; @@ -692,25 +676,25 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) { if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || - (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) + (zone->HasWaterMap() && !zone->watermap->InWater(m_Position))) { - Map::Vertex dest(x_pos, y_pos, z_pos); + Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z); float newz = zone->zonemap->FindBestZ(dest, nullptr); - mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); + mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z); if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check. { - if(ABS(x - x_pos) < 0.5 && ABS(y - y_pos) < 0.5) + if(ABS(x - m_Position.m_X) < 0.5 && ABS(y - m_Position.m_Y) < 0.5) { - if(ABS(z - z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving)) - z_pos = z; + if(ABS(z - m_Position.m_Z) <= RuleR(Map, FixPathingZMaxDeltaMoving)) + m_Position.m_Z = z; else - z_pos = newz + 1; + m_Position.m_Z = newz + 1; } else - z_pos = newz+1; + m_Position.m_Z = newz+1; } } } @@ -718,10 +702,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b SetMoving(true); moved=true; - delta_x=x_pos-nx; - delta_y=y_pos-ny; - delta_z=z_pos-nz; - delta_heading=0; + m_Delta = xyz_heading(m_Position.m_X - nx, m_Position.m_Y - ny, m_Position.m_Z - nz, 0.0f); if (IsClient()) SendPosUpdate(1); @@ -746,9 +727,9 @@ bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool chec if(GetID()==0) return true; - float nx = x_pos; - float ny = y_pos; - float nz = z_pos; + float nx = m_Position.m_X; + float ny = m_Position.m_Y; + float nz = m_Position.m_Z; // if NPC is rooted if (speed == 0.0) { @@ -764,46 +745,46 @@ bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool chec } float old_test_vector=test_vector; - tar_vx = x - nx; - tar_vy = y - ny; - tar_vz = z - nz; + m_TargetV.m_X = x - nx; + m_TargetV.m_Y = y - ny; + m_TargetV.m_Z = z - nz; - if (tar_vx == 0 && tar_vy == 0) + if (m_TargetV.m_X == 0 && m_TargetV.m_Y == 0) return false; pRunAnimSpeed = (uint8)(speed*NPC_RUNANIM_RATIO); speed *= NPC_SPEED_MULTIPLIER; - mlog(AI__WAYPOINTS, "Calculating new position to (%.3f, %.3f, %.3f) vector (%.3f, %.3f, %.3f) rate %.3f RAS %d", x, y, z, tar_vx, tar_vy, tar_vz, speed, pRunAnimSpeed); + mlog(AI__WAYPOINTS, "Calculating new position to (%.3f, %.3f, %.3f) vector (%.3f, %.3f, %.3f) rate %.3f RAS %d", x, y, z, m_TargetV.m_X, m_TargetV.m_Y, m_TargetV.m_Z, speed, pRunAnimSpeed); // -------------------------------------------------------------------------- // 2: get unit vector // -------------------------------------------------------------------------- test_vector=sqrtf (x*x + y*y + z*z); - tar_vector = speed / sqrtf (tar_vx*tar_vx + tar_vy*tar_vy + tar_vz*tar_vz); - heading = CalculateHeadingToTarget(x, y); + tar_vector = speed / sqrtf (m_TargetV.m_X*m_TargetV.m_X + m_TargetV.m_Y*m_TargetV.m_Y + m_TargetV.m_Z*m_TargetV.m_Z); + m_Position.m_Heading = CalculateHeadingToTarget(x, y); if (tar_vector >= 1.0) { if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), x, y, z); } - x_pos = x; - y_pos = y; - z_pos = z; + m_Position.m_X = x; + m_Position.m_Y = y; + m_Position.m_Z = z; mlog(AI__WAYPOINTS, "Close enough, jumping to waypoint"); } else { - float new_x = x_pos + tar_vx*tar_vector; - float new_y = y_pos + tar_vy*tar_vector; - float new_z = z_pos + tar_vz*tar_vector; + float new_x = m_Position.m_X + m_TargetV.m_X*tar_vector; + float new_y = m_Position.m_Y + m_TargetV.m_Y*tar_vector; + float new_z = m_Position.m_Z + m_TargetV.m_Z*tar_vector; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } - x_pos = new_x; - y_pos = new_y; - z_pos = new_z; - mlog(AI__WAYPOINTS, "Next position (%.3f, %.3f, %.3f)", x_pos, y_pos, z_pos); + m_Position.m_X = new_x; + m_Position.m_Y = new_y; + m_Position.m_Z = new_z; + mlog(AI__WAYPOINTS, "Next position (%.3f, %.3f, %.3f)", m_Position.m_X, m_Position.m_Y, m_Position.m_Z); } uint8 NPCFlyMode = 0; @@ -817,25 +798,25 @@ bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool chec if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) { if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || - (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) + (zone->HasWaterMap() && !zone->watermap->InWater(m_Position))) { - Map::Vertex dest(x_pos, y_pos, z_pos); + Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z); float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f; - mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); + mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z); if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check. { - if(ABS(x - x_pos) < 0.5 && ABS(y - y_pos) < 0.5) + if(ABS(x - m_Position.m_X) < 0.5 && ABS(y - m_Position.m_Y) < 0.5) { - if(ABS(z - z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving)) - z_pos = z; + if(ABS(z - m_Position.m_Z) <= RuleR(Map, FixPathingZMaxDeltaMoving)) + m_Position.m_Z = z; else - z_pos = newz + 1; + m_Position.m_Z = newz + 1; } else - z_pos = newz+1; + m_Position.m_Z = newz+1; } } } @@ -845,10 +826,7 @@ bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool chec tar_ndx=0; this->SetMoving(true); moved=true; - delta_x=(x_pos-nx); - delta_y=(y_pos-ny); - delta_z=(z_pos-nz); - delta_heading=0;//(heading-nh)*8; + m_Delta = xyz_heading(m_Position.m_X - nx, m_Position.m_Y - ny, m_Position.m_Z - nz, 0.0f); SendPosUpdate(); } tar_ndx++; @@ -914,8 +892,9 @@ void NPC::AssignWaypoints(int32 grid) { if(zone->HasMap() && RuleB(Map, FixPathingZWhenLoading) ) { + auto positon = xyz_location(newwp.x,newwp.y,newwp.z); if(!RuleB(Watermap, CheckWaypointsInWaterWhenLoading) || !zone->HasWaterMap() || - (zone->HasWaterMap() && !zone->watermap->InWater(newwp.x, newwp.y, newwp.z))) + (zone->HasWaterMap() && !zone->watermap->InWater(positon))) { Map::Vertex dest(newwp.x, newwp.y, newwp.z); @@ -948,9 +927,9 @@ void Mob::SendTo(float new_x, float new_y, float new_z) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } - x_pos = new_x; - y_pos = new_y; - z_pos = new_z; + m_Position.m_X = new_x; + m_Position.m_Y = new_y; + m_Position.m_Z = new_z; mlog(AI__WAYPOINTS, "Sent To (%.3f, %.3f, %.3f)", new_x, new_y, new_z); if(flymode == FlyMode1) @@ -961,20 +940,20 @@ void Mob::SendTo(float new_x, float new_y, float new_z) { if(zone->HasMap() && RuleB(Map, FixPathingZOnSendTo) ) { if(!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() || - (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) + (zone->HasWaterMap() && !zone->watermap->InWater(m_Position))) { - Map::Vertex dest(x_pos, y_pos, z_pos); + Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z); float newz = zone->zonemap->FindBestZ(dest, nullptr); - mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); + mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z); if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaSendTo)) // Sanity check. - z_pos = newz + 1; + m_Position.m_Z = newz + 1; } } else - z_pos += 0.1; + m_Position.m_Z += 0.1; } void Mob::SendToFixZ(float new_x, float new_y, float new_z) { @@ -982,9 +961,9 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z + 0.1); } - x_pos = new_x; - y_pos = new_y; - z_pos = new_z + 0.1; + m_Position.m_X = new_x; + m_Position.m_Y = new_y; + m_Position.m_Z = new_z + 0.1; //fix up pathing Z, this shouldent be needed IF our waypoints //are corrected instead @@ -992,16 +971,16 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) { if(zone->HasMap() && RuleB(Map, FixPathingZOnSendTo)) { if(!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() || - (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) + (zone->HasWaterMap() && !zone->watermap->InWater(m_Position))) { - Map::Vertex dest(x_pos, y_pos, z_pos); + Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z); float newz = zone->zonemap->FindBestZ(dest, nullptr); - mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); + mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z); if( (newz > -2000) && ABS(newz-dest.z) < RuleR(Map, FixPathingZMaxDeltaSendTo)) // Sanity check. - z_pos = newz + 1; + m_Position.m_Z = newz + 1; } } } @@ -1067,15 +1046,14 @@ bool ZoneDatabase::GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* return true; } -void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid) +void ZoneDatabase::AssignGrid(Client *client, const xy_location& location, uint32 grid) { int matches = 0, fuzzy = 0, spawn2id = 0; - float dbx = 0, dby = 0; // looks like most of the stuff in spawn2 is straight integers // so let's try that first std::string query = StringFormat("SELECT id, x, y FROM spawn2 WHERE zone = '%s' AND x = %i AND y = %i", - zone->GetShortName(), (int)x, (int)y); + zone->GetShortName(), (int)location.m_X, (int)location.m_Y); auto results = QueryDatabase(query); if(!results.Success()) { LogFile->write(EQEmuLog::Error, "Error querying spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); @@ -1089,7 +1067,7 @@ void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid) query = StringFormat("SELECT id,x,y FROM spawn2 WHERE zone='%s' AND " "ABS( ABS(x) - ABS(%f) ) < %f AND " "ABS( ABS(y) - ABS(%f) ) < %f", - zone->GetShortName(), x, _GASSIGN_TOLERANCE, y, _GASSIGN_TOLERANCE); + zone->GetShortName(), location.m_X, _GASSIGN_TOLERANCE, location.m_Y, _GASSIGN_TOLERANCE); results = QueryDatabase(query); if (!results.Success()) { LogFile->write(EQEmuLog::Error, "Error querying fuzzy spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); @@ -1115,8 +1093,7 @@ void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid) auto row = results.begin(); spawn2id = atoi(row[0]); - dbx = atof(row[1]); - dby = atof(row[2]); + xy_location dbLocation = xy_location(atof(row[1]), atof(row[2])); query = StringFormat("UPDATE spawn2 SET pathgrid = %d WHERE id = %d", grid, spawn2id); results = QueryDatabase(query); @@ -1141,7 +1118,7 @@ void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid) return; } - float difference = sqrtf(pow(fabs(x - dbx) , 2) + pow(fabs(y - dby), 2)); + float difference = sqrtf(pow(fabs(location.m_X - dbLocation.m_X) , 2) + pow(fabs(location.m_Y - dbLocation.m_Y), 2)); client->Message(0, "Grid assign: spawn2 id = %d updated - fuzzy match: deviation %f", spawn2id, difference); } @@ -1189,11 +1166,11 @@ void ZoneDatabase::ModifyGrid(Client *client, bool remove, uint32 id, uint8 type /************************************** * AddWP - Adds a new waypoint to a specific grid for a specific zone. */ -void ZoneDatabase::AddWP(Client *client, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading) +void ZoneDatabase::AddWP(Client *client, uint32 gridid, uint32 wpnum, const xyz_heading& position, uint32 pause, uint16 zoneid) { std::string query = StringFormat("INSERT INTO grid_entries (gridid, zoneid, `number`, x, y, z, pause, heading) " "VALUES (%i, %i, %i, %f, %f, %f, %i, %f)", - gridid, zoneid, wpnum, xpos, ypos, zpos, pause, heading); + gridid, zoneid, wpnum, position.m_X, position.m_Y, position.m_Z, pause, position.m_Heading); auto results = QueryDatabase(query); if (!results.Success()) { LogFile->write(EQEmuLog::Error, "Error adding waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); @@ -1238,7 +1215,7 @@ void ZoneDatabase::DeleteWaypoint(Client *client, uint32 grid_num, uint32 wp_num * Returns 0 if the function didn't have to create a new grid. If the function had to create a new grid for the spawn, then the ID of * the created grid is returned. */ -uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading) { +uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, const xyz_heading& position, uint32 pause, int type1, int type2, uint16 zoneid) { uint32 grid_num; // The grid number the spawn is assigned to (if spawn has no grid, will be the grid number we end up creating) uint32 next_wp_num; // The waypoint number we should be assigning to the new waypoint @@ -1301,7 +1278,7 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos, query = StringFormat("INSERT INTO grid_entries(gridid, zoneid, `number`, x, y, z, pause, heading) " "VALUES (%i, %i, %i, %f, %f, %f, %i, %f)", - grid_num, zoneid, next_wp_num, xpos, ypos, zpos, pause, heading); + grid_num, zoneid, next_wp_num, position.m_X, position.m_Y, position.m_Z, pause, position.m_Heading); results = QueryDatabase(query); if(!results.Success()) LogFile->write(EQEmuLog::Error, "Error adding grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); @@ -1349,16 +1326,10 @@ int ZoneDatabase::GetHighestWaypoint(uint32 zoneid, uint32 gridid) { void NPC::SaveGuardSpotCharm() { - guard_x_saved = guard_x; - guard_y_saved = guard_y; - guard_z_saved = guard_z; - guard_heading_saved = guard_heading; + m_GuardPointSaved = m_GuardPoint; } void NPC::RestoreGuardSpotCharm() { - guard_x = guard_x_saved; - guard_y = guard_y_saved; - guard_z = guard_z_saved; - guard_heading = guard_heading_saved; + m_GuardPoint = m_GuardPointSaved; } diff --git a/zone/zone.cpp b/zone/zone.cpp index 3ee15be83..23bc03ad6 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -97,7 +97,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) { } zone->zonemap = Map::LoadMapFile(zone->map_name); zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name); - zone->pathing = PathManager::LoadPathFile(zone->map_name); + zone->pathing = PathManager::LoadPathFile(zone->map_name); char tmp[10]; if (database.GetVariable("loglevel",tmp, 9)) { @@ -482,14 +482,14 @@ void Zone::GetMerchantDataForZoneLoad() { "WHERE nt.merchant_id = ml.merchantid AND nt.id = se.npcid " "AND se.spawngroupid = s2.spawngroupid AND s2.zone = '%s' AND s2.version = %i " "ORDER BY ml.slot ", GetShortName(), GetInstanceVersion()); - auto results = database.QueryDatabase(query); + auto results = database.QueryDatabase(query); std::map >::iterator cur; uint32 npcid = 0; if (results.RowCount() == 0) { LogFile->write(EQEmuLog::Debug, "No Merchant Data found for %s.", GetShortName()); return; } - for (auto row = results.begin(); row != results.end(); ++row) { + for (auto row = results.begin(); row != results.end(); ++row) { MerchantList ml; ml.id = atoul(row[0]); if (npcid != ml.id) { @@ -736,7 +736,9 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name) clientauth_timer(AUTHENTICATION_TIMEOUT * 1000), spawn2_timer(1000), qglobal_purge_timer(30000), - hotzone_timer(120000) + hotzone_timer(120000), + m_SafePoint(0.0f,0.0f,0.0f), + m_Graveyard(0.0f,0.0f,0.0f,0.0f) { zoneid = in_zoneid; instanceid = in_instanceid; @@ -762,28 +764,20 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name) memset(file_name, 0, sizeof(file_name)); long_name = 0; aggroedmobs =0; - - psafe_x = 0; - psafe_y = 0; - psafe_z = 0; pgraveyard_id = 0; pgraveyard_zoneid = 0; - pgraveyard_x = 0; - pgraveyard_y = 0; - pgraveyard_z = 0; - pgraveyard_heading = 0; pMaxClients = 0; pQueuedMerchantsWorkID = 0; pvpzone = false; if(database.GetServerType() == 1) pvpzone = true; - database.GetZoneLongName(short_name, &long_name, file_name, &psafe_x, &psafe_y, &psafe_z, &pgraveyard_id, &pMaxClients); + database.GetZoneLongName(short_name, &long_name, file_name, &m_SafePoint.m_X, &m_SafePoint.m_Y, &m_SafePoint.m_Z, &pgraveyard_id, &pMaxClients); if(graveyard_id() > 0) { LogFile->write(EQEmuLog::Debug, "Graveyard ID is %i.", graveyard_id()); - bool GraveYardLoaded = database.GetZoneGraveyard(graveyard_id(), &pgraveyard_zoneid, &pgraveyard_x, &pgraveyard_y, &pgraveyard_z, &pgraveyard_heading); + bool GraveYardLoaded = database.GetZoneGraveyard(graveyard_id(), &pgraveyard_zoneid, &m_Graveyard.m_X, &m_Graveyard.m_Y, &m_Graveyard.m_Z, &m_Graveyard.m_Heading); if(GraveYardLoaded) - LogFile->write(EQEmuLog::Debug, "Loaded a graveyard for zone %s: graveyard zoneid is %u x is %f y is %f z is %f heading is %f.", short_name, graveyard_zoneid(), graveyard_x(), graveyard_y(), graveyard_z(), graveyard_heading()); + LogFile->write(EQEmuLog::Debug, "Loaded a graveyard for zone %s: graveyard zoneid is %u at %s.", short_name, graveyard_zoneid(), to_string(m_Graveyard).c_str()); else LogFile->write(EQEmuLog::Error, "Unable to load the graveyard id %i for zone %s.", graveyard_id(), short_name); } @@ -1520,7 +1514,7 @@ void Zone::SetTime(uint8 hour, uint8 minute) } } -ZonePoint* Zone::GetClosestZonePoint(float x, float y, float z, uint32 to, Client* client, float max_distance) { +ZonePoint* Zone::GetClosestZonePoint(const xyz_location& location, uint32 to, Client* client, float max_distance) { LinkedListIterator iterator(zone_point_list); ZonePoint* closest_zp = 0; float closest_dist = FLT_MAX; @@ -1538,14 +1532,10 @@ ZonePoint* Zone::GetClosestZonePoint(float x, float y, float z, uint32 to, Clien if (zp->target_zone_id == to) { - float delta_x = zp->x - x; - float delta_y = zp->y - y; - if(zp->x == 999999 || zp->x == -999999) - delta_x = 0; - if(zp->y == 999999 || zp->y == -999999) - delta_y = 0; + auto dist = Distance(xy_location(zp->x,zp->y), location); + if ((zp->x == 999999 || zp->x == -999999) && (zp->y == 999999 || zp->y == -999999)) + dist = 0; - float dist = sqrt(delta_x * delta_x + delta_y * delta_y); if (dist < closest_dist) { closest_zp = zp; @@ -1558,24 +1548,24 @@ ZonePoint* Zone::GetClosestZonePoint(float x, float y, float z, uint32 to, Clien if(closest_dist > 400.0f && closest_dist < max_distance2) { if(client) - client->CheatDetected(MQZoneUnknownDest, x, y, z); // Someone is trying to use /zone + client->CheatDetected(MQZoneUnknownDest, location.m_X, location.m_Y, location.m_Z); // Someone is trying to use /zone LogFile->write(EQEmuLog::Status, "WARNING: Closest zone point for zone id %d is %f, you might need to update your zone_points table if you dont arrive at the right spot.", to, closest_dist); - LogFile->write(EQEmuLog::Status, ". %f x %f y %f z ", x, y, z); + LogFile->write(EQEmuLog::Status, ". %s", to_string(location).c_str()); } if(closest_dist > max_distance2) closest_zp = nullptr; if(!closest_zp) - closest_zp = GetClosestZonePointWithoutZone(x, y, z, client); + closest_zp = GetClosestZonePointWithoutZone(location.m_X, location.m_Y, location.m_Z, client); return closest_zp; } -ZonePoint* Zone::GetClosestZonePoint(float x, float y, float z, const char* to_name, Client* client, float max_distance) { +ZonePoint* Zone::GetClosestZonePoint(const xyz_location& location, const char* to_name, Client* client, float max_distance) { if(to_name == nullptr) - return GetClosestZonePointWithoutZone(x,y,z, client, max_distance); - return GetClosestZonePoint(x, y, z, database.GetZoneID(to_name), client, max_distance); + return GetClosestZonePointWithoutZone(location.m_X, location.m_Y, location.m_Z, client, max_distance); + return GetClosestZonePoint(location, database.GetZoneID(to_name), client, max_distance); } ZonePoint* Zone::GetClosestZonePointWithoutZone(float x, float y, float z, Client* client, float max_distance) { @@ -1823,12 +1813,9 @@ bool Zone::HasGraveyard() { return Result; } -void Zone::SetGraveyard(uint32 zoneid, uint32 x, uint32 y, uint32 z, uint32 heading) { +void Zone::SetGraveyard(uint32 zoneid, const xyz_heading& graveyardPosition) { pgraveyard_zoneid = zoneid; - pgraveyard_x = x; - pgraveyard_y = y; - pgraveyard_z = z; - pgraveyard_heading = heading; + m_Graveyard = graveyardPosition; } void Zone::LoadBlockedSpells(uint32 zoneid) @@ -1855,7 +1842,7 @@ void Zone::ClearBlockedSpells() } } -bool Zone::IsSpellBlocked(uint32 spell_id, float nx, float ny, float nz) +bool Zone::IsSpellBlocked(uint32 spell_id, const xyz_location& location) { if (blocked_spells) { @@ -1905,12 +1892,8 @@ bool Zone::IsSpellBlocked(uint32 spell_id, float nx, float ny, float nz) } case 2: { - if ((( nx >= (blocked_spells[x].x-blocked_spells[x].xdiff)) && (nx <= (blocked_spells[x].x+blocked_spells[x].xdiff))) && - (( ny >= (blocked_spells[x].y-blocked_spells[x].ydiff)) && (ny <= (blocked_spells[x].y+blocked_spells[x].ydiff))) && - (( nz >= (blocked_spells[x].z-blocked_spells[x].zdiff)) && (nz <= (blocked_spells[x].z+blocked_spells[x].zdiff)))) - { + if (!IsWithinAxisAlignedBox(location, blocked_spells[x].m_Location - blocked_spells[x].m_Difference, blocked_spells[x].m_Location + blocked_spells[x].m_Difference)) return true; - } break; } default: @@ -1925,7 +1908,7 @@ bool Zone::IsSpellBlocked(uint32 spell_id, float nx, float ny, float nz) return false; } -const char* Zone::GetSpellBlockedMessage(uint32 spell_id, float nx, float ny, float nz) +const char* Zone::GetSpellBlockedMessage(uint32 spell_id, const xyz_location& location) { if(blocked_spells) { @@ -1943,12 +1926,8 @@ const char* Zone::GetSpellBlockedMessage(uint32 spell_id, float nx, float ny, fl } case 2: { - if((( nx > (blocked_spells[x].x-blocked_spells[x].xdiff)) && (nx < (blocked_spells[x].x+blocked_spells[x].xdiff))) && - (( ny > (blocked_spells[x].y-blocked_spells[x].ydiff)) && (ny < (blocked_spells[x].y+blocked_spells[x].ydiff))) && - (( nz > (blocked_spells[x].z-blocked_spells[x].zdiff)) && (nz < (blocked_spells[x].z+blocked_spells[x].zdiff)))) - { + if(!IsWithinAxisAlignedBox(location, blocked_spells[x].m_Location - blocked_spells[x].m_Difference, blocked_spells[x].m_Location + blocked_spells[x].m_Difference)) return blocked_spells[x].message; - } break; } default: @@ -2185,7 +2164,7 @@ void Zone::DoAdventureActions() const NPCType* tmp = database.GetNPCType(ds->data_id); if(tmp) { - NPC* npc = new NPC(tmp, 0, ds->assa_x, ds->assa_y, ds->assa_z, ds->assa_h, FlyMode3); + NPC* npc = new NPC(tmp, nullptr, xyz_heading(ds->assa_x, ds->assa_y, ds->assa_z, ds->assa_h), FlyMode3); npc->AddLootTable(); entity_list.AddNPC(npc); npc->Shout("Rarrrgh!"); diff --git a/zone/zone.h b/zone/zone.h index bbf273069..ce6b61d23 100644 --- a/zone/zone.h +++ b/zone/zone.h @@ -100,14 +100,9 @@ public: inline Timer* GetInstanceTimer() { return Instance_Timer; } - inline const float& safe_x() { return psafe_x; } - inline const float& safe_y() { return psafe_y; } - inline const float& safe_z() { return psafe_z; } + inline xyz_location GetSafePoint() { return m_SafePoint; } inline const uint32& graveyard_zoneid() { return pgraveyard_zoneid; } - inline const float& graveyard_x() { return pgraveyard_x; } - inline const float& graveyard_y() { return pgraveyard_y; } - inline const float& graveyard_z() { return pgraveyard_z; } - inline const float& graveyard_heading() { return pgraveyard_heading; } + inline xyz_heading GetGraveyardPoint() { return m_Graveyard; } inline const uint32& graveyard_id() { return pgraveyard_id; } inline const uint32& GetMaxClients() { return pMaxClients; } @@ -123,8 +118,8 @@ public: void ReloadStaticData(); uint32 CountSpawn2(); - ZonePoint* GetClosestZonePoint(float x, float y, float z, const char* to_name, Client *client, float max_distance = 40000.0f); - ZonePoint* GetClosestZonePoint(float x, float y, float z, uint32 to, Client *client, float max_distance = 40000.0f); + ZonePoint* GetClosestZonePoint(const xyz_location& location, const char* to_name, Client *client, float max_distance = 40000.0f); + ZonePoint* GetClosestZonePoint(const xyz_location& location, uint32 to, Client *client, float max_distance = 40000.0f); ZonePoint* GetClosestZonePointWithoutZone(float x, float y, float z, Client *client, float max_distance = 40000.0f); SpawnGroupList spawn_group_list; @@ -232,12 +227,12 @@ public: uint8 lootvar; bool HasGraveyard(); - void SetGraveyard(uint32 zoneid, uint32 x, uint32 y, uint32 z, uint32 heading); + void SetGraveyard(uint32 zoneid, const xyz_heading& graveyardPosition); void LoadBlockedSpells(uint32 zoneid); void ClearBlockedSpells(); - bool IsSpellBlocked(uint32 spell_id, float nx, float ny, float nz); - const char *GetSpellBlockedMessage(uint32 spell_id, float nx, float ny, float nz); + bool IsSpellBlocked(uint32 spell_id, const xyz_location& location); + const char *GetSpellBlockedMessage(uint32 spell_id, const xyz_location& location); int GetTotalBlockedSpells() { return totalBS; } inline bool HasMap() { return zonemap != nullptr; } inline bool HasWaterMap() { return watermap != nullptr; } @@ -275,7 +270,7 @@ private: char* long_name; char* map_name; bool pvpzone; - float psafe_x, psafe_y, psafe_z; + xyz_location m_SafePoint; uint32 pMaxClients; bool can_bind; bool is_city; @@ -286,7 +281,7 @@ private: uint8 zone_type; bool allow_mercs; uint32 pgraveyard_id, pgraveyard_zoneid; - float pgraveyard_x, pgraveyard_y, pgraveyard_z, pgraveyard_heading; + xyz_heading m_Graveyard; int default_ruleset; int totalBS; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index a1fdb1a76..0007b9e74 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -566,7 +566,7 @@ TraderCharges_Struct* ZoneDatabase::LoadTraderItemWithCharges(uint32 char_id) return loadti; } -ItemInst* ZoneDatabase::LoadSingleTraderItem(uint32 CharID, int SerialNumber) { +ItemInst* ZoneDatabase::LoadSingleTraderItem(uint32 CharID, int SerialNumber) { std::string query = StringFormat("SELECT * FROM trader WHERE char_id = %i AND serialnumber = %i " "ORDER BY slot_id LIMIT 80", CharID, SerialNumber); auto results = QueryDatabase(query); @@ -623,7 +623,7 @@ void ZoneDatabase::SaveTraderItem(uint32 CharID, uint32 ItemID, uint32 SerialNum } -void ZoneDatabase::UpdateTraderItemCharges(int CharID, uint32 SerialNumber, int32 Charges) { +void ZoneDatabase::UpdateTraderItemCharges(int CharID, uint32 SerialNumber, int32 Charges) { _log(TRADING__CLIENT, "ZoneDatabase::UpdateTraderItemCharges(%i, %i, %i)", CharID, SerialNumber, Charges); std::string query = StringFormat("UPDATE trader SET charges = %i WHERE char_id = %i AND serialnumber = %i", @@ -717,7 +717,7 @@ void ZoneDatabase::DeleteBuyLines(uint32 CharID) { } -void ZoneDatabase::AddBuyLine(uint32 CharID, uint32 BuySlot, uint32 ItemID, const char* ItemName, uint32 Quantity, uint32 Price) { +void ZoneDatabase::AddBuyLine(uint32 CharID, uint32 BuySlot, uint32 ItemID, const char* ItemName, uint32 Quantity, uint32 Price) { std::string query = StringFormat("REPLACE INTO buyer VALUES(%i, %i, %i, \"%s\", %i, %i)", CharID, BuySlot, ItemID, ItemName, Quantity, Price); auto results = QueryDatabase(query); @@ -726,7 +726,7 @@ void ZoneDatabase::AddBuyLine(uint32 CharID, uint32 BuySlot, uint32 ItemID, cons } -void ZoneDatabase::RemoveBuyLine(uint32 CharID, uint32 BuySlot) { +void ZoneDatabase::RemoveBuyLine(uint32 CharID, uint32 BuySlot) { std::string query = StringFormat("DELETE FROM buyer WHERE charid = %i AND buyslot = %i", CharID, BuySlot); auto results = QueryDatabase(query); if (!results.Success()) @@ -734,7 +734,7 @@ void ZoneDatabase::RemoveBuyLine(uint32 CharID, uint32 BuySlot) { } -void ZoneDatabase::UpdateBuyLine(uint32 CharID, uint32 BuySlot, uint32 Quantity) { +void ZoneDatabase::UpdateBuyLine(uint32 CharID, uint32 BuySlot, uint32 Quantity) { if(Quantity <= 0) { RemoveBuyLine(CharID, BuySlot); return; @@ -958,16 +958,16 @@ bool ZoneDatabase::LoadCharacterMemmedSpells(uint32 character_id, PlayerProfile_ "FROM " "`character_memmed_spells` " "WHERE `id` = %u ORDER BY `slot_id`", character_id); - auto results = database.QueryDatabase(query); + auto results = database.QueryDatabase(query); int i = 0; /* Initialize Spells */ for (i = 0; i < MAX_PP_MEMSPELL; i++){ pp->mem_spells[i] = 0xFFFFFFFF; } for (auto row = results.begin(); row != results.end(); ++row) { - i = atoi(row[0]); + i = atoi(row[0]); if (i < MAX_PP_MEMSPELL && atoi(row[1]) <= SPDAT_RECORDS){ - pp->mem_spells[i] = atoi(row[1]); + pp->mem_spells[i] = atoi(row[1]); } } return true; @@ -981,49 +981,50 @@ bool ZoneDatabase::LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Str "FROM " "`character_spells` " "WHERE `id` = %u ORDER BY `slot_id`", character_id); - auto results = database.QueryDatabase(query); + auto results = database.QueryDatabase(query); int i = 0; /* Initialize Spells */ for (i = 0; i < MAX_PP_SPELLBOOK; i++){ - pp->spell_book[i] = 0xFFFFFFFF; + pp->spell_book[i] = 0xFFFFFFFF; } - for (auto row = results.begin(); row != results.end(); ++row) { + for (auto row = results.begin(); row != results.end(); ++row) { i = atoi(row[0]); if (i < MAX_PP_SPELLBOOK && atoi(row[1]) <= SPDAT_RECORDS){ - pp->spell_book[i] = atoi(row[1]); - } - } + pp->spell_book[i] = atoi(row[1]); + } + } return true; } -bool ZoneDatabase::LoadCharacterLanguages(uint32 character_id, PlayerProfile_Struct* pp){ +bool ZoneDatabase::LoadCharacterLanguages(uint32 character_id, PlayerProfile_Struct* pp){ std::string query = StringFormat( "SELECT " "lang_id, " "`value` " "FROM " "`character_languages` " - "WHERE `id` = %u ORDER BY `lang_id`", character_id); - auto results = database.QueryDatabase(query); int i = 0; + "WHERE `id` = %u ORDER BY `lang_id`", character_id); + auto results = database.QueryDatabase(query); int i = 0; /* Initialize Languages */ - for (i = 0; i < MAX_PP_LANGUAGE; i++){ + for (i = 0; i < MAX_PP_LANGUAGE; ++i) pp->languages[i] = 0; - } + for (auto row = results.begin(); row != results.end(); ++row) { i = atoi(row[0]); if (i < MAX_PP_LANGUAGE){ pp->languages[i] = atoi(row[1]); } } + return true; } bool ZoneDatabase::LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp){ std::string query = StringFormat("SELECT slot, rank FROM character_leadership_abilities WHERE `id` = %u", character_id); auto results = database.QueryDatabase(query); uint32 slot = 0; - for (auto row = results.begin(); row != results.end(); ++row) { + for (auto row = results.begin(); row != results.end(); ++row) { slot = atoi(row[0]); - pp->leader_abilities.ranks[slot] = atoi(row[1]); + pp->leader_abilities.ranks[slot] = atoi(row[1]); } return true; } @@ -1035,17 +1036,17 @@ bool ZoneDatabase::LoadCharacterDisciplines(uint32 character_id, PlayerProfile_S "FROM " "`character_disciplines`" "WHERE `id` = %u ORDER BY `slot_id`", character_id); - auto results = database.QueryDatabase(query); + auto results = database.QueryDatabase(query); int i = 0; + /* Initialize Disciplines */ memset(pp->disciplines.values, 0, (sizeof(pp->disciplines.values[0]) * MAX_PP_DISCIPLINES)); - for (auto row = results.begin(); row != results.end(); ++row) { - if (i < MAX_PP_DISCIPLINES){ + for (auto row = results.begin(); row != results.end(); ++row) { + if (i < MAX_PP_DISCIPLINES) pp->disciplines.values[i] = atoi(row[0]); - } - i++; - } - return true; + ++i; + } + return true; } bool ZoneDatabase::LoadCharacterSkills(uint32 character_id, PlayerProfile_Struct* pp){ @@ -1056,17 +1057,18 @@ bool ZoneDatabase::LoadCharacterSkills(uint32 character_id, PlayerProfile_Struct "FROM " "`character_skills` " "WHERE `id` = %u ORDER BY `skill_id`", character_id); - auto results = database.QueryDatabase(query); int i = 0; + auto results = database.QueryDatabase(query); + int i = 0; /* Initialize Skill */ - for (i = 0; i < MAX_PP_SKILL; i++){ + for (i = 0; i < MAX_PP_SKILL; ++i) pp->skills[i] = 0; - } + for (auto row = results.begin(); row != results.end(); ++row) { i = atoi(row[0]); - if (i < MAX_PP_SKILL){ + if (i < MAX_PP_SKILL) pp->skills[i] = atoi(row[1]); - } } + return true; } @@ -1090,7 +1092,7 @@ bool ZoneDatabase::LoadCharacterCurrency(uint32 character_id, PlayerProfile_Stru "ebon_crystals, " "career_ebon_crystals " "FROM " - "character_currency " + "character_currency " "WHERE `id` = %i ", character_id); auto results = database.QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { @@ -1133,7 +1135,7 @@ bool ZoneDatabase::LoadCharacterBandolier(uint32 character_id, PlayerProfile_Str auto results = database.QueryDatabase(query); int i = 0; int r = 0; int si = 0; for (i = 0; i <= EmuConstants::BANDOLIERS_COUNT; i++){ for (int si = 0; si < EmuConstants::BANDOLIER_SIZE; si++){ - pp->bandoliers[i].items[si].icon = 0; + pp->bandoliers[i].items[si].icon = 0; } } @@ -1141,9 +1143,9 @@ bool ZoneDatabase::LoadCharacterBandolier(uint32 character_id, PlayerProfile_Str r = 0; i = atoi(row[r]); /* Bandolier ID */ r++; si = atoi(row[r]); /* Bandolier Slot */ r++; - pp->bandoliers[i].items[si].item_id = atoi(row[r]); r++; + pp->bandoliers[i].items[si].item_id = atoi(row[r]); r++; pp->bandoliers[i].items[si].icon = atoi(row[r]); r++; - strcpy(pp->bandoliers[i].name, row[r]); r++; + strcpy(pp->bandoliers[i].name, row[r]); r++; si++; } return true; @@ -1151,7 +1153,7 @@ bool ZoneDatabase::LoadCharacterBandolier(uint32 character_id, PlayerProfile_Str bool ZoneDatabase::LoadCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp){ std::string query = StringFormat("SELECT `tier`, `tribute` FROM `character_tribute` WHERE `id` = %u", character_id); - auto results = database.QueryDatabase(query); + auto results = database.QueryDatabase(query); int i = 0; for (i = 0; i < EmuConstants::TRIBUTE_SIZE; i++){ pp->tributes[i].tribute = 0xFFFFFFFF; @@ -1169,51 +1171,56 @@ bool ZoneDatabase::LoadCharacterTribute(uint32 character_id, PlayerProfile_Struc } bool ZoneDatabase::LoadCharacterPotions(uint32 character_id, PlayerProfile_Struct* pp){ - std::string query = StringFormat("SELECT `potion_id`, `item_id`, `icon` FROM `character_potionbelt` WHERE `id` = %u LIMIT 4", character_id); + std::string query = StringFormat("SELECT `potion_id`, `item_id`, `icon` FROM `character_potionbelt` WHERE `id` = %u LIMIT 4", character_id); auto results = database.QueryDatabase(query); int i = 0; for (i = 0; i < EmuConstants::POTION_BELT_SIZE; i++){ pp->potionbelt.items[i].icon = 0; pp->potionbelt.items[i].item_id = 0; strncpy(pp->potionbelt.items[i].item_name, "\0", 1); } + for (auto row = results.begin(); row != results.end(); ++row) { i = atoi(row[0]); /* Potion belt slot number */ uint32 item_id = atoi(row[1]); const Item_Struct *item = database.GetItem(item_id); - if(item) { - pp->potionbelt.items[i].item_id = item_id; - pp->potionbelt.items[i].icon = atoi(row[2]); - strncpy(pp->potionbelt.items[i].item_name, item->Name, 64); - } + if(!item) + continue; + + pp->potionbelt.items[i].item_id = item_id; + pp->potionbelt.items[i].icon = atoi(row[2]); + strncpy(pp->potionbelt.items[i].item_name, item->Name, 64); } + return true; } bool ZoneDatabase::LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct* pp){ std::string query = StringFormat("SELECT `zone_id`, `instance_id`, `x`, `y`, `z`, `heading`, `is_home` FROM `character_bind` WHERE `id` = %u LIMIT 2", character_id); - auto results = database.QueryDatabase(query); int i = 0; - for (auto row = results.begin(); row != results.end(); ++row) { - i = 0; + auto results = database.QueryDatabase(query); + + for (auto row = results.begin(); row != results.end(); ++row) { + /* Is home bind */ - if (atoi(row[6]) == 1){ - pp->binds[4].zoneId = atoi(row[i++]); - pp->binds[4].instance_id = atoi(row[i++]); - pp->binds[4].x = atoi(row[i++]); - pp->binds[4].y = atoi(row[i++]); - pp->binds[4].z = atoi(row[i++]); - pp->binds[4].heading = atoi(row[i++]); + if (atoi(row[6]) == 1){ + pp->binds[4].zoneId = atoi(row[0]); + pp->binds[4].instance_id = atoi(row[1]); + pp->binds[4].x = atoi(row[2]); + pp->binds[4].y = atoi(row[3]); + pp->binds[4].z = atoi(row[4]); + pp->binds[4].heading = atoi(row[5]); + continue; } + /* Is regular bind point */ - else{ - pp->binds[0].zoneId = atoi(row[i++]); - pp->binds[0].instance_id = atoi(row[i++]); - pp->binds[0].x = atoi(row[i++]); - pp->binds[0].y = atoi(row[i++]); - pp->binds[0].z = atoi(row[i++]); - pp->binds[0].heading = atoi(row[i++]); - } + pp->binds[0].zoneId = atoi(row[0]); + pp->binds[0].instance_id = atoi(row[1]); + pp->binds[0].x = atoi(row[2]); + pp->binds[0].y = atoi(row[3]); + pp->binds[0].z = atoi(row[4]); + pp->binds[0].heading = atoi(row[5]); } + return true; } @@ -1223,16 +1230,16 @@ bool ZoneDatabase::SaveCharacterLanguage(uint32 character_id, uint32 lang_id, ui return true; } -bool ZoneDatabase::SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, float x, float y, float z, float heading, uint8 is_home){ - if (zone_id <= 0) { +bool ZoneDatabase::SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, const xyz_heading& position, uint8 is_home){ + if (zone_id <= 0) { return false; } /* Save Home Bind Point */ std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" - " VALUES (%u, %u, %u, %f, %f, %f, %f, %i)", character_id, zone_id, instance_id, x, y, z, heading, is_home); - LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterBindPoint for character ID: %i zone_id: %u instance_id: %u x: %f y: %f z: %f heading: %f ishome: %u", character_id, zone_id, instance_id, x, y, z, heading, is_home); - auto results = QueryDatabase(query); + " VALUES (%u, %u, %u, %f, %f, %f, %f, %i)", character_id, zone_id, instance_id, position.m_X, position.m_Y, position.m_Z, position.m_Heading, is_home); + LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterBindPoint for character ID: %i zone_id: %u instance_id: %u position: %s ishome: %u", character_id, zone_id, instance_id, to_string(position).c_str(), is_home); + auto results = QueryDatabase(query); if (!results.RowsAffected()) { LogFile->write(EQEmuLog::Debug, "ERROR Bind Home Save: %s. %s", results.ErrorMessage().c_str(), query.c_str()); } @@ -1240,9 +1247,9 @@ bool ZoneDatabase::SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, u } bool ZoneDatabase::SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color){ - uint8 red = (color & 0x00FF0000) >> 16; + uint8 red = (color & 0x00FF0000) >> 16; uint8 green = (color & 0x0000FF00) >> 8; - uint8 blue = (color & 0x000000FF); + uint8 blue = (color & 0x000000FF); std::string query = StringFormat("REPLACE INTO `character_material` (id, slot, red, green, blue, color, use_tint) VALUES (%u, %u, %u, %u, %u, %u, 255)", character_id, slot_id, red, green, blue, color); auto results = QueryDatabase(query); LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterMaterialColor for character ID: %i, slot_id: %u color: %u done", character_id, slot_id, color); @@ -1256,30 +1263,30 @@ bool ZoneDatabase::SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint } bool ZoneDatabase::SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 disc_id){ - std::string query = StringFormat("REPLACE INTO `character_disciplines` (id, slot_id, disc_id) VALUES (%u, %u, %u)", character_id, slot_id, disc_id); + std::string query = StringFormat("REPLACE INTO `character_disciplines` (id, slot_id, disc_id) VALUES (%u, %u, %u)", character_id, slot_id, disc_id); auto results = QueryDatabase(query); LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterDisc for character ID: %i, slot:%u disc_id:%u done", character_id, slot_id, disc_id); - return true; + return true; } bool ZoneDatabase::SaveCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp){ - std::string query = StringFormat("DELETE FROM `character_tribute` WHERE `id` = %u", character_id); + std::string query = StringFormat("DELETE FROM `character_tribute` WHERE `id` = %u", character_id); QueryDatabase(query); /* Save Tributes only if we have values... */ for (int i = 0; i < EmuConstants::TRIBUTE_SIZE; i++){ if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != TRIBUTE_NONE){ - std::string query = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); + std::string query = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); QueryDatabase(query); LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterTribute for character ID: %i, tier:%u tribute:%u done", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); } - } + } return true; } bool ZoneDatabase::SaveCharacterBandolier(uint32 character_id, uint8 bandolier_id, uint8 bandolier_slot, uint32 item_id, uint32 icon, const char* bandolier_name){ char bandolier_name_esc[64]; DoEscapeString(bandolier_name_esc, bandolier_name, strlen(bandolier_name)); - std::string query = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%u, %u, %u, %u, %u,'%s')", character_id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name_esc); + std::string query = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%u, %u, %u, %u, %u,'%s')", character_id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name_esc); auto results = QueryDatabase(query); LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterBandolier for character ID: %i, bandolier_id: %u, bandolier_slot: %u item_id: %u, icon:%u band_name:%s done", character_id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name); if (!results.RowsAffected()){ std::cout << "ERROR Bandolier Save: " << results.ErrorMessage() << "\n\n" << query << "\n" << std::endl; } @@ -1500,7 +1507,7 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla "%u," // e_aa_effects "%u," // e_percent_to_aa "%u" // e_expended_aa_spent - ")", + ")", character_id, // " id, " account_id, // " account_id, " EscapeString(pp->name).c_str(), // " `name`, " @@ -1652,62 +1659,62 @@ bool ZoneDatabase::SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 cur bool ZoneDatabase::SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id){ if (spell_id > SPDAT_RECORDS){ return false; } - std::string query = StringFormat("REPLACE INTO `character_memmed_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, slot_id, spell_id); - QueryDatabase(query); + std::string query = StringFormat("REPLACE INTO `character_memmed_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, slot_id, spell_id); + QueryDatabase(query); return true; } bool ZoneDatabase::SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id){ if (spell_id > SPDAT_RECORDS){ return false; } - std::string query = StringFormat("REPLACE INTO `character_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, slot_id, spell_id); - QueryDatabase(query); + std::string query = StringFormat("REPLACE INTO `character_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, slot_id, spell_id); + QueryDatabase(query); return true; } bool ZoneDatabase::DeleteCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id){ - std::string query = StringFormat("DELETE FROM `character_spells` WHERE `slot_id` = %u AND `id` = %u", slot_id, character_id); - QueryDatabase(query); + std::string query = StringFormat("DELETE FROM `character_spells` WHERE `slot_id` = %u AND `id` = %u", slot_id, character_id); + QueryDatabase(query); return true; } bool ZoneDatabase::DeleteCharacterDisc(uint32 character_id, uint32 slot_id){ - std::string query = StringFormat("DELETE FROM `character_disciplines` WHERE `slot_id` = %u AND `id` = %u", slot_id, character_id); - QueryDatabase(query); - return true; + std::string query = StringFormat("DELETE FROM `character_disciplines` WHERE `slot_id` = %u AND `id` = %u", slot_id, character_id); + QueryDatabase(query); + return true; } bool ZoneDatabase::DeleteCharacterBandolier(uint32 character_id, uint32 band_id){ - std::string query = StringFormat("DELETE FROM `character_bandolier` WHERE `bandolier_id` = %u AND `id` = %u", band_id, character_id); - QueryDatabase(query); - return true; + std::string query = StringFormat("DELETE FROM `character_bandolier` WHERE `bandolier_id` = %u AND `id` = %u", band_id, character_id); + QueryDatabase(query); + return true; } bool ZoneDatabase::DeleteCharacterLeadershipAAs(uint32 character_id){ - std::string query = StringFormat("DELETE FROM `character_leadership_abilities` WHERE `id` = %u", character_id); - QueryDatabase(query); - return true; + std::string query = StringFormat("DELETE FROM `character_leadership_abilities` WHERE `id` = %u", character_id); + QueryDatabase(query); + return true; } bool ZoneDatabase::DeleteCharacterAAs(uint32 character_id){ - std::string query = StringFormat("DELETE FROM `character_alternate_abilities` WHERE `id` = %u", character_id); - QueryDatabase(query); + std::string query = StringFormat("DELETE FROM `character_alternate_abilities` WHERE `id` = %u", character_id); + QueryDatabase(query); return true; } bool ZoneDatabase::DeleteCharacterDye(uint32 character_id){ std::string query = StringFormat("DELETE FROM `character_material` WHERE `id` = %u", character_id); - QueryDatabase(query); + QueryDatabase(query); return true; } -bool ZoneDatabase::DeleteCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id){ - std::string query = StringFormat("DELETE FROM `character_memmed_spells` WHERE `slot_id` = %u AND `id` = %u", slot_id, character_id); - QueryDatabase(query); +bool ZoneDatabase::DeleteCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id){ + std::string query = StringFormat("DELETE FROM `character_memmed_spells` WHERE `slot_id` = %u AND `id` = %u", slot_id, character_id); + QueryDatabase(query); return true; } bool ZoneDatabase::NoRentExpired(const char* name){ - std::string query = StringFormat("SELECT (UNIX_TIMESTAMP(NOW()) - last_login) FROM `character_data` WHERE name = '%s'", name); + std::string query = StringFormat("SELECT (UNIX_TIMESTAMP(NOW()) - last_login) FROM `character_data` WHERE name = '%s'", name); auto results = QueryDatabase(query); if (!results.Success()) return false; @@ -1884,15 +1891,11 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { armor_tint_id); auto armortint_results = QueryDatabase(armortint_query); if (!armortint_results.Success() || armortint_results.RowCount() == 0) - { - armor_tint_id = 0; - } - else - { + armor_tint_id = 0; + else { auto armorTint_row = armortint_results.begin(); - for (int index = EmuConstants::MATERIAL_BEGIN; index <= EmuConstants::MATERIAL_END; index++) - { + for (int index = EmuConstants::MATERIAL_BEGIN; index <= EmuConstants::MATERIAL_END; index++) { tmpNPCType->armor_tint[index] = atoi(armorTint_row[index * 3]) << 16; tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 1]) << 8; tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 2]); @@ -2163,7 +2166,7 @@ bool ZoneDatabase::LoadMercInfo(Client *client) { auto results = QueryDatabase(query); if (!results.Success()) return false; - + if(results.RowCount() == 0) return false; @@ -2524,10 +2527,11 @@ void ZoneDatabase::DeleteMerchantTemp(uint32 npcid, uint32 slot){ } -bool ZoneDatabase::UpdateZoneSafeCoords(const char* zonename, float x=0, float y=0, float z=0) { +bool ZoneDatabase::UpdateZoneSafeCoords(const char* zonename, const xyz_location& location) { std::string query = StringFormat("UPDATE zone SET safe_x='%f', safe_y='%f', safe_z='%f' " - "WHERE short_name='%s';", x, y, z, zonename); + "WHERE short_name='%s';", + location.m_X, location.m_Y, location.m_Z, zonename); auto results = QueryDatabase(query); if (!results.Success() || results.RowsAffected() == 0) return false; @@ -2719,12 +2723,8 @@ bool ZoneDatabase::LoadBlockedSpells(int32 blockedSpellsCount, ZoneSpellsBlocked memset(&into[index], 0, sizeof(ZoneSpellsBlocked)); into[index].spellid = atoi(row[1]); into[index].type = atoi(row[2]); - into[index].x = atof(row[3]); - into[index].y = atof(row[4]); - into[index].z = atof(row[5]); - into[index].xdiff = atof(row[6]); - into[index].ydiff = atof(row[7]); - into[index].zdiff = atof(row[8]); + into[index].m_Location = xyz_location(atof(row[3]), atof(row[4]), atof(row[5])); + into[index].m_Difference = xyz_location(atof(row[6]), atof(row[7]), atof(row[8])); strn0cpy(into[index].message, row[9], 255); } @@ -2803,7 +2803,7 @@ void ZoneDatabase::QGlobalPurge() database.QueryDatabase(query); } -void ZoneDatabase::InsertDoor(uint32 ddoordbid, uint16 ddoorid, const char* ddoor_name, float dxpos, float dypos, float dzpos, float dheading, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize){ +void ZoneDatabase::InsertDoor(uint32 ddoordbid, uint16 ddoorid, const char* ddoor_name, const xyz_heading& position, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize){ std::string query = StringFormat("REPLACE INTO doors (id, doorid, zone, version, name, " "pos_x, pos_y, pos_z, heading, opentype, guild, lockpick, " @@ -2811,8 +2811,8 @@ void ZoneDatabase::InsertDoor(uint32 ddoordbid, uint16 ddoorid, const char* ddoo "VALUES('%i', '%i', '%s', '%i', '%s', '%f', '%f', " "'%f', '%f', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i')", ddoordbid, ddoorid, zone->GetShortName(), zone->GetInstanceVersion(), - ddoor_name, dxpos, dypos, dzpos, dheading, dopentype, dguildid, - dlockpick, dkeyitem, ddoor_param, dinvert, dincline, dsize); + ddoor_name, position.m_X, position.m_Y, position.m_Z, position.m_Heading, + dopentype, dguildid, dlockpick, dkeyitem, ddoor_param, dinvert, dincline, dsize); auto results = QueryDatabase(query); if (!results.Success()) std::cerr << "Error in InsertDoor" << query << "' " << results.ErrorMessage() << std::endl; @@ -3385,37 +3385,36 @@ bool ZoneDatabase::DeleteGraveyard(uint32 zone_id, uint32 graveyard_id) { if (results.Success() && results2.Success()){ return true; } - + return false; } uint32 ZoneDatabase::AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id) { std::string query = StringFormat( - "UPDATE `zone` SET `graveyard_id` = %u WHERE `zone_idnumber` = %u AND `version` = 0", + "UPDATE `zone` SET `graveyard_id` = %u WHERE `zone_idnumber` = %u AND `version` = 0", graveyard_id, zone_id ); auto results = QueryDatabase(query); return zone_id; } -uint32 ZoneDatabase::CreateGraveyardRecord(uint32 graveyard_zone_id, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading) { - std::string query = StringFormat( - "INSERT INTO `graveyard` SET `zone_id` = %u, `x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f", - graveyard_zone_id, graveyard_x, graveyard_y, graveyard_z, graveyard_heading - ); +uint32 ZoneDatabase::CreateGraveyardRecord(uint32 graveyard_zone_id, const xyz_heading& position) { + std::string query = StringFormat("INSERT INTO `graveyard` " + "SET `zone_id` = %u, `x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f", + graveyard_zone_id, position.m_X, position.m_Y, position.m_Z, position.m_Heading); auto results = QueryDatabase(query); - if (results.Success()){ + if (results.Success()) return results.LastInsertedID(); - } + return 0; } -uint32 ZoneDatabase::SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zone_id, uint16 instance_id, float x, float y, float z, float heading) { - std::string query = StringFormat( - "UPDATE `character_corpses` " - "SET `zone_id` = %u, `instance_id` = 0, `x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f, `was_at_graveyard` = 1 " - "WHERE `id` = %d", - zone_id, x, y, z, heading, dbid - ); +uint32 ZoneDatabase::SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zone_id, uint16 instance_id, const xyz_heading& position) { + std::string query = StringFormat("UPDATE `character_corpses` " + "SET `zone_id` = %u, `instance_id` = 0, " + "`x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f, " + "`was_at_graveyard` = 1 " + "WHERE `id` = %d", + zone_id, position.m_X, position.m_Y, position.m_Z, position.m_Heading, dbid); QueryDatabase(query); return dbid; } @@ -3424,99 +3423,38 @@ uint32 ZoneDatabase::GetCharacterCorpseDecayTimer(uint32 corpse_db_id){ std::string query = StringFormat("SELECT(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) FROM `character_corpses` WHERE `id` = %d AND NOT `time_of_death` = 0", corpse_db_id); auto results = QueryDatabase(query); auto row = results.begin(); - if (results.Success() && results.RowsAffected() != 0){ + if (results.Success() && results.RowsAffected() != 0) return atoul(row[0]); - } + return 0; } -uint32 ZoneDatabase::UpdateCharacterCorpse(uint32 db_id, uint32 char_id, const char* char_name, uint32 zone_id, uint16 instance_id, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading, bool is_rezzed) { - std::string query = StringFormat("UPDATE `character_corpses` SET \n" - "`charname` = '%s',\n" - "`zone_id` = %u,\n" - "`instance_id` = %u,\n" - "`charid` = %d,\n" - "`x` = %1.1f,\n" - "`y` = %1.1f,\n" - "`z` = %1.1f,\n" - "`heading` = %1.1f,\n" - "`is_locked` = %d,\n" - "`exp` = %u,\n" - "`size` = %f,\n" - "`level` = %u,\n" - "`race` = %u,\n" - "`gender` = %u,\n" - "`class` = %u,\n" - "`deity` = %u,\n" - "`texture` = %u,\n" - "`helm_texture` = %u,\n" - "`copper` = %u,\n" - "`silver` = %u,\n" - "`gold` = %u,\n" - "`platinum` = %u,\n" - "`hair_color` = %u,\n" - "`beard_color` = %u,\n" - "`eye_color_1` = %u,\n" - "`eye_color_2` = %u,\n" - "`hair_style` = %u,\n" - "`face` = %u,\n" - "`beard` = %u,\n" - "`drakkin_heritage` = %u,\n" - "`drakkin_tattoo` = %u,\n" - "`drakkin_details` = %u,\n" - "`wc_1` = %u,\n" - "`wc_2` = %u,\n" - "`wc_3` = %u,\n" - "`wc_4` = %u,\n" - "`wc_5` = %u,\n" - "`wc_6` = %u,\n" - "`wc_7` = %u,\n" - "`wc_8` = %u,\n" - "`wc_9` = %u \n" - "WHERE `id` = %u", - EscapeString(char_name).c_str(), - zone_id, - instance_id, - char_id, - x, - y, - z, - heading, - dbpc->locked, - dbpc->exp, - dbpc->size, - dbpc->level, - dbpc->race, - dbpc->gender, - dbpc->class_, - dbpc->deity, - dbpc->texture, - dbpc->helmtexture, - dbpc->copper, - dbpc->silver, - dbpc->gold, - dbpc->plat, - dbpc->haircolor, - dbpc->beardcolor, - dbpc->eyecolor1, - dbpc->eyecolor2, - dbpc->hairstyle, - dbpc->face, - dbpc->beard, - dbpc->drakkin_heritage, - dbpc->drakkin_tattoo, - dbpc->drakkin_details, - dbpc->item_tint[0].color, - dbpc->item_tint[1].color, - dbpc->item_tint[2].color, - dbpc->item_tint[3].color, - dbpc->item_tint[4].color, - dbpc->item_tint[5].color, - dbpc->item_tint[6].color, - dbpc->item_tint[7].color, - dbpc->item_tint[8].color, - db_id - ); +uint32 ZoneDatabase::UpdateCharacterCorpse(uint32 db_id, uint32 char_id, const char* char_name, uint32 zone_id, uint16 instance_id, PlayerCorpse_Struct* dbpc, const xyz_heading& position, bool is_rezzed) { + std::string query = StringFormat("UPDATE `character_corpses` " + "SET `charname` = '%s', `zone_id` = %u, `instance_id` = %u, `charid` = %d, " + "`x` = %1.1f,`y` = %1.1f,`z` = %1.1f, `heading` = %1.1f, " + "`is_locked` = %d, `exp` = %u, `size` = %f, `level` = %u, " + "`race` = %u, `gender` = %u, `class` = %u, `deity` = %u, " + "`texture` = %u, `helm_texture` = %u, `copper` = %u, " + "`silver` = %u, `gold` = %u, `platinum` = %u, `hair_color` = %u, " + "`beard_color` = %u, `eye_color_1` = %u, `eye_color_2` = %u, " + "`hair_style` = %u, `face` = %u, `beard` = %u, `drakkin_heritage` = %u, " + "`drakkin_tattoo` = %u, `drakkin_details` = %u, `wc_1` = %u, " + "`wc_2` = %u, `wc_3` = %u, `wc_4` = %u, `wc_5` = %u, `wc_6` = %u, " + "`wc_7` = %u, `wc_8` = %u, `wc_9` = %u " + "WHERE `id` = %u", + EscapeString(char_name).c_str(), zone_id, instance_id, char_id, + position.m_X, position.m_Y, position.m_Z, position.m_Heading, + dbpc->locked, dbpc->exp, dbpc->size, dbpc->level, dbpc->race, + dbpc->gender, dbpc->class_, dbpc->deity, dbpc->texture, + dbpc->helmtexture, dbpc->copper, dbpc->silver, dbpc->gold, + dbpc->plat, dbpc->haircolor, dbpc->beardcolor, dbpc->eyecolor1, + dbpc->eyecolor2, dbpc->hairstyle, dbpc->face, dbpc->beard, + dbpc->drakkin_heritage, dbpc->drakkin_tattoo, dbpc->drakkin_details, + dbpc->item_tint[0].color, dbpc->item_tint[1].color, dbpc->item_tint[2].color, + dbpc->item_tint[3].color, dbpc->item_tint[4].color, dbpc->item_tint[5].color, + dbpc->item_tint[6].color, dbpc->item_tint[7].color, dbpc->item_tint[8].color, + db_id); auto results = QueryDatabase(query); return db_id; @@ -3527,100 +3465,38 @@ void ZoneDatabase::MarkCorpseAsRezzed(uint32 db_id) { auto results = QueryDatabase(query); } -uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading) { +uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const xyz_heading& position) { /* Dump Basic Corpse Data */ - std::string query = StringFormat("INSERT INTO `character_corpses` SET \n" - "`charname` = '%s',\n" - "`zone_id` = %u,\n" - "`instance_id` = %u,\n" - "`charid` = %d,\n" - "`x` = %1.1f,\n" - "`y` = %1.1f,\n" - "`z` = %1.1f,\n" - "`heading` = %1.1f,\n" - "`time_of_death` = NOW(),\n" - "`is_buried` = 0," - "`is_locked` = %d,\n" - "`exp` = %u,\n" - "`size` = %f,\n" - "`level` = %u,\n" - "`race` = %u,\n" - "`gender` = %u,\n" - "`class` = %u,\n" - "`deity` = %u,\n" - "`texture` = %u,\n" - "`helm_texture` = %u,\n" - "`copper` = %u,\n" - "`silver` = %u,\n" - "`gold` = %u,\n" - "`platinum` = %u,\n" - "`hair_color` = %u,\n" - "`beard_color` = %u,\n" - "`eye_color_1` = %u,\n" - "`eye_color_2` = %u,\n" - "`hair_style` = %u,\n" - "`face` = %u,\n" - "`beard` = %u,\n" - "`drakkin_heritage` = %u,\n" - "`drakkin_tattoo` = %u,\n" - "`drakkin_details` = %u,\n" - "`wc_1` = %u,\n" - "`wc_2` = %u,\n" - "`wc_3` = %u,\n" - "`wc_4` = %u,\n" - "`wc_5` = %u,\n" - "`wc_6` = %u,\n" - "`wc_7` = %u,\n" - "`wc_8` = %u,\n" - "`wc_9` = %u \n", - EscapeString(charname).c_str(), - zoneid, - instanceid, - charid, - x, - y, - z, - heading, - dbpc->locked, - dbpc->exp, - dbpc->size, - dbpc->level, - dbpc->race, - dbpc->gender, - dbpc->class_, - dbpc->deity, - dbpc->texture, - dbpc->helmtexture, - dbpc->copper, - dbpc->silver, - dbpc->gold, - dbpc->plat, - dbpc->haircolor, - dbpc->beardcolor, - dbpc->eyecolor1, - dbpc->eyecolor2, - dbpc->hairstyle, - dbpc->face, - dbpc->beard, - dbpc->drakkin_heritage, - dbpc->drakkin_tattoo, - dbpc->drakkin_details, - dbpc->item_tint[0].color, - dbpc->item_tint[1].color, - dbpc->item_tint[2].color, - dbpc->item_tint[3].color, - dbpc->item_tint[4].color, - dbpc->item_tint[5].color, - dbpc->item_tint[6].color, - dbpc->item_tint[7].color, - dbpc->item_tint[8].color - ); - auto results = QueryDatabase(query); + std::string query = StringFormat("INSERT INTO `character_corpses` " + "SET `charname` = '%s', `zone_id` = %u, `instance_id` = %u, `charid` = %d," + "`x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f," + "`time_of_death` = NOW(), `is_buried` = 0, `is_locked` = %d," + "`exp` = %u, `size` = %f, `level` = %u, `race` = %u, `gender` = %u," + "`class` = %u, `deity` = %u, `texture` = %u, `helm_texture` = %u," + "`copper` = %u, `silver` = %u,`gold` = %u,`platinum` = %u," + "`hair_color` = %u, `beard_color` = %u, `eye_color_1` = %u," + "`eye_color_2` = %u, `hair_style` = %u, `face` = %u," + "`beard` = %u, `drakkin_heritage` = %u, `drakkin_tattoo` = %u," + "`drakkin_details` = %u, `wc_1` = %u, `wc_2` = %u," + "`wc_3` = %u, `wc_4` = %u, `wc_5` = %u, `wc_6` = %u," + "`wc_7` = %u,`wc_8` = %u,`wc_9` = %u", + EscapeString(charname).c_str(), zoneid, instanceid, charid, + position.m_X, position.m_Y, position.m_Z, position.m_Heading, + dbpc->locked, dbpc->exp, dbpc->size, dbpc->level, dbpc->race, + dbpc->gender, dbpc->class_, dbpc->deity, dbpc->texture, + dbpc->helmtexture, dbpc->copper, dbpc->silver, dbpc->gold, + dbpc->plat, dbpc->haircolor, dbpc->beardcolor, dbpc->eyecolor1, + dbpc->eyecolor2, dbpc->hairstyle, dbpc->face, dbpc->beard, + dbpc->drakkin_heritage, dbpc->drakkin_tattoo, dbpc->drakkin_details, + dbpc->item_tint[0].color, dbpc->item_tint[1].color, dbpc->item_tint[2].color, + dbpc->item_tint[3].color, dbpc->item_tint[4].color, dbpc->item_tint[5].color, + dbpc->item_tint[6].color, dbpc->item_tint[7].color, dbpc->item_tint[8].color); + auto results = QueryDatabase(query); uint32 last_insert_id = results.LastInsertedID(); /* Dump Items from Inventory */ uint8 first_entry = 0; - for (unsigned int i = 0; i < dbpc->itemcount; i++) { + for (unsigned int i = 0; i < dbpc->itemcount; i++) { if (first_entry != 1){ query = StringFormat("REPLACE INTO `character_corpse_items` \n" " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n" @@ -3655,13 +3531,13 @@ uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, ui ); } } - auto sc_results = QueryDatabase(query); + auto sc_results = QueryDatabase(query); return last_insert_id; } uint32 ZoneDatabase::GetCharacterBuriedCorpseCount(uint32 char_id) { std::string query = StringFormat("SELECT COUNT(*) FROM `character_corpses` WHERE `charid` = '%u' AND `is_buried` = 1", char_id); - auto results = QueryDatabase(query); + auto results = QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { return atoi(row[0]); @@ -3671,7 +3547,7 @@ uint32 ZoneDatabase::GetCharacterBuriedCorpseCount(uint32 char_id) { uint32 ZoneDatabase::GetCharacterCorpseCount(uint32 char_id) { std::string query = StringFormat("SELECT COUNT(*) FROM `character_corpses` WHERE `charid` = '%u'", char_id); - auto results = QueryDatabase(query); + auto results = QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { return atoi(row[0]); @@ -3755,7 +3631,7 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct "WHERE `id` = %u LIMIT 1\n", corpse_id ); - auto results = QueryDatabase(query); + auto results = QueryDatabase(query); uint16 i = 0; for (auto row = results.begin(); row != results.end(); ++row) { pcs->locked = atoi(row[i++]); // is_locked, @@ -3812,7 +3688,7 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct ); results = QueryDatabase(query); - i = 0; + i = 0; pcs->itemcount = results.RowCount(); uint16 r = 0; for (auto row = results.begin(); row != results.end(); ++row) { @@ -3834,72 +3710,68 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct return true; } -Corpse* ZoneDatabase::SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, float dest_x, float dest_y, float dest_z, float dest_heading) { - Corpse* NewCorpse = 0; - std::string query = StringFormat( - "SELECT `id`, `charname`, `time_of_death`, `is_rezzed` FROM `character_corpses` WHERE `charid` = '%u' AND `is_buried` = 1 ORDER BY `time_of_death` LIMIT 1", - char_id - ); +Corpse* ZoneDatabase::SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, const xyz_heading& position) { + Corpse* corpse = nullptr; + std::string query = StringFormat("SELECT `id`, `charname`, `time_of_death`, `is_rezzed` " + "FROM `character_corpses` " + "WHERE `charid` = '%u' AND `is_buried` = 1 " + "ORDER BY `time_of_death` LIMIT 1", + char_id); auto results = QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { - NewCorpse = Corpse::LoadCharacterCorpseEntity( + corpse = Corpse::LoadCharacterCorpseEntity( atoul(row[0]), // uint32 in_dbid char_id, // uint32 in_charid row[1], // char* in_charname - dest_x, // float in_x - dest_y, // float in_y - dest_z, // float in_z - dest_heading, // float in_heading + position, row[2], // char* time_of_death atoi(row[3]) == 1, // bool rezzed false // bool was_at_graveyard ); - if (NewCorpse) { - entity_list.AddCorpse(NewCorpse); - NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); - NewCorpse->Spawn(); - if (!UnburyCharacterCorpse(NewCorpse->GetCorpseDBID(), dest_zone_id, dest_instance_id, dest_x, dest_y, dest_z, dest_heading)) - LogFile->write(EQEmuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id); - } + if (!corpse) + continue; + + entity_list.AddCorpse(corpse); + corpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); + corpse->Spawn(); + if (!UnburyCharacterCorpse(corpse->GetCorpseDBID(), dest_zone_id, dest_instance_id, position)) + LogFile->write(EQEmuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id); } - return NewCorpse; + return corpse; } -bool ZoneDatabase::SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, float dest_x, float dest_y, float dest_z, float dest_heading) { - Corpse* NewCorpse = 0; +bool ZoneDatabase::SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, const xyz_heading& position) { + Corpse* corpse = nullptr; int CorpseCount = 0; std::string query = StringFormat( "UPDATE character_corpses SET zone_id = %i, instance_id = %i, x = %f, y = %f, z = %f, heading = %f, is_buried = 0, was_at_graveyard = 0 WHERE charid = %i", - dest_zone_id, dest_instance_id, dest_x, dest_y, dest_z, dest_heading, char_id + dest_zone_id, dest_instance_id, position.m_X, position.m_Y, position.m_Z, position.m_Heading, char_id ); auto results = QueryDatabase(query); query = StringFormat( "SELECT `id`, `charname`, `time_of_death`, `is_rezzed` FROM `character_corpses` WHERE `charid` = '%u'" - "ORDER BY time_of_death", - char_id - ); + "ORDER BY time_of_death", + char_id); results = QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { - NewCorpse = Corpse::LoadCharacterCorpseEntity( + corpse = Corpse::LoadCharacterCorpseEntity( atoul(row[0]), char_id, row[1], - dest_x, - dest_y, - dest_z, - dest_heading, + position, row[2], atoi(row[3]) == 1, false); - if (NewCorpse) { - entity_list.AddCorpse(NewCorpse); - NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); - NewCorpse->Spawn(); + + if (corpse) { + entity_list.AddCorpse(corpse); + corpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); + corpse->Spawn(); ++CorpseCount; } else{ @@ -3910,34 +3782,35 @@ bool ZoneDatabase::SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zone_id return (CorpseCount > 0); } -bool ZoneDatabase::UnburyCharacterCorpse(uint32 db_id, uint32 new_zone_id, uint16 new_instance_id, float new_x, float new_y, float new_z, float new_heading) { - std::string query = StringFormat( - "UPDATE `character_corpses` SET `is_buried` = 0, `zone_id` = %u, `instance_id` = %u, `x` = %f, `y` = %f, `z` = %f, `heading` = %f, `time_of_death` = Now(), `was_at_graveyard` = 0 WHERE `id` = %u", - new_zone_id, new_instance_id, new_x, new_y, new_z, new_heading, db_id - ); +bool ZoneDatabase::UnburyCharacterCorpse(uint32 db_id, uint32 new_zone_id, uint16 new_instance_id, const xyz_heading& position) { + std::string query = StringFormat("UPDATE `character_corpses` " + "SET `is_buried` = 0, `zone_id` = %u, `instance_id` = %u, " + "`x` = %f, `y` = %f, `z` = %f, `heading` = %f, " + "`time_of_death` = Now(), `was_at_graveyard` = 0 " + "WHERE `id` = %u", + new_zone_id, new_instance_id, + position.m_X, position.m_Y, position.m_Z, position.m_Heading, db_id); auto results = QueryDatabase(query); - if (results.Success() && results.RowsAffected() != 0){ + if (results.Success() && results.RowsAffected() != 0) return true; - } + return false; } Corpse* ZoneDatabase::LoadCharacterCorpse(uint32 player_corpse_id) { Corpse* NewCorpse = 0; std::string query = StringFormat( - "SELECT `id`, `charid`, `charname`, `x`, `y`, `z`, `heading`, `time_of_death`, `is_rezzed`, `was_at_graveyard` FROM `character_corpses` WHERE `id` = '%u' LIMIT 1", + "SELECT `id`, `charid`, `charname`, `x`, `y`, `z`, `heading`, `time_of_death`, `is_rezzed`, `was_at_graveyard` FROM `character_corpses` WHERE `id` = '%u' LIMIT 1", player_corpse_id ); auto results = QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { + auto position = xyz_heading(atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6])); NewCorpse = Corpse::LoadCharacterCorpseEntity( atoul(row[0]), // id uint32 in_dbid atoul(row[1]), // charid uint32 in_charid row[2], // char_name - atof(row[3]), // x float in_x - atof(row[4]), // y float in_y - atof(row[5]), // z float in_z - atof(row[6]), // heading float in_heading + position, row[7], // time_of_death char* time_of_death atoi(row[8]) == 1, // is_rezzed bool rezzed atoi(row[9]) // was_at_graveyard bool was_at_graveyard @@ -3948,7 +3821,7 @@ Corpse* ZoneDatabase::LoadCharacterCorpse(uint32 player_corpse_id) { } bool ZoneDatabase::LoadCharacterCorpses(uint32 zone_id, uint16 instance_id) { - std::string query; + std::string query; if (!RuleB(Zone, EnableShadowrest)){ query = StringFormat("SELECT id, charid, charname, x, y, z, heading, time_of_death, is_rezzed, was_at_graveyard FROM character_corpses WHERE zone_id='%u' AND instance_id='%u'", zone_id, instance_id); } @@ -3958,15 +3831,13 @@ bool ZoneDatabase::LoadCharacterCorpses(uint32 zone_id, uint16 instance_id) { auto results = QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { + auto position = xyz_heading(atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6])); entity_list.AddCorpse( Corpse::LoadCharacterCorpseEntity( atoul(row[0]), // id uint32 in_dbid atoul(row[1]), // charid uint32 in_charid - row[2], // char_name - atof(row[3]), // x float in_x - atof(row[4]), // y float in_y - atof(row[5]), // z float in_z - atof(row[6]), // heading float in_heading + row[2], // char_name + position, row[7], // time_of_death char* time_of_death atoi(row[8]) == 1, // is_rezzed bool rezzed atoi(row[9])) @@ -3977,7 +3848,7 @@ bool ZoneDatabase::LoadCharacterCorpses(uint32 zone_id, uint16 instance_id) { } uint32 ZoneDatabase::GetFirstCorpseID(uint32 char_id) { - std::string query = StringFormat("SELECT `id` FROM `character_corpses` WHERE `charid` = '%u' AND `is_buried` = 0 ORDER BY `time_of_death` LIMIT 1", char_id); + std::string query = StringFormat("SELECT `id` FROM `character_corpses` WHERE `charid` = '%u' AND `is_buried` = 0 ORDER BY `time_of_death` LIMIT 1", char_id); auto results = QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { return atoi(row[0]); @@ -4016,8 +3887,8 @@ bool ZoneDatabase::BuryAllCharacterCorpses(uint32 char_id) { bool ZoneDatabase::DeleteCharacterCorpse(uint32 db_id) { std::string query = StringFormat("DELETE FROM `character_corpses` WHERE `id` = %d", db_id); auto results = QueryDatabase(query); - if (results.Success() && results.RowsAffected() != 0){ + if (results.Success() && results.RowsAffected() != 0) return true; - } + return false; } diff --git a/zone/zonedb.h b/zone/zonedb.h index 1c103074a..ade485326 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -3,6 +3,7 @@ #include "../common/shareddb.h" #include "../common/eq_packet_structs.h" +#include "position.h" #include "../common/faction.h" class Client; @@ -129,12 +130,8 @@ struct PetInfo { struct ZoneSpellsBlocked { uint32 spellid; int8 type; - float x; - float y; - float z; - float xdiff; - float ydiff; - float zdiff; + xyz_location m_Location; + xyz_location m_Difference; char message[256]; }; @@ -235,7 +232,7 @@ public: /* Traders */ void SaveTraderItem(uint32 char_id,uint32 itemid,uint32 uniqueid, int32 charges,uint32 itemcost,uint8 slot); void UpdateTraderItemCharges(int char_id, uint32 ItemInstID, int32 charges); - void UpdateTraderItemPrice(int CharID, uint32 ItemID, uint32 Charges, uint32 NewPrice); + void UpdateTraderItemPrice(int CharID, uint32 ItemID, uint32 Charges, uint32 NewPrice); void DeleteTraderItem(uint32 char_id); void DeleteTraderItem(uint32 char_id,uint16 slot_id); @@ -276,7 +273,7 @@ public: bool LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp); /* Character Data Saves */ - bool SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, float x, float y, float z, float heading, uint8 is_home); + bool SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, const xyz_heading& position, uint8 is_home); 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); @@ -308,24 +305,24 @@ public: uint32 GetCharacterCorpseItemCount(uint32 corpse_id); bool LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs); Corpse* LoadCharacterCorpse(uint32 player_corpse_id); - Corpse* SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); + Corpse* SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, const xyz_heading& position); void MarkCorpseAsRezzed(uint32 dbid); - bool GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes); + bool GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes); bool BuryCharacterCorpse(uint32 dbid); bool BuryAllCharacterCorpses(uint32 charid); - bool DeleteCharacterCorpse(uint32 dbid); - bool SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); - bool SummonAllGraveyardCorpses(uint32 cur_zoneid, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); - bool UnburyCharacterCorpse(uint32 dbid, uint32 new_zoneid, uint16 dest_instanceid, float new_x, float new_y, float new_z, float new_heading); - bool LoadCharacterCorpses(uint32 iZoneID, uint16 iInstanceID); + bool DeleteCharacterCorpse(uint32 dbid); + bool SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, const xyz_heading& position); + bool SummonAllGraveyardCorpses(uint32 cur_zoneid, uint32 dest_zoneid, uint16 dest_instanceid, const xyz_heading& position); + bool UnburyCharacterCorpse(uint32 dbid, uint32 new_zoneid, uint16 dest_instanceid, const xyz_heading& position); + bool LoadCharacterCorpses(uint32 iZoneID, uint16 iInstanceID); bool DeleteGraveyard(uint32 zone_id, uint32 graveyard_id); uint32 GetCharacterCorpseDecayTimer(uint32 corpse_db_id); uint32 GetCharacterBuriedCorpseCount(uint32 char_id); - uint32 SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zoneid, uint16 instanceid, float x, float y, float z, float heading); - uint32 CreateGraveyardRecord(uint32 graveyard_zoneid, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading); + uint32 SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zoneid, uint16 instanceid, const xyz_heading& position); + uint32 CreateGraveyardRecord(uint32 graveyard_zoneid, const xyz_heading& position); uint32 AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id); - uint32 SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading); - uint32 UpdateCharacterCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading, bool rezzed = false); + uint32 SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const xyz_heading& position); + uint32 UpdateCharacterCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const xyz_heading& position, bool rezzed = false); uint32 GetFirstCorpseID(uint32 char_id); uint32 GetCharacterCorpseCount(uint32 char_id); uint32 GetCharacterCorpseID(uint32 char_id, uint8 corpse); @@ -356,7 +353,7 @@ public: bool GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct *data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city, bool &is_hotzone, bool &allow_mercs, uint8 &zone_type, int &ruleset, char **map_filename); bool SaveZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct* zd); bool LoadStaticZonePoints(LinkedList* zone_point_list,const char* zonename, uint32 version); - bool UpdateZoneSafeCoords(const char* zonename, float x, float y, float z); + bool UpdateZoneSafeCoords(const char* zonename, const xyz_location& location); uint8 GetUseCFGSafeCoords(); int getZoneShutDownDelay(uint32 zoneID, uint32 version); @@ -365,7 +362,7 @@ public: bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list); bool PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version, uint32 repopdelay = 0); Spawn2* LoadSpawn2(LinkedList &spawn2_list, uint32 spawn2id, uint32 timeleft); - bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value); + bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, const xyz_heading& position, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value); void UpdateSpawn2Timeleft(uint32 id, uint16 instance_id,uint32 timeleft); uint32 GetSpawnTimeLeft(uint32 id, uint16 instance_id); void UpdateSpawn2Status(uint32 id, uint8 new_status); @@ -374,19 +371,19 @@ public: uint32 GetFreeGrid(uint16 zoneid); void DeleteGrid(Client *c, uint32 sg2, uint32 grid_num, bool grid_too, uint16 zoneid); void DeleteWaypoint(Client *c, uint32 grid_num, uint32 wp_num, uint16 zoneid); - void AddWP(Client *c, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading); - uint32 AddWPForSpawn(Client *c, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading); + void AddWP(Client *c, uint32 gridid, uint32 wpnum, const xyz_heading& position, uint32 pause, uint16 zoneid); + uint32 AddWPForSpawn(Client *c, uint32 spawn2id, const xyz_heading& position, uint32 pause, int type1, int type2, uint16 zoneid); void ModifyGrid(Client *c, bool remove, uint32 id, uint8 type = 0, uint8 type2 = 0, uint16 zoneid = 0); - void ModifyWP(Client *c, uint32 grid_id, uint32 wp_num, float xpos, float ypos, float zpos, uint32 script = 0, uint16 zoneid = 0); + void ModifyWP(Client *c, uint32 grid_id, uint32 wp_num, const xyz_location& location, uint32 script = 0, uint16 zoneid = 0); uint8 GetGridType(uint32 grid, uint32 zoneid); uint8 GetGridType2(uint32 grid, uint16 zoneid); bool GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp); - void AssignGrid(Client *client, float x, float y, uint32 id); + void AssignGrid(Client *client, const xy_location& location, uint32 id); int GetHighestGrid(uint32 zoneid); int GetHighestWaypoint(uint32 zoneid, uint32 gridid); /* NPCs */ - + uint32 NPCSpawnDB(uint8 command, const char* zone, uint32 zone_version, Client *c, NPC* spawn = 0, uint32 extra = 0); // 0 = Create 1 = Add; 2 = Update; 3 = Remove; 4 = Delete uint32 CreateNewNPCCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 extra); uint32 AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime); @@ -453,7 +450,7 @@ public: int32 GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version); int32 GetDoorsCountPlusOne(const char *zone_name, int16 version); int32 GetDoorsDBCountPlusOne(const char *zone_name, int16 version); - void InsertDoor(uint32 did, uint16 ddoorid, const char* ddoor_name, float dxpos, float dypos, float dzpos, float dheading, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize); + void InsertDoor(uint32 did, uint16 ddoorid, const char* ddoor_name, const xyz_heading& position, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize); /* Blocked Spells */ int32 GetBlockedSpellsCount(uint32 zoneid); diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 9566a9a5c..f50c6b798 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -124,7 +124,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { return; } - zone_point = zone->GetClosestZonePoint(GetX(), GetY(), GetZ(), target_zone_id, this, ZONEPOINT_ZONE_RANGE); + zone_point = zone->GetClosestZonePoint(GetPosition(), target_zone_id, this, ZONEPOINT_ZONE_RANGE); //if we didnt get a zone point, or its to a different zone, //then we assume this is invalid. if(!zone_point || zone_point->target_zone_id != target_zone_id) { @@ -198,9 +198,9 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { dest_z = safe_z; break; case GMSummon: - dest_x = zonesummon_x; - dest_y = zonesummon_y; - dest_z = zonesummon_z; + dest_x = m_ZoneSummonLocation.m_X; + dest_y = m_ZoneSummonLocation.m_Y; + dest_z = m_ZoneSummonLocation.m_Z; ignorerestrictions = 1; break; case GateToBindPoint: @@ -216,9 +216,9 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { break; case ZoneSolicited: //we told the client to zone somewhere, so we know where they are going. //recycle zonesummon variables - dest_x = zonesummon_x; - dest_y = zonesummon_y; - dest_z = zonesummon_z; + dest_x = m_ZoneSummonLocation.m_X; + dest_y = m_ZoneSummonLocation.m_Y; + dest_z = m_ZoneSummonLocation.m_Z; break; case ZoneUnsolicited: //client came up with this on its own. //client requested a zoning... what are the cases when this could happen? @@ -350,16 +350,16 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc //set the player's coordinates in the new zone so they have them //when they zone into it - x_pos = dest_x; //these coordinates will now be saved when ~client is called - y_pos = dest_y; - z_pos = dest_z; - heading = dest_h; // Cripp: fix for zone heading + m_Position.m_X = dest_x; //these coordinates will now be saved when ~client is called + m_Position.m_Y = dest_y; + m_Position.m_Z = dest_z; + m_Position.m_Heading = dest_h; // Cripp: fix for zone heading m_pp.heading = dest_h; m_pp.zone_id = zone_id; m_pp.zoneInstance = instance_id; //Force a save so its waiting for them when they zone - Save(2); + Save(2); if (zone_id == zone->GetZoneID() && instance_id == zone->GetInstanceID()) { // No need to ask worldserver if we're zoning to ourselves (most @@ -394,9 +394,7 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc //reset to unsolicited. zone_mode = ZoneUnsolicited; - zonesummon_x = 0; - zonesummon_y = 0; - zonesummon_z = 0; + m_ZoneSummonLocation = xyz_location::Origin(); zonesummon_id = 0; zonesummon_ignorerestrictions = 0; } @@ -493,59 +491,53 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z return; } iZoneNameLength = strlen(pZoneName); + xyz_heading safePoint; switch(zm) { case EvacToSafeCoords: case ZoneToSafeCoords: - x = zone->safe_x(); - y = zone->safe_y(); - z = zone->safe_z(); + safePoint = zone->GetSafePoint(); + x = safePoint.m_X; + y = safePoint.m_Y; + z = safePoint.m_Z; SetHeading(heading); break; case GMSummon: - zonesummon_x = x_pos = x; - zonesummon_y = y_pos = y; - zonesummon_z = z_pos = z; + m_ZoneSummonLocation = m_Position = xyz_heading(x,y,z,heading); SetHeading(heading); zonesummon_id = zoneID; zonesummon_ignorerestrictions = 1; break; case ZoneSolicited: - zonesummon_x = x; - zonesummon_y = y; - zonesummon_z = z; + m_ZoneSummonLocation = xyz_location(x,y,z); SetHeading(heading); zonesummon_id = zoneID; zonesummon_ignorerestrictions = ignorerestrictions; break; case GateToBindPoint: - x = x_pos = m_pp.binds[0].x; - y = y_pos = m_pp.binds[0].y; - z = z_pos = m_pp.binds[0].z; + x = m_Position.m_X = m_pp.binds[0].x; + y = m_Position.m_Y = m_pp.binds[0].y; + z = m_Position.m_Z = m_pp.binds[0].z; heading = m_pp.binds[0].heading; break; case ZoneToBindPoint: - x = x_pos = m_pp.binds[0].x; - y = y_pos = m_pp.binds[0].y; - z = z_pos = m_pp.binds[0].z; + x = m_Position.m_X = m_pp.binds[0].x; + y = m_Position.m_Y = m_pp.binds[0].y; + z = m_Position.m_Z = m_pp.binds[0].z; heading = m_pp.binds[0].heading; zonesummon_ignorerestrictions = 1; LogFile->write(EQEmuLog::Debug, "Player %s has died and will be zoned to bind point in zone: %s at LOC x=%f, y=%f, z=%f, heading=%f", GetName(), pZoneName, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, m_pp.binds[0].heading); break; case SummonPC: - zonesummon_x = x_pos = x; - zonesummon_y = y_pos = y; - zonesummon_z = z_pos = z; + m_ZoneSummonLocation = m_Position = xyz_location(x, y, z); SetHeading(heading); break; case Rewind: - LogFile->write(EQEmuLog::Debug, "%s has requested a /rewind from %f, %f, %f, to %f, %f, %f in %s", GetName(), x_pos, y_pos, z_pos, rewind_x, rewind_y, rewind_z, zone->GetShortName()); - zonesummon_x = x_pos = x; - zonesummon_y = y_pos = y; - zonesummon_z = z_pos = z; + LogFile->write(EQEmuLog::Debug, "%s has requested a /rewind from %f, %f, %f, to %f, %f, %f in %s", GetName(), m_Position.m_X, m_Position.m_Y, m_Position.m_Z, m_RewindLocation.m_X, m_RewindLocation.m_Y, m_RewindLocation.m_Z, zone->GetShortName()); + m_ZoneSummonLocation = m_Position = xyz_location(x, y, z); SetHeading(heading); break; default: @@ -655,10 +647,8 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z else { if(zoneID == GetZoneID()) { //properly handle proximities - entity_list.ProcessMove(this, x_pos, y_pos, z_pos); - proximity_x = x_pos; - proximity_y = y_pos; - proximity_z = z_pos; + entity_list.ProcessMove(this, m_Position); + m_Proximity = m_Position; //send out updates to people in zone. SendPosition(); @@ -687,9 +677,7 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z { if(zm != EvacToSafeCoords && zm != ZoneToSafeCoords && zm != ZoneToBindPoint) { - zonesummon_x = 0; - zonesummon_y = 0; - zonesummon_z = 0; + m_ZoneSummonLocation = xyz_location::Origin(); zonesummon_id = 0; zonesummon_ignorerestrictions = 0; zone_mode = ZoneUnsolicited; @@ -722,22 +710,23 @@ void NPC::Gate() { Mob::Gate(); } -void Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y, float new_z) { +void Client::SetBindPoint(int to_zone, int to_instance, const xyz_location& location) { if (to_zone == -1) { m_pp.binds[0].zoneId = zone->GetZoneID(); m_pp.binds[0].instance_id = (zone->GetInstanceID() != 0 && zone->IsInstancePersistent()) ? zone->GetInstanceID() : 0; - m_pp.binds[0].x = x_pos; - m_pp.binds[0].y = y_pos; - m_pp.binds[0].z = z_pos; + m_pp.binds[0].x = m_Position.m_X; + m_pp.binds[0].y = m_Position.m_Y; + m_pp.binds[0].z = m_Position.m_Z; } else { m_pp.binds[0].zoneId = to_zone; m_pp.binds[0].instance_id = to_instance; - m_pp.binds[0].x = new_x; - m_pp.binds[0].y = new_y; - m_pp.binds[0].z = new_z; + m_pp.binds[0].x = location.m_X; + m_pp.binds[0].y = location.m_Y; + m_pp.binds[0].z = location.m_Z; } - database.SaveCharacterBindPoint(this->CharacterID(), m_pp.binds[0].zoneId, m_pp.binds[0].instance_id, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0, 0); + auto regularBindPoint = xyz_heading(m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0.0f); + database.SaveCharacterBindPoint(this->CharacterID(), m_pp.binds[0].zoneId, m_pp.binds[0].instance_id, regularBindPoint, 0); } void Client::GoToBind(uint8 bindnum) {