Merge pull request #313 from addtheice/data_bundling

Data bundling
This commit is contained in:
Michael Cook (mackal) 2015-01-17 17:30:14 -05:00
commit fd77fbf163
60 changed files with 1772 additions and 1974 deletions

View File

@ -92,6 +92,7 @@ SET(zone_sources
perlpacket.cpp perlpacket.cpp
petitions.cpp petitions.cpp
pets.cpp pets.cpp
position.cpp
qglobals.cpp qglobals.cpp
queryserv.cpp queryserv.cpp
questmgr.cpp questmgr.cpp
@ -183,6 +184,7 @@ SET(zone_headers
perlpacket.h perlpacket.h
petitions.h petitions.h
pets.h pets.h
position.h
qglobals.h qglobals.h
quest_interface.h quest_interface.h
queryserv.h queryserv.h

View File

@ -546,12 +546,12 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
if(summon_count > MAX_SWARM_PETS) if(summon_count > MAX_SWARM_PETS)
summon_count = MAX_SWARM_PETS; summon_count = MAX_SWARM_PETS;
static const float swarm_pet_x[MAX_SWARM_PETS] = { 5, -5, 5, -5, static const xy_location swarmPetLocations[MAX_SWARM_PETS] = {
10, -10, 10, -10, {5, 5}, {-5, 5}, {5, -5}, {-5, -5},
8, -8, 8, -8 }; {10, 10}, {-10, 10}, {10, -10}, {-10, -10},
static const float swarm_pet_y[MAX_SWARM_PETS] = { 5, 5, -5, -5, {8, 8}, {-8, 8}, {8, -8}, {-8, -8}
10, 10, -10, -10, };
8, 8, -8, -8 };
while(summon_count > 0) { while(summon_count > 0) {
int pet_duration = pet.duration; int pet_duration = pet.duration;
if(duration_override > 0) 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* npca = new NPC(
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer (npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
0, 0,
GetX()+swarm_pet_x[summon_count], GetY()+swarm_pet_y[summon_count], GetPosition() + swarmPetLocations[summon_count],
GetZ(), GetHeading(), FlyMode3); FlyMode3);
if (followme) if (followme)
npca->SetFollowID(GetID()); npca->SetFollowID(GetID());
@ -643,12 +643,11 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
if(summon_count > MAX_SWARM_PETS) if(summon_count > MAX_SWARM_PETS)
summon_count = MAX_SWARM_PETS; summon_count = MAX_SWARM_PETS;
static const float swarm_pet_x[MAX_SWARM_PETS] = { 5, -5, 5, -5, static const xy_location swarmPetLocations[MAX_SWARM_PETS] = {
10, -10, 10, -10, {5, 5}, {-5, 5}, {5, -5}, {-5, -5},
8, -8, 8, -8 }; {10, 10}, {-10, 10}, {10, -10}, {-10, -10},
static const float swarm_pet_y[MAX_SWARM_PETS] = { 5, 5, -5, -5, {8, 8}, {-8, 8}, {8, -8}, {-8, -8}
10, 10, -10, -10, };
8, 8, -8, -8 };
while(summon_count > 0) { while(summon_count > 0) {
int pet_duration = pet.duration; 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* npca = new NPC(
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer (npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
0, 0,
GetX()+swarm_pet_x[summon_count], GetY()+swarm_pet_y[summon_count], GetPosition()+swarmPetLocations[summon_count],
GetZ(), GetHeading(), FlyMode3); FlyMode3);
if (followme) if (followme)
npca->SetFollowID(GetID()); 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_texture1 = 0;
make_npc->d_melee_texture2 = 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()){ if(!npca->GetSwarmInfo()){
AA_SwarmPetInfo* nSI = new AA_SwarmPetInfo; AA_SwarmPetInfo* nSI = new AA_SwarmPetInfo;

View File

@ -2471,7 +2471,7 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
} }
if(IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { if(IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
if(!zone->watermap->InLiquid(other->GetX(), other->GetY(), other->GetZ())) { if(!zone->watermap->InLiquid(other->GetPosition())) {
return; return;
} }
} }

View File

@ -53,7 +53,7 @@ extern Zone* zone;
Beacon::Beacon(Mob *at_mob, int lifetime) Beacon::Beacon(Mob *at_mob, int lifetime)
:Mob :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 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), remove_timer(lifetime),
@ -67,12 +67,6 @@ Beacon::Beacon(Mob *at_mob, int lifetime)
spell_iterations = 0; spell_iterations = 0;
caster_id = 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) if(lifetime)
{ {
remove_timer.Start(); remove_timer.Start();

View File

@ -9,7 +9,7 @@
extern volatile bool ZoneLoaded; extern volatile bool ZoneLoaded;
// This constructor is used during the bot create command // 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) { if(botOwner) {
this->SetBotOwner(botOwner); this->SetBotOwner(botOwner);
this->_botOwnerCharacterID = botOwner->CharacterID(); 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 // 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; this->_botOwnerCharacterID = botOwnerCharacterID;
if(this->_botOwnerCharacterID > 0) { if(this->_botOwnerCharacterID > 0) {
@ -3354,7 +3354,7 @@ void Bot::AI_Process() {
if(GetHasBeenSummoned()) { if(GetHasBeenSummoned()) {
if(IsBotCaster() || IsBotArcher()) { if(IsBotCaster() || IsBotArcher()) {
if (AImovement_timer->Check()) { 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()) if(GetTarget())
FaceTarget(GetTarget()); FaceTarget(GetTarget());
SetHasBeenSummoned(false); SetHasBeenSummoned(false);
@ -3363,8 +3363,8 @@ void Bot::AI_Process() {
if(GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this) if(GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this)
{ {
mlog(AI__WAYPOINTS, "Returning to location prior to being summoned."); mlog(AI__WAYPOINTS, "Returning to location prior to being summoned.");
CalculateNewPosition2(GetPreSummonX(), GetPreSummonY(), GetPreSummonZ(), GetRunspeed()); CalculateNewPosition2(m_PreSummonLocation.m_X, m_PreSummonLocation.m_Y, m_PreSummonLocation.m_Z, GetRunspeed());
SetHeading(CalculateHeadingToTarget(GetPreSummonX(), GetPreSummonY())); SetHeading(CalculateHeadingToTarget(m_PreSummonLocation.m_X, m_PreSummonLocation.m_Y));
return; return;
} }
} }
@ -4105,9 +4105,9 @@ void Bot::Spawn(Client* botCharacterOwner, std::string* errorMessage) {
this->GetBotOwner()->CastToClient()->Message(13, "%s save failed!", this->GetCleanName()); this->GetBotOwner()->CastToClient()->Message(13, "%s save failed!", this->GetCleanName());
// Spawn the bot at the bow owner's loc // Spawn the bot at the bow owner's loc
this->x_pos = botCharacterOwner->GetX(); this->m_Position.m_X = botCharacterOwner->GetX();
this->y_pos = botCharacterOwner->GetY(); this->m_Position.m_Y = botCharacterOwner->GetY();
this->z_pos = botCharacterOwner->GetZ(); this->m_Position.m_Z = botCharacterOwner->GetZ();
// Make the bot look at the bot owner // Make the bot look at the bot owner
FaceTarget(botCharacterOwner); 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 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; 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", 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); 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()) { if(botMember->GetBotOwnerCharacterID() == client->CharacterID()) {
botMember->SetTarget(botMember->GetBotOwner()); botMember->SetTarget(botMember->GetBotOwner());
botMember->WipeHateList(); botMember->WipeHateList();
botMember->Warp(botMember->GetBotOwner()->GetX(), botMember->GetBotOwner()->GetY(), botMember->GetBotOwner()->GetZ()); botMember->Warp(botMember->GetBotOwner()->GetPosition());
if(botMember->HasPet() && botMember->GetPet()) { if(botMember->HasPet() && botMember->GetPet()) {
botMember->GetPet()->SetTarget(botMember); botMember->GetPet()->SetTarget(botMember);
botMember->GetPet()->WipeHateList(); 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 else
{ {
b->SetTarget(c->CastToMob()); b->SetTarget(c->CastToMob());
b->Warp(c->GetX(), c->GetY(), c->GetZ()); b->Warp(c->GetPosition());
} }
} }
} }
@ -15741,19 +15741,19 @@ std::list<Bot*> EntityList::GetBotsByBotOwnerCharacterID(uint32 botOwnerCharacte
void EntityList::BotPickLock(Bot* rogue) void EntityList::BotPickLock(Bot* rogue)
{ {
auto it = door_list.begin();
for (auto it = door_list.begin(); it != door_list.end(); ++it) { for (auto it = door_list.begin(); it != door_list.end(); ++it) {
Doors *cdoor = it->second; Doors *cdoor = it->second;
if(cdoor && !cdoor->IsDoorOpen()) { if(!cdoor || cdoor->IsDoorOpen())
float zdiff = rogue->GetZ() - cdoor->GetZ(); continue;
if(zdiff < 0)
zdiff = 0 - zdiff; auto diff = rogue->GetPosition() - cdoor->GetPosition();
float curdist = 0; diff.ABS_XYZ();
float tmp = rogue->GetX() - cdoor->GetX();
curdist += (tmp * tmp); float curdist = diff.m_X * diff.m_X + diff.m_Y * diff.m_Y;
tmp = rogue->GetY() - cdoor->GetY();
curdist += (tmp * tmp); if((diff.m_Z * diff.m_Z >= 10) || (curdist > 130))
if((zdiff < 10) && (curdist <= 130)) { continue;
// All rogue items with lock pick bonuses are hands or primary // All rogue items with lock pick bonuses are hands or primary
const ItemInst* item1 = rogue->GetBotItem(MainHands); const ItemInst* item1 = rogue->GetBotItem(MainHands);
const ItemInst* item2 = rogue->GetBotItem(MainPrimary); const ItemInst* item2 = rogue->GetBotItem(MainPrimary);
@ -15762,28 +15762,20 @@ void EntityList::BotPickLock(Bot* rogue)
float bonus2 = 0.0f; float bonus2 = 0.0f;
float skill = rogue->GetSkill(SkillPickLock); float skill = rogue->GetSkill(SkillPickLock);
if(item1) { // Hand slot item if(item1) // Hand slot item
if(item1->GetItem()->SkillModType == SkillPickLock) { if(item1->GetItem()->SkillModType == SkillPickLock)
bonus1 = skill * (((float)item1->GetItem()->SkillModValue) / 100.0f); bonus1 = skill * (((float)item1->GetItem()->SkillModValue) / 100.0f);
}
}
if(item2) { // Primary slot item if(item2) // Primary slot item
if(item2->GetItem()->SkillModType == SkillPickLock) { if(item2->GetItem()->SkillModType == SkillPickLock)
bonus2 = skill * (((float)item2->GetItem()->SkillModValue) / 100.0f); bonus2 = skill * (((float)item2->GetItem()->SkillModValue) / 100.0f);
}
}
if((skill+bonus1+bonus2) >= cdoor->GetLockpick()) { if((skill+bonus1+bonus2) >= cdoor->GetLockpick())
cdoor->ForceOpen(rogue); cdoor->ForceOpen(rogue);
} else
else {
rogue->Say("I am not skilled enough for this lock."); rogue->Say("I am not skilled enough for this lock.");
} }
} }
}
}
}
bool EntityList::RemoveBot(uint16 entityID) { bool EntityList::RemoveBot(uint16 entityID) {
bool Result = false; bool Result = false;
@ -16168,11 +16160,9 @@ bool Bot::HasOrMayGetAggro() {
void Bot::SetHasBeenSummoned(bool wasSummoned) { void Bot::SetHasBeenSummoned(bool wasSummoned) {
_hasBeenSummoned = wasSummoned; _hasBeenSummoned = wasSummoned;
if(!wasSummoned) { if(!wasSummoned)
_preSummonX = 0; m_PreSummonLocation = xyz_location::Origin();
_preSummonY = 0;
_preSummonZ = 0;
}
} }
void Bot::SetDefaultBotStance() { void Bot::SetDefaultBotStance() {

View File

@ -448,9 +448,7 @@ public:
uint32 GetAA(uint32 aa_id); uint32 GetAA(uint32 aa_id);
void ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon); void ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon);
bool GetHasBeenSummoned() { return _hasBeenSummoned; } bool GetHasBeenSummoned() { return _hasBeenSummoned; }
float GetPreSummonX() { return _preSummonX; } const xyz_location GetPreSummonLocation() const { return m_PreSummonLocation; }
float GetPreSummonY() { return _preSummonY; }
float GetPreSummonZ() { return _preSummonZ; }
bool GetGroupMessagesOn() { return _groupMessagesOn; } bool GetGroupMessagesOn() { return _groupMessagesOn; }
bool GetInHealRotation() { return _isInHealRotation; } bool GetInHealRotation() { return _isInHealRotation; }
bool GetHealRotationActive() { return (GetInHealRotation() && _isHealRotationActive); } bool GetHealRotationActive() { return (GetInHealRotation() && _isHealRotationActive); }
@ -535,9 +533,7 @@ public:
void SetSpellRecastTimer(int timer_index, int32 recast_delay); void SetSpellRecastTimer(int timer_index, int32 recast_delay);
void SetDisciplineRecastTimer(int timer_index, int32 recast_delay); void SetDisciplineRecastTimer(int timer_index, int32 recast_delay);
void SetHasBeenSummoned(bool s); void SetHasBeenSummoned(bool s);
void SetPreSummonX(float x) { _preSummonX = x; } void SetPreSummonLocation(const xyz_location& location) { m_PreSummonLocation = location; }
void SetPreSummonY(float y) { _preSummonY = y; }
void SetPreSummonZ(float z) { _preSummonZ = z; }
void SetGroupMessagesOn(bool groupMessagesOn) { _groupMessagesOn = groupMessagesOn; } void SetGroupMessagesOn(bool groupMessagesOn) { _groupMessagesOn = groupMessagesOn; }
void SetInHealRotation( bool inRotation ) { _isInHealRotation = inRotation; } void SetInHealRotation( bool inRotation ) { _isInHealRotation = inRotation; }
void SetHealRotationActive( bool isActive ) { _isHealRotationActive = isActive; } void SetHealRotationActive( bool isActive ) { _isHealRotationActive = isActive; }
@ -604,9 +600,7 @@ private:
int32 end_regen; int32 end_regen;
uint32 timers[MaxTimer]; uint32 timers[MaxTimer];
bool _hasBeenSummoned; bool _hasBeenSummoned;
float _preSummonX; xyz_location m_PreSummonLocation;
float _preSummonY;
float _preSummonZ;
uint8 _spellCastingChances[MaxStances][MaxSpellTypes]; uint8 _spellCastingChances[MaxStances][MaxSpellTypes];
bool _groupMessagesOn; bool _groupMessagesOn;
bool _isInHealRotation; bool _isInHealRotation;

View File

@ -75,10 +75,7 @@ Client::Client(EQStreamInterface* ieqs)
0, // npctypeid 0, // npctypeid
0, // size 0, // size
0.7, // runspeed 0.7, // runspeed
0, // heading xyz_heading::Origin(),
0, // x
0, // y
0, // z
0, // light 0, // light
0xFF, // texture 0xFF, // texture
0xFF, // helmtexture 0xFF, // helmtexture
@ -144,7 +141,11 @@ Client::Client(EQStreamInterface* ieqs)
RespawnFromHoverTimer(0), RespawnFromHoverTimer(0),
merc_timer(RuleI(Mercs, UpkeepIntervalMS)), merc_timer(RuleI(Mercs, UpkeepIntervalMS)),
ItemTickTimer(10000), 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++) for(int cf=0; cf < _FilterCount; cf++)
ClientFilters[cf] = FilterShow; ClientFilters[cf] = FilterShow;
@ -190,16 +191,10 @@ Client::Client(EQStreamInterface* ieqs)
auto_attack = false; auto_attack = false;
auto_fire = false; auto_fire = false;
linkdead_timer.Disable(); linkdead_timer.Disable();
zonesummon_x = -2;
zonesummon_y = -2;
zonesummon_z = -2;
zonesummon_id = 0; zonesummon_id = 0;
zonesummon_ignorerestrictions = 0; zonesummon_ignorerestrictions = 0;
zoning = false; zoning = false;
zone_mode = ZoneUnsolicited; zone_mode = ZoneUnsolicited;
proximity_x = FLT_MAX; //arbitrary large number
proximity_y = FLT_MAX;
proximity_z = FLT_MAX;
casting_spell_id = 0; casting_spell_id = 0;
npcflag = false; npcflag = false;
npclevel = 0; npclevel = 0;
@ -268,13 +263,6 @@ Client::Client(EQStreamInterface* ieqs)
m_AssistExemption = 0; m_AssistExemption = 0;
m_CheatDetectMoved = false; m_CheatDetectMoved = false;
CanUseReport = true; 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; aa_los_them_mob = nullptr;
los_status = false; los_status = false;
los_status_facing = false; los_status_facing = false;
@ -385,9 +373,9 @@ Client::~Client() {
{ {
m_pp.zone_id = m_pp.binds[0].zoneId; m_pp.zone_id = m_pp.binds[0].zoneId;
m_pp.zoneInstance = m_pp.binds[0].instance_id; m_pp.zoneInstance = m_pp.binds[0].instance_id;
x_pos = m_pp.binds[0].x; m_Position.m_X = m_pp.binds[0].x;
y_pos = m_pp.binds[0].y; m_Position.m_Y = m_pp.binds[0].y;
z_pos = m_pp.binds[0].z; m_Position.m_Z = m_pp.binds[0].z;
} }
// we save right now, because the client might be zoning and the world // we save right now, because the client might be zoning and the world
@ -511,11 +499,11 @@ bool Client::Save(uint8 iCommitNow) {
return false; return false;
/* Wrote current basics to PP for saves */ /* Wrote current basics to PP for saves */
m_pp.x = x_pos; m_pp.x = m_Position.m_X;
m_pp.y = y_pos; m_pp.y = m_Position.m_Y;
m_pp.z = z_pos; m_pp.z = m_Position.m_Z;
m_pp.guildrank = guildrank; m_pp.guildrank = guildrank;
m_pp.heading = heading; m_pp.heading = m_Position.m_Heading;
/* Mana and HP */ /* Mana and HP */
if (GetHP() <= 0) { if (GetHP() <= 0) {
@ -532,8 +520,10 @@ bool Client::Save(uint8 iCommitNow) {
database.SaveCharacterCurrency(CharacterID(), &m_pp); database.SaveCharacterCurrency(CharacterID(), &m_pp);
/* Save Current Bind Points */ /* 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 */ auto regularBindPosition = xyz_heading(m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0.0f);
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 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 */ /* Save Character Buffs */
database.SaveBuffs(this); database.SaveBuffs(this);
@ -4800,8 +4790,7 @@ void Client::SummonAndRezzAllCorpses()
entity_list.RemoveAllCorpsesByCharID(CharacterID()); entity_list.RemoveAllCorpsesByCharID(CharacterID());
int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), GetPosition());
GetX(), GetY(), GetZ(), GetHeading());
if(CorpseCount <= 0) if(CorpseCount <= 0)
{ {
Message(clientMessageYellow, "You have no corpses to summnon."); 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."); 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)
{ {
auto summonLocation = position;
if(dest_x == 0 && dest_y == 0 && dest_z == 0 && dest_heading == 0) if(position.isOrigin() && position.m_Heading == 0.0f)
{ summonLocation = GetPosition();
dest_x = GetX(); dest_y = GetY(); dest_z = GetZ(); dest_heading = GetHeading();
}
ServerPacket *Pack = new ServerPacket(ServerOP_DepopAllPlayersCorpses, sizeof(ServerDepopAllPlayersCorpses_Struct)); 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()); entity_list.RemoveAllCorpsesByCharID(CharacterID());
int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), summonLocation);
dest_x, dest_y, dest_z, dest_heading);
if(CorpseCount <= 0)
{
return;
}
} }
void Client::DepopAllCorpses() 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) if(summon_count > MAX_SWARM_PETS)
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 xy_location swarmPetLocations[MAX_SWARM_PETS] = {
static const float swarm_pet_y[MAX_SWARM_PETS] = { 5, 5, -5, -5, 10, 10, -10, -10, 8, 8, -8, -8 }; {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) { while(summon_count > 0) {
NPCType *npc_dup = nullptr; 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* npca = new NPC(
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer (npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
0, 0,
GetX()+swarm_pet_x[summon_count], GetY()+swarm_pet_y[summon_count], GetPosition()+swarmPetLocations[summon_count],
GetZ(), GetHeading(), FlyMode3); FlyMode3);
if(!npca->GetSwarmInfo()){ if(!npca->GetSwarmInfo()){
AA_SwarmPetInfo* nSI = new AA_SwarmPetInfo; AA_SwarmPetInfo* nSI = new AA_SwarmPetInfo;

View File

@ -398,10 +398,10 @@ public:
inline const char* GetLastName() const { return lastname; } inline const char* GetLastName() const { return lastname; }
inline float ProximityX() const { return(proximity_x); } inline float ProximityX() const { return m_Proximity.m_X; }
inline float ProximityY() const { return(proximity_y); } inline float ProximityY() const { return m_Proximity.m_Y; }
inline float ProximityZ() const { return(proximity_z); } inline float ProximityZ() const { return m_Proximity.m_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 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 Begin client modifiers
@ -580,7 +580,7 @@ public:
void GoToBind(uint8 bindnum = 0); void GoToBind(uint8 bindnum = 0);
void GoToSafeCoords(uint16 zone_id, uint16 instance_id); void GoToSafeCoords(uint16 zone_id, uint16 instance_id);
void Gate(); 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); void SetStartZone(uint32 zoneid, float x = 0.0f, float y =0.0f, float z = 0.0f);
uint32 GetStartZone(void); uint32 GetStartZone(void);
void MovePC(const char* zonename, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); 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(); void DoItemEnterZone();
bool DoItemEnterZone(uint32 slot_x, uint32 slot_y); // behavior change: 'slot_y' is now [RANGE]_END and not [RANGE]_END + 1 bool DoItemEnterZone(uint32 slot_x, uint32 slot_y); // behavior change: 'slot_y' is now [RANGE]_END and not [RANGE]_END + 1
void SummonAndRezzAllCorpses(); 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 DepopAllCorpses();
void DepopPlayerCorpse(uint32 dbid); void DepopPlayerCorpse(uint32 dbid);
void BuryPlayerCorpses(); void BuryPlayerCorpses();
@ -1267,11 +1267,10 @@ protected:
Mob* bind_sight_target; Mob* bind_sight_target;
Map::Vertex aa_los_me; xyz_heading m_AutoAttackPosition;
Map::Vertex aa_los_them; xyz_location m_AutoAttackTargetLocation;
Mob *aa_los_them_mob; Mob *aa_los_them_mob;
bool los_status; bool los_status;
float aa_los_me_heading;
bool los_status_facing; bool los_status_facing;
QGlobalCache *qGlobals; 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 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 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); 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; xyz_location m_ZoneSummonLocation;
float zonesummon_z;
uint16 zonesummon_id; uint16 zonesummon_id;
uint8 zonesummon_ignorerestrictions; uint8 zonesummon_ignorerestrictions;
ZoneMode zone_mode; ZoneMode zone_mode;
@ -1465,10 +1463,7 @@ private:
Timer RespawnFromHoverTimer; Timer RespawnFromHoverTimer;
Timer merc_timer; Timer merc_timer;
float proximity_x; xyz_location m_Proximity;
float proximity_y;
float proximity_z;
void BulkSendInventoryItems(); void BulkSendInventoryItems();

View File

@ -1455,9 +1455,10 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
strcpy(lastname, m_pp.last_name); strcpy(lastname, m_pp.last_name);
/* If PP is set to weird coordinates */ /* 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)) { 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(); auto safePoint = zone->GetSafePoint();
m_pp.y = zone->safe_y(); m_pp.x = safePoint.m_X;
m_pp.z = zone->safe_z(); m_pp.y = safePoint.m_Y;
m_pp.z = safePoint.m_Z;
} }
/* If too far below ground, then fix */ /* If too far below ground, then fix */
// float ground_z = GetGroundZ(m_pp.x, m_pp.y, m_pp.z); // 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 */ /* Set Mob variables for spawn */
class_ = m_pp.class_; class_ = m_pp.class_;
level = m_pp.level; level = m_pp.level;
x_pos = m_pp.x; m_Position.m_X = m_pp.x;
y_pos = m_pp.y; m_Position.m_Y = m_pp.y;
z_pos = m_pp.z; m_Position.m_Z = m_pp.z;
heading = m_pp.heading; m_Position.m_Heading = m_pp.heading;
race = m_pp.race; race = m_pp.race;
base_race = m_pp.race; base_race = m_pp.race;
gender = m_pp.gender; gender = m_pp.gender;
@ -3240,13 +3241,8 @@ void Client::Handle_OP_AutoAttack(const EQApplicationPacket *app)
ranged_timer.Disable(); ranged_timer.Disable();
attack_dw_timer.Disable(); attack_dw_timer.Disable();
aa_los_me.x = 0; m_AutoAttackPosition = xyz_heading::Origin();
aa_los_me.y = 0; m_AutoAttackTargetLocation = xyz_location::Origin();
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; aa_los_them_mob = nullptr;
} }
else if (app->pBuffer[0] == 1) else if (app->pBuffer[0] == 1)
@ -3260,25 +3256,15 @@ void Client::Handle_OP_AutoAttack(const EQApplicationPacket *app)
if (GetTarget()) if (GetTarget())
{ {
aa_los_them_mob = GetTarget(); aa_los_them_mob = GetTarget();
aa_los_me.x = GetX(); m_AutoAttackPosition = GetPosition();
aa_los_me.y = GetY(); m_AutoAttackTargetLocation = aa_los_them_mob->GetPosition();
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();
los_status = CheckLosFN(aa_los_them_mob); los_status = CheckLosFN(aa_los_them_mob);
los_status_facing = IsFacingMob(aa_los_them_mob); los_status_facing = IsFacingMob(aa_los_them_mob);
} }
else else
{ {
aa_los_me.x = GetX(); m_AutoAttackPosition = GetPosition();
aa_los_me.y = GetY(); m_AutoAttackTargetLocation = xyz_location::Origin();
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;
aa_los_them_mob = nullptr; aa_los_them_mob = nullptr;
los_status = false; los_status = false;
los_status_facing = false; los_status_facing = false;
@ -4000,9 +3986,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
CastSpell_Struct* castspell = (CastSpell_Struct*)app->pBuffer; CastSpell_Struct* castspell = (CastSpell_Struct*)app->pBuffer;
targetring_x = castspell->x_pos; m_TargetRing = xyz_location(castspell->x_pos, castspell->y_pos, castspell->z_pos);
targetring_y = castspell->y_pos;
targetring_z = castspell->z_pos;
#ifdef _EQDEBUG #ifdef _EQDEBUG
LogFile->write(EQEmuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[0], castspell->cs_unknown[0]); 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; return;
} }
targetring_x = castspell->x_pos; m_TargetRing = xyz_location(castspell->x_pos, castspell->y_pos, castspell->z_pos);
targetring_y = castspell->y_pos;
targetring_z = castspell->z_pos;
CastSpell(spell_to_cast, castspell->target_id, castspell->slot); 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 // 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 // send an update to everyone nearby except the client controlling the boat
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
PlayerPositionUpdateServer_Struct* ppus = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer; PlayerPositionUpdateServer_Struct* ppus = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer;
@ -4396,9 +4379,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
float dist = 0; float dist = 0;
float tmp; float tmp;
tmp = x_pos - ppu->x_pos; tmp = m_Position.m_X - ppu->x_pos;
dist += tmp*tmp; dist += tmp*tmp;
tmp = y_pos - ppu->y_pos; tmp = m_Position.m_Y - ppu->y_pos;
dist += tmp*tmp; dist += tmp*tmp;
dist = sqrt(dist); dist = sqrt(dist);
@ -4541,51 +4524,41 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
float rewind_x_diff = 0; float rewind_x_diff = 0;
float rewind_y_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_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; rewind_y_diff *= rewind_y_diff;
//We only need to store updated values if the player has moved. //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 //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. //his pre-PPU x and y for /rewind, in case he gets stuck.
if ((rewind_x_diff > 750) || (rewind_y_diff > 750)) { if ((rewind_x_diff > 750) || (rewind_y_diff > 750))
rewind_x = x_pos; m_RewindLocation = m_Position;
rewind_y = y_pos;
rewind_z = z_pos;
}
//If the PPU was a large jump, such as a cross zone gate or Call of Hero, //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. //just update rewind coords to the new ppu coords. This will prevent exploitation.
if ((rewind_x_diff > 5000) || (rewind_y_diff > 5000)) { if ((rewind_x_diff > 5000) || (rewind_y_diff > 5000))
rewind_x = ppu->x_pos; m_RewindLocation = xyz_location(ppu->x_pos, ppu->y_pos, ppu->z_pos);
rewind_y = ppu->y_pos;
rewind_z = ppu->z_pos;
}
if(proximity_timer.Check()) { 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)) if(RuleB(TaskSystem, EnableTaskSystem) && RuleB(TaskSystem,EnableTaskProximity))
ProcessTaskProximities(ppu->x_pos, ppu->y_pos, ppu->z_pos); ProcessTaskProximities(ppu->x_pos, ppu->y_pos, ppu->z_pos);
proximity_x = ppu->x_pos;
proximity_y = ppu->y_pos; m_Proximity = xyz_location(ppu->x_pos, ppu->y_pos, ppu->z_pos);
proximity_z = ppu->z_pos;
} }
// Update internal state // Update internal state
delta_x = ppu->delta_x; m_Delta = xyz_heading(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading);
delta_y = ppu->delta_y;
delta_z = ppu->delta_z;
delta_heading = 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 if(zone->random.Real(0, 100) < 70)//should be good
CheckIncreaseSkill(SkillTracking, nullptr, -20); CheckIncreaseSkill(SkillTracking, nullptr, -20);
} }
// Break Hide if moving without sneaking and set rewind timer if moved // 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){ if((hidden || improved_hidden) && !sneaking){
hidden = false; hidden = false;
improved_hidden = false; improved_hidden = false;
@ -4605,13 +4578,14 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
// Outgoing client packet // Outgoing client packet
float tmpheading = EQ19toFloat(ppu->heading); 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; m_Position.m_X = ppu->x_pos;
y_pos = ppu->y_pos; m_Position.m_Y = ppu->y_pos;
z_pos = ppu->z_pos; m_Position.m_Z = ppu->z_pos;
m_Position.m_Heading = tmpheading;
animation = ppu->animation; animation = ppu->animation;
heading = tmpheading;
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
PlayerPositionUpdateServer_Struct* ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer; PlayerPositionUpdateServer_Struct* ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer;
@ -4623,13 +4597,8 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
safe_delete(outapp); safe_delete(outapp);
} }
if(zone->watermap) if(zone->watermap && zone->watermap->InLiquid(m_Position))
{
if(zone->watermap->InLiquid(x_pos, y_pos, z_pos))
{
CheckIncreaseSkill(SkillSwimming, nullptr, -17); CheckIncreaseSkill(SkillSwimming, nullptr, -17);
}
}
return; return;
} }
@ -11706,7 +11675,7 @@ void Client::Handle_OP_Rewind(const EQApplicationPacket *app)
Message_StringID(MT_System, REWIND_WAIT); Message_StringID(MT_System, REWIND_WAIT);
} }
else { 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); rewind_timer.Start(30000, true);
} }
} }
@ -11830,29 +11799,29 @@ void Client::Handle_OP_SenseTraps(const EQApplicationPacket *app)
int uskill = GetSkill(SkillSenseTraps); int uskill = GetSkill(SkillSenseTraps);
if ((zone->random.Int(0, 99) + uskill) >= (zone->random.Int(0, 99) + trap->skill*0.75)) if ((zone->random.Int(0, 99) + uskill) >= (zone->random.Int(0, 99) + trap->skill*0.75))
{ {
float xdif = trap->x - GetX(); auto diff = trap->m_Position - GetPosition();
float ydif = trap->y - GetY();
if (xdif == 0 && ydif == 0) if (diff.m_X == 0 && diff.m_Y == 0)
Message(MT_Skills, "You sense a trap right under your feet!"); 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."); 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."); 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."); 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."); 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."); 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."); 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."); Message(MT_Skills, "You sense a trap to the West.");
else else
Message(MT_Skills, "You sense a trap to the East."); Message(MT_Skills, "You sense a trap to the East.");
trap->detected = true; 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) if (angle < 0)
angle = (256 + angle); angle = (256 + angle);

View File

@ -340,41 +340,31 @@ bool Client::Process() {
if(aa_los_them_mob) if(aa_los_them_mob)
{ {
if(auto_attack_target != aa_los_them_mob || if(auto_attack_target != aa_los_them_mob ||
aa_los_me.x != GetX() || m_AutoAttackPosition.m_X != GetX() ||
aa_los_me.y != GetY() || m_AutoAttackPosition.m_Y != GetY() ||
aa_los_me.z != GetZ() || m_AutoAttackPosition.m_Z != GetZ() ||
aa_los_them.x != aa_los_them_mob->GetX() || m_AutoAttackTargetLocation.m_X != aa_los_them_mob->GetX() ||
aa_los_them.y != aa_los_them_mob->GetY() || m_AutoAttackTargetLocation.m_Y != aa_los_them_mob->GetY() ||
aa_los_them.z != aa_los_them_mob->GetZ()) m_AutoAttackTargetLocation.m_Z != aa_los_them_mob->GetZ())
{ {
aa_los_them_mob = auto_attack_target; aa_los_them_mob = auto_attack_target;
aa_los_me.x = GetX(); m_AutoAttackPosition = GetPosition();
aa_los_me.y = GetY(); m_AutoAttackTargetLocation = aa_los_them_mob->GetPosition();
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();
los_status = CheckLosFN(auto_attack_target); los_status = CheckLosFN(auto_attack_target);
aa_los_me_heading = GetHeading();
los_status_facing = IsFacingMob(aa_los_them_mob); los_status_facing = IsFacingMob(aa_los_them_mob);
} }
// If only our heading changes, we can skip the CheckLosFN call // If only our heading changes, we can skip the CheckLosFN call
// but above we still need to update los_status_facing // but above we still need to update los_status_facing
if (aa_los_me_heading != GetHeading()) { if (m_AutoAttackPosition.m_Heading != GetHeading()) {
aa_los_me_heading = GetHeading(); m_AutoAttackPosition.m_Heading = GetHeading();
los_status_facing = IsFacingMob(aa_los_them_mob); los_status_facing = IsFacingMob(aa_los_them_mob);
} }
} }
else else
{ {
aa_los_them_mob = auto_attack_target; aa_los_them_mob = auto_attack_target;
aa_los_me.x = GetX(); m_AutoAttackPosition = GetPosition();
aa_los_me.y = GetY(); m_AutoAttackTargetLocation = aa_los_them_mob->GetPosition();
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();
los_status = CheckLosFN(auto_attack_target); los_status = CheckLosFN(auto_attack_target);
los_status_facing = IsFacingMob(aa_los_them_mob); los_status_facing = IsFacingMob(aa_los_them_mob);
} }
@ -529,9 +519,7 @@ bool Client::Process() {
else else
{ {
animation = 0; animation = 0;
delta_x = 0; m_Delta = xyz_heading(0.0f, 0.0f, 0.0f, m_Delta.m_Heading);
delta_y = 0;
delta_z = 0;
SendPosUpdate(2); SendPosUpdate(2);
} }
} }
@ -2129,9 +2117,9 @@ void Client::HandleRespawnFromHover(uint32 Option)
if (corpse) if (corpse)
{ {
x_pos = corpse->GetX(); m_Position.m_X = corpse->GetX();
y_pos = corpse->GetY(); m_Position.m_Y = corpse->GetY();
z_pos = corpse->GetZ(); m_Position.m_Z = corpse->GetZ();
} }
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) + 10); EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) + 10);
@ -2184,10 +2172,10 @@ void Client::HandleRespawnFromHover(uint32 Option)
SetMana(GetMaxMana()); SetMana(GetMaxMana());
SetEndurance(GetMaxEndurance()); SetEndurance(GetMaxEndurance());
x_pos = chosen->x; m_Position.m_X = chosen->x;
y_pos = chosen->y; m_Position.m_Y = chosen->y;
z_pos = chosen->z; m_Position.m_Z = chosen->z;
heading = chosen->heading; m_Position.m_Heading = chosen->heading;
ClearHover(); ClearHover();
entity_list.RefreshClientXTargets(this); entity_list.RefreshClientXTargets(this);

View File

@ -1839,14 +1839,7 @@ void command_itemtest(Client *c, const Seperator *sep)
void command_gassign(Client *c, const Seperator *sep) void command_gassign(Client *c, const Seperator *sep)
{ {
if (sep->IsNumber(1) && c->GetTarget() && c->GetTarget()->IsNPC()) if (sep->IsNumber(1) && c->GetTarget() && c->GetTarget()->IsNPC())
{ database.AssignGrid(c, c->GetTarget()->CastToNPC()->m_SpawnPoint, atoi(sep->arg[1]));
database.AssignGrid(
c,
(c->GetTarget()->CastToNPC()->org_x),
(c->GetTarget()->CastToNPC()->org_y),
atoi(sep->arg[1])
);
}
else else
c->Message(0,"Usage: #gassign [num] - must have an npc target!"); 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)) if(sep->IsNumber(5))
cond_min = atoi(sep->arg[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 { else {
c->Message(0, "Usage: #dbspawn2 spawngroup respawn variance [condition_id] [condition_min]"); 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 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; wp = database.GetHighestWaypoint(zone->GetZoneID(), atoi(sep->arg[2])) + 1;
if (strcasecmp("-h",sep->arg[5]) == 0) { 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 { 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) 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:"); LogFile->write(EQEmuLog::Debug,"#spawn Spawning:");
#endif #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) { 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, "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."); 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; const NPCType* tmp = 0;
if ((tmp = database.GetNPCType(atoi(sep->arg[1])))) { if ((tmp = database.GetNPCType(atoi(sep->arg[1])))) {
//tmp->fixedZ = 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)) if (npc && sep->IsNumber(2))
npc->SetNPCFactionID(atoi(sep->arg[2])); npc->SetNPCFactionID(atoi(sep->arg[2]));
@ -5420,8 +5415,7 @@ void command_wpadd(Client *c, const Seperator *sep)
{ {
int type1=0, int type1=0,
type2=0, type2=0,
pause=0, pause=0; // Defaults for a new grid
heading=-1; // Defaults for a new grid
Mob *t=c->GetTarget(); Mob *t=c->GetTarget();
if (t && t->IsNPC()) if (t && t->IsNPC())
@ -5444,9 +5438,11 @@ void command_wpadd(Client *c, const Seperator *sep)
return; return;
} }
} }
if (strcmp("-h",sep->arg[2]) == 0) auto position = c->GetPosition();
heading = c->GetHeading(); if (strcmp("-h",sep->arg[2]) != 0)
uint32 tmp_grid = database.AddWPForSpawn(c, s2info->GetID(), c->GetX(),c->GetY(),c->GetZ(), pause, type1, type2, zone->GetZoneID(), heading); position.m_Heading = -1;
uint32 tmp_grid = database.AddWPForSpawn(c, s2info->GetID(), position, pause, type1, type2, zone->GetZoneID());
if (tmp_grid) if (tmp_grid)
t->CastToNPC()->SetGrid(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) 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]"); c->Message(0, "Usage: #itemsearch [search string]");
}
else else
{ {
const char *search_criteria=sep->argplus[1]; 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."); c->Message(0, "50 items shown...too many results.");
else else
c->Message(0, "%i items found", count); c->Message(0, "%i items found", count);
} }
} }
@ -7334,7 +7330,7 @@ void command_pf(Client *c, const Seperator *sep)
{ {
Mob *who = c->GetTarget(); Mob *who = c->GetTarget();
c->Message(0, "POS: (%.2f, %.2f, %.2f)", who->GetX(), who->GetY(), who->GetZ()); 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, "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, "TARV: (%.2f, %.2f, %.2f)", who->GetTarVX(), who->GetTarVY(), who->GetTarVZ());
c->Message(0, "|TV|=%.2f index=%d", who->GetTarVector(), who->GetTarNDX()); 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()) { if(c->GetTarget()) {
z=c->GetTarget()->GetZ(); z=c->GetTarget()->GetZ();
RegionType = zone->watermap->ReturnRegionType(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z); auto position = xyz_location(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z);
c->Message(0,"InWater returns %d", zone->watermap->InWater(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z)); RegionType = zone->watermap->ReturnRegionType(position);
c->Message(0,"InLava returns %d", zone->watermap->InLava(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z)); c->Message(0,"InWater returns %d", zone->watermap->InWater(position));
c->Message(0,"InLava returns %d", zone->watermap->InLava(position));
} }
else { else {
z=c->GetZ(); z=c->GetZ();
RegionType = zone->watermap->ReturnRegionType(c->GetX(), c->GetY(), z); auto position = xyz_location(c->GetX(), c->GetY(), z);
c->Message(0,"InWater returns %d", zone->watermap->InWater(c->GetX(), c->GetY(), z)); RegionType = zone->watermap->ReturnRegionType(position);
c->Message(0,"InLava returns %d", zone->watermap->InLava(c->GetX(), c->GetY(), z)); 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]); zoneid = database.GetZoneID(sep->arg[1]);
if(zoneid > 0) { 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) { if(graveyard_id > 0) {
c->Message(0, "Successfuly added a new record for this graveyard!"); c->Message(0, "Successfuly added a new record for this graveyard!");
@ -8263,7 +8261,7 @@ void command_summonburriedplayercorpse(Client *c, const Seperator *sep)
return; 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) if(!PlayerCorpse)
c->Message(0, "Your target doesn't have any burried corpses."); c->Message(0, "Your target doesn't have any burried corpses.");

View File

@ -70,7 +70,7 @@ void Corpse::SendLootReqErrorPacket(Client* client, uint8 response) {
safe_delete(outapp); 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); uint32 item_count = database.GetCharacterCorpseItemCount(in_dbid);
char *buffer = new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))]; char *buffer = new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))];
PlayerCorpse_Struct *pcs = (PlayerCorpse_Struct*)buffer; PlayerCorpse_Struct *pcs = (PlayerCorpse_Struct*)buffer;
@ -95,10 +95,7 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
pcs->silver, // uint32 in_silver pcs->silver, // uint32 in_silver
pcs->gold, // uint32 in_gold pcs->gold, // uint32 in_gold
pcs->plat, // uint32 in_plat pcs->plat, // uint32 in_plat
in_x, // float in_x position,
in_y, // float in_y
in_z, // float in_z
in_heading, // float in_heading
pcs->size, // float in_size pcs->size, // float in_size
pcs->gender, // uint8 in_gender pcs->gender, // uint8 in_gender
pcs->race, // uint16 in_race pcs->race, // uint16 in_race
@ -110,9 +107,9 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
pcs->exp, // uint32 in_rezexp pcs->exp, // uint32 in_rezexp
was_at_graveyard // bool wasAtGraveyard was_at_graveyard // bool wasAtGraveyard
); );
if (pcs->locked){
if (pcs->locked)
pc->Lock(); pc->Lock();
}
/* Load Item Tints */ /* Load Item Tints */
pc->item_tint[0].color = pcs->item_tint[0].color; pc->item_tint[0].color = pcs->item_tint[0].color;
@ -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) 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, // vesuvias - appearence fix
"", // const char* in_lastname, : Mob("Unnamed_Corpse","",0,0,in_npc->GetGender(),in_npc->GetRace(),in_npc->GetClass(),BT_Humanoid,//bodytype added
0, // int32 in_cur_hp, in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0,
0, // int32 in_max_hp, in_npc->GetPosition(), 0, in_npc->GetTexture(),in_npc->GetHelmTexture(),
in_npc->GetGender(), // uint8 in_gender, 0,0,0,0,0,0,0,0,0,
in_npc->GetRace(), // uint16 in_race, 0,0,0,0,0,0,0,0,0,0,0,0xff,0,0,0,0,0,0,0,0,0),
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
),
corpse_decay_timer(in_decaytime), corpse_decay_timer(in_decaytime),
corpse_rez_timer(0), corpse_rez_timer(0),
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
@ -260,10 +212,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
0, // uint32 in_npctype_id, 0, // uint32 in_npctype_id,
client->GetSize(), // float in_size, client->GetSize(), // float in_size,
0, // float in_runspeed, 0, // float in_runspeed,
client->GetHeading(), // float in_heading, client->GetPosition(),
client->GetX(), // float in_x_pos,
client->GetY(), // float in_y_pos,
client->GetZ(), // float in_z_pos,
0, // uint8 in_light, 0, // uint8 in_light,
client->GetTexture(), // uint8 in_texture, client->GetTexture(), // uint8 in_texture,
client->GetHelmTexture(), // uint8 in_helmtexture, client->GetHelmTexture(), // uint8 in_helmtexture,
@ -485,59 +434,55 @@ std::list<uint32> Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16
return returnlist; return returnlist;
} }
/* Called from Database Load */ // 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)
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",
: Mob("Unnamed_Corpse", // const char* in_name, "",
"", // const char* in_lastname, 0,
0, // int32 in_cur_hp, 0,
0, // int32 in_max_hp, in_gender,
in_gender, // uint8 in_gender, in_race,
in_race, // uint16 in_race, in_class,
in_class, // uint8 in_class, BT_Humanoid,
BT_Humanoid, // bodyType in_bodytype, in_deity,
in_deity, // uint8 in_deity, in_level,
in_level, // uint8 in_level, 0,
0, // uint32 in_npctype_id, in_size,
in_size, // float in_size, 0,
0, // float in_runspeed, position,
in_heading, // float in_heading, 0,
in_x, // float in_x_pos, in_texture,
in_y, // float in_y_pos, in_helmtexture,
in_z, // float in_z_pos, 0,
0, // uint8 in_light, 0,
in_texture, // uint8 in_texture, 0,
in_helmtexture, // uint8 in_helmtexture, 0,
0, // uint16 in_ac, 0,
0, // uint16 in_atk, 0,
0, // uint16 in_str, 0,
0, // uint16 in_sta, 0,
0, // uint16 in_dex, 0,
0, // uint16 in_agi, 0,
0, // uint16 in_int, 0,
0, // uint16 in_wis, 0,
0, // uint16 in_cha, 0,
0, // uint8 in_haircolor, 0,
0, // uint8 in_beardcolor, 0,
0, // uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye? 0,
0, // uint8 in_eyecolor2, 0,
0, // uint8 in_hairstyle, 0,
0, // uint8 in_luclinface, 0,
0, // uint8 in_beard, 0,
0, // uint32 in_drakkin_heritage, 0xff,
0, // uint32 in_drakkin_tattoo, 0,
0, // uint32 in_drakkin_details, 0,
0, // uint32 in_armor_tint[_MaterialCount], 0,
0xff, // uint8 in_aa_title, 0,
0, // uint8 in_see_invis, // see through invis/ivu 0,
0, // uint8 in_see_invis_undead, 0,
0, // uint8 in_see_hide, 0,
0, // uint8 in_see_improved_hide, 0,
0, // int32 in_hp_regen, 0),
0, // int32 in_mana_regen,
0, // uint8 in_qglobal,
0, // uint8 in_maxlevel,
0), // uint32 in_scalerate
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)), corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), 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); LoadPlayerCorpseDecayTime(in_dbid);
if (!zone->HasGraveyard() || wasAtGraveyard){ if (!zone->HasGraveyard() || wasAtGraveyard)
corpse_graveyard_timer.Disable(); corpse_graveyard_timer.Disable();
}
memset(item_tint, 0, sizeof(item_tint)); memset(item_tint, 0, sizeof(item_tint));
@ -659,11 +603,11 @@ bool Corpse::Save() {
/* Create New Corpse*/ /* Create New Corpse*/
if (corpse_db_id == 0) { 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 */ /* Update Corpse Data */
else{ 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); safe_delete_array(dbpc);
@ -680,9 +624,8 @@ void Corpse::Delete() {
} }
void Corpse::Bury() { void Corpse::Bury() {
if (IsPlayerCorpse() && corpse_db_id != 0){ if (IsPlayerCorpse() && corpse_db_id != 0)
database.BuryCharacterCorpse(corpse_db_id); database.BuryCharacterCorpse(corpse_db_id);
}
corpse_db_id = 0; corpse_db_id = 0;
player_corpse_depop = true; player_corpse_depop = true;
} }
@ -827,14 +770,12 @@ bool Corpse::IsEmpty() const {
} }
bool Corpse::Process() { bool Corpse::Process() {
if (player_corpse_depop){ if (player_corpse_depop)
return false; return false;
}
if (corpse_delay_timer.Check()) { 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; allowed_looters[i] = 0;
}
corpse_delay_timer.Disable(); corpse_delay_timer.Disable();
return true; return true;
} }
@ -844,8 +785,7 @@ bool Corpse::Process() {
Save(); Save();
player_corpse_depop = true; player_corpse_depop = true;
database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(), database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(),
(zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->graveyard_x(), (zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->GetGraveyardPoint());
zone->graveyard_y(), zone->graveyard_z(), zone->graveyard_heading());
corpse_graveyard_timer.Disable(); corpse_graveyard_timer.Disable();
ServerPacket* pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct)); ServerPacket* pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct));
SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer; SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer;
@ -911,15 +851,11 @@ bool Corpse::CanPlayerLoot(int charid) {
looters++; looters++;
} }
if (allowed_looters[i] == charid){ if (allowed_looters[i] == charid)
return true; return true;
} }
}
/* If we have no looters, obviously client can loot */ /* If we have no looters, obviously client can loot */
if (looters == 0){ return looters == 0;
return true;
}
return false;
} }
void Corpse::AllowPlayerLoot(Mob *them, uint8 slot) { void Corpse::AllowPlayerLoot(Mob *them, uint8 slot) {
@ -952,21 +888,20 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
return; return;
} }
if(being_looted_by == 0) { if(being_looted_by == 0)
being_looted_by = 0xFFFFFFFF; being_looted_by = 0xFFFFFFFF;
}
if(this->being_looted_by != 0xFFFFFFFF) { if(this->being_looted_by != 0xFFFFFFFF) {
// lets double check.... // lets double check....
Entity* looter = entity_list.GetID(this->being_looted_by); Entity* looter = entity_list.GetID(this->being_looted_by);
if(looter == 0) { if(looter == 0)
this->being_looted_by = 0xFFFFFFFF; this->being_looted_by = 0xFFFFFFFF;
} }
}
uint8 Loot_Request_Type = 1; uint8 Loot_Request_Type = 1;
bool loot_coin = false; 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()) { if (this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) {
SendLootReqErrorPacket(client, 0); SendLootReqErrorPacket(client, 0);

View File

@ -41,18 +41,15 @@ class Corpse : public Mob {
Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime = 600000); 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(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(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(); ~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); 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 */ /* Corpse: General */
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; } 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 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, virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; }
bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) {
return false;
}
virtual bool HasRaid() { return false; } virtual bool HasRaid() { return false; }
virtual bool HasGroup() { return false; } virtual bool HasGroup() { return false; }
virtual Raid* GetRaid() { return 0; } virtual Raid* GetRaid() { return 0; }

View File

@ -39,17 +39,15 @@
extern EntityList entity_list; extern EntityList entity_list;
extern WorldServer worldserver; extern WorldServer worldserver;
Doors::Doors(const Door* door) Doors::Doors(const Door* door) :
: close_timer(5000) 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; db_id = door->db_id;
door_id = door->door_id; door_id = door->door_id;
strn0cpy(zone_name,door->zone_name,32); strn0cpy(zone_name,door->zone_name,32);
strn0cpy(door_name,door->door_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; incline = door->incline;
opentype = door->opentype; opentype = door->opentype;
guild_id = door->guild_id; guild_id = door->guild_id;
@ -66,28 +64,22 @@ Doors::Doors(const Door* door)
close_timer.Disable(); 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_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; is_ldon_door = door->is_ldon_door;
client_version_mask = door->client_version_mask; client_version_mask = door->client_version_mask;
} }
Doors::Doors(const char *dmodel, float dx, float dy, float dz, float dheading, uint8 dopentype, uint16 dsize) Doors::Doors(const char *dmodel, const xyz_heading& position, uint8 dopentype, uint16 dsize) :
: close_timer(5000) close_timer(5000),
m_Position(position),
m_Destination(xyz_heading::Origin())
{ {
db_id = database.GetDoorsCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); db_id = database.GetDoorsCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion());
door_id = database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion()); door_id = database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion());
strn0cpy(zone_name,zone->GetShortName(),32); strn0cpy(zone_name,zone->GetShortName(),32);
strn0cpy(door_name,dmodel,32); strn0cpy(door_name,dmodel,32);
pos_x = dx;
pos_y = dy;
pos_z = dz;
heading = dheading;
incline = 0; incline = 0;
opentype = dopentype; opentype = dopentype;
guild_id = 0; 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); strn0cpy(dest_zone,"NONE",32);
dest_instance_id = 0; dest_instance_id = 0;
dest_x = 0;
dest_y = 0;
dest_z = 0;
dest_heading = 0;
is_ldon_door = 0; is_ldon_door = 0;
client_version_mask = 4294967295u; client_version_mask = 4294967295u;
@ -144,9 +132,9 @@ bool Doors::Process()
void Doors::HandleClick(Client* sender, uint8 trigger) void Doors::HandleClick(Client* sender, uint8 trigger)
{ {
//door debugging info dump //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, " 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)); EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer; MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer;
@ -422,7 +410,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
{ {
sender->KeyRingAdd(playerkey); 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()))) 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()) 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 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 (( !IsDoorOpen() || opentype == 58 ) && (!keyneeded))
{ {
if(database.GetZoneID(dest_zone) == zone->GetZoneID()) 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 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(){ void Doors::DumpDoor(){
LogFile->write(EQEmuLog::Debug, 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:%i door_id:%i zone_name:%s door_name:%s %s",
db_id, door_id, zone_name, door_name, pos_x, pos_y, pos_z, heading); db_id, door_id, zone_name, door_name, to_string(m_Position).c_str());
LogFile->write(EQEmuLog::Debug, 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:%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"); opentype, guild_id, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param, (isopen) ? "open":"closed");
LogFile->write(EQEmuLog::Debug, LogFile->write(EQEmuLog::Debug,
"dest_zone:%s dest_x:%f dest_y:%f dest_z:%f dest_heading:%f", "dest_zone:%s destination:%s ",
dest_zone, dest_x, dest_y, dest_z, dest_heading); dest_zone, to_string(m_Destination).c_str());
} }
int32 ZoneDatabase::GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version) { 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) void Doors::SetLocation(float x, float y, float z)
{ {
entity_list.DespawnAllDoors(); entity_list.DespawnAllDoors();
pos_x = x; m_Position = xyz_location(x, y, z);
pos_y = y;
pos_z = z;
entity_list.RespawnAllDoors(); entity_list.RespawnAllDoors();
} }
void Doors::SetX(float in) { void Doors::SetPosition(const xyz_heading& position) {
entity_list.DespawnAllDoors(); entity_list.DespawnAllDoors();
pos_x = in; m_Position = position;
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;
entity_list.RespawnAllDoors(); entity_list.RespawnAllDoors();
} }
@ -767,6 +738,6 @@ void Doors::CreateDatabaseEntry()
{ {
return; 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());
} }

View File

@ -17,7 +17,7 @@ class Doors : public Entity
{ {
public: public:
Doors(const Door* door); 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(); ~Doors();
bool IsDoor() const { return true; } bool IsDoor() const { return true; }
void HandleClick(Client* sender, uint8 trigger); void HandleClick(Client* sender, uint8 trigger);
@ -29,10 +29,7 @@ public:
char* GetDoorName() { return door_name; } char* GetDoorName() { return door_name; }
uint32 GetDoorParam() { return door_param; } uint32 GetDoorParam() { return door_param; }
int GetInvertState() { return invert_state; } int GetInvertState() { return invert_state; }
float GetX() { return pos_x; } const xyz_heading GetPosition() const{ return m_Position; }
float GetY() { return pos_y; }
float GetZ() { return pos_z; }
float GetHeading() { return heading; }
int GetIncline() { return incline; } int GetIncline() { return incline; }
bool triggered; bool triggered;
void SetOpenState(bool st) { isopen = st; } void SetOpenState(bool st) { isopen = st; }
@ -54,10 +51,7 @@ public:
void SetEntityID(uint32 entity) { entity_id = entity; } void SetEntityID(uint32 entity) { entity_id = entity; }
void DumpDoor(); void DumpDoor();
float GetDestX() { return dest_x; } const xyz_heading GetDestination() const { return m_Destination; }
float GetDestY() { return dest_y; }
float GetDestZ() { return dest_z; }
float GetDestHeading() { return dest_heading; }
uint8 IsLDoNDoor() { return is_ldon_door; } uint8 IsLDoNDoor() { return is_ldon_door; }
uint32 GetClientVersionMask() { return client_version_mask; } uint32 GetClientVersionMask() { return client_version_mask; }
@ -67,14 +61,11 @@ public:
void ForceClose(Mob *sender, bool alt_mode=false); void ForceClose(Mob *sender, bool alt_mode=false);
void ToggleState(Mob *sender); void ToggleState(Mob *sender);
void SetX(float in); void SetPosition(const xyz_heading& position);
void SetY(float in); void SetLocation(float x, float y, float z);
void SetZ(float in);
void SetHeading(float in);
void SetIncline(int in); void SetIncline(int in);
void SetDoorName(const char* name); void SetDoorName(const char* name);
void SetOpenType(uint8 in); void SetOpenType(uint8 in);
void SetLocation(float x, float y, float z);
void SetSize(uint16 size); void SetSize(uint16 size);
void CreateDatabaseEntry(); void CreateDatabaseEntry();
@ -84,10 +75,7 @@ private:
uint8 door_id; uint8 door_id;
char zone_name[32]; char zone_name[32];
char door_name[32]; char door_name[32];
float pos_x; xyz_heading m_Position;
float pos_y;
float pos_z;
float heading;
int incline; int incline;
uint8 opentype; uint8 opentype;
uint32 guild_id; uint32 guild_id;
@ -106,10 +94,7 @@ private:
char dest_zone[16]; char dest_zone[16];
int dest_instance_id; int dest_instance_id;
float dest_x; xyz_heading m_Destination;
float dest_y;
float dest_z;
float dest_heading;
uint8 is_ldon_door; uint8 is_ldon_door;
uint32 client_version_mask; uint32 client_version_mask;

View File

@ -219,11 +219,9 @@ XS(XS__spawn)
int npc_type = (int)SvIV(ST(0)); int npc_type = (int)SvIV(ST(0));
int grid = (int)SvIV(ST(1)); int grid = (int)SvIV(ST(1));
int unused = (int)SvIV(ST(2)); int unused = (int)SvIV(ST(2));
float x = (float)SvNV(ST(3)); auto position = xyz_heading((float)SvNV(ST(3)), (float)SvNV(ST(4)), (float)SvNV(ST(5)), 0.0f);
float y = (float)SvNV(ST(4));
float z = (float)SvNV(ST(5));
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; RETVAL = (r != nullptr) ? r->GetID() : 0;
XSprePUSH; PUSHu((UV)RETVAL); XSprePUSH; PUSHu((UV)RETVAL);
@ -243,12 +241,9 @@ XS(XS__spawn2)
int npc_type = (int)SvIV(ST(0)); int npc_type = (int)SvIV(ST(0));
int grid = (int)SvIV(ST(1)); int grid = (int)SvIV(ST(1));
int unused = (int)SvIV(ST(2)); int unused = (int)SvIV(ST(2));
float x = (float)SvNV(ST(3)); auto position = xyz_heading((float)SvNV(ST(3)), (float)SvNV(ST(4)), (float)SvNV(ST(5)), (float)SvNV(ST(6)));
float y = (float)SvNV(ST(4));
float z = (float)SvNV(ST(5));
float heading = (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; RETVAL = (r != nullptr) ? r->GetID() : 0;
XSprePUSH; PUSHu((UV)RETVAL); XSprePUSH; PUSHu((UV)RETVAL);
@ -275,7 +270,7 @@ XS(XS__unique_spawn)
if(items == 7) if(items == 7)
heading = (float)SvNV(ST(6)); 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; RETVAL = (r != nullptr) ? r->GetID() : 0;
XSprePUSH; PUSHu((UV)RETVAL); XSprePUSH; PUSHu((UV)RETVAL);
@ -1322,11 +1317,9 @@ XS(XS__rebind)
Perl_croak(aTHX_ "Usage: rebind(zoneid, x, y, z)"); Perl_croak(aTHX_ "Usage: rebind(zoneid, x, y, z)");
int zoneid = (int)SvIV(ST(0)); int zoneid = (int)SvIV(ST(0));
float x = (float)SvNV(ST(1)); auto location = xyz_location((float)SvNV(ST(1)),(float)SvNV(ST(2)),(float)SvNV(ST(3)));
float y = (float)SvNV(ST(2));
float z = (float)SvNV(ST(3));
quest_manager.rebind(zoneid, x, y, z); quest_manager.rebind(zoneid, location);
XSRETURN_EMPTY; XSRETURN_EMPTY;
} }
@ -1395,7 +1388,7 @@ XS(XS__moveto)
else else
saveguard = false; saveguard = false;
quest_manager.moveto(x, y, z, h, saveguard); quest_manager.moveto(xyz_heading(x, y, z, h), saveguard);
XSRETURN_EMPTY; XSRETURN_EMPTY;
} }
@ -1750,12 +1743,9 @@ XS(XS__summonburriedplayercorpse)
bool RETVAL; bool RETVAL;
uint32 char_id = (int)SvIV(ST(0)); uint32 char_id = (int)SvIV(ST(0));
float dest_x = (float)SvIV(ST(1)); auto position = xyz_heading((float)SvIV(ST(1)), (float)SvIV(ST(2)), (float)SvIV(ST(3)),(float)SvIV(ST(4)));
float dest_y = (float)SvIV(ST(2));
float dest_z = (float)SvIV(ST(3));
float dest_heading = (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); ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0)); sv_2mortal(ST(0));
@ -1771,12 +1761,9 @@ XS(XS__summonallplayercorpses)
bool RETVAL; bool RETVAL;
uint32 char_id = (int)SvIV(ST(0)); uint32 char_id = (int)SvIV(ST(0));
float dest_x = (float)SvIV(ST(1)); auto position = xyz_heading((float)SvIV(ST(1)),(float)SvIV(ST(2)),(float)SvIV(ST(3)),(float)SvIV(ST(4)));
float dest_y = (float)SvIV(ST(2));
float dest_z = (float)SvIV(ST(3));
float dest_heading = (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); ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0)); sv_2mortal(ST(0));
@ -2673,10 +2660,10 @@ XS(XS__CreateGroundObject)
uint16 id = 0; uint16 id = 0;
if(items == 5) if(items == 5)
id = quest_manager.CreateGroundObject(itemid, x, y, z, heading); id = quest_manager.CreateGroundObject(itemid, xyz_heading(x, y, z, heading));
else{ else{
uint32 decay_time = (uint32)SvIV(ST(5)); 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); XSRETURN_IV(id);
@ -2704,7 +2691,7 @@ XS(XS__CreateGroundObjectFromModel)
if (items > 6) if (items > 6)
decay_time = (uint32)SvIV(ST(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); XSRETURN_IV(id);
} }
@ -2979,12 +2966,12 @@ XS(XS__MovePCInstance)
if (items == 4) 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 else
{ {
float heading = (float)SvNV(ST(5)); 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; XSRETURN_EMPTY;

View File

@ -846,10 +846,11 @@ bool EntityList::MakeDoorSpawnPacket(EQApplicationPacket *app, Client *client)
strlen(door->GetDoorName()) > 3) { strlen(door->GetDoorName()) > 3) {
memset(&nd, 0, sizeof(nd)); memset(&nd, 0, sizeof(nd));
memcpy(nd.name, door->GetDoorName(), 32); memcpy(nd.name, door->GetDoorName(), 32);
nd.xPos = door->GetX(); auto position = door->GetPosition();
nd.yPos = door->GetY(); nd.xPos = position.m_X;
nd.zPos = door->GetZ(); nd.yPos = position.m_Y;
nd.heading = door->GetHeading(); nd.zPos = position.m_Z;
nd.heading = position.m_Heading;
nd.incline = door->GetIncline(); nd.incline = door->GetIncline();
nd.size = door->GetSize(); nd.size = door->GetSize();
nd.doorId = door->GetDoorID(); nd.doorId = door->GetDoorID();
@ -1551,16 +1552,14 @@ Client *EntityList::GetClientByWID(uint32 iWID)
return nullptr; 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<Client *> ClientsInRange; std::vector<Client *> ClientsInRange;
auto it = client_list.begin();
while (it != client_list.end()) { for (auto it = client_list.begin();it != client_list.end(); ++it)
if ((it->second != ExcludeClient) && (it->second->DistNoRoot(x, y, z) <= Distance)) if ((it->second != ExcludeClient) && (it->second->DistNoRoot(location.m_X, location.m_Y, location.m_Z) <= Distance))
ClientsInRange.push_back(it->second); ClientsInRange.push_back(it->second);
++it;
}
if (ClientsInRange.empty()) if (ClientsInRange.empty())
return nullptr; return nullptr;
@ -3065,56 +3064,45 @@ void EntityList::AddHealAggro(Mob *target, Mob *caster, uint16 thedam)
void EntityList::OpenDoorsNear(NPC *who) 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; Doors *cdoor = it->second;
if (cdoor && !cdoor->IsDoorOpen()) { if (!cdoor || cdoor->IsDoorOpen())
float zdiff = who->GetZ() - cdoor->GetZ(); continue;
if (zdiff < 0)
zdiff = 0 - zdiff; auto diff = who->GetPosition() - cdoor->GetPosition();
float curdist = 0; diff.ABS_XYZ();
float tmp = who->GetX() - cdoor->GetX();
curdist += tmp * tmp; float curdist = diff.m_X * diff.m_X + diff.m_Y * diff.m_Y;
tmp = who->GetY() - cdoor->GetY();
curdist += tmp * tmp; if (diff.m_Z * diff.m_Z < 10 && curdist <= 100)
if (zdiff < 10 && curdist <= 100)
cdoor->NPCOpen(who); cdoor->NPCOpen(who);
} }
++it;
}
} }
void EntityList::SendAlarm(Trap *trap, Mob *currenttarget, uint8 kos) 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(); for (auto it = npc_list.begin();it != npc_list.end(); ++it) {
while (it != npc_list.end()) {
NPC *cur = it->second; NPC *cur = it->second;
float curdist = 0;
float tmp = cur->GetX() - trap->x; auto diff = cur->GetPosition() - trap->m_Position;
curdist += tmp*tmp; float curdist = diff.m_X * diff.m_X + diff.m_Y * diff.m_Y + diff.m_Z * diff.m_Z;
tmp = cur->GetY() - trap->y;
curdist += tmp*tmp; if (cur->GetOwner() || cur->IsEngaged() || curdist > preSquareDistance )
tmp = cur->GetZ() - trap->z; continue;
curdist += tmp*tmp;
if (!cur->GetOwner() &&
/*!cur->CastToMob()->dead && */
!cur->IsEngaged() &&
curdist <= val2 )
{
if (kos) { if (kos) {
uint8 factioncon = currenttarget->GetReverseFactionCon(cur); uint8 factioncon = currenttarget->GetReverseFactionCon(cur);
if (factioncon == FACTION_THREATENLY || factioncon == FACTION_SCOWLS) { if (factioncon == FACTION_THREATENLY || factioncon == FACTION_SCOWLS) {
cur->AddToHateList(currenttarget,1); cur->AddToHateList(currenttarget,1);
} }
} else { }
else
cur->AddToHateList(currenttarget,1); cur->AddToHateList(currenttarget,1);
} }
} }
++it;
}
}
void EntityList::AddProximity(NPC *proximity_for) void EntityList::AddProximity(NPC *proximity_for)
{ {
@ -3149,7 +3137,7 @@ struct quest_proximity_event {
int area_type; 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_x = c->ProximityX();
float last_y = c->ProximityY(); 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) { last_z < l->min_z || last_z > l->max_z) {
old_in = false; old_in = false;
} }
if (x < l->min_x || x > l->max_x || if (location.m_X < l->min_x || location.m_X > l->max_x ||
y < l->min_y || y > l->max_y || location.m_Y < l->min_y || location.m_Y > l->max_y ||
z < l->min_z || z > l->max_z) { location.m_Z < l->min_z || location.m_Z > l->max_z) {
new_in = false; new_in = false;
} }
@ -3206,9 +3194,9 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z)
old_in = false; old_in = false;
} }
if (x < a.min_x || x > a.max_x || if (location.m_X < a.min_x || location.m_X > a.max_x ||
y < a.min_y || y > a.max_y || location.m_Y < a.min_y || location.m_Y > a.max_y ||
z < a.min_z || z > a.max_z ) { location.m_Z < a.min_z || location.m_Z > a.max_z ) {
new_in = false; new_in = false;
} }
@ -3802,43 +3790,46 @@ void EntityList::GroupMessage(uint32 gid, const char *from, const char *message)
} }
} }
uint16 EntityList::CreateGroundObject(uint32 itemid, float x, float y, float z, uint16 EntityList::CreateGroundObject(uint32 itemid, const xyz_heading& position, uint32 decay_time)
float heading, uint32 decay_time)
{ {
const Item_Struct *is = database.GetItem(itemid); const Item_Struct *is = database.GetItem(itemid);
if (is) { if (!is)
return 0;
ItemInst *i = new ItemInst(is, is->MaxCharges); ItemInst *i = new ItemInst(is, is->MaxCharges);
if (i) { if (!i)
Object *object = new Object(i, x, y, z, heading,decay_time); 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); entity_list.AddObject(object, true);
safe_delete(i); safe_delete(i);
if (object) if (!object)
return 0;
return object->GetID(); return object->GetID();
} }
return 0; // fell through itemstruct
}
return 0; // fell through everything, this is bad/incomplete from perl
}
uint16 EntityList::CreateGroundObjectFromModel(const char *model, float x, uint16 EntityList::CreateGroundObjectFromModel(const char *model, const xyz_heading& position, uint8 type, uint32 decay_time)
float y, float z, float heading, uint8 type, uint32 decay_time)
{ {
if (model) { if (!model)
Object *object = new Object(model, x, y, z, heading, type); return 0;
Object *object = new Object(model, position.m_X, position.m_Y, position.m_Z, position.m_Heading, type);
entity_list.AddObject(object, true); entity_list.AddObject(object, true);
if (object) if (!object)
return 0;
return object->GetID(); return object->GetID();
} }
return 0; // fell through everything, this is bad/incomplete from perl
}
uint16 EntityList::CreateDoor(const char *model, float x, float y, float z, uint16 EntityList::CreateDoor(const char *model, const xyz_heading& position, uint8 opentype, uint16 size)
float heading, uint8 opentype, uint16 size)
{ {
if (model) { if (!model)
Doors *door = new Doors(model, x, y, z, heading, opentype, size); return 0; // fell through everything, this is bad/incomplete from perl
Doors *door = new Doors(model, position, opentype, size);
RemoveAllDoors(); RemoveAllDoors();
zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion()); zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion());
entity_list.AddDoor(door); entity_list.AddDoor(door);
@ -3846,7 +3837,7 @@ uint16 EntityList::CreateDoor(const char *model, float x, float y, float z,
if (door) if (door)
return door->GetEntityID(); return door->GetEntityID();
}
return 0; // fell through everything, this is bad/incomplete from perl return 0; // fell through everything, this is bad/incomplete from perl
} }

View File

@ -27,6 +27,7 @@
#include "../common/bodytypes.h" #include "../common/bodytypes.h"
#include "../common/eq_constants.h" #include "../common/eq_constants.h"
#include "position.h"
#include "zonedump.h" #include "zonedump.h"
class Beacon; class Beacon;
@ -154,7 +155,7 @@ public:
Client *GetClientByCharID(uint32 iCharID); Client *GetClientByCharID(uint32 iCharID);
Client *GetClientByWID(uint32 iWID); Client *GetClientByWID(uint32 iWID);
Client *GetClient(uint32 ip, uint16 port); 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 *GetGroupByMob(Mob* mob);
Group *GetGroupByClient(Client* client); Group *GetGroupByClient(Client* client);
Group *GetGroupByID(uint32 id); Group *GetGroupByID(uint32 id);
@ -202,7 +203,7 @@ public:
void MobProcess(); void MobProcess();
void TrapProcess(); void TrapProcess();
void BeaconProcess(); 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 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 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); void RemoveArea(int id);
@ -393,9 +394,9 @@ public:
void SaveAllClientsTaskState(); void SaveAllClientsTaskState();
void ReloadAllClientsTaskState(int TaskID=0); void ReloadAllClientsTaskState(int TaskID=0);
uint16 CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time = 300000); uint16 CreateGroundObject(uint32 itemid, const xyz_heading& position, 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 CreateGroundObjectFromModel(const char *model, const xyz_heading& position, 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 CreateDoor(const char *model, const xyz_heading& position, uint8 type = 0, uint16 size = 100);
void ZoneWho(Client *c, Who_All_Struct* Who); void ZoneWho(Client *c, Who_All_Struct* Who);
void UnMarkNPC(uint16 ID); void UnMarkNPC(uint16 ID);

View File

@ -162,9 +162,7 @@ void Mob::CalculateNewFearpoint()
if(Route.size() > 0) if(Route.size() > 0)
{ {
fear_walkto_x = Loc.x; m_FearWalkTarget = xyz_location(Loc.x, Loc.y, Loc.z);
fear_walkto_y = Loc.y;
fear_walkto_z = Loc.z;
curfp = true; curfp = true;
mlog(PATHING__DEBUG, "Feared to node %i (%8.3f, %8.3f, %8.3f)", Node, Loc.x, Loc.y, Loc.z); 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) if (curfp)
{ m_FearWalkTarget = xyz_location(ranx, rany, ranz);
fear_walkto_x = ranx;
fear_walkto_y = rany;
fear_walkto_z = ranz;
}
else //Break fear else //Break fear
{
BuffFadeByEffect(SE_Fear); BuffFadeByEffect(SE_Fear);
} }
}

View File

@ -174,7 +174,8 @@ bool Client::CanFish() {
} }
if(zone->zonemap != nullptr && zone->watermap != nullptr && RuleB(Watermap, CheckForWaterWhenFishing)) { if(zone->zonemap != nullptr && zone->watermap != nullptr && RuleB(Watermap, CheckForWaterWhenFishing)) {
float RodX, RodY, RodZ;
xyz_location rodPosition;
// Tweak Rod and LineLength if required // Tweak Rod and LineLength if required
const float RodLength = RuleR(Watermap, FishingRodLength); const float RodLength = RuleR(Watermap, FishingRodLength);
const float LineLength = RuleR(Watermap, FishingLineLength); const float LineLength = RuleR(Watermap, FishingLineLength);
@ -183,25 +184,25 @@ bool Client::CanFish() {
HeadingDegrees = (int) ((GetHeading()*360)/256); HeadingDegrees = (int) ((GetHeading()*360)/256);
HeadingDegrees = HeadingDegrees % 360; HeadingDegrees = HeadingDegrees % 360;
RodX = x_pos + RodLength * sin(HeadingDegrees * M_PI/180.0f); rodPosition.m_X = m_Position.m_X + RodLength * sin(HeadingDegrees * M_PI/180.0f);
RodY = y_pos + RodLength * cos(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). // 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. // and go 1 unit into the water.
Map::Vertex dest; Map::Vertex dest;
dest.x = RodX; dest.x = rodPosition.m_X;
dest.y = RodY; dest.y = rodPosition.m_Y;
dest.z = z_pos+10; dest.z = m_Position.m_Z+10;
RodZ = zone->zonemap->FindBestZ(dest, nullptr) + 4; rodPosition.m_Z = zone->zonemap->FindBestZ(dest, nullptr) + 4;
bool in_lava = zone->watermap->InLava(RodX, RodY, RodZ); bool in_lava = zone->watermap->InLava(rodPosition);
bool in_water = zone->watermap->InWater(RodX, RodY, RodZ) || zone->watermap->InVWater(RodX, RodY, RodZ); 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); //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) { if (in_lava) {
Message_StringID(MT_Skills, FISHING_LAVA); //Trying to catch a fire elemental or something? Message_StringID(MT_Skills, FISHING_LAVA); //Trying to catch a fire elemental or something?
return false; 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? Message_StringID(MT_Skills, FISHING_LAND); //Trying to catch land sharks perhaps?
return false; return false;
} }
@ -272,7 +273,9 @@ void Client::GoFish()
if(npc_chance < zone->random.Int(0, 99)) { if(npc_chance < zone->random.Int(0, 99)) {
const NPCType* tmp = database.GetNPCType(npc_id); const NPCType* tmp = database.GetNPCType(npc_id);
if(tmp != nullptr) { 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->AddLootTable();
npc->AddToHateList(this, 1, 0, false); //no help yelling npc->AddToHateList(this, 1, 0, false); //no help yelling

View File

@ -308,8 +308,9 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center)
continue; 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 (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++; skipped_count++;
++iterator; ++iterator;
continue; continue;
@ -434,7 +435,7 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center)
{ {
struct_HateList *cur = (*iterator); struct_HateList *cur = (*iterator);
if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { 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++; skipped_count++;
++iterator; ++iterator;
continue; continue;

View File

@ -28,8 +28,8 @@
std::map<uint16, const NPCType *> Horse::horse_types; std::map<uint16, const NPCType *> Horse::horse_types;
LinkedList<NPCType *> horses_auto_delete; LinkedList<NPCType *> horses_auto_delete;
Horse::Horse(Client *_owner, uint16 spell_id, float x, float y, float z, float heading) Horse::Horse(Client *_owner, uint16 spell_id, const xyz_heading& position)
: NPC(GetHorseType(spell_id), nullptr, x, y, z, heading, FlyMode3) : NPC(GetHorseType(spell_id), nullptr, position, FlyMode3)
{ {
//give the horse its proper name. //give the horse its proper name.
strn0cpy(name, _owner->GetCleanName(), 55); strn0cpy(name, _owner->GetCleanName(), 55);
@ -126,7 +126,7 @@ void Client::SummonHorse(uint16 spell_id) {
// No Horse, lets get them one. // 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. //we want to manage the spawn packet ourself.
//another reason is we dont want quests executing on it. //another reason is we dont want quests executing on it.

View File

@ -29,7 +29,7 @@ struct NewSpawn_Struct;
class Horse : public NPC { class Horse : public NPC {
public: 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); virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);

View File

@ -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) { void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x) {
Lua_Safe_Call_Void(); 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) { void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y) {
Lua_Safe_Call_Void(); 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) { void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y, float new_z) {
Lua_Safe_Call_Void(); 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() { float Lua_Client::GetBindX() {

View File

@ -20,42 +20,50 @@ const char *Lua_Door::GetDoorName() {
float Lua_Door::GetX() { float Lua_Door::GetX() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetX(); return self->GetPosition().m_X;
} }
float Lua_Door::GetY() { float Lua_Door::GetY() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetY(); return self->GetPosition().m_Y;
} }
float Lua_Door::GetZ() { float Lua_Door::GetZ() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetZ(); return self->GetPosition().m_Z;
} }
float Lua_Door::GetHeading() { float Lua_Door::GetHeading() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetHeading(); return self->GetPosition().m_Heading;
} }
void Lua_Door::SetX(float x) { void Lua_Door::SetX(float x) {
Lua_Safe_Call_Void(); Lua_Safe_Call_Void();
self->SetX(x); auto position = self->GetPosition();
position.m_X = x;
self->SetPosition(position);
} }
void Lua_Door::SetY(float y) { void Lua_Door::SetY(float y) {
Lua_Safe_Call_Void(); Lua_Safe_Call_Void();
self->SetY(y); auto position = self->GetPosition();
position.m_Y = y;
self->SetPosition(position);
} }
void Lua_Door::SetZ(float z) { void Lua_Door::SetZ(float z) {
Lua_Safe_Call_Void(); Lua_Safe_Call_Void();
self->SetZ(z); auto position = self->GetPosition();
position.m_Z = z;
self->SetPosition(position);
} }
void Lua_Door::SetHeading(float h) { void Lua_Door::SetHeading(float h) {
Lua_Safe_Call_Void(); 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) { void Lua_Door::SetLocation(float x, float y, float z) {

View File

@ -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_Client Lua_EntityList::GetRandomClient(float x, float y, float z, float dist) {
Lua_Safe_Call_Class(Lua_Client); 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_Client Lua_EntityList::GetRandomClient(float x, float y, float z, float dist, Lua_Client exclude) {
Lua_Safe_Call_Class(Lua_Client); 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() { Lua_Mob_List Lua_EntityList::GetMobList() {

View File

@ -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) { 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, auto position = xyz_heading(x, y, z, heading);
static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(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) { 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, auto position = xyz_heading(x,y,z,heading);
static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(heading))); return Lua_Mob(quest_manager.unique_spawn(npc_type, grid, unused, position));
} }
Lua_Mob lua_spawn_from_spawn2(uint32 spawn2_id) { 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) { 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) { 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) { 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() { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { void lua_create_door(const char *model, float x, float y, float z, float h, int open_type, int size) {
@ -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(raid_target, bool, false);
LuaCreateNPCParse(probability, uint8, 0); 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); npc->GiveNPCTypeData(npc_type);
entity_list.AddNPC(npc); entity_list.AddNPC(npc);
} }

View File

@ -674,22 +674,22 @@ double Lua_Mob::GetHeading() {
double Lua_Mob::GetWaypointX() { double Lua_Mob::GetWaypointX() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetCWPX(); return self->GetCurrentWayPoint().m_X;
} }
double Lua_Mob::GetWaypointY() { double Lua_Mob::GetWaypointY() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetCWPY(); return self->GetCurrentWayPoint().m_Y;
} }
double Lua_Mob::GetWaypointZ() { double Lua_Mob::GetWaypointZ() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetCWPZ(); return self->GetCurrentWayPoint().m_Z;
} }
double Lua_Mob::GetWaypointH() { double Lua_Mob::GetWaypointH() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetCWPH(); return self->GetCurrentWayPoint().m_Heading;
} }
double Lua_Mob::GetWaypointPause() { double Lua_Mob::GetWaypointPause() {

View File

@ -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) { void Lua_NPC::MoveTo(float x, float y, float z, float h, bool save) {
Lua_Safe_Call_Void(); 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() { void Lua_NPC::NextGuardPosition() {
@ -314,37 +315,37 @@ int Lua_NPC::GetSpawnPointID() {
float Lua_NPC::GetSpawnPointX() { float Lua_NPC::GetSpawnPointX() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetSpawnPointX(); return self->GetSpawnPoint().m_X;
} }
float Lua_NPC::GetSpawnPointY() { float Lua_NPC::GetSpawnPointY() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetSpawnPointY(); return self->GetSpawnPoint().m_Y;
} }
float Lua_NPC::GetSpawnPointZ() { float Lua_NPC::GetSpawnPointZ() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetSpawnPointZ(); return self->GetSpawnPoint().m_Z;
} }
float Lua_NPC::GetSpawnPointH() { float Lua_NPC::GetSpawnPointH() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetSpawnPointH(); return self->GetSpawnPoint().m_Heading;
} }
float Lua_NPC::GetGuardPointX() { float Lua_NPC::GetGuardPointX() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetGuardPointX(); return self->GetGuardPoint().m_X;
} }
float Lua_NPC::GetGuardPointY() { float Lua_NPC::GetGuardPointY() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetGuardPointY(); return self->GetGuardPoint().m_Y;
} }
float Lua_NPC::GetGuardPointZ() { float Lua_NPC::GetGuardPointZ() {
Lua_Safe_Call_Real(); Lua_Safe_Call_Real();
return self->GetGuardPointZ(); return self->GetGuardPoint().m_Z;
} }
void Lua_NPC::SetPrimSkill(int skill_id) { void Lua_NPC::SetPrimSkill(int skill_id) {

View File

@ -22,6 +22,7 @@
#ifndef ZONE_MAP_H #ifndef ZONE_MAP_H
#define ZONE_MAP_H #define ZONE_MAP_H
#include "position.h"
#include <stdio.h> #include <stdio.h>
#define BEST_Z_INVALID -99999 #define BEST_Z_INVALID -99999
@ -39,6 +40,10 @@ public:
{ {
return((v.x == x) && (v.y == y) && (v.z == z)); return((v.x == x) && (v.y == y) && (v.z == z));
} }
operator xyz_location() const
{
return xyz_location(x,y,z);
}
float x; float x;
float y; float y;

View File

@ -20,7 +20,7 @@
extern volatile bool ZoneLoaded; extern volatile bool ZoneLoaded;
Merc::Merc(const NPCType* d, float x, float y, float z, float heading) 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_hp = d->max_hp;
base_mana = d->Mana; base_mana = d->Mana;

View File

@ -49,11 +49,7 @@ Mob::Mob(const char* in_name,
uint32 in_npctype_id, uint32 in_npctype_id,
float in_size, float in_size,
float in_runspeed, float in_runspeed,
float in_heading, const xyz_heading& position,
float in_x_pos,
float in_y_pos,
float in_z_pos,
uint8 in_light, uint8 in_light,
uint8 in_texture, uint8 in_texture,
uint8 in_helmtexture, uint8 in_helmtexture,
@ -102,29 +98,21 @@ Mob::Mob(const char* in_name,
bardsong_timer(6000), bardsong_timer(6000),
gravity_timer(1000), gravity_timer(1000),
viral_timer(0), 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; targeted = 0;
tar_ndx=0; tar_ndx=0;
tar_vector=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; curfp = false;
AI_Init(); AI_Init();
SetMoving(false); SetMoving(false);
moved=false; moved=false;
rewind_x = 0; //Stored x_pos for /rewind m_RewindLocation = xyz_location::Origin();
rewind_y = 0; //Stored y_pos for /rewind
rewind_z = 0; //Stored z_pos for /rewind
move_tic_count = 0; move_tic_count = 0;
_egnode = nullptr; _egnode = nullptr;
@ -161,10 +149,6 @@ Mob::Mob(const char* in_name,
if (runspeed < 0 || runspeed > 20) if (runspeed < 0 || runspeed > 20)
runspeed = 1.25f; runspeed = 1.25f;
heading = in_heading;
x_pos = in_x_pos;
y_pos = in_y_pos;
z_pos = in_z_pos;
light = in_light; light = in_light;
texture = in_texture; texture = in_texture;
helmtexture = in_helmtexture; helmtexture = in_helmtexture;
@ -259,10 +243,7 @@ Mob::Mob(const char* in_name,
} }
} }
delta_heading = 0; m_Delta = xyz_heading::Origin();
delta_x = 0;
delta_y = 0;
delta_z = 0;
animation = 0; animation = 0;
logging_enabled = false; logging_enabled = false;
@ -335,17 +316,12 @@ Mob::Mob(const char* in_name,
wandertype=0; wandertype=0;
pausetype=0; pausetype=0;
cur_wp = 0; cur_wp = 0;
cur_wp_x = 0; m_CurrentWayPoint = xyz_heading::Origin();
cur_wp_y = 0;
cur_wp_z = 0;
cur_wp_pause = 0; cur_wp_pause = 0;
patrol=0; patrol=0;
follow=0; follow=0;
follow_dist = 100; // Default Distance for Follow follow_dist = 100; // Default Distance for Follow
flee_mode = false; flee_mode = false;
fear_walkto_x = -999999;
fear_walkto_y = -999999;
fear_walkto_z = -999999;
curfp = false; curfp = false;
flee_timer.Start(); flee_timer.Start();
@ -387,9 +363,7 @@ Mob::Mob(const char* in_name,
nimbus_effect3 = 0; nimbus_effect3 = 0;
m_targetable = true; m_targetable = true;
targetring_x = 0.0f; m_TargetRing = xyz_location::Origin();
targetring_y = 0.0f;
targetring_z = 0.0f;
flymode = FlyMode3; flymode = FlyMode3;
// Pathing // Pathing
@ -908,10 +882,10 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName)); strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName));
} }
ns->spawn.heading = FloatToEQ19(heading); ns->spawn.heading = FloatToEQ19(m_Position.m_Heading);
ns->spawn.x = FloatToEQ19(x_pos);//((int32)x_pos)<<3; ns->spawn.x = FloatToEQ19(m_Position.m_X);//((int32)x_pos)<<3;
ns->spawn.y = FloatToEQ19(y_pos);//((int32)y_pos)<<3; ns->spawn.y = FloatToEQ19(m_Position.m_Y);//((int32)y_pos)<<3;
ns->spawn.z = FloatToEQ19(z_pos);//((int32)z_pos)<<3; ns->spawn.z = FloatToEQ19(m_Position.m_Z);//((int32)z_pos)<<3;
ns->spawn.spawnId = GetID(); ns->spawn.spawnId = GetID();
ns->spawn.curHp = static_cast<uint8>(GetHPRatio()); ns->spawn.curHp = static_cast<uint8>(GetHPRatio());
ns->spawn.max_hp = 100; //this field needs a better name 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 // 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. // (in water or not) according to 6.2 era packet collects.
if(IsClient()) if(IsClient())
{
ns->spawn.flymode = FindType(SE_Levitate) ? 2 : 0; ns->spawn.flymode = FindType(SE_Levitate) ? 2 : 0;
}
else else
{
ns->spawn.flymode = flymode; ns->spawn.flymode = flymode;
}
ns->spawn.lastName[0] = '\0'; ns->spawn.lastName[0] = '\0';
@ -1240,13 +1210,13 @@ void Mob::SendPosUpdate(uint8 iSendToSelf) {
void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu){ void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu){
memset(spu,0xff,sizeof(PlayerPositionUpdateServer_Struct)); memset(spu,0xff,sizeof(PlayerPositionUpdateServer_Struct));
spu->spawn_id = GetID(); spu->spawn_id = GetID();
spu->x_pos = FloatToEQ19(x_pos); spu->x_pos = FloatToEQ19(m_Position.m_X);
spu->y_pos = FloatToEQ19(y_pos); spu->y_pos = FloatToEQ19(m_Position.m_Y);
spu->z_pos = FloatToEQ19(z_pos); spu->z_pos = FloatToEQ19(m_Position.m_Z);
spu->delta_x = NewFloatToEQ13(0); spu->delta_x = NewFloatToEQ13(0);
spu->delta_y = NewFloatToEQ13(0); spu->delta_y = NewFloatToEQ13(0);
spu->delta_z = NewFloatToEQ13(0); spu->delta_z = NewFloatToEQ13(0);
spu->heading = FloatToEQ19(heading); spu->heading = FloatToEQ19(m_Position.m_Heading);
spu->animation = 0; spu->animation = 0;
spu->delta_heading = NewFloatToEQ13(0); spu->delta_heading = NewFloatToEQ13(0);
spu->padding0002 =0; spu->padding0002 =0;
@ -1259,13 +1229,13 @@ void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu){
// this is for SendPosUpdate() // this is for SendPosUpdate()
void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) { void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) {
spu->spawn_id = GetID(); spu->spawn_id = GetID();
spu->x_pos = FloatToEQ19(x_pos); spu->x_pos = FloatToEQ19(m_Position.m_X);
spu->y_pos = FloatToEQ19(y_pos); spu->y_pos = FloatToEQ19(m_Position.m_Y);
spu->z_pos = FloatToEQ19(z_pos); spu->z_pos = FloatToEQ19(m_Position.m_Z);
spu->delta_x = NewFloatToEQ13(delta_x); spu->delta_x = NewFloatToEQ13(m_Delta.m_X);
spu->delta_y = NewFloatToEQ13(delta_y); spu->delta_y = NewFloatToEQ13(m_Delta.m_Y);
spu->delta_z = NewFloatToEQ13(delta_z); spu->delta_z = NewFloatToEQ13(m_Delta.m_Z);
spu->heading = FloatToEQ19(heading); spu->heading = FloatToEQ19(m_Position.m_Heading);
spu->padding0002 =0; spu->padding0002 =0;
spu->padding0006 =7; spu->padding0006 =7;
spu->padding0014 =0x7f; spu->padding0014 =0x7f;
@ -1274,7 +1244,7 @@ void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) {
spu->animation = animation; spu->animation = animation;
else else
spu->animation = pRunAnimSpeed;//animation; spu->animation = pRunAnimSpeed;//animation;
spu->delta_heading = NewFloatToEQ13(static_cast<float>(delta_heading)); spu->delta_heading = NewFloatToEQ13(m_Delta.m_Heading);
} }
void Mob::ShowStats(Client* client) 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); entity_list.ProcessMove(CastToNPC(), x, y, z);
} }
x_pos = x; m_Position.m_X = x;
y_pos = y; m_Position.m_Y = y;
z_pos = z; m_Position.m_Z = z;
if (heading != 0.01) if (m_Position.m_Heading != 0.01)
this->heading = heading; this->m_Position.m_Heading = heading;
if(IsNPC()) if(IsNPC())
CastToNPC()->SaveGuardSpot(true); CastToNPC()->SaveGuardSpot(true);
if(SendUpdate) if(SendUpdate)
@ -2305,9 +2275,9 @@ bool Mob::CanThisClassBlock(void) const
} }
float Mob::Dist(const Mob &other) const { float Mob::Dist(const Mob &other) const {
float xDiff = other.x_pos - x_pos; float xDiff = other.m_Position.m_X - m_Position.m_X;
float yDiff = other.y_pos - y_pos; float yDiff = other.m_Position.m_Y - m_Position.m_Y;
float zDiff = other.z_pos - z_pos; float zDiff = other.m_Position.m_Z - m_Position.m_Z;
return sqrtf( (xDiff * xDiff) return sqrtf( (xDiff * xDiff)
+ (yDiff * yDiff) + (yDiff * yDiff)
@ -2315,17 +2285,17 @@ float Mob::Dist(const Mob &other) const {
} }
float Mob::DistNoZ(const Mob &other) const { float Mob::DistNoZ(const Mob &other) const {
float xDiff = other.x_pos - x_pos; float xDiff = other.m_Position.m_X - m_Position.m_X;
float yDiff = other.y_pos - y_pos; float yDiff = other.m_Position.m_Y - m_Position.m_Y;
return sqrtf( (xDiff * xDiff) return sqrtf( (xDiff * xDiff)
+ (yDiff * yDiff) ); + (yDiff * yDiff) );
} }
float Mob::DistNoRoot(const Mob &other) const { float Mob::DistNoRoot(const Mob &other) const {
float xDiff = other.x_pos - x_pos; float xDiff = other.m_Position.m_X - m_Position.m_X;
float yDiff = other.y_pos - y_pos; float yDiff = other.m_Position.m_Y - m_Position.m_Y;
float zDiff = other.z_pos - z_pos; float zDiff = other.m_Position.m_Z - m_Position.m_Z;
return ( (xDiff * xDiff) return ( (xDiff * xDiff)
+ (yDiff * yDiff) + (yDiff * yDiff)
@ -2333,9 +2303,9 @@ float Mob::DistNoRoot(const Mob &other) const {
} }
float Mob::DistNoRoot(float x, float y, float z) const { float Mob::DistNoRoot(float x, float y, float z) const {
float xDiff = x - x_pos; float xDiff = x - m_Position.m_X;
float yDiff = y - y_pos; float yDiff = y - m_Position.m_Y;
float zDiff = z - z_pos; float zDiff = z - m_Position.m_Z;
return ( (xDiff * xDiff) return ( (xDiff * xDiff)
+ (yDiff * yDiff) + (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 Mob::DistNoRootNoZ(float x, float y) const {
float xDiff = x - x_pos; float xDiff = x - m_Position.m_X;
float yDiff = y - y_pos; float yDiff = y - m_Position.m_Y;
return ( (xDiff * xDiff) + (yDiff * yDiff) ); return ( (xDiff * xDiff) + (yDiff * yDiff) );
} }
float Mob::DistNoRootNoZ(const Mob &other) const { float Mob::DistNoRootNoZ(const Mob &other) const {
float xDiff = other.x_pos - x_pos; float xDiff = other.m_Position.m_X - m_Position.m_X;
float yDiff = other.y_pos - y_pos; float yDiff = other.m_Position.m_Y - m_Position.m_Y;
return ( (xDiff * xDiff) + (yDiff * yDiff) ); 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() ); entity_list.MessageClose(this, true, 500, MT_Say, "%s says,'You will not evade me, %s!' ", GetCleanName(), target->GetCleanName() );
if (target->IsClient()) { 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 { else {
#ifdef BOTS #ifdef BOTS
if(target && target->IsBot()) { if(target && target->IsBot()) {
// set pre summoning info to return to (to get out of melee range for caster) // set pre summoning info to return to (to get out of melee range for caster)
target->CastToBot()->SetHasBeenSummoned(true); target->CastToBot()->SetHasBeenSummoned(true);
target->CastToBot()->SetPreSummonX(target->GetX()); target->CastToBot()->SetPreSummonLocation(target->GetPosition());
target->CastToBot()->SetPreSummonY(target->GetY());
target->CastToBot()->SetPreSummonZ(target->GetZ());
} }
#endif //BOTS #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; return true;
@ -2798,14 +2766,10 @@ uint32 Mob::GetEquipmentColor(uint8 material_slot) const
{ {
return armor_tint[material_slot]; return armor_tint[material_slot];
} }
else
{
item = database.GetItem(GetEquipment(material_slot)); item = database.GetItem(GetEquipment(material_slot));
if (item != 0) if (item != 0)
{
return item->Color; return item->Color;
}
}
return 0; return 0;
} }
@ -2927,20 +2891,16 @@ void Mob::SetNextIncHPEvent( int inchpevent )
nextinchpevent = inchpevent; nextinchpevent = inchpevent;
} }
//warp for quest function,from sandy //warp for quest function,from sandy
void Mob::Warp( float x, float y, float z ) void Mob::Warp(const xyz_location& location)
{ {
if(IsNPC()) { if(IsNPC())
entity_list.ProcessMove(CastToNPC(), x, y, z); entity_list.ProcessMove(CastToNPC(), location.m_X, location.m_Y, location.m_Z);
}
x_pos = x; m_Position = location;
y_pos = y;
z_pos = z;
Mob* target = GetTarget(); Mob* target = GetTarget();
if (target) { if (target)
FaceTarget( target ); FaceTarget( target );
}
SendPosition(); SendPosition();
} }
@ -3026,7 +2986,7 @@ int32 Mob::GetActSpellCasttime(uint16 spell_id, int32 casttime) {
} }
casttime = (casttime*(100 - cast_reducer)/100); casttime = (casttime*(100 - cast_reducer)/100);
return(casttime); return casttime;
} }
void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on) { 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; bool twinproc = false;
int32 twinproc_chance = 0; 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)) if(twinproc_chance && zone->random.Roll(twinproc_chance))
twinproc = true; twinproc = true;
@ -3153,9 +3114,9 @@ float Mob::FindGroundZ(float new_x, float new_y, float z_offset)
if (zone->zonemap != nullptr) if (zone->zonemap != nullptr)
{ {
Map::Vertex me; Map::Vertex me;
me.x = new_x; me.x = m_Position.m_X;
me.y = new_y; me.y = m_Position.m_Y;
me.z = z_pos+z_offset; me.z = m_Position.m_Z + z_offset;
Map::Vertex hit; Map::Vertex hit;
float best_z = zone->zonemap->FindBestZ(me, &hit); float best_z = zone->zonemap->FindBestZ(me, &hit);
if (best_z != -999999) if (best_z != -999999)
@ -3173,9 +3134,9 @@ float Mob::GetGroundZ(float new_x, float new_y, float z_offset)
if (zone->zonemap != 0) if (zone->zonemap != 0)
{ {
Map::Vertex me; Map::Vertex me;
me.x = new_x; me.x = m_Position.m_X;
me.y = new_y; me.y = m_Position.m_Y;
me.z = z_pos+z_offset; me.z = m_Position.m_Z+z_offset;
Map::Vertex hit; Map::Vertex hit;
float best_z = zone->zonemap->FindBestZ(me, &hit); float best_z = zone->zonemap->FindBestZ(me, &hit);
if (best_z != -999999) 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) { void Mob::SetDelta(const xyz_heading& delta) {
delta_x = dx; m_Delta = delta;
delta_y = dy;
delta_z = dz;
delta_heading = static_cast<int>(dh);
} }
void Mob::SetEntityVariable(const char *id, const char *m_var) void Mob::SetEntityVariable(const char *id, const char *m_var)

View File

@ -22,6 +22,7 @@
#include "entity.h" #include "entity.h"
#include "hate_list.h" #include "hate_list.h"
#include "pathing.h" #include "pathing.h"
#include "position.h"
#include <set> #include <set>
#include <vector> #include <vector>
@ -77,10 +78,7 @@ public:
uint32 in_npctype_id, uint32 in_npctype_id,
float in_size, float in_size,
float in_runspeed, float in_runspeed,
float in_heading, const xyz_heading& position,
float in_x_pos,
float in_y_pos,
float in_z_pos,
uint8 in_light, uint8 in_light,
uint8 in_texture, uint8 in_texture,
uint8 in_helmtexture, uint8 in_helmtexture,
@ -296,9 +294,9 @@ public:
inline virtual uint32 GetNimbusEffect2() const { return nimbus_effect2; } inline virtual uint32 GetNimbusEffect2() const { return nimbus_effect2; }
inline virtual uint32 GetNimbusEffect3() const { return nimbus_effect3; } inline virtual uint32 GetNimbusEffect3() const { return nimbus_effect3; }
void RemoveNimbusEffect(int effectid); void RemoveNimbusEffect(int effectid);
inline float GetTargetRingX() const { return targetring_x; } inline float GetTargetRingX() const { return m_TargetRing.m_X; }
inline float GetTargetRingY() const { return targetring_y; } inline float GetTargetRingY() const { return m_TargetRing.m_Y; }
inline float GetTargetRingZ() const { return targetring_z; } inline float GetTargetRingZ() const { return m_TargetRing.m_Z; }
inline bool HasEndurUpkeep() const { return endur_upkeep; } inline bool HasEndurUpkeep() const { return endur_upkeep; }
inline void SetEndurUpkeep(bool val) { endur_upkeep = val; } inline void SetEndurUpkeep(bool val) { endur_upkeep = val; }
@ -400,18 +398,19 @@ public:
((static_cast<float>(cur_mana) / max_mana) * 100); } ((static_cast<float>(cur_mana) / max_mana) * 100); }
virtual int32 CalcMaxMana(); virtual int32 CalcMaxMana();
uint32 GetNPCTypeID() const { return npctype_id; } uint32 GetNPCTypeID() const { return npctype_id; }
inline const float GetX() const { return x_pos; } inline const xyz_heading GetPosition() const { return m_Position; }
inline const float GetY() const { return y_pos; } inline const float GetX() const { return m_Position.m_X; }
inline const float GetZ() const { return z_pos; } inline const float GetY() const { return m_Position.m_Y; }
inline const float GetHeading() const { return heading; } 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 GetSize() const { return size; }
inline const float GetBaseSize() const { return base_size; } inline const float GetBaseSize() const { return base_size; }
inline const float GetTarX() const { return tarx; } inline const float GetTarX() const { return m_TargetLocation.m_X; }
inline const float GetTarY() const { return tary; } inline const float GetTarY() const { return m_TargetLocation.m_Y; }
inline const float GetTarZ() const { return tarz; } inline const float GetTarZ() const { return m_TargetLocation.m_Z; }
inline const float GetTarVX() const { return tar_vx; } inline const float GetTarVX() const { return m_TargetV.m_X; }
inline const float GetTarVY() const { return tar_vy; } inline const float GetTarVY() const { return m_TargetV.m_Y; }
inline const float GetTarVZ() const { return tar_vz; } inline const float GetTarVZ() const { return m_TargetV.m_Z; }
inline const float GetTarVector() const { return tar_vector; } inline const float GetTarVector() const { return tar_vector; }
inline const uint8 GetTarNDX() const { return tar_ndx; } inline const uint8 GetTarNDX() const { return tar_ndx; }
bool IsBoat() const; bool IsBoat() const;
@ -426,9 +425,9 @@ public:
virtual inline int32 GetPrimaryFaction() const { return 0; } virtual inline int32 GetPrimaryFaction() const { return 0; }
//Movement //Movement
void Warp( float x, float y, float z ); void Warp(const xyz_location& location);
inline bool IsMoving() const { return moving; } 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 GoToBind(uint8 bindnum = 0) { }
virtual void Gate(); virtual void Gate();
float GetWalkspeed() const { return(_GetMovementSpeed(-47)); } float GetWalkspeed() const { return(_GetMovementSpeed(-47)); }
@ -438,15 +437,15 @@ public:
bool IsRunning() const { return m_is_running; } bool IsRunning() const { return m_is_running; }
void SetRunning(bool val) { m_is_running = val; } void SetRunning(bool val) { m_is_running = val; }
virtual void GMMove(float x, float y, float z, float heading = 0.01, bool SendUpdate = true); 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 SetTargetDestSteps(uint8 target_steps) { tar_ndx = target_steps; }
void SendPosUpdate(uint8 iSendToSelf = 0); void SendPosUpdate(uint8 iSendToSelf = 0);
void MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct* spu); void MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct* spu);
void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu); void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu);
void SendPosition(); void SendPosition();
void SetFlyMode(uint8 flymode); void SetFlyMode(uint8 flymode);
inline void Teleport(Map::Vertex NewPosition) { x_pos = NewPosition.x; y_pos = NewPosition.y; inline void Teleport(Map::Vertex NewPosition) { m_Position.m_X = NewPosition.x; m_Position.m_Y = NewPosition.y;
z_pos = NewPosition.z; }; m_Position.m_Z = NewPosition.z; };
//AI //AI
static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel); static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel);
@ -467,8 +466,8 @@ public:
bool IsEngaged() { return(!hate_list.IsHateListEmpty()); } bool IsEngaged() { return(!hate_list.IsHateListEmpty()); }
bool HateSummon(); bool HateSummon();
void FaceTarget(Mob* MobToFace = 0); void FaceTarget(Mob* MobToFace = 0);
void SetHeading(float iHeading) { if(heading != iHeading) { pLastChange = Timer::GetCurrentTime(); void SetHeading(float iHeading) { if(m_Position.m_Heading != iHeading) { pLastChange = Timer::GetCurrentTime();
heading = iHeading; } } m_Position.m_Heading = iHeading; } }
void WipeHateList(); void WipeHateList();
void AddFeignMemory(Client* attacker); void AddFeignMemory(Client* attacker);
void RemoveFromFeignMemory(Client* attacker); void RemoveFromFeignMemory(Client* attacker);
@ -821,10 +820,10 @@ public:
void SetDontCureMeBefore(uint32 time) { pDontCureMeBefore = time; } void SetDontCureMeBefore(uint32 time) { pDontCureMeBefore = time; }
// calculate interruption of spell via movement of mob // calculate interruption of spell via movement of mob
void SaveSpellLoc() {spell_x = x_pos; spell_y = y_pos; spell_z = z_pos; } void SaveSpellLoc() {m_SpellLocation = m_Position; }
inline float GetSpellX() const {return spell_x;} inline float GetSpellX() const {return m_SpellLocation.m_X;}
inline float GetSpellY() const {return spell_y;} inline float GetSpellY() const {return m_SpellLocation.m_Y;}
inline float GetSpellZ() const {return spell_z;} inline float GetSpellZ() const {return m_SpellLocation.m_Z;}
inline bool IsGrouped() const { return isgrouped; } inline bool IsGrouped() const { return isgrouped; }
void SetGrouped(bool v); void SetGrouped(bool v);
inline bool IsRaidGrouped() const { return israidgrouped; } inline bool IsRaidGrouped() const { return israidgrouped; }
@ -876,10 +875,7 @@ public:
Shielders_Struct shielder[MAX_SHIELDERS]; Shielders_Struct shielder[MAX_SHIELDERS];
Trade* trade; Trade* trade;
inline float GetCWPX() const { return(cur_wp_x); } inline xyz_heading GetCurrentWayPoint() const { return m_CurrentWayPoint; }
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 float GetCWPP() const { return(static_cast<float>(cur_wp_pause)); } inline float GetCWPP() const { return(static_cast<float>(cur_wp_pause)); }
inline int GetCWP() const { return(cur_wp); } inline int GetCWP() const { return(cur_wp); }
void SetCurrentWP(uint16 waypoint) { cur_wp = waypoint; } void SetCurrentWP(uint16 waypoint) { cur_wp = waypoint; }
@ -1023,10 +1019,7 @@ protected:
uint8 level; uint8 level;
uint8 orig_level; uint8 orig_level;
uint32 npctype_id; uint32 npctype_id;
float x_pos; xyz_heading m_Position;
float y_pos;
float z_pos;
float heading;
uint16 animation; uint16 animation;
float base_size; float base_size;
float size; float size;
@ -1075,10 +1068,7 @@ protected:
char clean_name[64]; char clean_name[64];
char lastname[64]; char lastname[64];
int32 delta_heading; xyz_heading m_Delta;
float delta_x;
float delta_y;
float delta_z;
uint8 light; uint8 light;
@ -1087,7 +1077,6 @@ protected:
uint8 pRunAnimSpeed; uint8 pRunAnimSpeed;
bool m_is_running; bool m_is_running;
Timer attack_timer; Timer attack_timer;
Timer attack_dw_timer; Timer attack_dw_timer;
Timer ranged_timer; Timer ranged_timer;
@ -1100,7 +1089,7 @@ protected:
//spell casting vars //spell casting vars
Timer spellend_timer; Timer spellend_timer;
uint16 casting_spell_id; uint16 casting_spell_id;
float spell_x, spell_y, spell_z; xyz_location m_SpellLocation;
int attacked_count; int attacked_count;
bool delaytimer; bool delaytimer;
uint16 casting_spell_targetid; uint16 casting_spell_targetid;
@ -1119,9 +1108,8 @@ protected:
bool ActiveProjectileATK; bool ActiveProjectileATK;
tProjatk ProjectileAtk[MAX_SPELL_PROJECTILE]; tProjatk ProjectileAtk[MAX_SPELL_PROJECTILE];
float rewind_x; xyz_location m_RewindLocation;
float rewind_y;
float rewind_z;
Timer rewind_timer; Timer rewind_timer;
// Currently 3 max nimbus particle effects at a time // Currently 3 max nimbus particle effects at a time
@ -1217,16 +1205,12 @@ protected:
int pausetype; int pausetype;
int cur_wp; int cur_wp;
float cur_wp_x; xyz_heading m_CurrentWayPoint;
float cur_wp_y;
float cur_wp_z;
int cur_wp_pause; int cur_wp_pause;
float cur_wp_heading;
int patrol; int patrol;
float fear_walkto_x; xyz_location m_FearWalkTarget;
float fear_walkto_y;
float fear_walkto_z;
bool curfp; bool curfp;
// Pathing // Pathing
@ -1261,19 +1245,13 @@ protected:
bool pet_owner_client; //Flags regular and pets as belonging to a client bool pet_owner_client; //Flags regular and pets as belonging to a client
EGNode *_egnode; //the EG node we are in EGNode *_egnode; //the EG node we are in
float tarx; xyz_location m_TargetLocation;
float tary;
float tarz;
uint8 tar_ndx; uint8 tar_ndx;
float tar_vector; float tar_vector;
float tar_vx; xyz_location m_TargetV;
float tar_vy;
float tar_vz;
float test_vector; float test_vector;
float targetring_x; xyz_location m_TargetRing;
float targetring_y;
float targetring_z;
uint32 m_spellHitsLeft[38]; // Used to track which spells will have their numhits incremented when spell finishes casting, 38 Buffslots uint32 m_spellHitsLeft[38]; // Used to track which spells will have their numhits incremented when spell finishes casting, 38 Buffslots
int flymode; int flymode;

View File

@ -493,10 +493,7 @@ void Mob::AI_Start(uint32 iMoveDelay) {
pAssistRange = 70; pAssistRange = 70;
hate_list.WipeHateList(); hate_list.WipeHateList();
delta_heading = 0; m_Delta = xyz_heading::Origin();
delta_x = 0;
delta_y = 0;
delta_z = 0;
pRunAnimSpeed = 0; pRunAnimSpeed = 0;
pLastChange = Timer::GetCurrentTime(); pLastChange = Timer::GetCurrentTime();
} }
@ -787,17 +784,17 @@ void Client::AI_Process()
if(AImovement_timer->Check()) { if(AImovement_timer->Check()) {
animation = GetRunspeed() * 21; animation = GetRunspeed() * 21;
// Check if we have reached the last fear point // 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 // Calculate a new point to run to
CalculateNewFearpoint(); CalculateNewFearpoint();
} }
if(!RuleB(Pathing, Fear) || !zone->pathing) 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 else
{ {
bool WaypointChanged, NodeReached; 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); GetFearSpeed(), WaypointChanged, NodeReached);
if(WaypointChanged) if(WaypointChanged)
@ -1055,17 +1052,17 @@ void Mob::AI_Process() {
} else { } else {
if(AImovement_timer->Check()) { if(AImovement_timer->Check()) {
// Check if we have reached the last fear point // 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 // Calculate a new point to run to
CalculateNewFearpoint(); CalculateNewFearpoint();
} }
if(!RuleB(Pathing, Fear) || !zone->pathing) 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 else
{ {
bool WaypointChanged, NodeReached; 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); GetFearSpeed(), WaypointChanged, NodeReached);
if(WaypointChanged) if(WaypointChanged)
@ -1127,19 +1124,20 @@ void Mob::AI_Process() {
if(DivineAura()) if(DivineAura())
return; return;
auto npcSpawnPoint = CastToNPC()->GetSpawnPoint();
if(GetSpecialAbility(TETHER)) { if(GetSpecialAbility(TETHER)) {
float tether_range = static_cast<float>(GetSpecialAbilityParam(TETHER, 0)); float tether_range = static_cast<float>(GetSpecialAbilityParam(TETHER, 0));
tether_range = tether_range > 0.0f ? tether_range * tether_range : pAggroRange * pAggroRange; tether_range = tether_range > 0.0f ? tether_range * tether_range : pAggroRange * pAggroRange;
if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > tether_range) { if(DistNoRootNoZ(npcSpawnPoint.m_X, npcSpawnPoint.m_Y) > tether_range) {
GMMove(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY(), CastToNPC()->GetSpawnPointZ(), CastToNPC()->GetSpawnPointH()); GMMove(npcSpawnPoint.m_X, npcSpawnPoint.m_Y, npcSpawnPoint.m_Z, npcSpawnPoint.m_Heading);
} }
} else if(GetSpecialAbility(LEASH)) { } else if(GetSpecialAbility(LEASH)) {
float leash_range = static_cast<float>(GetSpecialAbilityParam(LEASH, 0)); float leash_range = static_cast<float>(GetSpecialAbilityParam(LEASH, 0));
leash_range = leash_range > 0.0f ? leash_range * leash_range : pAggroRange * pAggroRange; leash_range = leash_range > 0.0f ? leash_range * leash_range : pAggroRange * pAggroRange;
if(DistNoRootNoZ(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY()) > leash_range) { if(DistNoRootNoZ(npcSpawnPoint.m_X, npcSpawnPoint.m_Y) > leash_range) {
GMMove(CastToNPC()->GetSpawnPointX(), CastToNPC()->GetSpawnPointY(), CastToNPC()->GetSpawnPointZ(), CastToNPC()->GetSpawnPointH()); GMMove(npcSpawnPoint.m_X, npcSpawnPoint.m_Y, npcSpawnPoint.m_Z, npcSpawnPoint.m_Heading);
SetHP(GetMaxHP()); SetHP(GetMaxHP());
BuffFadeAll(); BuffFadeAll();
WipeHateList(); WipeHateList();
@ -1373,7 +1371,8 @@ void Mob::AI_Process() {
//we cannot reach our target... //we cannot reach our target...
//underwater stuff only works with water maps in the zone! //underwater stuff only works with water maps in the zone!
if(IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) { 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); Mob *tar = hate_list.GetEntWithMostHateOnList(this);
if(tar == target) { if(tar == target) {
WipeHateList(); WipeHateList();
@ -1725,15 +1724,15 @@ void NPC::AI_DoMovement() {
} // endif (movetimercompleted==true) } // endif (movetimercompleted==true)
else if (!(AIwalking_timer->Enabled())) else if (!(AIwalking_timer->Enabled()))
{ // currently moving { // 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 { // 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()); mlog(AI__WAYPOINTS, "We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d", cur_wp, GetX(), GetY(), GetZ(), GetGrid());
SetWaypointPause(); SetWaypointPause();
if(GetAppearance() != eaStanding) if(GetAppearance() != eaStanding)
SetAppearance(eaStanding, false); SetAppearance(eaStanding, false);
SetMoving(false); SetMoving(false);
if (cur_wp_heading >= 0.0) { if (m_CurrentWayPoint.m_Heading >= 0.0) {
SetHeading(cur_wp_heading); SetHeading(m_CurrentWayPoint.m_Heading);
} }
SendPosition(); SendPosition();
@ -1749,12 +1748,12 @@ void NPC::AI_DoMovement() {
else else
{ // not at waypoint yet, so keep moving { // not at waypoint yet, so keep moving
if(!RuleB(Pathing, AggroReturnToGrid) || !zone->pathing || (DistractedFromGrid == 0)) 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 else
{ {
bool WaypointChanged; bool WaypointChanged;
bool NodeReached; 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) if(WaypointChanged)
tar_ndx = 20; tar_ndx = 20;
@ -1787,13 +1786,13 @@ void NPC::AI_DoMovement() {
{ {
bool CP2Moved; bool CP2Moved;
if(!RuleB(Pathing, Guard) || !zone->pathing) 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 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; 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) if(WaypointChanged)
tar_ndx = 20; tar_ndx = 20;
@ -1809,13 +1808,13 @@ void NPC::AI_DoMovement() {
if (!CP2Moved) if (!CP2Moved)
{ {
if(moved) { 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(); ClearFeignMemory();
moved=false; moved=false;
SetMoving(false); SetMoving(false);
if (GetTarget() == nullptr || DistNoRoot(*GetTarget()) >= 5*5 ) if (GetTarget() == nullptr || DistNoRoot(*GetTarget()) >= 5*5 )
{ {
SetHeading(guard_heading); SetHeading(m_GuardPoint.m_Heading);
} else { } else {
FaceTarget(GetTarget()); FaceTarget(GetTarget());
} }

View File

@ -56,7 +56,7 @@ extern Zone* zone;
extern volatile bool ZoneLoaded; extern volatile bool ZoneLoaded;
extern EntityList entity_list; 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, : Mob(d->name,
d->lastname, d->lastname,
d->max_hp, 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->npc_id,
d->size, d->size,
d->runspeed, d->runspeed,
heading, position,
x,
y,
z,
d->light, d->light,
d->texture, d->texture,
d->helmtexture, 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), qglobal_purge_timer(30000),
sendhpupdate_timer(1000), sendhpupdate_timer(1000),
enraged_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.. //What is the point of this, since the names get mangled..
Mob* mob = entity_list.GetMob(name); 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; MerchantType = d->merchanttype;
merchant_open = GetClass() == MERCHANT; merchant_open = GetClass() == MERCHANT;
adventure_template_id = d->adventure_template; adventure_template_id = d->adventure_template;
org_x = x;
org_y = y;
org_z = z;
flymode = iflymode; 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; guard_anim = eaStanding;
roambox_distance = 0; roambox_distance = 0;
roambox_max_x = -2; 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_movingto_y = -2;
roambox_min_delay = 1000; roambox_min_delay = 1000;
roambox_delay = 1000; roambox_delay = 1000;
org_heading = heading;
p_depop = false; p_depop = false;
loottable_id = d->loottable_id; 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 = new Timer(15000);
reface_timer->Disable(); reface_timer->Disable();
qGlobals = nullptr; qGlobals = nullptr;
guard_x_saved = 0;
guard_y_saved = 0;
guard_z_saved = 0;
guard_heading_saved = 0;
SetEmoteID(d->emoteid); SetEmoteID(d->emoteid);
InitializeBuffSlots(); InitializeBuffSlots();
CalcBonuses(); CalcBonuses();
@ -674,8 +662,8 @@ bool NPC::Process()
DoGravityEffect(); DoGravityEffect();
} }
if(reface_timer->Check() && !IsEngaged() && (guard_x == GetX() && guard_y == GetY() && guard_z == GetZ())) { if(reface_timer->Check() && !IsEngaged() && (m_GuardPoint.m_X == GetX() && m_GuardPoint.m_Y == GetY() && m_GuardPoint.m_Z == GetZ())) {
SetHeading(guard_heading); SetHeading(m_GuardPoint.m_Heading);
SendPosition(); SendPosition();
reface_timer->Disable(); reface_timer->Disable();
} }
@ -780,7 +768,7 @@ bool NPC::DatabaseCastAccepted(int spell_id) {
return false; 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) { if(spawncommand == 0 || spawncommand[0] == 0) {
return 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->prim_melee_type = 28;
npc_type->sec_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); npc->GiveNPCTypeData(npc_type);
entity_list.AddNPC(npc); entity_list.AddNPC(npc);

View File

@ -95,10 +95,10 @@ struct Item_Struct;
class NPC : public Mob class NPC : public Mob
{ {
public: 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); 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(); virtual ~NPC();
@ -162,7 +162,7 @@ public:
FACTION_VALUE CheckNPCFactionAlly(int32 other_faction); FACTION_VALUE CheckNPCFactionAlly(int32 other_faction);
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther); 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 Gate();
void GetPetState(SpellBuff_Struct *buffs, uint32 *items, char *name); void GetPetState(SpellBuff_Struct *buffs, uint32 *items, char *name);
@ -210,14 +210,8 @@ public:
uint32 GetSp2() const { return spawn_group; } uint32 GetSp2() const { return spawn_group; }
uint32 GetSpawnPointID() const; uint32 GetSpawnPointID() const;
float GetSpawnPointX() const { return org_x; } xyz_heading const GetSpawnPoint() const { return m_SpawnPoint; }
float GetSpawnPointY() const { return org_y; } xyz_heading const GetGuardPoint() const { return m_GuardPoint; }
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; }
EmuAppearance GetGuardPointAnim() const { return guard_anim; } EmuAppearance GetGuardPointAnim() const { return guard_anim; }
void SaveGuardPointAnim(EmuAppearance anim) { guard_anim = 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); } 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 GetMaxDMG() const {return max_dmg;}
uint32 GetMinDMG() const {return min_dmg;} uint32 GetMinDMG() const {return min_dmg;}
@ -288,15 +282,15 @@ public:
void StopWandering(); void StopWandering();
void ResumeWandering(); void ResumeWandering();
void PauseWandering(int pausetime); void PauseWandering(int pausetime);
void MoveTo(float mtx, float mty, float mtz, float mth, bool saveguardspot); void MoveTo(const xyz_heading& position, bool saveguardspot);
void GetClosestWaypoint(std::list<wplist> &wp_list, int count, float m_x, float m_y, float m_z); void GetClosestWaypoint(std::list<wplist> &wp_list, int count, const xyz_location& location);
uint32 GetEquipment(uint8 material_slot) const; // returns item id uint32 GetEquipment(uint8 material_slot) const; // returns item id
int32 GetEquipmentMaterial(uint8 material_slot) const; int32 GetEquipmentMaterial(uint8 material_slot) const;
void NextGuardPosition(); void NextGuardPosition();
void SaveGuardSpot(bool iClearGuardSpot = false); 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 SaveGuardSpotCharm();
void RestoreGuardSpotCharm(); void RestoreGuardSpotCharm();
void AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay = 2500, uint32 iMinDelay = 2500); void AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay = 2500, uint32 iMinDelay = 2500);
@ -450,7 +444,6 @@ protected:
AISpellsVar_Struct AISpellVar; AISpellsVar_Struct AISpellVar;
int16 GetFocusEffect(focusType type, uint16 spell_id); int16 GetFocusEffect(focusType type, uint16 spell_id);
uint32 npc_spells_effects_id; uint32 npc_spells_effects_id;
std::vector<AISpellsEffects_Struct> AIspellsEffects; std::vector<AISpellsEffects_Struct> AIspellsEffects;
bool HasAISpellEffects; bool HasAISpellEffects;
@ -480,8 +473,8 @@ protected:
void _ClearWaypints(); void _ClearWaypints();
int max_wp; int max_wp;
int save_wp; int save_wp;
float guard_x, guard_y, guard_z, guard_heading; xyz_heading m_GuardPoint;
float guard_x_saved, guard_y_saved, guard_z_saved, guard_heading_saved; xyz_heading m_GuardPointSaved;
EmuAppearance guard_anim; EmuAppearance guard_anim;
float roambox_max_x; float roambox_max_x;
float roambox_max_y; float roambox_max_y;

View File

@ -587,8 +587,8 @@ void PathManager::SpawnPathNodes()
npc_type->CHA = 150; npc_type->CHA = 150;
npc_type->findable = 1; npc_type->findable = 1;
auto position = xyz_heading(PathNodes[i].v.x, PathNodes[i].v.y, PathNodes[i].v.z, 0.0f);
NPC* npc = new NPC(npc_type, 0, PathNodes[i].v.x, PathNodes[i].v.y, PathNodes[i].v.z, 0, FlyMode1); NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1);
npc->GiveNPCTypeData(npc_type); npc->GiveNPCTypeData(npc_type);
entity_list.AddNPC(npc, true, true); 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)
{ {
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; break;
} }
auto testPointNewZ = xyz_location(TestPoint.x, TestPoint.y, NewZ);
if (zone->watermap->InLiquid(TestPoint.x, TestPoint.y, NewZ)) if (zone->watermap->InLiquid(testPointNewZ))
{ {
Map::Vertex TestPointWater(TestPoint.x, TestPoint.y, NewZ - 0.5f); Map::Vertex TestPointWater(TestPoint.x, TestPoint.y, NewZ - 0.5f);
Map::Vertex TestPointWaterDest = TestPointWater; 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->CHA = 150;
npc_type->findable = 1; 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); npc->GiveNPCTypeData(npc_type);
entity_list.AddNPC(npc, true, true); 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->CHA = 150;
npc_type->findable = 1; 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); npc->GiveNPCTypeData(npc_type);
entity_list.AddNPC(npc, true, true); entity_list.AddNPC(npc, true, true);

View File

@ -1072,7 +1072,7 @@ XS(XS_Client_SetBindPoint)
new_z = (float)SvNV(ST(5)); 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; XSRETURN_EMPTY;
} }

View File

@ -138,7 +138,7 @@ XS(XS_Doors_GetX)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetX(); RETVAL = THIS->GetPosition().m_X;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -164,7 +164,7 @@ XS(XS_Doors_GetY)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetY(); RETVAL = THIS->GetPosition().m_Y;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -190,7 +190,7 @@ XS(XS_Doors_GetZ)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetZ(); RETVAL = THIS->GetPosition().m_Z;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -216,7 +216,7 @@ XS(XS_Doors_GetHeading)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetHeading(); RETVAL = THIS->GetPosition().m_Heading;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -556,7 +556,7 @@ XS(XS_Doors_SetX)
Perl_croak(aTHX_ "Usage: Doors::SetX(THIS, XPos)"); Perl_croak(aTHX_ "Usage: Doors::SetX(THIS, XPos)");
{ {
Doors * THIS; Doors * THIS;
float pos = (float)SvNV(ST(1)); float x = (float)SvNV(ST(1));
if (sv_derived_from(ST(0), "Doors")) { if (sv_derived_from(ST(0), "Doors")) {
IV tmp = SvIV((SV*)SvRV(ST(0))); IV tmp = SvIV((SV*)SvRV(ST(0)));
@ -566,8 +566,9 @@ XS(XS_Doors_SetX)
Perl_croak(aTHX_ "THIS is not of type Doors"); Perl_croak(aTHX_ "THIS is not of type Doors");
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
auto position = THIS->GetPosition();
THIS->SetX(pos); position.m_X = x;
THIS->SetPosition(position);
} }
XSRETURN_EMPTY; XSRETURN_EMPTY;
} }
@ -580,7 +581,7 @@ XS(XS_Doors_SetY)
Perl_croak(aTHX_ "Usage: Doors::SetY(THIS, YPos)"); Perl_croak(aTHX_ "Usage: Doors::SetY(THIS, YPos)");
{ {
Doors * THIS; Doors * THIS;
float pos = (float)SvNV(ST(1)); float y = (float)SvNV(ST(1));
if (sv_derived_from(ST(0), "Doors")) { if (sv_derived_from(ST(0), "Doors")) {
IV tmp = SvIV((SV*)SvRV(ST(0))); IV tmp = SvIV((SV*)SvRV(ST(0)));
@ -591,7 +592,9 @@ XS(XS_Doors_SetY)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->SetY(pos); auto position = THIS->GetPosition();
position.m_Y = y;
THIS->SetPosition(position);
} }
XSRETURN_EMPTY; XSRETURN_EMPTY;
} }
@ -604,7 +607,7 @@ XS(XS_Doors_SetZ)
Perl_croak(aTHX_ "Usage: Doors::SetZ(THIS, ZPos)"); Perl_croak(aTHX_ "Usage: Doors::SetZ(THIS, ZPos)");
{ {
Doors * THIS; Doors * THIS;
float pos = (float)SvNV(ST(1)); float z = (float)SvNV(ST(1));
if (sv_derived_from(ST(0), "Doors")) { if (sv_derived_from(ST(0), "Doors")) {
IV tmp = SvIV((SV*)SvRV(ST(0))); IV tmp = SvIV((SV*)SvRV(ST(0)));
@ -615,7 +618,9 @@ XS(XS_Doors_SetZ)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->SetZ(pos); auto position = THIS->GetPosition();
position.m_Z = z;
THIS->SetPosition(position);
} }
XSRETURN_EMPTY; XSRETURN_EMPTY;
} }
@ -639,7 +644,9 @@ XS(XS_Doors_SetHeading)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->SetHeading(heading); auto position = THIS->GetPosition();
position.m_Heading = heading;
THIS->SetPosition(position);
} }
XSRETURN_EMPTY; XSRETURN_EMPTY;
} }

View File

@ -1875,7 +1875,7 @@ XS(XS_EntityList_GetRandomClient)
c = INT2PTR(Client *,tmp); 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(); ST(0) = sv_newmortal();
sv_setref_pv(ST(0), "Client", (void*)RETVAL); sv_setref_pv(ST(0), "Client", (void*)RETVAL);
} }

View File

@ -3551,7 +3551,7 @@ XS(XS_Mob_GetWaypointX)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetCWPX(); RETVAL = THIS->GetCurrentWayPoint().m_X;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -3577,7 +3577,7 @@ XS(XS_Mob_GetWaypointY)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetCWPY(); RETVAL = THIS->GetCurrentWayPoint().m_Y;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -3603,7 +3603,7 @@ XS(XS_Mob_GetWaypointZ)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetCWPZ(); RETVAL = THIS->GetCurrentWayPoint().m_Z;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -3629,7 +3629,7 @@ XS(XS_Mob_GetWaypointH)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetCWPH(); RETVAL = THIS->GetCurrentWayPoint().m_Heading;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); 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)"); Perl_croak(aTHX_ "Usage: Mob::SetDeltas(THIS, delta_x, delta_y, delta_z, delta_h)");
{ {
Mob * THIS; Mob * THIS;
float delta_x = (float)SvNV(ST(1)); auto delta = xyz_heading((float)SvNV(ST(1)), (float)SvNV(ST(2)), (float)SvNV(ST(3)), (float)SvNV(ST(4)));
float delta_y = (float)SvNV(ST(2));
float delta_z = (float)SvNV(ST(3));
float delta_h = (float)SvNV(ST(4));
if (sv_derived_from(ST(0), "Mob")) { if (sv_derived_from(ST(0), "Mob")) {
IV tmp = SvIV((SV*)SvRV(ST(0))); IV tmp = SvIV((SV*)SvRV(ST(0)));
@ -7676,7 +7673,7 @@ XS(XS_Mob_SetDeltas)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->SetDeltas(delta_x, delta_y, delta_z, delta_h); THIS->SetDelta(delta);
} }
XSRETURN_EMPTY; XSRETURN_EMPTY;
} }

View File

@ -1345,7 +1345,8 @@ XS(XS_NPC_MoveTo)
if(THIS == nullptr) if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); 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; XSRETURN_EMPTY;
} }
@ -1545,7 +1546,7 @@ XS(XS_NPC_GetSpawnPointX)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetSpawnPointX(); RETVAL = THIS->GetSpawnPoint().m_X;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -1572,7 +1573,7 @@ XS(XS_NPC_GetSpawnPointY)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetSpawnPointY(); RETVAL = THIS->GetSpawnPoint().m_Y;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -1599,7 +1600,7 @@ XS(XS_NPC_GetSpawnPointZ)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetSpawnPointZ(); RETVAL = THIS->GetSpawnPoint().m_Z;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -1626,7 +1627,7 @@ XS(XS_NPC_GetSpawnPointH)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetSpawnPointH(); RETVAL = THIS->GetSpawnPoint().m_Heading;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -1653,7 +1654,7 @@ XS(XS_NPC_GetGuardPointX)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetGuardPointX(); RETVAL = THIS->GetGuardPoint().m_X;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -1680,7 +1681,7 @@ XS(XS_NPC_GetGuardPointY)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetGuardPointY(); RETVAL = THIS->GetGuardPoint().m_Y;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);
@ -1707,7 +1708,7 @@ XS(XS_NPC_GetGuardPointZ)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetGuardPointZ(); RETVAL = THIS->GetGuardPoint().m_Z;
XSprePUSH; PUSHn((double)RETVAL); XSprePUSH; PUSHn((double)RETVAL);
} }
XSRETURN(1); XSRETURN(1);

View File

@ -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 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.*/ 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) 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); GiveNPCTypeData(type_data);
typeofpet = type; typeofpet = type;

196
zone/position.cpp Normal file
View File

@ -0,0 +1,196 @@
#include <string>
#include <cmath>
#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<float>(x)),
m_Y(static_cast<float>(y)),
m_Z(static_cast<float>(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<xy_location>(point1),static_cast<xy_location>(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<xy_location>(point1),static_cast<xy_location>(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;
}

97
zone/position.h Normal file
View File

@ -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 <string>
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

View File

@ -201,11 +201,11 @@ void QuestManager::write(const char *file, const char *str) {
fclose (pFile); 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; const NPCType* tmp = 0;
if (tmp = database.GetNPCType(npc_type)) 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(); npc->AddLootTable();
entity_list.AddNPC(npc,true,true); entity_list.AddNPC(npc,true,true);
if(grid > 0) if(grid > 0)
@ -218,7 +218,7 @@ Mob* QuestManager::spawn2(int npc_type, int grid, int unused, float x, float y,
return nullptr; 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); Mob *other = entity_list.GetMobByNpcTypeID(npc_type);
if(other != nullptr) { if(other != nullptr) {
return other; return other;
@ -227,7 +227,7 @@ Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, flo
const NPCType* tmp = 0; const NPCType* tmp = 0;
if (tmp = database.GetNPCType(npc_type)) 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(); npc->AddLootTable();
entity_list.AddNPC(npc,true,true); entity_list.AddNPC(npc,true,true);
if(grid > 0) if(grid > 0)
@ -300,8 +300,8 @@ Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id)
database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0); database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0);
found_spawn->SetCurrentNPCID(npcid); found_spawn->SetCurrentNPCID(npcid);
NPC* npc = new NPC(tmp, found_spawn, found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(), auto position = xyz_heading(found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(), found_spawn->GetHeading());
found_spawn->GetHeading(), FlyMode3); NPC* npc = new NPC(tmp, found_spawn, position, FlyMode3);
found_spawn->SetNPCPointer(npc); found_spawn->SetNPCPointer(npc);
npc->AddLootTable(); npc->AddLootTable();
@ -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(); QuestManagerCurrentQuestVars();
if(initiator && initiator->IsClient()) { 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); 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(); QuestManagerCurrentQuestVars();
if (!owner || !owner->IsNPC()) if (!owner || !owner->IsNPC())
return; return;
owner->CastToNPC()->MoveTo(x, y, z, h, saveguardspot); owner->CastToNPC()->MoveTo(position, saveguardspot);
} }
void QuestManager::resume() { void QuestManager::resume() {
@ -1563,26 +1563,20 @@ void QuestManager::setnextinchpevent(int at) {
owner->SetNextIncHPEvent(at); owner->SetNextIncHPEvent(at);
} }
void QuestManager::respawn(int npc_type, int grid) { void QuestManager::respawn(int npcTypeID, int grid) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (!owner || !owner->IsNPC()) if (!owner || !owner->IsNPC())
return; return;
float x,y,z,h;
x = owner->GetX();
y = owner->GetY();
z = owner->GetZ();
h = owner->GetHeading();
running_quest e = quests_running_.top(); running_quest e = quests_running_.top();
e.depop_npc = true; e.depop_npc = true;
quests_running_.pop(); quests_running_.pop();
quests_running_.push(e); quests_running_.push(e);
const NPCType* tmp = 0; const NPCType* npcType = nullptr;
if ((tmp = database.GetNPCType(npc_type))) 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(); owner->CastToNPC()->AddLootTable();
entity_list.AddNPC(owner->CastToNPC(),true,true); entity_list.AddNPC(owner->CastToNPC(),true,true);
if(grid > 0) if(grid > 0)
@ -1704,27 +1698,28 @@ void QuestManager::sethp(int hpperc) {
owner->Damage(owner, newhp, SPELL_UNKNOWN, SkillHandtoHand, false, 0, false); 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; bool Result = false;
if(char_id > 0) { if(char_id <= 0)
Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(char_id, zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); return false;
if(PlayerCorpse) {
Result = true; Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(char_id, zone->GetZoneID(), zone->GetInstanceID(), position);
} if(!PlayerCorpse)
} return false;
return Result;
return true;
} }
bool QuestManager::summonallplayercorpses(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading) { bool QuestManager::summonallplayercorpses(uint32 char_id, const xyz_heading& position) {
bool Result = false;
if(char_id <= 0)
return false;
if(char_id > 0) {
Client* c = entity_list.GetClientByCharID(char_id); Client* c = entity_list.GetClientByCharID(char_id);
c->SummonAllCorpses(dest_x, dest_y, dest_z, dest_heading); c->SummonAllCorpses(position);
Result = true;
} return true;
return Result;
} }
uint32 QuestManager::getplayerburriedcorpsecount(uint32 char_id) { uint32 QuestManager::getplayerburriedcorpsecount(uint32 char_id) {
@ -2312,17 +2307,17 @@ int QuestManager::getlevel(uint8 type)
return 0; 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 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; 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 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; 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(); QuestManagerCurrentQuestVars();
if(initiator) 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 QuestManager::CreateDoor(const char* model, float x, float y, float z, float heading, uint8 opentype, uint16 size)
{ {
uint16 entid = 0; //safety check 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; return entid;
} }

View File

@ -57,8 +57,8 @@ public:
void me(const char *str); void me(const char *str);
void summonitem(uint32 itemid, int16 charges = -1); void summonitem(uint32 itemid, int16 charges = -1);
void write(const char *file, const char *str); 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* spawn2(int npc_type, int grid, int unused, const xyz_heading& position);
Mob* unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading = 0); Mob* unique_spawn(int npc_type, int grid, int unused, const xyz_heading& position);
Mob* spawn_from_spawn2(uint32 spawn2_id); Mob* spawn_from_spawn2(uint32 spawn2_id);
void enable_spawn2(uint32 spawn2_id); void enable_spawn2(uint32 spawn2_id);
void disable_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 targlobal(const char *varname, const char *value, const char *duration, int npcid, int charid, int zoneid);
void delglobal(const char *varname); void delglobal(const char *varname);
void ding(); 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 start(int wp);
void stop(); void stop();
void pause(int duration); 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 resume();
void addldonpoints(int32 points, uint32 theme); void addldonpoints(int32 points, uint32 theme);
void addldonwin(int32 wins, uint32 theme); void addldonwin(int32 wins, uint32 theme);
@ -157,8 +157,8 @@ public:
void set_zone_flag(int zone_id); void set_zone_flag(int zone_id);
void clear_zone_flag(int zone_id); void clear_zone_flag(int zone_id);
void sethp(int hpperc); void sethp(int hpperc);
bool summonburriedplayercorpse(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, float dest_x, float dest_y, float dest_z, float dest_heading); bool summonallplayercorpses(uint32 char_id, const xyz_heading& position);
uint32 getplayerburriedcorpsecount(uint32 char_id); uint32 getplayerburriedcorpsecount(uint32 char_id);
bool buryplayercorpse(uint32 char_id); bool buryplayercorpse(uint32 char_id);
void forcedooropen(uint32 doorid, bool altmode); void forcedooropen(uint32 doorid, bool altmode);
@ -208,8 +208,8 @@ public:
void enabletitle(int titleset); void enabletitle(int titleset);
bool checktitle(int titlecheck); bool checktitle(int titlecheck);
void removetitle(int titlecheck); void removetitle(int titlecheck);
uint16 CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time = 300000); uint16 CreateGroundObject(uint32 itemid, const xyz_heading& position, 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 CreateGroundObjectFromModel(const char* model, const xyz_heading& position, uint8 type = 0x00, uint32 decay_time = 0);
void ModifyNPCStat(const char *identifier, const char *newValue); void ModifyNPCStat(const char *identifier, const char *newValue);
void UpdateSpawnTimer(uint32 id, uint32 newTime); void UpdateSpawnTimer(uint32 id, uint32 newTime);
void MerchantSetItem(uint32 NPCid, uint32 itemid, uint32 quantity = 0); 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 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 RemoveRaidFromInstance(uint16 instance_id); //potentially useful but not implmented at this time.
void RemoveAllFromInstance(uint16 instance_id); 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 FlagInstanceByGroupLeader(uint32 zone, int16 version);
void FlagInstanceByRaidLeader(uint32 zone, int16 version); void FlagInstanceByRaidLeader(uint32 zone, int16 version);
const char* varlink(char* perltext, int item_id); const char* varlink(char* perltext, int item_id);

View File

@ -218,7 +218,7 @@ bool Spawn2::Process() {
database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0); database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0);
currentnpcid = npcid; 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); npc->mod_prespawn(this);
@ -414,13 +414,13 @@ Spawn2* ZoneDatabase::LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2
return newSpawn; 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, " std::string query = StringFormat("INSERT INTO spawn2 (spawngroupID, zone, x, y, z, heading, "
"respawntime, variance, _condition, cond_value) " "respawntime, variance, _condition, cond_value) "
"VALUES (%i, '%s', %f, %f, %f, %f, %i, %i, %u, %i)", "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); respawn, variance, condition, cond_value);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()) { if (!results.Success()) {

View File

@ -362,7 +362,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
casting_spell_type = type; casting_spell_type = type;
SaveSpellLoc(); 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 // 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 // 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; return false;
} }
if (zone->IsSpellBlocked(spell_id, GetX(), GetY(), GetZ())) { if (zone->IsSpellBlocked(spell_id, GetPosition())) {
const char *msg = zone->GetSpellBlockedMessage(spell_id, GetX(), GetY(), GetZ()); const char *msg = zone->GetSpellBlockedMessage(spell_id, GetPosition());
if (msg) { if (msg) {
Message(13, msg); Message(13, msg);
return false; return false;
@ -1918,8 +1918,8 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
if(IsClient() && !CastToClient()->GetGM()){ if(IsClient() && !CastToClient()->GetGM()){
if(zone->IsSpellBlocked(spell_id, GetX(), GetY(), GetZ())){ if(zone->IsSpellBlocked(spell_id, GetPosition())){
const char *msg = zone->GetSpellBlockedMessage(spell_id, GetX(), GetY(), GetZ()); const char *msg = zone->GetSpellBlockedMessage(spell_id, GetPosition());
if(msg){ if(msg){
Message(13, msg); Message(13, msg);
return false; return false;
@ -3856,9 +3856,9 @@ void Corpse::CastRezz(uint16 spellid, Mob* Caster)
rezz->zone_id = zone->GetZoneID(); rezz->zone_id = zone->GetZoneID();
rezz->instance_id = zone->GetInstanceID(); rezz->instance_id = zone->GetInstanceID();
rezz->spellid = spellid; rezz->spellid = spellid;
rezz->x = this->x_pos; rezz->x = this->m_Position.m_X;
rezz->y = this->y_pos; rezz->y = this->m_Position.m_Y;
rezz->z = this->z_pos; rezz->z = this->m_Position.m_Z;
rezz->unknown000 = 0x00000000; rezz->unknown000 = 0x00000000;
rezz->unknown020 = 0x00000000; rezz->unknown020 = 0x00000000;
rezz->unknown088 = 0x00000000; rezz->unknown088 = 0x00000000;

View File

@ -52,12 +52,10 @@ CREATE TABLE traps (
Trap::Trap() : Trap::Trap() :
Entity(), Entity(),
respawn_timer(600000), respawn_timer(600000),
chkarea_timer(500) chkarea_timer(500),
m_Position(xyz_location::Origin())
{ {
trap_id = 0; trap_id = 0;
x = 0;
y = 0;
z = 0;
maxzdiff = 0; maxzdiff = 0;
radius = 0; radius = 0;
effect = 0; effect = 0;
@ -146,7 +144,9 @@ void Trap::Trigger(Mob* trigger)
{ {
if ((tmp = database.GetNPCType(effectvalue))) 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(); new_npc->AddLootTable();
entity_list.AddNPC(new_npc); entity_list.AddNPC(new_npc);
new_npc->AddToHateList(trigger,1); new_npc->AddToHateList(trigger,1);
@ -167,7 +167,9 @@ void Trap::Trigger(Mob* trigger)
{ {
if ((tmp = database.GetNPCType(effectvalue))) 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(); new_npc->AddLootTable();
entity_list.AddNPC(new_npc); entity_list.AddNPC(new_npc);
new_npc->AddToHateList(trigger,1); new_npc->AddToHateList(trigger,1);
@ -210,17 +212,14 @@ Trap* EntityList::FindNearbyTrap(Mob* searcher, float max_dist) {
float max_dist2 = max_dist*max_dist; float max_dist2 = max_dist*max_dist;
Trap *cur; Trap *cur;
auto it = trap_list.begin();
while (it != trap_list.end()) { for (auto it = trap_list.begin(); it != trap_list.end(); ++it) {
cur = it->second; cur = it->second;
if(!cur->disarmed) { if(cur->disarmed)
float curdist = 0; continue;
float tmp = searcher->GetX() - cur->x;
curdist += tmp*tmp; auto diff = searcher->GetPosition() - cur->m_Position;
tmp = searcher->GetY() - cur->y; float curdist = diff.m_X * diff.m_X + diff.m_Y * diff.m_Y + diff.m_Z * diff.m_Z;
curdist += tmp*tmp;
tmp = searcher->GetZ() - cur->z;
curdist += tmp*tmp;
if (curdist < max_dist2 && curdist < dist) if (curdist < max_dist2 && curdist < dist)
{ {
@ -228,37 +227,32 @@ Trap* EntityList::FindNearbyTrap(Mob* searcher, float max_dist) {
current_trap = cur; current_trap = cur;
} }
} }
++it;
}
return current_trap; return current_trap;
} }
Mob* EntityList::GetTrapTrigger(Trap* trap) { Mob* EntityList::GetTrapTrigger(Trap* trap) {
Mob* savemob = 0; Mob* savemob = 0;
float xdiff, ydiff, zdiff;
float maxdist = trap->radius * trap->radius; float maxdist = trap->radius * trap->radius;
auto it = client_list.begin(); for (auto it = client_list.begin(); it != client_list.end(); ++it) {
while (it != client_list.end()) {
Client* cur = it->second; Client* cur = it->second;
zdiff = cur->GetZ() - trap->z;
if(zdiff < 0)
zdiff = 0 - zdiff;
xdiff = cur->GetX() - trap->x; auto diff = cur->GetPosition() - trap->m_Position;
ydiff = cur->GetY() - trap->y; diff.ABS_XYZ();
if ((xdiff*xdiff + ydiff*ydiff) <= maxdist
&& zdiff < trap->maxzdiff) 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)) if (zone->random.Roll(trap->chance))
return(cur); return(cur);
else else
savemob = cur; savemob = cur;
} }
++it;
} }
return savemob; return savemob;
} }
@ -277,9 +271,7 @@ bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) {
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
Trap* trap = new Trap(); Trap* trap = new Trap();
trap->trap_id = atoi(row[0]); trap->trap_id = atoi(row[0]);
trap->x = atof(row[1]); trap->m_Position = xyz_location(atof(row[1]), atof(row[2]), atof(row[3]));
trap->y = atof(row[2]);
trap->z = atof(row[3]);
trap->effect = atoi(row[4]); trap->effect = atoi(row[4]);
trap->effectvalue = atoi(row[5]); trap->effectvalue = atoi(row[5]);
trap->effectvalue2 = atoi(row[6]); trap->effectvalue2 = atoi(row[6]);
@ -320,7 +312,7 @@ void Trap::CreateHiddenTrigger()
make_npc->trackable = 0; make_npc->trackable = 0;
make_npc->level = level; make_npc->level = level;
strcpy(make_npc->special_abilities, "19,1^20,1^24,1^25,1"); 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); npca->GiveNPCTypeData(make_npc);
entity_list.AddNPC(npca); entity_list.AddNPC(npca);

View File

@ -54,9 +54,7 @@ public:
Timer respawn_timer; //Respawn Time when Trap's been disarmed Timer respawn_timer; //Respawn Time when Trap's been disarmed
Timer chkarea_timer; Timer chkarea_timer;
uint32 trap_id; //Database ID of trap uint32 trap_id; //Database ID of trap
float x; //X position xyz_location m_Position;
float y; //Y position
float z; //Z position
float maxzdiff; //maximum z diff to be triggerable float maxzdiff; //maximum z diff to be triggerable
float radius; //radius around trap to be triggerable float radius; //radius around trap to be triggerable
uint8 chance; //%chance that the trap is triggered each 'tick' uint8 chance; //%chance that the trap is triggered each 'tick'

View File

@ -2,8 +2,10 @@
#define EQEMU_WATER_MAP_H #define EQEMU_WATER_MAP_H
#include "../common/types.h" #include "../common/types.h"
#include "position.h"
#include <string> #include <string>
enum WaterRegionType { enum WaterRegionType {
RegionTypeUnsupported = -2, RegionTypeUnsupported = -2,
RegionTypeUntagged = -1, RegionTypeUntagged = -1,
@ -24,11 +26,11 @@ public:
virtual ~WaterMap() { } virtual ~WaterMap() { }
static WaterMap* LoadWaterMapfile(std::string zone_name); static WaterMap* LoadWaterMapfile(std::string zone_name);
virtual WaterRegionType ReturnRegionType(float y, float x, float z) const { return RegionTypeNormal; } virtual WaterRegionType ReturnRegionType(const xyz_location& location) const { return RegionTypeNormal; }
virtual bool InWater(float y, float x, float z) const { return false; } virtual bool InWater(const xyz_location& location) const { return false; }
virtual bool InVWater(float y, float x, float z) const { return false; } virtual bool InVWater(const xyz_location& location) const { return false; }
virtual bool InLava(float y, float x, float z) const { return false; } virtual bool InLava(const xyz_location& location) const { return false; }
virtual bool InLiquid(float y, float x, float z) const { return false; } virtual bool InLiquid(const xyz_location& location) const { return false; }
protected: protected:
virtual bool Load(FILE *fp) { return false; } virtual bool Load(FILE *fp) { return false; }

View File

@ -6,31 +6,31 @@ WaterMapV2::WaterMapV2() {
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(); size_t sz = regions.size();
for(size_t i = 0; i < sz; ++i) { for(size_t i = 0; i < sz; ++i) {
auto const &region = regions[i]; auto const &region = 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 region.first;
} }
} }
return RegionTypeNormal; return RegionTypeNormal;
} }
bool WaterMapV2::InWater(float y, float x, float z) const { bool WaterMapV2::InWater(const xyz_location& location) const {
return ReturnRegionType(y, x, z) == RegionTypeWater; return ReturnRegionType(location) == RegionTypeWater;
} }
bool WaterMapV2::InVWater(float y, float x, float z) const { bool WaterMapV2::InVWater(const xyz_location& location) const {
return ReturnRegionType(y, x, z) == RegionTypeVWater; return ReturnRegionType(location) == RegionTypeVWater;
} }
bool WaterMapV2::InLava(float y, float x, float z) const { bool WaterMapV2::InLava(const xyz_location& location) const {
return ReturnRegionType(y, x, z) == RegionTypeLava; return ReturnRegionType(location) == RegionTypeLava;
} }
bool WaterMapV2::InLiquid(float y, float x, float z) const { bool WaterMapV2::InLiquid(const xyz_location& location) const {
return InWater(y, x, z) || InLava(y, x, z); return InWater(location) || InLava(location);
} }
bool WaterMapV2::Load(FILE *fp) { bool WaterMapV2::Load(FILE *fp) {

View File

@ -12,11 +12,11 @@ public:
WaterMapV2(); WaterMapV2();
~WaterMapV2(); ~WaterMapV2();
virtual WaterRegionType ReturnRegionType(float y, float x, float z) const; virtual WaterRegionType ReturnRegionType(const xyz_location& location) const;
virtual bool InWater(float y, float x, float z) const; virtual bool InWater(const xyz_location& location) const;
virtual bool InVWater(float y, float x, float z) const; virtual bool InVWater(const xyz_location& location) const;
virtual bool InLava(float y, float x, float z) const; virtual bool InLava(const xyz_location& location) const;
virtual bool InLiquid(float y, float x, float z) const; virtual bool InLiquid(const xyz_location& location) const;
protected: protected:
virtual bool Load(FILE *fp); virtual bool Load(FILE *fp);

View File

@ -120,7 +120,7 @@ void NPC::ResumeWandering()
return; 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 { // are we we at a waypoint? if so, trigger event and start to next
char temp[100]; char temp[100];
itoa(cur_wp,temp,10); //do this before updating to next waypoint itoa(cur_wp,temp,10); //do this before updating to next waypoint
@ -159,7 +159,7 @@ void NPC::PauseWandering(int pausetime)
return; 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 { // makes mob walk to specified location
if (IsNPC() && GetGrid() != 0) if (IsNPC() && GetGrid() != 0)
{ // he is on a grid { // 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 save_wp=cur_wp; // save the current waypoint
cur_wp=-1; // flag this move as quest controlled 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<xyz_location>(position)).c_str(), -GetGrid(), save_wp);
} }
else else
{ // not on a grid { // not on a grid
roamer=true; roamer=true;
save_wp=0; save_wp=0;
cur_wp=-2; // flag as quest controlled w/no grid 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<xyz_location>(position)).c_str());
} }
if (saveguardspot) if (saveguardspot)
{ {
guard_x = mtx; m_GuardPoint = position;
guard_y = mty;
guard_z = mtz;
guard_heading = mth;
if(guard_heading == 0) if(m_GuardPoint.m_Heading == 0)
guard_heading = 0.0001; //hack to make IsGuarding simpler m_GuardPoint.m_Heading = 0.0001; //hack to make IsGuarding simpler
if(guard_heading == -1) if(m_GuardPoint.m_Heading == -1)
guard_heading = this->CalculateHeadingToTarget(mtx, mty); 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<xyz_location>(m_GuardPoint)).c_str());
} }
cur_wp_x = mtx; m_CurrentWayPoint = position;
cur_wp_y = mty;
cur_wp_z = mtz;
cur_wp_pause = 0; cur_wp_pause = 0;
cur_wp_heading = mth;
pLastFightingDelayMoving = 0; pLastFightingDelayMoving = 0;
if(AIwalking_timer->Enabled()) if(AIwalking_timer->Enabled())
AIwalking_timer->Start(100); AIwalking_timer->Start(100);
@ -219,26 +213,23 @@ void NPC::UpdateWaypoint(int wp_index)
cur = Waypoints.begin(); cur = Waypoints.begin();
cur += wp_index; cur += wp_index;
cur_wp_x = cur->x; m_CurrentWayPoint = xyz_heading(cur->x, cur->y, cur->z, cur->heading);
cur_wp_y = cur->y;
cur_wp_z = cur->z;
cur_wp_pause = cur->pause; cur_wp_pause = cur->pause;
cur_wp_heading = cur->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);
mlog(AI__WAYPOINTS, "Next waypoint %d: (%.3f, %.3f, %.3f, %.3f)", wp_index, cur_wp_x, cur_wp_y, cur_wp_z, cur_wp_heading);
//fix up pathing Z //fix up pathing Z
if(zone->HasMap() && RuleB(Map, FixPathingZAtWaypoints)) if(zone->HasMap() && RuleB(Map, FixPathingZAtWaypoints))
{ {
if(!RuleB(Watermap, CheckForWaterAtWaypoints) || !zone->HasWaterMap() || 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); float newz = zone->zonemap->FindBestZ(dest, nullptr);
if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaWaypoint)) 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 case 1: //10 closest
{ {
std::list<wplist> closest; std::list<wplist> closest;
GetClosestWaypoint(closest, 10, GetX(), GetY(), GetZ()); GetClosestWaypoint(closest, 10, GetPosition());
std::list<wplist>::iterator iter = closest.begin(); std::list<wplist>::iterator iter = closest.begin();
if(closest.size() != 0) if(closest.size() != 0)
{ {
@ -323,7 +314,7 @@ void NPC::CalculateNewWaypoint()
case 5: //pick random closest 5 and pick one that's in sight case 5: //pick random closest 5 and pick one that's in sight
{ {
std::list<wplist> closest; std::list<wplist> closest;
GetClosestWaypoint(closest, 5, GetX(), GetY(), GetZ()); GetClosestWaypoint(closest, 5, GetPosition());
std::list<wplist>::iterator iter = closest.begin(); std::list<wplist>::iterator iter = closest.begin();
while(iter != closest.end()) 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; return left.dist < right.dist;
} }
void NPC::GetClosestWaypoint(std::list<wplist> &wp_list, int count, float m_x, float m_y, float m_z) void NPC::GetClosestWaypoint(std::list<wplist> &wp_list, int count, const xyz_location& location)
{ {
wp_list.clear(); wp_list.clear();
if(Waypoints.size() <= count) if(Waypoints.size() <= count)
@ -379,11 +370,11 @@ void NPC::GetClosestWaypoint(std::list<wplist> &wp_list, int count, float m_x, f
std::list<wp_distance> distances; std::list<wp_distance> distances;
for(int i = 0; i < Waypoints.size(); ++i) 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; 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; 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; cur_z *= cur_z;
float cur_dist = cur_x + cur_y + cur_z; float cur_dist = cur_x + cur_y + cur_z;
wp_distance w_dist; wp_distance w_dist;
@ -431,28 +422,23 @@ void NPC::SetWaypointPause()
void NPC::SaveGuardSpot(bool iClearGuardSpot) { void NPC::SaveGuardSpot(bool iClearGuardSpot) {
if (iClearGuardSpot) { if (iClearGuardSpot) {
mlog(AI__WAYPOINTS, "Clearing guard order."); mlog(AI__WAYPOINTS, "Clearing guard order.");
guard_x = 0; m_GuardPoint = xyz_heading(0, 0, 0, 0);
guard_y = 0;
guard_z = 0;
guard_heading = 0;
} }
else { else {
guard_x = x_pos; m_GuardPoint = m_Position;
guard_y = y_pos;
guard_z = z_pos; if(m_GuardPoint.m_Heading == 0)
guard_heading = heading; m_GuardPoint.m_Heading = 0.0001; //hack to make IsGuarding simpler
if(guard_heading == 0) mlog(AI__WAYPOINTS, "Setting guard position to %s", to_string(static_cast<xyz_location>(m_GuardPoint)).c_str());
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);
} }
} }
void NPC::NextGuardPosition() { void NPC::NextGuardPosition() {
if (!CalculateNewPosition2(guard_x, guard_y, guard_z, GetMovespeed())) { if (!CalculateNewPosition2(m_GuardPoint.m_X, m_GuardPoint.m_Y, m_GuardPoint.m_Z, GetMovespeed())) {
SetHeading(guard_heading); SetHeading(m_GuardPoint.m_Heading);
mlog(AI__WAYPOINTS, "Unable to move to next guard position. Probably rooted."); 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) if(moved)
{ {
@ -480,7 +466,7 @@ void Mob::SaveSpawnSpot() {
}*/ }*/
float Mob::CalculateDistance(float x, float y, float z) { 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 Mob::CalculateHeadingToTarget(float in_x, float in_y) {
float angle; float angle;
if (in_x-x_pos > 0) if (in_x-m_Position.m_X > 0)
angle = - 90 + atan((float)(in_y-y_pos) / (float)(in_x-x_pos)) * 180 / M_PI; angle = - 90 + atan((float)(in_y-m_Position.m_Y) / (float)(in_x-m_Position.m_X)) * 180 / M_PI;
else if (in_x-x_pos < 0) else if (in_x-m_Position.m_X < 0)
angle = + 90 + atan((float)(in_y-y_pos) / (float)(in_x-x_pos)) * 180 / M_PI; angle = + 90 + atan((float)(in_y-m_Position.m_Y) / (float)(in_x-m_Position.m_X)) * 180 / M_PI;
else // Added? else // Added?
{ {
if (in_y-y_pos > 0) if (in_y-m_Position.m_Y > 0)
angle = 0; angle = 0;
else else
angle = 180; angle = 180;
@ -513,16 +499,16 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
if(GetID()==0) if(GetID()==0)
return true; return true;
if ((x_pos-x == 0) && (y_pos-y == 0)) {//spawn is at target coords if ((m_Position.m_X-x == 0) && (m_Position.m_Y-y == 0)) {//spawn is at target coords
if(z_pos-z != 0) { if(m_Position.m_Z-z != 0) {
z_pos = z; m_Position.m_Z = z;
mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z); mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z);
return true; return true;
} }
mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater); mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater);
return false; 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); 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); entity_list.ProcessMove(CastToNPC(), x, y, z);
} }
x_pos = x; m_Position.m_X = x;
y_pos = y; m_Position.m_Y = y;
z_pos = z; m_Position.m_Z = z;
return true; return true;
} }
int compare_steps = IsBoat() ? 1 : 20; 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_x = m_Position.m_X + m_TargetV.m_X*tar_vector;
float new_y = y_pos + tar_vy*tar_vector; float new_y = m_Position.m_Y + m_TargetV.m_Y*tar_vector;
float new_z = z_pos + tar_vz*tar_vector; float new_z = m_Position.m_Z + m_TargetV.m_Z*tar_vector;
if(IsNPC()) { if(IsNPC()) {
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
} }
x_pos = new_x; m_Position.m_X = new_x;
y_pos = new_y; m_Position.m_Y = new_y;
z_pos = new_z; 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; 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(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving))
{ {
if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || 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; 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( (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)) if(ABS(z-m_Position.m_Z) <= RuleR(Map, FixPathingZMaxDeltaMoving))
z_pos = z; m_Position.m_Z = z;
else else
z_pos = newz + 1; m_Position.m_Z = newz + 1;
} }
else 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 { } else {
tar_ndx=0; tar_ndx=0;
} }
tarx=x; m_TargetLocation = xyz_location(x, y, z);
tary=y;
tarz=z;
float nx = this->x_pos; float nx = this->m_Position.m_X;
float ny = this->y_pos; float ny = this->m_Position.m_Y;
float nz = this->z_pos; float nz = this->m_Position.m_Z;
// float nh = this->heading; // float nh = this->heading;
tar_vx = x - nx; m_TargetV.m_X = x - nx;
tar_vy = y - ny; m_TargetV.m_Y = y - ny;
tar_vz = z - nz; m_TargetV.m_Z = z - nz;
//pRunAnimSpeed = (int8)(speed*NPC_RUNANIM_RATIO); //pRunAnimSpeed = (int8)(speed*NPC_RUNANIM_RATIO);
//speed *= NPC_SPEED_MULTIPLIER; //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 // 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; tar_vector = speed / mag;
// mob move fix // mob move fix
@ -631,23 +615,23 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
if (numsteps>1) if (numsteps>1)
{ {
tar_vector=1.0f ; tar_vector=1.0f ;
tar_vx = tar_vx/numsteps; m_TargetV.m_X = m_TargetV.m_X/numsteps;
tar_vy = tar_vy/numsteps; m_TargetV.m_Y = m_TargetV.m_Y/numsteps;
tar_vz = tar_vz/numsteps; m_TargetV.m_Z = m_TargetV.m_Z/numsteps;
float new_x = x_pos + tar_vx; float new_x = m_Position.m_X + m_TargetV.m_X;
float new_y = y_pos + tar_vy; float new_y = m_Position.m_Y + m_TargetV.m_Y;
float new_z = z_pos + tar_vz; float new_z = m_Position.m_Z + m_TargetV.m_Z;
if(IsNPC()) { if(IsNPC()) {
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
} }
x_pos = new_x; m_Position.m_X = new_x;
y_pos = new_y; m_Position.m_Y = new_y;
z_pos = new_z; m_Position.m_Z = new_z;
m_Position.m_Heading = CalculateHeadingToTarget(x, y);
tar_ndx=22-numsteps; tar_ndx=22-numsteps;
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);
mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", x_pos, y_pos, z_pos, numsteps);
} }
else else
{ {
@ -655,9 +639,9 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
entity_list.ProcessMove(CastToNPC(), x, y, z); entity_list.ProcessMove(CastToNPC(), x, y, z);
} }
x_pos = x; m_Position.m_X = x;
y_pos = y; m_Position.m_Y = y;
z_pos = z; m_Position.m_Z = z;
mlog(AI__WAYPOINTS, "Only a single step to get there... jumping."); 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 { else {
tar_vector/=20; tar_vector/=20;
float new_x = x_pos + tar_vx*tar_vector; float new_x = m_Position.m_X + m_TargetV.m_X*tar_vector;
float new_y = y_pos + tar_vy*tar_vector; float new_y = m_Position.m_Y + m_TargetV.m_Y*tar_vector;
float new_z = z_pos + tar_vz*tar_vector; float new_z = m_Position.m_Z + m_TargetV.m_Z*tar_vector;
if(IsNPC()) { if(IsNPC()) {
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
} }
x_pos = new_x; m_Position.m_X = new_x;
y_pos = new_y; m_Position.m_Y = new_y;
z_pos = new_z; m_Position.m_Z = new_z;
heading = CalculateHeadingToTarget(x, y); m_Position.m_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);
} }
uint8 NPCFlyMode = 0; 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(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) {
if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || 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); 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( (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)) if(ABS(z - m_Position.m_Z) <= RuleR(Map, FixPathingZMaxDeltaMoving))
z_pos = z; m_Position.m_Z = z;
else else
z_pos = newz + 1; m_Position.m_Z = newz + 1;
} }
else 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); SetMoving(true);
moved=true; moved=true;
delta_x=x_pos-nx; m_Delta = xyz_heading(m_Position.m_X - nx, m_Position.m_Y - ny, m_Position.m_Z - nz, 0.0f);
delta_y=y_pos-ny;
delta_z=z_pos-nz;
delta_heading=0;
if (IsClient()) if (IsClient())
SendPosUpdate(1); SendPosUpdate(1);
@ -746,9 +727,9 @@ bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool chec
if(GetID()==0) if(GetID()==0)
return true; return true;
float nx = x_pos; float nx = m_Position.m_X;
float ny = y_pos; float ny = m_Position.m_Y;
float nz = z_pos; float nz = m_Position.m_Z;
// if NPC is rooted // if NPC is rooted
if (speed == 0.0) { 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; float old_test_vector=test_vector;
tar_vx = x - nx; m_TargetV.m_X = x - nx;
tar_vy = y - ny; m_TargetV.m_Y = y - ny;
tar_vz = z - nz; 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; return false;
pRunAnimSpeed = (uint8)(speed*NPC_RUNANIM_RATIO); pRunAnimSpeed = (uint8)(speed*NPC_RUNANIM_RATIO);
speed *= NPC_SPEED_MULTIPLIER; 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 // 2: get unit vector
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
test_vector=sqrtf (x*x + y*y + z*z); 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); 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);
heading = CalculateHeadingToTarget(x, y); m_Position.m_Heading = CalculateHeadingToTarget(x, y);
if (tar_vector >= 1.0) { if (tar_vector >= 1.0) {
if(IsNPC()) { if(IsNPC()) {
entity_list.ProcessMove(CastToNPC(), x, y, z); entity_list.ProcessMove(CastToNPC(), x, y, z);
} }
x_pos = x; m_Position.m_X = x;
y_pos = y; m_Position.m_Y = y;
z_pos = z; m_Position.m_Z = z;
mlog(AI__WAYPOINTS, "Close enough, jumping to waypoint"); mlog(AI__WAYPOINTS, "Close enough, jumping to waypoint");
} }
else { else {
float new_x = x_pos + tar_vx*tar_vector; float new_x = m_Position.m_X + m_TargetV.m_X*tar_vector;
float new_y = y_pos + tar_vy*tar_vector; float new_y = m_Position.m_Y + m_TargetV.m_Y*tar_vector;
float new_z = z_pos + tar_vz*tar_vector; float new_z = m_Position.m_Z + m_TargetV.m_Z*tar_vector;
if(IsNPC()) { if(IsNPC()) {
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
} }
x_pos = new_x; m_Position.m_X = new_x;
y_pos = new_y; m_Position.m_Y = new_y;
z_pos = new_z; m_Position.m_Z = new_z;
mlog(AI__WAYPOINTS, "Next position (%.3f, %.3f, %.3f)", x_pos, y_pos, z_pos); mlog(AI__WAYPOINTS, "Next position (%.3f, %.3f, %.3f)", m_Position.m_X, m_Position.m_Y, m_Position.m_Z);
} }
uint8 NPCFlyMode = 0; 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(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving))
{ {
if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || 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; 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( (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)) if(ABS(z - m_Position.m_Z) <= RuleR(Map, FixPathingZMaxDeltaMoving))
z_pos = z; m_Position.m_Z = z;
else else
z_pos = newz + 1; m_Position.m_Z = newz + 1;
} }
else 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; tar_ndx=0;
this->SetMoving(true); this->SetMoving(true);
moved=true; moved=true;
delta_x=(x_pos-nx); m_Delta = xyz_heading(m_Position.m_X - nx, m_Position.m_Y - ny, m_Position.m_Z - nz, 0.0f);
delta_y=(y_pos-ny);
delta_z=(z_pos-nz);
delta_heading=0;//(heading-nh)*8;
SendPosUpdate(); SendPosUpdate();
} }
tar_ndx++; tar_ndx++;
@ -914,8 +892,9 @@ void NPC::AssignWaypoints(int32 grid) {
if(zone->HasMap() && RuleB(Map, FixPathingZWhenLoading) ) if(zone->HasMap() && RuleB(Map, FixPathingZWhenLoading) )
{ {
auto positon = xyz_location(newwp.x,newwp.y,newwp.z);
if(!RuleB(Watermap, CheckWaypointsInWaterWhenLoading) || !zone->HasWaterMap() || 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); 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); entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
} }
x_pos = new_x; m_Position.m_X = new_x;
y_pos = new_y; m_Position.m_Y = new_y;
z_pos = new_z; m_Position.m_Z = new_z;
mlog(AI__WAYPOINTS, "Sent To (%.3f, %.3f, %.3f)", new_x, new_y, new_z); mlog(AI__WAYPOINTS, "Sent To (%.3f, %.3f, %.3f)", new_x, new_y, new_z);
if(flymode == FlyMode1) 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(zone->HasMap() && RuleB(Map, FixPathingZOnSendTo) )
{ {
if(!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() || 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); 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. if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaSendTo)) // Sanity check.
z_pos = newz + 1; m_Position.m_Z = newz + 1;
} }
} }
else else
z_pos += 0.1; m_Position.m_Z += 0.1;
} }
void Mob::SendToFixZ(float new_x, float new_y, float new_z) { 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); entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z + 0.1);
} }
x_pos = new_x; m_Position.m_X = new_x;
y_pos = new_y; m_Position.m_Y = new_y;
z_pos = new_z + 0.1; m_Position.m_Z = new_z + 0.1;
//fix up pathing Z, this shouldent be needed IF our waypoints //fix up pathing Z, this shouldent be needed IF our waypoints
//are corrected instead //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(zone->HasMap() && RuleB(Map, FixPathingZOnSendTo))
{ {
if(!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() || 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); 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. 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; 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; int matches = 0, fuzzy = 0, spawn2id = 0;
float dbx = 0, dby = 0;
// looks like most of the stuff in spawn2 is straight integers // looks like most of the stuff in spawn2 is straight integers
// so let's try that first // 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", 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); auto results = QueryDatabase(query);
if(!results.Success()) { if(!results.Success()) {
LogFile->write(EQEmuLog::Error, "Error querying spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); 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 " query = StringFormat("SELECT id,x,y FROM spawn2 WHERE zone='%s' AND "
"ABS( ABS(x) - ABS(%f) ) < %f AND " "ABS( ABS(x) - ABS(%f) ) < %f AND "
"ABS( ABS(y) - ABS(%f) ) < %f", "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); results = QueryDatabase(query);
if (!results.Success()) { if (!results.Success()) {
LogFile->write(EQEmuLog::Error, "Error querying fuzzy spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); 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(); auto row = results.begin();
spawn2id = atoi(row[0]); spawn2id = atoi(row[0]);
dbx = atof(row[1]); xy_location dbLocation = xy_location(atof(row[1]), atof(row[2]));
dby = atof(row[2]);
query = StringFormat("UPDATE spawn2 SET pathgrid = %d WHERE id = %d", grid, spawn2id); query = StringFormat("UPDATE spawn2 SET pathgrid = %d WHERE id = %d", grid, spawn2id);
results = QueryDatabase(query); results = QueryDatabase(query);
@ -1141,7 +1118,7 @@ void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid)
return; 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); 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. * 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) " 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)", "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); auto results = QueryDatabase(query);
if (!results.Success()) { if (!results.Success()) {
LogFile->write(EQEmuLog::Error, "Error adding waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); 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 * 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. * 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 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 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) " query = StringFormat("INSERT INTO grid_entries(gridid, zoneid, `number`, x, y, z, pause, heading) "
"VALUES (%i, %i, %i, %f, %f, %f, %i, %f)", "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); results = QueryDatabase(query);
if(!results.Success()) if(!results.Success())
LogFile->write(EQEmuLog::Error, "Error adding grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); 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() void NPC::SaveGuardSpotCharm()
{ {
guard_x_saved = guard_x; m_GuardPointSaved = m_GuardPoint;
guard_y_saved = guard_y;
guard_z_saved = guard_z;
guard_heading_saved = guard_heading;
} }
void NPC::RestoreGuardSpotCharm() void NPC::RestoreGuardSpotCharm()
{ {
guard_x = guard_x_saved; m_GuardPoint = m_GuardPointSaved;
guard_y = guard_y_saved;
guard_z = guard_z_saved;
guard_heading = guard_heading_saved;
} }

View File

@ -736,7 +736,9 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
clientauth_timer(AUTHENTICATION_TIMEOUT * 1000), clientauth_timer(AUTHENTICATION_TIMEOUT * 1000),
spawn2_timer(1000), spawn2_timer(1000),
qglobal_purge_timer(30000), 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; zoneid = in_zoneid;
instanceid = in_instanceid; 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)); memset(file_name, 0, sizeof(file_name));
long_name = 0; long_name = 0;
aggroedmobs =0; aggroedmobs =0;
psafe_x = 0;
psafe_y = 0;
psafe_z = 0;
pgraveyard_id = 0; pgraveyard_id = 0;
pgraveyard_zoneid = 0; pgraveyard_zoneid = 0;
pgraveyard_x = 0;
pgraveyard_y = 0;
pgraveyard_z = 0;
pgraveyard_heading = 0;
pMaxClients = 0; pMaxClients = 0;
pQueuedMerchantsWorkID = 0; pQueuedMerchantsWorkID = 0;
pvpzone = false; pvpzone = false;
if(database.GetServerType() == 1) if(database.GetServerType() == 1)
pvpzone = true; 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) if(graveyard_id() > 0)
{ {
LogFile->write(EQEmuLog::Debug, "Graveyard ID is %i.", graveyard_id()); 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) 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 else
LogFile->write(EQEmuLog::Error, "Unable to load the graveyard id %i for zone %s.", graveyard_id(), short_name); 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<ZonePoint*> iterator(zone_point_list); LinkedListIterator<ZonePoint*> iterator(zone_point_list);
ZonePoint* closest_zp = 0; ZonePoint* closest_zp = 0;
float closest_dist = FLT_MAX; 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) if (zp->target_zone_id == to)
{ {
float delta_x = zp->x - x; auto dist = Distance(xy_location(zp->x,zp->y), location);
float delta_y = zp->y - y; if ((zp->x == 999999 || zp->x == -999999) && (zp->y == 999999 || zp->y == -999999))
if(zp->x == 999999 || zp->x == -999999) dist = 0;
delta_x = 0;
if(zp->y == 999999 || zp->y == -999999)
delta_y = 0;
float dist = sqrt(delta_x * delta_x + delta_y * delta_y);
if (dist < closest_dist) if (dist < closest_dist)
{ {
closest_zp = zp; 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(closest_dist > 400.0f && closest_dist < max_distance2)
{ {
if(client) 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, "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, "<Real Zone Points>. %f x %f y %f z ", x, y, z); LogFile->write(EQEmuLog::Status, "<Real Zone Points>. %s", to_string(location).c_str());
} }
if(closest_dist > max_distance2) if(closest_dist > max_distance2)
closest_zp = nullptr; closest_zp = nullptr;
if(!closest_zp) 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; 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) if(to_name == nullptr)
return GetClosestZonePointWithoutZone(x,y,z, client, max_distance); return GetClosestZonePointWithoutZone(location.m_X, location.m_Y, location.m_Z, client, max_distance);
return GetClosestZonePoint(x, y, z, database.GetZoneID(to_name), 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) { ZonePoint* Zone::GetClosestZonePointWithoutZone(float x, float y, float z, Client* client, float max_distance) {
@ -1823,12 +1813,9 @@ bool Zone::HasGraveyard() {
return Result; 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_zoneid = zoneid;
pgraveyard_x = x; m_Graveyard = graveyardPosition;
pgraveyard_y = y;
pgraveyard_z = z;
pgraveyard_heading = heading;
} }
void Zone::LoadBlockedSpells(uint32 zoneid) 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) if (blocked_spells)
{ {
@ -1905,12 +1892,8 @@ bool Zone::IsSpellBlocked(uint32 spell_id, float nx, float ny, float nz)
} }
case 2: case 2:
{ {
if ((( nx >= (blocked_spells[x].x-blocked_spells[x].xdiff)) && (nx <= (blocked_spells[x].x+blocked_spells[x].xdiff))) && if (!IsWithinAxisAlignedBox(location, blocked_spells[x].m_Location - blocked_spells[x].m_Difference, blocked_spells[x].m_Location + blocked_spells[x].m_Difference))
(( 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))))
{
return true; return true;
}
break; break;
} }
default: default:
@ -1925,7 +1908,7 @@ bool Zone::IsSpellBlocked(uint32 spell_id, float nx, float ny, float nz)
return false; 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) if(blocked_spells)
{ {
@ -1943,12 +1926,8 @@ const char* Zone::GetSpellBlockedMessage(uint32 spell_id, float nx, float ny, fl
} }
case 2: case 2:
{ {
if((( nx > (blocked_spells[x].x-blocked_spells[x].xdiff)) && (nx < (blocked_spells[x].x+blocked_spells[x].xdiff))) && if(!IsWithinAxisAlignedBox(location, blocked_spells[x].m_Location - blocked_spells[x].m_Difference, blocked_spells[x].m_Location + blocked_spells[x].m_Difference))
(( 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))))
{
return blocked_spells[x].message; return blocked_spells[x].message;
}
break; break;
} }
default: default:
@ -2185,7 +2164,7 @@ void Zone::DoAdventureActions()
const NPCType* tmp = database.GetNPCType(ds->data_id); const NPCType* tmp = database.GetNPCType(ds->data_id);
if(tmp) 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(); npc->AddLootTable();
entity_list.AddNPC(npc); entity_list.AddNPC(npc);
npc->Shout("Rarrrgh!"); npc->Shout("Rarrrgh!");

View File

@ -100,14 +100,9 @@ public:
inline Timer* GetInstanceTimer() { return Instance_Timer; } inline Timer* GetInstanceTimer() { return Instance_Timer; }
inline const float& safe_x() { return psafe_x; } inline xyz_location GetSafePoint() { return m_SafePoint; }
inline const float& safe_y() { return psafe_y; }
inline const float& safe_z() { return psafe_z; }
inline const uint32& graveyard_zoneid() { return pgraveyard_zoneid; } inline const uint32& graveyard_zoneid() { return pgraveyard_zoneid; }
inline const float& graveyard_x() { return pgraveyard_x; } inline xyz_heading GetGraveyardPoint() { return m_Graveyard; }
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 const uint32& graveyard_id() { return pgraveyard_id; } inline const uint32& graveyard_id() { return pgraveyard_id; }
inline const uint32& GetMaxClients() { return pMaxClients; } inline const uint32& GetMaxClients() { return pMaxClients; }
@ -123,8 +118,8 @@ public:
void ReloadStaticData(); void ReloadStaticData();
uint32 CountSpawn2(); uint32 CountSpawn2();
ZonePoint* GetClosestZonePoint(float x, float y, float z, const char* to_name, 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(float x, float y, float z, uint32 to, 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); ZonePoint* GetClosestZonePointWithoutZone(float x, float y, float z, Client *client, float max_distance = 40000.0f);
SpawnGroupList spawn_group_list; SpawnGroupList spawn_group_list;
@ -232,12 +227,12 @@ public:
uint8 lootvar; uint8 lootvar;
bool HasGraveyard(); 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 LoadBlockedSpells(uint32 zoneid);
void ClearBlockedSpells(); void ClearBlockedSpells();
bool IsSpellBlocked(uint32 spell_id, float nx, float ny, float nz); bool IsSpellBlocked(uint32 spell_id, const xyz_location& location);
const char *GetSpellBlockedMessage(uint32 spell_id, float nx, float ny, float nz); const char *GetSpellBlockedMessage(uint32 spell_id, const xyz_location& location);
int GetTotalBlockedSpells() { return totalBS; } int GetTotalBlockedSpells() { return totalBS; }
inline bool HasMap() { return zonemap != nullptr; } inline bool HasMap() { return zonemap != nullptr; }
inline bool HasWaterMap() { return watermap != nullptr; } inline bool HasWaterMap() { return watermap != nullptr; }
@ -275,7 +270,7 @@ private:
char* long_name; char* long_name;
char* map_name; char* map_name;
bool pvpzone; bool pvpzone;
float psafe_x, psafe_y, psafe_z; xyz_location m_SafePoint;
uint32 pMaxClients; uint32 pMaxClients;
bool can_bind; bool can_bind;
bool is_city; bool is_city;
@ -286,7 +281,7 @@ private:
uint8 zone_type; uint8 zone_type;
bool allow_mercs; bool allow_mercs;
uint32 pgraveyard_id, pgraveyard_zoneid; uint32 pgraveyard_id, pgraveyard_zoneid;
float pgraveyard_x, pgraveyard_y, pgraveyard_z, pgraveyard_heading; xyz_heading m_Graveyard;
int default_ruleset; int default_ruleset;
int totalBS; int totalBS;

View File

@ -1006,15 +1006,16 @@ bool ZoneDatabase::LoadCharacterLanguages(uint32 character_id, PlayerProfile_Str
"WHERE `id` = %u ORDER BY `lang_id`", character_id); "WHERE `id` = %u ORDER BY `lang_id`", character_id);
auto results = database.QueryDatabase(query); int i = 0; auto results = database.QueryDatabase(query); int i = 0;
/* Initialize Languages */ /* Initialize Languages */
for (i = 0; i < MAX_PP_LANGUAGE; i++){ for (i = 0; i < MAX_PP_LANGUAGE; ++i)
pp->languages[i] = 0; pp->languages[i] = 0;
}
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
i = atoi(row[0]); i = atoi(row[0]);
if (i < MAX_PP_LANGUAGE){ if (i < MAX_PP_LANGUAGE){
pp->languages[i] = atoi(row[1]); pp->languages[i] = atoi(row[1]);
} }
} }
return true; return true;
} }
@ -1037,13 +1038,13 @@ bool ZoneDatabase::LoadCharacterDisciplines(uint32 character_id, PlayerProfile_S
"WHERE `id` = %u ORDER BY `slot_id`", character_id); "WHERE `id` = %u ORDER BY `slot_id`", character_id);
auto results = database.QueryDatabase(query); auto results = database.QueryDatabase(query);
int i = 0; int i = 0;
/* Initialize Disciplines */ /* Initialize Disciplines */
memset(pp->disciplines.values, 0, (sizeof(pp->disciplines.values[0]) * MAX_PP_DISCIPLINES)); memset(pp->disciplines.values, 0, (sizeof(pp->disciplines.values[0]) * MAX_PP_DISCIPLINES));
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
if (i < MAX_PP_DISCIPLINES){ if (i < MAX_PP_DISCIPLINES)
pp->disciplines.values[i] = atoi(row[0]); pp->disciplines.values[i] = atoi(row[0]);
} ++i;
i++;
} }
return true; return true;
} }
@ -1056,17 +1057,18 @@ bool ZoneDatabase::LoadCharacterSkills(uint32 character_id, PlayerProfile_Struct
"FROM " "FROM "
"`character_skills` " "`character_skills` "
"WHERE `id` = %u ORDER BY `skill_id`", character_id); "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 */ /* Initialize Skill */
for (i = 0; i < MAX_PP_SKILL; i++){ for (i = 0; i < MAX_PP_SKILL; ++i)
pp->skills[i] = 0; pp->skills[i] = 0;
}
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
i = atoi(row[0]); i = atoi(row[0]);
if (i < MAX_PP_SKILL){ if (i < MAX_PP_SKILL)
pp->skills[i] = atoi(row[1]); pp->skills[i] = atoi(row[1]);
} }
}
return true; return true;
} }
@ -1176,44 +1178,49 @@ bool ZoneDatabase::LoadCharacterPotions(uint32 character_id, PlayerProfile_Struc
pp->potionbelt.items[i].item_id = 0; pp->potionbelt.items[i].item_id = 0;
strncpy(pp->potionbelt.items[i].item_name, "\0", 1); strncpy(pp->potionbelt.items[i].item_name, "\0", 1);
} }
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
i = atoi(row[0]); /* Potion belt slot number */ i = atoi(row[0]); /* Potion belt slot number */
uint32 item_id = atoi(row[1]); uint32 item_id = atoi(row[1]);
const Item_Struct *item = database.GetItem(item_id); const Item_Struct *item = database.GetItem(item_id);
if(item) { if(!item)
continue;
pp->potionbelt.items[i].item_id = item_id; pp->potionbelt.items[i].item_id = item_id;
pp->potionbelt.items[i].icon = atoi(row[2]); pp->potionbelt.items[i].icon = atoi(row[2]);
strncpy(pp->potionbelt.items[i].item_name, item->Name, 64); strncpy(pp->potionbelt.items[i].item_name, item->Name, 64);
} }
}
return true; return true;
} }
bool ZoneDatabase::LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct* pp){ 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); 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; auto results = database.QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
i = 0;
/* Is home bind */ /* Is home bind */
if (atoi(row[6]) == 1){ if (atoi(row[6]) == 1){
pp->binds[4].zoneId = atoi(row[i++]); pp->binds[4].zoneId = atoi(row[0]);
pp->binds[4].instance_id = atoi(row[i++]); pp->binds[4].instance_id = atoi(row[1]);
pp->binds[4].x = atoi(row[i++]); pp->binds[4].x = atoi(row[2]);
pp->binds[4].y = atoi(row[i++]); pp->binds[4].y = atoi(row[3]);
pp->binds[4].z = atoi(row[i++]); pp->binds[4].z = atoi(row[4]);
pp->binds[4].heading = atoi(row[i++]); pp->binds[4].heading = atoi(row[5]);
continue;
} }
/* Is regular bind point */ /* Is regular bind point */
else{ pp->binds[0].zoneId = atoi(row[0]);
pp->binds[0].zoneId = atoi(row[i++]); pp->binds[0].instance_id = atoi(row[1]);
pp->binds[0].instance_id = atoi(row[i++]); pp->binds[0].x = atoi(row[2]);
pp->binds[0].x = atoi(row[i++]); pp->binds[0].y = atoi(row[3]);
pp->binds[0].y = atoi(row[i++]); pp->binds[0].z = atoi(row[4]);
pp->binds[0].z = atoi(row[i++]); pp->binds[0].heading = atoi(row[5]);
pp->binds[0].heading = atoi(row[i++]);
}
} }
return true; return true;
} }
@ -1223,15 +1230,15 @@ bool ZoneDatabase::SaveCharacterLanguage(uint32 character_id, uint32 lang_id, ui
return true; 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){ bool ZoneDatabase::SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, const xyz_heading& position, uint8 is_home){
if (zone_id <= 0) { if (zone_id <= 0) {
return false; return false;
} }
/* Save Home Bind Point */ /* Save Home Bind Point */
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" 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); " 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 x: %f y: %f z: %f heading: %f ishome: %u", 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 position: %s ishome: %u", character_id, zone_id, instance_id, to_string(position).c_str(), is_home);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.RowsAffected()) { if (!results.RowsAffected()) {
LogFile->write(EQEmuLog::Debug, "ERROR Bind Home Save: %s. %s", results.ErrorMessage().c_str(), query.c_str()); LogFile->write(EQEmuLog::Debug, "ERROR Bind Home Save: %s. %s", results.ErrorMessage().c_str(), query.c_str());
@ -1884,15 +1891,11 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
armor_tint_id); armor_tint_id);
auto armortint_results = QueryDatabase(armortint_query); auto armortint_results = QueryDatabase(armortint_query);
if (!armortint_results.Success() || armortint_results.RowCount() == 0) if (!armortint_results.Success() || armortint_results.RowCount() == 0)
{
armor_tint_id = 0; armor_tint_id = 0;
} else {
else
{
auto armorTint_row = armortint_results.begin(); 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]) << 16;
tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 1]) << 8; tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 1]) << 8;
tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 2]); tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 2]);
@ -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' " 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); auto results = QueryDatabase(query);
if (!results.Success() || results.RowsAffected() == 0) if (!results.Success() || results.RowsAffected() == 0)
return false; return false;
@ -2719,12 +2723,8 @@ bool ZoneDatabase::LoadBlockedSpells(int32 blockedSpellsCount, ZoneSpellsBlocked
memset(&into[index], 0, sizeof(ZoneSpellsBlocked)); memset(&into[index], 0, sizeof(ZoneSpellsBlocked));
into[index].spellid = atoi(row[1]); into[index].spellid = atoi(row[1]);
into[index].type = atoi(row[2]); into[index].type = atoi(row[2]);
into[index].x = atof(row[3]); into[index].m_Location = xyz_location(atof(row[3]), atof(row[4]), atof(row[5]));
into[index].y = atof(row[4]); into[index].m_Difference = xyz_location(atof(row[6]), atof(row[7]), atof(row[8]));
into[index].z = atof(row[5]);
into[index].xdiff = atof(row[6]);
into[index].ydiff = atof(row[7]);
into[index].zdiff = atof(row[8]);
strn0cpy(into[index].message, row[9], 255); strn0cpy(into[index].message, row[9], 255);
} }
@ -2803,7 +2803,7 @@ void ZoneDatabase::QGlobalPurge()
database.QueryDatabase(query); 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, " std::string query = StringFormat("REPLACE INTO doors (id, doorid, zone, version, name, "
"pos_x, pos_y, pos_z, heading, opentype, guild, lockpick, " "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', " "VALUES('%i', '%i', '%s', '%i', '%s', '%f', '%f', "
"'%f', '%f', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i')", "'%f', '%f', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i')",
ddoordbid, ddoorid, zone->GetShortName(), zone->GetInstanceVersion(), ddoordbid, ddoorid, zone->GetShortName(), zone->GetInstanceVersion(),
ddoor_name, dxpos, dypos, dzpos, dheading, dopentype, dguildid, ddoor_name, position.m_X, position.m_Y, position.m_Z, position.m_Heading,
dlockpick, dkeyitem, ddoor_param, dinvert, dincline, dsize); dopentype, dguildid, dlockpick, dkeyitem, ddoor_param, dinvert, dincline, dsize);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()) if (!results.Success())
std::cerr << "Error in InsertDoor" << query << "' " << results.ErrorMessage() << std::endl; std::cerr << "Error in InsertDoor" << query << "' " << results.ErrorMessage() << std::endl;
@ -3398,24 +3398,23 @@ uint32 ZoneDatabase::AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id) {
return zone_id; return zone_id;
} }
uint32 ZoneDatabase::CreateGraveyardRecord(uint32 graveyard_zone_id, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading) { uint32 ZoneDatabase::CreateGraveyardRecord(uint32 graveyard_zone_id, const xyz_heading& position) {
std::string query = StringFormat( std::string query = StringFormat("INSERT INTO `graveyard` "
"INSERT INTO `graveyard` SET `zone_id` = %u, `x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f", "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 graveyard_zone_id, position.m_X, position.m_Y, position.m_Z, position.m_Heading);
);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (results.Success()){ if (results.Success())
return results.LastInsertedID(); return results.LastInsertedID();
}
return 0; return 0;
} }
uint32 ZoneDatabase::SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zone_id, uint16 instance_id, float x, float y, float z, float heading) { uint32 ZoneDatabase::SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zone_id, uint16 instance_id, const xyz_heading& position) {
std::string query = StringFormat( std::string query = StringFormat("UPDATE `character_corpses` "
"UPDATE `character_corpses` " "SET `zone_id` = %u, `instance_id` = 0, "
"SET `zone_id` = %u, `instance_id` = 0, `x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f, `was_at_graveyard` = 1 " "`x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f, "
"`was_at_graveyard` = 1 "
"WHERE `id` = %d", "WHERE `id` = %d",
zone_id, x, y, z, heading, dbid zone_id, position.m_X, position.m_Y, position.m_Z, position.m_Heading, dbid);
);
QueryDatabase(query); QueryDatabase(query);
return dbid; 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); 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 results = QueryDatabase(query);
auto row = results.begin(); auto row = results.begin();
if (results.Success() && results.RowsAffected() != 0){ if (results.Success() && results.RowsAffected() != 0)
return atoul(row[0]); return atoul(row[0]);
}
return 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) { 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 \n" std::string query = StringFormat("UPDATE `character_corpses` "
"`charname` = '%s',\n" "SET `charname` = '%s', `zone_id` = %u, `instance_id` = %u, `charid` = %d, "
"`zone_id` = %u,\n" "`x` = %1.1f,`y` = %1.1f,`z` = %1.1f, `heading` = %1.1f, "
"`instance_id` = %u,\n" "`is_locked` = %d, `exp` = %u, `size` = %f, `level` = %u, "
"`charid` = %d,\n" "`race` = %u, `gender` = %u, `class` = %u, `deity` = %u, "
"`x` = %1.1f,\n" "`texture` = %u, `helm_texture` = %u, `copper` = %u, "
"`y` = %1.1f,\n" "`silver` = %u, `gold` = %u, `platinum` = %u, `hair_color` = %u, "
"`z` = %1.1f,\n" "`beard_color` = %u, `eye_color_1` = %u, `eye_color_2` = %u, "
"`heading` = %1.1f,\n" "`hair_style` = %u, `face` = %u, `beard` = %u, `drakkin_heritage` = %u, "
"`is_locked` = %d,\n" "`drakkin_tattoo` = %u, `drakkin_details` = %u, `wc_1` = %u, "
"`exp` = %u,\n" "`wc_2` = %u, `wc_3` = %u, `wc_4` = %u, `wc_5` = %u, `wc_6` = %u, "
"`size` = %f,\n" "`wc_7` = %u, `wc_8` = %u, `wc_9` = %u "
"`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", "WHERE `id` = %u",
EscapeString(char_name).c_str(), EscapeString(char_name).c_str(), zone_id, instance_id, char_id,
zone_id, position.m_X, position.m_Y, position.m_Z, position.m_Heading,
instance_id, dbpc->locked, dbpc->exp, dbpc->size, dbpc->level, dbpc->race,
char_id, dbpc->gender, dbpc->class_, dbpc->deity, dbpc->texture,
x, dbpc->helmtexture, dbpc->copper, dbpc->silver, dbpc->gold,
y, dbpc->plat, dbpc->haircolor, dbpc->beardcolor, dbpc->eyecolor1,
z, dbpc->eyecolor2, dbpc->hairstyle, dbpc->face, dbpc->beard,
heading, dbpc->drakkin_heritage, dbpc->drakkin_tattoo, dbpc->drakkin_details,
dbpc->locked, dbpc->item_tint[0].color, dbpc->item_tint[1].color, dbpc->item_tint[2].color,
dbpc->exp, dbpc->item_tint[3].color, dbpc->item_tint[4].color, dbpc->item_tint[5].color,
dbpc->size, dbpc->item_tint[6].color, dbpc->item_tint[7].color, dbpc->item_tint[8].color,
dbpc->level, db_id);
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); auto results = QueryDatabase(query);
return db_id; return db_id;
@ -3527,94 +3465,32 @@ void ZoneDatabase::MarkCorpseAsRezzed(uint32 db_id) {
auto results = QueryDatabase(query); 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 */ /* Dump Basic Corpse Data */
std::string query = StringFormat("INSERT INTO `character_corpses` SET \n" std::string query = StringFormat("INSERT INTO `character_corpses` "
"`charname` = '%s',\n" "SET `charname` = '%s', `zone_id` = %u, `instance_id` = %u, `charid` = %d,"
"`zone_id` = %u,\n" "`x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f,"
"`instance_id` = %u,\n" "`time_of_death` = NOW(), `is_buried` = 0, `is_locked` = %d,"
"`charid` = %d,\n" "`exp` = %u, `size` = %f, `level` = %u, `race` = %u, `gender` = %u,"
"`x` = %1.1f,\n" "`class` = %u, `deity` = %u, `texture` = %u, `helm_texture` = %u,"
"`y` = %1.1f,\n" "`copper` = %u, `silver` = %u,`gold` = %u,`platinum` = %u,"
"`z` = %1.1f,\n" "`hair_color` = %u, `beard_color` = %u, `eye_color_1` = %u,"
"`heading` = %1.1f,\n" "`eye_color_2` = %u, `hair_style` = %u, `face` = %u,"
"`time_of_death` = NOW(),\n" "`beard` = %u, `drakkin_heritage` = %u, `drakkin_tattoo` = %u,"
"`is_buried` = 0," "`drakkin_details` = %u, `wc_1` = %u, `wc_2` = %u,"
"`is_locked` = %d,\n" "`wc_3` = %u, `wc_4` = %u, `wc_5` = %u, `wc_6` = %u,"
"`exp` = %u,\n" "`wc_7` = %u,`wc_8` = %u,`wc_9` = %u",
"`size` = %f,\n" EscapeString(charname).c_str(), zoneid, instanceid, charid,
"`level` = %u,\n" position.m_X, position.m_Y, position.m_Z, position.m_Heading,
"`race` = %u,\n" dbpc->locked, dbpc->exp, dbpc->size, dbpc->level, dbpc->race,
"`gender` = %u,\n" dbpc->gender, dbpc->class_, dbpc->deity, dbpc->texture,
"`class` = %u,\n" dbpc->helmtexture, dbpc->copper, dbpc->silver, dbpc->gold,
"`deity` = %u,\n" dbpc->plat, dbpc->haircolor, dbpc->beardcolor, dbpc->eyecolor1,
"`texture` = %u,\n" dbpc->eyecolor2, dbpc->hairstyle, dbpc->face, dbpc->beard,
"`helm_texture` = %u,\n" dbpc->drakkin_heritage, dbpc->drakkin_tattoo, dbpc->drakkin_details,
"`copper` = %u,\n" dbpc->item_tint[0].color, dbpc->item_tint[1].color, dbpc->item_tint[2].color,
"`silver` = %u,\n" dbpc->item_tint[3].color, dbpc->item_tint[4].color, dbpc->item_tint[5].color,
"`gold` = %u,\n" dbpc->item_tint[6].color, dbpc->item_tint[7].color, dbpc->item_tint[8].color);
"`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); auto results = QueryDatabase(query);
uint32 last_insert_id = results.LastInsertedID(); uint32 last_insert_id = results.LastInsertedID();
@ -3834,72 +3710,68 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct
return true; 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* ZoneDatabase::SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, const xyz_heading& position) {
Corpse* NewCorpse = 0; Corpse* corpse = nullptr;
std::string query = StringFormat( std::string query = StringFormat("SELECT `id`, `charname`, `time_of_death`, `is_rezzed` "
"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", "FROM `character_corpses` "
char_id "WHERE `charid` = '%u' AND `is_buried` = 1 "
); "ORDER BY `time_of_death` LIMIT 1",
char_id);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
NewCorpse = Corpse::LoadCharacterCorpseEntity( corpse = Corpse::LoadCharacterCorpseEntity(
atoul(row[0]), // uint32 in_dbid atoul(row[0]), // uint32 in_dbid
char_id, // uint32 in_charid char_id, // uint32 in_charid
row[1], // char* in_charname row[1], // char* in_charname
dest_x, // float in_x position,
dest_y, // float in_y
dest_z, // float in_z
dest_heading, // float in_heading
row[2], // char* time_of_death row[2], // char* time_of_death
atoi(row[3]) == 1, // bool rezzed atoi(row[3]) == 1, // bool rezzed
false // bool was_at_graveyard false // bool was_at_graveyard
); );
if (NewCorpse) { if (!corpse)
entity_list.AddCorpse(NewCorpse); continue;
NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS));
NewCorpse->Spawn(); entity_list.AddCorpse(corpse);
if (!UnburyCharacterCorpse(NewCorpse->GetCorpseDBID(), dest_zone_id, dest_instance_id, dest_x, dest_y, dest_z, dest_heading)) 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); LogFile->write(EQEmuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id);
} }
return corpse;
} }
return NewCorpse; bool ZoneDatabase::SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, const xyz_heading& position) {
} Corpse* corpse = nullptr;
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;
int CorpseCount = 0; int CorpseCount = 0;
std::string query = StringFormat( 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", "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); auto results = QueryDatabase(query);
query = StringFormat( query = StringFormat(
"SELECT `id`, `charname`, `time_of_death`, `is_rezzed` FROM `character_corpses` WHERE `charid` = '%u'" "SELECT `id`, `charname`, `time_of_death`, `is_rezzed` FROM `character_corpses` WHERE `charid` = '%u'"
"ORDER BY time_of_death", "ORDER BY time_of_death",
char_id char_id);
);
results = QueryDatabase(query); results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
NewCorpse = Corpse::LoadCharacterCorpseEntity( corpse = Corpse::LoadCharacterCorpseEntity(
atoul(row[0]), atoul(row[0]),
char_id, char_id,
row[1], row[1],
dest_x, position,
dest_y,
dest_z,
dest_heading,
row[2], row[2],
atoi(row[3]) == 1, atoi(row[3]) == 1,
false); false);
if (NewCorpse) {
entity_list.AddCorpse(NewCorpse); if (corpse) {
NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); entity_list.AddCorpse(corpse);
NewCorpse->Spawn(); corpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS));
corpse->Spawn();
++CorpseCount; ++CorpseCount;
} }
else{ else{
@ -3910,15 +3782,18 @@ bool ZoneDatabase::SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zone_id
return (CorpseCount > 0); 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) { bool ZoneDatabase::UnburyCharacterCorpse(uint32 db_id, uint32 new_zone_id, uint16 new_instance_id, const xyz_heading& position) {
std::string query = StringFormat( std::string query = StringFormat("UPDATE `character_corpses` "
"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", "SET `is_buried` = 0, `zone_id` = %u, `instance_id` = %u, "
new_zone_id, new_instance_id, new_x, new_y, new_z, new_heading, db_id "`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); auto results = QueryDatabase(query);
if (results.Success() && results.RowsAffected() != 0){ if (results.Success() && results.RowsAffected() != 0)
return true; return true;
}
return false; return false;
} }
@ -3930,14 +3805,12 @@ Corpse* ZoneDatabase::LoadCharacterCorpse(uint32 player_corpse_id) {
); );
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) { 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( NewCorpse = Corpse::LoadCharacterCorpseEntity(
atoul(row[0]), // id uint32 in_dbid atoul(row[0]), // id uint32 in_dbid
atoul(row[1]), // charid uint32 in_charid atoul(row[1]), // charid uint32 in_charid
row[2], // char_name row[2], // char_name
atof(row[3]), // x float in_x position,
atof(row[4]), // y float in_y
atof(row[5]), // z float in_z
atof(row[6]), // heading float in_heading
row[7], // time_of_death char* time_of_death row[7], // time_of_death char* time_of_death
atoi(row[8]) == 1, // is_rezzed bool rezzed atoi(row[8]) == 1, // is_rezzed bool rezzed
atoi(row[9]) // was_at_graveyard bool was_at_graveyard atoi(row[9]) // was_at_graveyard bool was_at_graveyard
@ -3958,15 +3831,13 @@ bool ZoneDatabase::LoadCharacterCorpses(uint32 zone_id, uint16 instance_id) {
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) { 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( entity_list.AddCorpse(
Corpse::LoadCharacterCorpseEntity( Corpse::LoadCharacterCorpseEntity(
atoul(row[0]), // id uint32 in_dbid atoul(row[0]), // id uint32 in_dbid
atoul(row[1]), // charid uint32 in_charid atoul(row[1]), // charid uint32 in_charid
row[2], // char_name row[2], // char_name
atof(row[3]), // x float in_x position,
atof(row[4]), // y float in_y
atof(row[5]), // z float in_z
atof(row[6]), // heading float in_heading
row[7], // time_of_death char* time_of_death row[7], // time_of_death char* time_of_death
atoi(row[8]) == 1, // is_rezzed bool rezzed atoi(row[8]) == 1, // is_rezzed bool rezzed
atoi(row[9])) atoi(row[9]))
@ -4016,8 +3887,8 @@ bool ZoneDatabase::BuryAllCharacterCorpses(uint32 char_id) {
bool ZoneDatabase::DeleteCharacterCorpse(uint32 db_id) { bool ZoneDatabase::DeleteCharacterCorpse(uint32 db_id) {
std::string query = StringFormat("DELETE FROM `character_corpses` WHERE `id` = %d", db_id); std::string query = StringFormat("DELETE FROM `character_corpses` WHERE `id` = %d", db_id);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (results.Success() && results.RowsAffected() != 0){ if (results.Success() && results.RowsAffected() != 0)
return true; return true;
}
return false; return false;
} }

View File

@ -3,6 +3,7 @@
#include "../common/shareddb.h" #include "../common/shareddb.h"
#include "../common/eq_packet_structs.h" #include "../common/eq_packet_structs.h"
#include "position.h"
#include "../common/faction.h" #include "../common/faction.h"
class Client; class Client;
@ -129,12 +130,8 @@ struct PetInfo {
struct ZoneSpellsBlocked { struct ZoneSpellsBlocked {
uint32 spellid; uint32 spellid;
int8 type; int8 type;
float x; xyz_location m_Location;
float y; xyz_location m_Difference;
float z;
float xdiff;
float ydiff;
float zdiff;
char message[256]; char message[256];
}; };
@ -276,7 +273,7 @@ public:
bool LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp); bool LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp);
/* Character Data Saves */ /* 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 SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
bool SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp); 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); bool SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level);
@ -308,24 +305,24 @@ public:
uint32 GetCharacterCorpseItemCount(uint32 corpse_id); uint32 GetCharacterCorpseItemCount(uint32 corpse_id);
bool LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs); bool LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs);
Corpse* LoadCharacterCorpse(uint32 player_corpse_id); 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); void MarkCorpseAsRezzed(uint32 dbid);
bool GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes); bool GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes);
bool BuryCharacterCorpse(uint32 dbid); bool BuryCharacterCorpse(uint32 dbid);
bool BuryAllCharacterCorpses(uint32 charid); bool BuryAllCharacterCorpses(uint32 charid);
bool DeleteCharacterCorpse(uint32 dbid); 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 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, float dest_x, float dest_y, float dest_z, float dest_heading); 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, float new_x, float new_y, float new_z, float new_heading); bool UnburyCharacterCorpse(uint32 dbid, uint32 new_zoneid, uint16 dest_instanceid, const xyz_heading& position);
bool LoadCharacterCorpses(uint32 iZoneID, uint16 iInstanceID); bool LoadCharacterCorpses(uint32 iZoneID, uint16 iInstanceID);
bool DeleteGraveyard(uint32 zone_id, uint32 graveyard_id); bool DeleteGraveyard(uint32 zone_id, uint32 graveyard_id);
uint32 GetCharacterCorpseDecayTimer(uint32 corpse_db_id); uint32 GetCharacterCorpseDecayTimer(uint32 corpse_db_id);
uint32 GetCharacterBuriedCorpseCount(uint32 char_id); uint32 GetCharacterBuriedCorpseCount(uint32 char_id);
uint32 SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zoneid, uint16 instanceid, float x, float y, float z, float heading); uint32 SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zoneid, uint16 instanceid, const xyz_heading& position);
uint32 CreateGraveyardRecord(uint32 graveyard_zoneid, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading); uint32 CreateGraveyardRecord(uint32 graveyard_zoneid, const xyz_heading& position);
uint32 AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id); 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 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, float x, float y, float z, float heading, bool rezzed = false); 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 GetFirstCorpseID(uint32 char_id);
uint32 GetCharacterCorpseCount(uint32 char_id); uint32 GetCharacterCorpseCount(uint32 char_id);
uint32 GetCharacterCorpseID(uint32 char_id, uint8 corpse); 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 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 SaveZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct* zd);
bool LoadStaticZonePoints(LinkedList<ZonePoint*>* zone_point_list,const char* zonename, uint32 version); bool LoadStaticZonePoints(LinkedList<ZonePoint*>* 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(); uint8 GetUseCFGSafeCoords();
int getZoneShutDownDelay(uint32 zoneID, uint32 version); int getZoneShutDownDelay(uint32 zoneID, uint32 version);
@ -365,7 +362,7 @@ public:
bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list); bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list);
bool PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay = 0); bool PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay = 0);
Spawn2* LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2id, uint32 timeleft); Spawn2* LoadSpawn2(LinkedList<Spawn2*> &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); void UpdateSpawn2Timeleft(uint32 id, uint16 instance_id,uint32 timeleft);
uint32 GetSpawnTimeLeft(uint32 id, uint16 instance_id); uint32 GetSpawnTimeLeft(uint32 id, uint16 instance_id);
void UpdateSpawn2Status(uint32 id, uint8 new_status); void UpdateSpawn2Status(uint32 id, uint8 new_status);
@ -374,14 +371,14 @@ public:
uint32 GetFreeGrid(uint16 zoneid); uint32 GetFreeGrid(uint16 zoneid);
void DeleteGrid(Client *c, uint32 sg2, uint32 grid_num, bool grid_too, 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 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); void AddWP(Client *c, uint32 gridid, uint32 wpnum, const xyz_heading& position, uint32 pause, uint16 zoneid);
uint32 AddWPForSpawn(Client *c, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading); 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 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 GetGridType(uint32 grid, uint32 zoneid);
uint8 GetGridType2(uint32 grid, uint16 zoneid); uint8 GetGridType2(uint32 grid, uint16 zoneid);
bool GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp); 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 GetHighestGrid(uint32 zoneid);
int GetHighestWaypoint(uint32 zoneid, uint32 gridid); int GetHighestWaypoint(uint32 zoneid, uint32 gridid);
@ -453,7 +450,7 @@ public:
int32 GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version); int32 GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version);
int32 GetDoorsCountPlusOne(const char *zone_name, int16 version); int32 GetDoorsCountPlusOne(const char *zone_name, int16 version);
int32 GetDoorsDBCountPlusOne(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 */ /* Blocked Spells */
int32 GetBlockedSpellsCount(uint32 zoneid); int32 GetBlockedSpellsCount(uint32 zoneid);

View File

@ -124,7 +124,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
return; 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, //if we didnt get a zone point, or its to a different zone,
//then we assume this is invalid. //then we assume this is invalid.
if(!zone_point || zone_point->target_zone_id != target_zone_id) { 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; dest_z = safe_z;
break; break;
case GMSummon: case GMSummon:
dest_x = zonesummon_x; dest_x = m_ZoneSummonLocation.m_X;
dest_y = zonesummon_y; dest_y = m_ZoneSummonLocation.m_Y;
dest_z = zonesummon_z; dest_z = m_ZoneSummonLocation.m_Z;
ignorerestrictions = 1; ignorerestrictions = 1;
break; break;
case GateToBindPoint: case GateToBindPoint:
@ -216,9 +216,9 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
break; break;
case ZoneSolicited: //we told the client to zone somewhere, so we know where they are going. case ZoneSolicited: //we told the client to zone somewhere, so we know where they are going.
//recycle zonesummon variables //recycle zonesummon variables
dest_x = zonesummon_x; dest_x = m_ZoneSummonLocation.m_X;
dest_y = zonesummon_y; dest_y = m_ZoneSummonLocation.m_Y;
dest_z = zonesummon_z; dest_z = m_ZoneSummonLocation.m_Z;
break; break;
case ZoneUnsolicited: //client came up with this on its own. case ZoneUnsolicited: //client came up with this on its own.
//client requested a zoning... what are the cases when this could happen? //client requested a zoning... what are the cases when this could happen?
@ -350,10 +350,10 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc
//set the player's coordinates in the new zone so they have them //set the player's coordinates in the new zone so they have them
//when they zone into it //when they zone into it
x_pos = dest_x; //these coordinates will now be saved when ~client is called m_Position.m_X = dest_x; //these coordinates will now be saved when ~client is called
y_pos = dest_y; m_Position.m_Y = dest_y;
z_pos = dest_z; m_Position.m_Z = dest_z;
heading = dest_h; // Cripp: fix for zone heading m_Position.m_Heading = dest_h; // Cripp: fix for zone heading
m_pp.heading = dest_h; m_pp.heading = dest_h;
m_pp.zone_id = zone_id; m_pp.zone_id = zone_id;
m_pp.zoneInstance = instance_id; m_pp.zoneInstance = instance_id;
@ -394,9 +394,7 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc
//reset to unsolicited. //reset to unsolicited.
zone_mode = ZoneUnsolicited; zone_mode = ZoneUnsolicited;
zonesummon_x = 0; m_ZoneSummonLocation = xyz_location::Origin();
zonesummon_y = 0;
zonesummon_z = 0;
zonesummon_id = 0; zonesummon_id = 0;
zonesummon_ignorerestrictions = 0; zonesummon_ignorerestrictions = 0;
} }
@ -493,59 +491,53 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z
return; return;
} }
iZoneNameLength = strlen(pZoneName); iZoneNameLength = strlen(pZoneName);
xyz_heading safePoint;
switch(zm) { switch(zm) {
case EvacToSafeCoords: case EvacToSafeCoords:
case ZoneToSafeCoords: case ZoneToSafeCoords:
x = zone->safe_x(); safePoint = zone->GetSafePoint();
y = zone->safe_y(); x = safePoint.m_X;
z = zone->safe_z(); y = safePoint.m_Y;
z = safePoint.m_Z;
SetHeading(heading); SetHeading(heading);
break; break;
case GMSummon: case GMSummon:
zonesummon_x = x_pos = x; m_ZoneSummonLocation = m_Position = xyz_heading(x,y,z,heading);
zonesummon_y = y_pos = y;
zonesummon_z = z_pos = z;
SetHeading(heading); SetHeading(heading);
zonesummon_id = zoneID; zonesummon_id = zoneID;
zonesummon_ignorerestrictions = 1; zonesummon_ignorerestrictions = 1;
break; break;
case ZoneSolicited: case ZoneSolicited:
zonesummon_x = x; m_ZoneSummonLocation = xyz_location(x,y,z);
zonesummon_y = y;
zonesummon_z = z;
SetHeading(heading); SetHeading(heading);
zonesummon_id = zoneID; zonesummon_id = zoneID;
zonesummon_ignorerestrictions = ignorerestrictions; zonesummon_ignorerestrictions = ignorerestrictions;
break; break;
case GateToBindPoint: case GateToBindPoint:
x = x_pos = m_pp.binds[0].x; x = m_Position.m_X = m_pp.binds[0].x;
y = y_pos = m_pp.binds[0].y; y = m_Position.m_Y = m_pp.binds[0].y;
z = z_pos = m_pp.binds[0].z; z = m_Position.m_Z = m_pp.binds[0].z;
heading = m_pp.binds[0].heading; heading = m_pp.binds[0].heading;
break; break;
case ZoneToBindPoint: case ZoneToBindPoint:
x = x_pos = m_pp.binds[0].x; x = m_Position.m_X = m_pp.binds[0].x;
y = y_pos = m_pp.binds[0].y; y = m_Position.m_Y = m_pp.binds[0].y;
z = z_pos = m_pp.binds[0].z; z = m_Position.m_Z = m_pp.binds[0].z;
heading = m_pp.binds[0].heading; heading = m_pp.binds[0].heading;
zonesummon_ignorerestrictions = 1; 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); 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; break;
case SummonPC: case SummonPC:
zonesummon_x = x_pos = x; m_ZoneSummonLocation = m_Position = xyz_location(x, y, z);
zonesummon_y = y_pos = y;
zonesummon_z = z_pos = z;
SetHeading(heading); SetHeading(heading);
break; break;
case Rewind: 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()); 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());
zonesummon_x = x_pos = x; m_ZoneSummonLocation = m_Position = xyz_location(x, y, z);
zonesummon_y = y_pos = y;
zonesummon_z = z_pos = z;
SetHeading(heading); SetHeading(heading);
break; break;
default: default:
@ -655,10 +647,8 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z
else { else {
if(zoneID == GetZoneID()) { if(zoneID == GetZoneID()) {
//properly handle proximities //properly handle proximities
entity_list.ProcessMove(this, x_pos, y_pos, z_pos); entity_list.ProcessMove(this, m_Position);
proximity_x = x_pos; m_Proximity = m_Position;
proximity_y = y_pos;
proximity_z = z_pos;
//send out updates to people in zone. //send out updates to people in zone.
SendPosition(); 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) if(zm != EvacToSafeCoords && zm != ZoneToSafeCoords && zm != ZoneToBindPoint)
{ {
zonesummon_x = 0; m_ZoneSummonLocation = xyz_location::Origin();
zonesummon_y = 0;
zonesummon_z = 0;
zonesummon_id = 0; zonesummon_id = 0;
zonesummon_ignorerestrictions = 0; zonesummon_ignorerestrictions = 0;
zone_mode = ZoneUnsolicited; zone_mode = ZoneUnsolicited;
@ -722,22 +710,23 @@ void NPC::Gate() {
Mob::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) { if (to_zone == -1) {
m_pp.binds[0].zoneId = zone->GetZoneID(); 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].instance_id = (zone->GetInstanceID() != 0 && zone->IsInstancePersistent()) ? zone->GetInstanceID() : 0;
m_pp.binds[0].x = x_pos; m_pp.binds[0].x = m_Position.m_X;
m_pp.binds[0].y = y_pos; m_pp.binds[0].y = m_Position.m_Y;
m_pp.binds[0].z = z_pos; m_pp.binds[0].z = m_Position.m_Z;
} }
else { else {
m_pp.binds[0].zoneId = to_zone; m_pp.binds[0].zoneId = to_zone;
m_pp.binds[0].instance_id = to_instance; m_pp.binds[0].instance_id = to_instance;
m_pp.binds[0].x = new_x; m_pp.binds[0].x = location.m_X;
m_pp.binds[0].y = new_y; m_pp.binds[0].y = location.m_Y;
m_pp.binds[0].z = new_z; 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) { void Client::GoToBind(uint8 bindnum) {