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

@ -16,7 +16,7 @@ SET(zone_sources
command.cpp
corpse.cpp
doors.cpp
effects.cpp
effects.cpp
embparser.cpp
embparser_api.cpp
embperl.cpp
@ -92,6 +92,7 @@ SET(zone_sources
perlpacket.cpp
petitions.cpp
pets.cpp
position.cpp
qglobals.cpp
queryserv.cpp
questmgr.cpp
@ -183,6 +184,7 @@ SET(zone_headers
perlpacket.h
petitions.h
pets.h
position.h
qglobals.h
quest_interface.h
queryserv.h

View File

@ -268,10 +268,10 @@ void Client::ActivateAA(aaID activate){
}
// Check if AA is expendable
if (aas_send[activate - activate_val]->special_category == 7) {
// Add the AA cost to the extended profile to track overall total
m_epp.expended_aa += aas_send[activate]->cost;
SetAA(activate, 0);
SaveAA(); /* Save Character AA */
@ -546,12 +546,12 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
if(summon_count > MAX_SWARM_PETS)
summon_count = MAX_SWARM_PETS;
static const float swarm_pet_x[MAX_SWARM_PETS] = { 5, -5, 5, -5,
10, -10, 10, -10,
8, -8, 8, -8 };
static const float swarm_pet_y[MAX_SWARM_PETS] = { 5, 5, -5, -5,
10, 10, -10, -10,
8, 8, -8, -8 };
static const xy_location swarmPetLocations[MAX_SWARM_PETS] = {
{5, 5}, {-5, 5}, {5, -5}, {-5, -5},
{10, 10}, {-10, 10}, {10, -10}, {-10, -10},
{8, 8}, {-8, 8}, {8, -8}, {-8, -8}
};
while(summon_count > 0) {
int pet_duration = pet.duration;
if(duration_override > 0)
@ -568,8 +568,8 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
NPC* npca = new NPC(
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
0,
GetX()+swarm_pet_x[summon_count], GetY()+swarm_pet_y[summon_count],
GetZ(), GetHeading(), FlyMode3);
GetPosition() + swarmPetLocations[summon_count],
FlyMode3);
if (followme)
npca->SetFollowID(GetID());
@ -643,12 +643,11 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
if(summon_count > MAX_SWARM_PETS)
summon_count = MAX_SWARM_PETS;
static const float swarm_pet_x[MAX_SWARM_PETS] = { 5, -5, 5, -5,
10, -10, 10, -10,
8, -8, 8, -8 };
static const float swarm_pet_y[MAX_SWARM_PETS] = { 5, 5, -5, -5,
10, 10, -10, -10,
8, 8, -8, -8 };
static const xy_location swarmPetLocations[MAX_SWARM_PETS] = {
{5, 5}, {-5, 5}, {5, -5}, {-5, -5},
{10, 10}, {-10, 10}, {10, -10}, {-10, -10},
{8, 8}, {-8, 8}, {8, -8}, {-8, -8}
};
while(summon_count > 0) {
int pet_duration = pet.duration;
@ -666,8 +665,8 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
NPC* npca = new NPC(
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
0,
GetX()+swarm_pet_x[summon_count], GetY()+swarm_pet_y[summon_count],
GetZ(), GetHeading(), FlyMode3);
GetPosition()+swarmPetLocations[summon_count],
FlyMode3);
if (followme)
npca->SetFollowID(GetID());
@ -853,7 +852,7 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration)
make_npc->d_melee_texture1 = 0;
make_npc->d_melee_texture2 = 0;
NPC* npca = new NPC(make_npc, 0, GetX(), GetY(), GetZ(), GetHeading(), FlyMode3);
NPC* npca = new NPC(make_npc, 0, GetPosition(), FlyMode3);
if(!npca->GetSwarmInfo()){
AA_SwarmPetInfo* nSI = new AA_SwarmPetInfo;
@ -1017,7 +1016,7 @@ void Client::BuyAA(AA_Action* action)
/* Do Player Profile rank calculations and set player profile */
SaveAA();
/* Save to Database to avoid having to write the whole AA array to the profile, only write changes*/
// database.SaveCharacterAA(this->CharacterID(), aa2->id, (cur_level + 1));
// database.SaveCharacterAA(this->CharacterID(), aa2->id, (cur_level + 1));
if ((RuleB(AA, Stacking) && (GetClientVersionBit() >= 4) && (aa2->hotkey_sid == 4294967295u))
&& ((aa2->max_level == (cur_level + 1)) && aa2->sof_next_id)){
@ -1038,7 +1037,7 @@ void Client::BuyAA(AA_Action* action)
if (cur_level < 1){
Message(15, "You have gained the ability \"%s\" at a cost of %d ability %s.", aa2->name, real_cost, (real_cost>1) ? "points" : "point");
/* QS: Player_Log_AA_Purchases */
/* QS: Player_Log_AA_Purchases */
if (RuleB(QueryServ, PlayerLogAAPurchases)){
std::string event_desc = StringFormat("Initial AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID());
QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc);

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(!zone->watermap->InLiquid(other->GetX(), other->GetY(), other->GetZ())) {
if(!zone->watermap->InLiquid(other->GetPosition())) {
return;
}
}

View File

@ -53,7 +53,7 @@ extern Zone* zone;
Beacon::Beacon(Mob *at_mob, int lifetime)
:Mob
(
nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, at_mob->GetPosition(), 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
),
remove_timer(lifetime),
@ -67,12 +67,6 @@ Beacon::Beacon(Mob *at_mob, int lifetime)
spell_iterations = 0;
caster_id = 0;
// copy location
x_pos = at_mob->GetX();
y_pos = at_mob->GetY();
z_pos = at_mob->GetZ();
heading = at_mob->GetHeading();
if(lifetime)
{
remove_timer.Start();

View File

@ -9,7 +9,7 @@
extern volatile bool ZoneLoaded;
// This constructor is used during the bot create command
Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, 0, 0, 0, 0, 0, 0, false), rest_timer(1) {
Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, xyz_heading::Origin(), 0, false), rest_timer(1) {
if(botOwner) {
this->SetBotOwner(botOwner);
this->_botOwnerCharacterID = botOwner->CharacterID();
@ -99,7 +99,7 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, 0, 0, 0, 0,
}
// This constructor is used when the bot is loaded out of the database
Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType npcTypeData) : NPC(&npcTypeData, 0, 0, 0, 0, 0, 0, false), rest_timer(1) {
Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType npcTypeData) : NPC(&npcTypeData, nullptr, xyz_heading::Origin(), 0, false), rest_timer(1) {
this->_botOwnerCharacterID = botOwnerCharacterID;
if(this->_botOwnerCharacterID > 0) {
@ -3354,7 +3354,7 @@ void Bot::AI_Process() {
if(GetHasBeenSummoned()) {
if(IsBotCaster() || IsBotArcher()) {
if (AImovement_timer->Check()) {
if(!GetTarget() || (IsBotCaster() && !IsBotCasterCombatRange(GetTarget())) || (IsBotArcher() && IsArcheryRange(GetTarget())) || (DistNoRootNoZ(GetPreSummonX(), GetPreSummonY()) < 10)) {
if(!GetTarget() || (IsBotCaster() && !IsBotCasterCombatRange(GetTarget())) || (IsBotArcher() && IsArcheryRange(GetTarget())) || (DistNoRootNoZ(m_PreSummonLocation.m_X, m_PreSummonLocation.m_Y) < 10)) {
if(GetTarget())
FaceTarget(GetTarget());
SetHasBeenSummoned(false);
@ -3363,8 +3363,8 @@ void Bot::AI_Process() {
if(GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this)
{
mlog(AI__WAYPOINTS, "Returning to location prior to being summoned.");
CalculateNewPosition2(GetPreSummonX(), GetPreSummonY(), GetPreSummonZ(), GetRunspeed());
SetHeading(CalculateHeadingToTarget(GetPreSummonX(), GetPreSummonY()));
CalculateNewPosition2(m_PreSummonLocation.m_X, m_PreSummonLocation.m_Y, m_PreSummonLocation.m_Z, GetRunspeed());
SetHeading(CalculateHeadingToTarget(m_PreSummonLocation.m_X, m_PreSummonLocation.m_Y));
return;
}
}
@ -4105,9 +4105,9 @@ void Bot::Spawn(Client* botCharacterOwner, std::string* errorMessage) {
this->GetBotOwner()->CastToClient()->Message(13, "%s save failed!", this->GetCleanName());
// Spawn the bot at the bow owner's loc
this->x_pos = botCharacterOwner->GetX();
this->y_pos = botCharacterOwner->GetY();
this->z_pos = botCharacterOwner->GetZ();
this->m_Position.m_X = botCharacterOwner->GetX();
this->m_Position.m_Y = botCharacterOwner->GetY();
this->m_Position.m_Z = botCharacterOwner->GetZ();
// Make the bot look at the bot owner
FaceTarget(botCharacterOwner);
@ -9076,7 +9076,7 @@ void Bot::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, int16 *resist_adjust) {
bool Result = false;
if(zone && !zone->IsSpellBlocked(spell_id, GetX(), GetY(), GetZ())) {
if(zone && !zone->IsSpellBlocked(spell_id, GetPosition())) {
mlog(SPELLS__CASTING, "CastSpell called for spell %s (%d) on entity %d, slot %d, time %d, mana %d, from item slot %d",
spells[spell_id].name, spell_id, target_id, slot, cast_time, mana_cost, (item_slot==0xFFFFFFFF)?999:item_slot);
@ -10663,12 +10663,12 @@ void Bot::BotGroupSummon(Group* group, Client* client) {
if(botMember->GetBotOwnerCharacterID() == client->CharacterID()) {
botMember->SetTarget(botMember->GetBotOwner());
botMember->WipeHateList();
botMember->Warp(botMember->GetBotOwner()->GetX(), botMember->GetBotOwner()->GetY(), botMember->GetBotOwner()->GetZ());
botMember->Warp(botMember->GetBotOwner()->GetPosition());
if(botMember->HasPet() && botMember->GetPet()) {
botMember->GetPet()->SetTarget(botMember);
botMember->GetPet()->WipeHateList();
botMember->GetPet()->Warp(botMember->GetBotOwner()->GetX(), botMember->GetBotOwner()->GetY(), botMember->GetBotOwner()->GetZ());
botMember->GetPet()->Warp(botMember->GetBotOwner()->GetPosition());
}
}
}
@ -11677,7 +11677,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
else
{
b->SetTarget(c->CastToMob());
b->Warp(c->GetX(), c->GetY(), c->GetZ());
b->Warp(c->GetPosition());
}
}
}
@ -15741,47 +15741,39 @@ std::list<Bot*> EntityList::GetBotsByBotOwnerCharacterID(uint32 botOwnerCharacte
void EntityList::BotPickLock(Bot* rogue)
{
auto it = door_list.begin();
for (auto it = door_list.begin(); it != door_list.end(); ++it) {
Doors *cdoor = it->second;
if(cdoor && !cdoor->IsDoorOpen()) {
float zdiff = rogue->GetZ() - cdoor->GetZ();
if(zdiff < 0)
zdiff = 0 - zdiff;
float curdist = 0;
float tmp = rogue->GetX() - cdoor->GetX();
curdist += (tmp * tmp);
tmp = rogue->GetY() - cdoor->GetY();
curdist += (tmp * tmp);
if((zdiff < 10) && (curdist <= 130)) {
// All rogue items with lock pick bonuses are hands or primary
const ItemInst* item1 = rogue->GetBotItem(MainHands);
const ItemInst* item2 = rogue->GetBotItem(MainPrimary);
if(!cdoor || cdoor->IsDoorOpen())
continue;
float bonus1 = 0.0f;
float bonus2 = 0.0f;
float skill = rogue->GetSkill(SkillPickLock);
auto diff = rogue->GetPosition() - cdoor->GetPosition();
diff.ABS_XYZ();
if(item1) { // Hand slot item
if(item1->GetItem()->SkillModType == SkillPickLock) {
bonus1 = skill * (((float)item1->GetItem()->SkillModValue) / 100.0f);
}
}
float curdist = diff.m_X * diff.m_X + diff.m_Y * diff.m_Y;
if(item2) { // Primary slot item
if(item2->GetItem()->SkillModType == SkillPickLock) {
bonus2 = skill * (((float)item2->GetItem()->SkillModValue) / 100.0f);
}
}
if((diff.m_Z * diff.m_Z >= 10) || (curdist > 130))
continue;
if((skill+bonus1+bonus2) >= cdoor->GetLockpick()) {
cdoor->ForceOpen(rogue);
}
else {
rogue->Say("I am not skilled enough for this lock.");
}
}
}
// All rogue items with lock pick bonuses are hands or primary
const ItemInst* item1 = rogue->GetBotItem(MainHands);
const ItemInst* item2 = rogue->GetBotItem(MainPrimary);
float bonus1 = 0.0f;
float bonus2 = 0.0f;
float skill = rogue->GetSkill(SkillPickLock);
if(item1) // Hand slot item
if(item1->GetItem()->SkillModType == SkillPickLock)
bonus1 = skill * (((float)item1->GetItem()->SkillModValue) / 100.0f);
if(item2) // Primary slot item
if(item2->GetItem()->SkillModType == SkillPickLock)
bonus2 = skill * (((float)item2->GetItem()->SkillModValue) / 100.0f);
if((skill+bonus1+bonus2) >= cdoor->GetLockpick())
cdoor->ForceOpen(rogue);
else
rogue->Say("I am not skilled enough for this lock.");
}
}
@ -16168,11 +16160,9 @@ bool Bot::HasOrMayGetAggro() {
void Bot::SetHasBeenSummoned(bool wasSummoned) {
_hasBeenSummoned = wasSummoned;
if(!wasSummoned) {
_preSummonX = 0;
_preSummonY = 0;
_preSummonZ = 0;
}
if(!wasSummoned)
m_PreSummonLocation = xyz_location::Origin();
}
void Bot::SetDefaultBotStance() {

View File

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

View File

@ -75,10 +75,7 @@ Client::Client(EQStreamInterface* ieqs)
0, // npctypeid
0, // size
0.7, // runspeed
0, // heading
0, // x
0, // y
0, // z
xyz_heading::Origin(),
0, // light
0xFF, // texture
0xFF, // helmtexture
@ -144,7 +141,11 @@ Client::Client(EQStreamInterface* ieqs)
RespawnFromHoverTimer(0),
merc_timer(RuleI(Mercs, UpkeepIntervalMS)),
ItemTickTimer(10000),
ItemQuestTimer(500)
ItemQuestTimer(500),
m_Proximity(FLT_MAX, FLT_MAX, FLT_MAX), //arbitrary large number
m_ZoneSummonLocation(-2.0f,-2.0f,-2.0f),
m_AutoAttackPosition(0.0f, 0.0f, 0.0f, 0.0f),
m_AutoAttackTargetLocation(0.0f, 0.0f, 0.0f)
{
for(int cf=0; cf < _FilterCount; cf++)
ClientFilters[cf] = FilterShow;
@ -190,16 +191,10 @@ Client::Client(EQStreamInterface* ieqs)
auto_attack = false;
auto_fire = false;
linkdead_timer.Disable();
zonesummon_x = -2;
zonesummon_y = -2;
zonesummon_z = -2;
zonesummon_id = 0;
zonesummon_ignorerestrictions = 0;
zoning = false;
zone_mode = ZoneUnsolicited;
proximity_x = FLT_MAX; //arbitrary large number
proximity_y = FLT_MAX;
proximity_z = FLT_MAX;
casting_spell_id = 0;
npcflag = false;
npclevel = 0;
@ -268,13 +263,6 @@ Client::Client(EQStreamInterface* ieqs)
m_AssistExemption = 0;
m_CheatDetectMoved = false;
CanUseReport = true;
aa_los_me.x = 0;
aa_los_me.y = 0;
aa_los_me.z = 0;
aa_los_me_heading = 0;
aa_los_them.x = 0;
aa_los_them.y = 0;
aa_los_them.z = 0;
aa_los_them_mob = nullptr;
los_status = false;
los_status_facing = false;
@ -385,9 +373,9 @@ Client::~Client() {
{
m_pp.zone_id = m_pp.binds[0].zoneId;
m_pp.zoneInstance = m_pp.binds[0].instance_id;
x_pos = m_pp.binds[0].x;
y_pos = m_pp.binds[0].y;
z_pos = m_pp.binds[0].z;
m_Position.m_X = m_pp.binds[0].x;
m_Position.m_Y = m_pp.binds[0].y;
m_Position.m_Z = m_pp.binds[0].z;
}
// we save right now, because the client might be zoning and the world
@ -511,11 +499,11 @@ bool Client::Save(uint8 iCommitNow) {
return false;
/* Wrote current basics to PP for saves */
m_pp.x = x_pos;
m_pp.y = y_pos;
m_pp.z = z_pos;
m_pp.x = m_Position.m_X;
m_pp.y = m_Position.m_Y;
m_pp.z = m_Position.m_Z;
m_pp.guildrank = guildrank;
m_pp.heading = heading;
m_pp.heading = m_Position.m_Heading;
/* Mana and HP */
if (GetHP() <= 0) {
@ -532,8 +520,10 @@ bool Client::Save(uint8 iCommitNow) {
database.SaveCharacterCurrency(CharacterID(), &m_pp);
/* Save Current Bind Points */
database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[0].zoneId, m_pp.binds[0].instance_id, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0, 0); /* Regular bind */
database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[4].zoneId, m_pp.binds[4].instance_id, m_pp.binds[4].x, m_pp.binds[4].y, m_pp.binds[4].z, 0, 1); /* Home Bind */
auto regularBindPosition = xyz_heading(m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0.0f);
auto homeBindPosition = xyz_heading(m_pp.binds[4].x, m_pp.binds[4].y, m_pp.binds[4].z, 0.0f);
database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[0].zoneId, m_pp.binds[0].instance_id, regularBindPosition, 0); /* Regular bind */
database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[4].zoneId, m_pp.binds[4].instance_id, homeBindPosition, 1); /* Home Bind */
/* Save Character Buffs */
database.SaveBuffs(this);
@ -3683,7 +3673,7 @@ void Client::Sacrifice(Client *caster)
void Client::SendOPTranslocateConfirm(Mob *Caster, uint16 SpellID) {
if(!Caster || PendingTranslocate)
if(!Caster || PendingTranslocate)
return;
const SPDat_Spell_Struct &Spell = spells[SpellID];
@ -4136,7 +4126,7 @@ bool Client::GroupFollow(Client* inviter) {
{
GetMerc()->MercJoinClientGroup();
}
if (inviter->IsLFP())
{
// If the player who invited us to a group is LFP, have them update world now that we have joined their group.
@ -4800,8 +4790,7 @@ void Client::SummonAndRezzAllCorpses()
entity_list.RemoveAllCorpsesByCharID(CharacterID());
int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(),
GetX(), GetY(), GetZ(), GetHeading());
int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), GetPosition());
if(CorpseCount <= 0)
{
Message(clientMessageYellow, "You have no corpses to summnon.");
@ -4816,13 +4805,11 @@ void Client::SummonAndRezzAllCorpses()
Message(clientMessageYellow, "All your corpses have been summoned to your feet and have received a 100% resurrection.");
}
void Client::SummonAllCorpses(float dest_x, float dest_y, float dest_z, float dest_heading)
void Client::SummonAllCorpses(const xyz_heading& position)
{
if(dest_x == 0 && dest_y == 0 && dest_z == 0 && dest_heading == 0)
{
dest_x = GetX(); dest_y = GetY(); dest_z = GetZ(); dest_heading = GetHeading();
}
auto summonLocation = position;
if(position.isOrigin() && position.m_Heading == 0.0f)
summonLocation = GetPosition();
ServerPacket *Pack = new ServerPacket(ServerOP_DepopAllPlayersCorpses, sizeof(ServerDepopAllPlayersCorpses_Struct));
@ -4838,12 +4825,7 @@ void Client::SummonAllCorpses(float dest_x, float dest_y, float dest_z, float de
entity_list.RemoveAllCorpsesByCharID(CharacterID());
int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(),
dest_x, dest_y, dest_z, dest_heading);
if(CorpseCount <= 0)
{
return;
}
database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), summonLocation);
}
void Client::DepopAllCorpses()
@ -6291,8 +6273,11 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
if(summon_count > MAX_SWARM_PETS)
summon_count = MAX_SWARM_PETS;
static const float swarm_pet_x[MAX_SWARM_PETS] = { 5, -5, 5, -5, 10, -10, 10, -10, 8, -8, 8, -8 };
static const float swarm_pet_y[MAX_SWARM_PETS] = { 5, 5, -5, -5, 10, 10, -10, -10, 8, 8, -8, -8 };
static const xy_location swarmPetLocations[MAX_SWARM_PETS] = {
{5, 5}, {-5, 5}, {5, -5}, {-5, -5},
{10, 10}, {-10, 10}, {10, -10}, {-10, -10},
{8, 8}, {-8, 8}, {8, -8}, {-8, -8}
};
while(summon_count > 0) {
NPCType *npc_dup = nullptr;
@ -6304,8 +6289,8 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
NPC* npca = new NPC(
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
0,
GetX()+swarm_pet_x[summon_count], GetY()+swarm_pet_y[summon_count],
GetZ(), GetHeading(), FlyMode3);
GetPosition()+swarmPetLocations[summon_count],
FlyMode3);
if(!npca->GetSwarmInfo()){
AA_SwarmPetInfo* nSI = new AA_SwarmPetInfo;
@ -7333,7 +7318,7 @@ void Client::SendMercPersonalInfo()
uint32 altCurrentType = 19; //TODO: Implement alternate currency purchases involving mercs!
MercTemplate *mercData = &zone->merc_templates[GetMercInfo().MercTemplateID];
int stancecount = 0;
stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size();
if(stancecount > MAX_MERC_STANCES || mercCount > MAX_MERC || mercTypeCount > MAX_MERC_GRADES)
@ -7435,7 +7420,7 @@ void Client::SendMercPersonalInfo()
}
if (MERC_DEBUG > 0)
Message(7, "Mercenary Debug: SendMercPersonalInfo Send Successful");
SendMercMerchantResponsePacket(0);
}
else

View File

@ -398,10 +398,10 @@ public:
inline const char* GetLastName() const { return lastname; }
inline float ProximityX() const { return(proximity_x); }
inline float ProximityY() const { return(proximity_y); }
inline float ProximityZ() const { return(proximity_z); }
inline void ClearAllProximities() { entity_list.ProcessMove(this, FLT_MAX, FLT_MAX, FLT_MAX); proximity_x = FLT_MAX; proximity_y = FLT_MAX; proximity_z = FLT_MAX; }
inline float ProximityX() const { return m_Proximity.m_X; }
inline float ProximityY() const { return m_Proximity.m_Y; }
inline float ProximityZ() const { return m_Proximity.m_Z; }
inline void ClearAllProximities() { entity_list.ProcessMove(this, xyz_location(FLT_MAX, FLT_MAX, FLT_MAX)); m_Proximity = xyz_location(FLT_MAX,FLT_MAX,FLT_MAX); }
/*
Begin client modifiers
@ -580,7 +580,7 @@ public:
void GoToBind(uint8 bindnum = 0);
void GoToSafeCoords(uint16 zone_id, uint16 instance_id);
void Gate();
void SetBindPoint(int to_zone = -1, int to_instance = 0, float new_x = 0.0f, float new_y = 0.0f, float new_z = 0.0f);
void SetBindPoint(int to_zone = -1, int to_instance = 0, const xyz_location& location = xyz_location::Origin());
void SetStartZone(uint32 zoneid, float x = 0.0f, float y =0.0f, float z = 0.0f);
uint32 GetStartZone(void);
void MovePC(const char* zonename, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
@ -1078,7 +1078,7 @@ public:
void DoItemEnterZone();
bool DoItemEnterZone(uint32 slot_x, uint32 slot_y); // behavior change: 'slot_y' is now [RANGE]_END and not [RANGE]_END + 1
void SummonAndRezzAllCorpses();
void SummonAllCorpses(float dest_x, float dest_y, float dest_z, float dest_heading);
void SummonAllCorpses(const xyz_heading& position);
void DepopAllCorpses();
void DepopPlayerCorpse(uint32 dbid);
void BuryPlayerCorpses();
@ -1267,11 +1267,10 @@ protected:
Mob* bind_sight_target;
Map::Vertex aa_los_me;
Map::Vertex aa_los_them;
xyz_heading m_AutoAttackPosition;
xyz_location m_AutoAttackTargetLocation;
Mob *aa_los_them_mob;
bool los_status;
float aa_los_me_heading;
bool los_status_facing;
QGlobalCache *qGlobals;
@ -1424,9 +1423,8 @@ private:
void DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instance_id, float dest_x, float dest_y, float dest_z, float dest_h, int8 ignore_r);
void ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm);
void ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
float zonesummon_x;
float zonesummon_y;
float zonesummon_z;
xyz_location m_ZoneSummonLocation;
uint16 zonesummon_id;
uint8 zonesummon_ignorerestrictions;
ZoneMode zone_mode;
@ -1465,10 +1463,7 @@ private:
Timer RespawnFromHoverTimer;
Timer merc_timer;
float proximity_x;
float proximity_y;
float proximity_z;
xyz_location m_Proximity;
void BulkSendInventoryItems();

View File

@ -1455,9 +1455,10 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
strcpy(lastname, m_pp.last_name);
/* If PP is set to weird coordinates */
if ((m_pp.x == -1 && m_pp.y == -1 && m_pp.z == -1) || (m_pp.x == -2 && m_pp.y == -2 && m_pp.z == -2)) {
m_pp.x = zone->safe_x();
m_pp.y = zone->safe_y();
m_pp.z = zone->safe_z();
auto safePoint = zone->GetSafePoint();
m_pp.x = safePoint.m_X;
m_pp.y = safePoint.m_Y;
m_pp.z = safePoint.m_Z;
}
/* If too far below ground, then fix */
// float ground_z = GetGroundZ(m_pp.x, m_pp.y, m_pp.z);
@ -1467,10 +1468,10 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
/* Set Mob variables for spawn */
class_ = m_pp.class_;
level = m_pp.level;
x_pos = m_pp.x;
y_pos = m_pp.y;
z_pos = m_pp.z;
heading = m_pp.heading;
m_Position.m_X = m_pp.x;
m_Position.m_Y = m_pp.y;
m_Position.m_Z = m_pp.z;
m_Position.m_Heading = m_pp.heading;
race = m_pp.race;
base_race = m_pp.race;
gender = m_pp.gender;
@ -3240,13 +3241,8 @@ void Client::Handle_OP_AutoAttack(const EQApplicationPacket *app)
ranged_timer.Disable();
attack_dw_timer.Disable();
aa_los_me.x = 0;
aa_los_me.y = 0;
aa_los_me.z = 0;
aa_los_me_heading = 0;
aa_los_them.x = 0;
aa_los_them.y = 0;
aa_los_them.z = 0;
m_AutoAttackPosition = xyz_heading::Origin();
m_AutoAttackTargetLocation = xyz_location::Origin();
aa_los_them_mob = nullptr;
}
else if (app->pBuffer[0] == 1)
@ -3260,25 +3256,15 @@ void Client::Handle_OP_AutoAttack(const EQApplicationPacket *app)
if (GetTarget())
{
aa_los_them_mob = GetTarget();
aa_los_me.x = GetX();
aa_los_me.y = GetY();
aa_los_me.z = GetZ();
aa_los_me_heading = GetHeading();
aa_los_them.x = aa_los_them_mob->GetX();
aa_los_them.y = aa_los_them_mob->GetY();
aa_los_them.z = aa_los_them_mob->GetZ();
m_AutoAttackPosition = GetPosition();
m_AutoAttackTargetLocation = aa_los_them_mob->GetPosition();
los_status = CheckLosFN(aa_los_them_mob);
los_status_facing = IsFacingMob(aa_los_them_mob);
}
else
{
aa_los_me.x = GetX();
aa_los_me.y = GetY();
aa_los_me.z = GetZ();
aa_los_me_heading = GetHeading();
aa_los_them.x = 0;
aa_los_them.y = 0;
aa_los_them.z = 0;
m_AutoAttackPosition = GetPosition();
m_AutoAttackTargetLocation = xyz_location::Origin();
aa_los_them_mob = nullptr;
los_status = false;
los_status_facing = false;
@ -4000,9 +3986,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
CastSpell_Struct* castspell = (CastSpell_Struct*)app->pBuffer;
targetring_x = castspell->x_pos;
targetring_y = castspell->y_pos;
targetring_z = castspell->z_pos;
m_TargetRing = xyz_location(castspell->x_pos, castspell->y_pos, castspell->z_pos);
#ifdef _EQDEBUG
LogFile->write(EQEmuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[0], castspell->cs_unknown[0]);
@ -4034,9 +4018,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
return;
}
targetring_x = castspell->x_pos;
targetring_y = castspell->y_pos;
targetring_z = castspell->z_pos;
m_TargetRing = xyz_location(castspell->x_pos, castspell->y_pos, castspell->z_pos);
CastSpell(spell_to_cast, castspell->target_id, castspell->slot);
}
@ -4380,7 +4362,8 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
}
// set the boat's position deltas
boat->SetDeltas(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading);
auto boatDelta = xyz_heading(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading);
boat->SetDelta(boatDelta);
// send an update to everyone nearby except the client controlling the boat
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
PlayerPositionUpdateServer_Struct* ppus = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer;
@ -4396,9 +4379,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
float dist = 0;
float tmp;
tmp = x_pos - ppu->x_pos;
tmp = m_Position.m_X - ppu->x_pos;
dist += tmp*tmp;
tmp = y_pos - ppu->y_pos;
tmp = m_Position.m_Y - ppu->y_pos;
dist += tmp*tmp;
dist = sqrt(dist);
@ -4541,51 +4524,41 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
float rewind_x_diff = 0;
float rewind_y_diff = 0;
rewind_x_diff = ppu->x_pos - rewind_x;
rewind_x_diff = ppu->x_pos - m_RewindLocation.m_X;
rewind_x_diff *= rewind_x_diff;
rewind_y_diff = ppu->y_pos - rewind_y;
rewind_y_diff = ppu->y_pos - m_RewindLocation.m_Y;
rewind_y_diff *= rewind_y_diff;
//We only need to store updated values if the player has moved.
//If the player has moved more than units for x or y, then we'll store
//his pre-PPU x and y for /rewind, in case he gets stuck.
if ((rewind_x_diff > 750) || (rewind_y_diff > 750)) {
rewind_x = x_pos;
rewind_y = y_pos;
rewind_z = z_pos;
}
if ((rewind_x_diff > 750) || (rewind_y_diff > 750))
m_RewindLocation = m_Position;
//If the PPU was a large jump, such as a cross zone gate or Call of Hero,
//just update rewind coords to the new ppu coords. This will prevent exploitation.
if ((rewind_x_diff > 5000) || (rewind_y_diff > 5000)) {
rewind_x = ppu->x_pos;
rewind_y = ppu->y_pos;
rewind_z = ppu->z_pos;
}
if ((rewind_x_diff > 5000) || (rewind_y_diff > 5000))
m_RewindLocation = xyz_location(ppu->x_pos, ppu->y_pos, ppu->z_pos);
if(proximity_timer.Check()) {
entity_list.ProcessMove(this, ppu->x_pos, ppu->y_pos, ppu->z_pos);
entity_list.ProcessMove(this, xyz_location(ppu->x_pos, ppu->y_pos, ppu->z_pos));
if(RuleB(TaskSystem, EnableTaskSystem) && RuleB(TaskSystem,EnableTaskProximity))
ProcessTaskProximities(ppu->x_pos, ppu->y_pos, ppu->z_pos);
proximity_x = ppu->x_pos;
proximity_y = ppu->y_pos;
proximity_z = ppu->z_pos;
m_Proximity = xyz_location(ppu->x_pos, ppu->y_pos, ppu->z_pos);
}
// Update internal state
delta_x = ppu->delta_x;
delta_y = ppu->delta_y;
delta_z = ppu->delta_z;
delta_heading = ppu->delta_heading;
m_Delta = xyz_heading(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading);
if(IsTracking() && ((x_pos!=ppu->x_pos) || (y_pos!=ppu->y_pos))){
if(IsTracking() && ((m_Position.m_X!=ppu->x_pos) || (m_Position.m_Y!=ppu->y_pos))){
if(zone->random.Real(0, 100) < 70)//should be good
CheckIncreaseSkill(SkillTracking, nullptr, -20);
}
// Break Hide if moving without sneaking and set rewind timer if moved
if(ppu->y_pos != y_pos || ppu->x_pos != x_pos){
if(ppu->y_pos != m_Position.m_Y || ppu->x_pos != m_Position.m_X){
if((hidden || improved_hidden) && !sneaking){
hidden = false;
improved_hidden = false;
@ -4605,13 +4578,14 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
// Outgoing client packet
float tmpheading = EQ19toFloat(ppu->heading);
if (!FCMP(ppu->y_pos, y_pos) || !FCMP(ppu->x_pos, x_pos) || !FCMP(tmpheading, heading) || ppu->animation != animation)
if (!FCMP(ppu->y_pos, m_Position.m_Y) || !FCMP(ppu->x_pos, m_Position.m_X) || !FCMP(tmpheading, m_Position.m_Heading) || ppu->animation != animation)
{
x_pos = ppu->x_pos;
y_pos = ppu->y_pos;
z_pos = ppu->z_pos;
animation = ppu->animation;
heading = tmpheading;
m_Position.m_X = ppu->x_pos;
m_Position.m_Y = ppu->y_pos;
m_Position.m_Z = ppu->z_pos;
m_Position.m_Heading = tmpheading;
animation = ppu->animation;
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
PlayerPositionUpdateServer_Struct* ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer;
@ -4623,13 +4597,8 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
safe_delete(outapp);
}
if(zone->watermap)
{
if(zone->watermap->InLiquid(x_pos, y_pos, z_pos))
{
CheckIncreaseSkill(SkillSwimming, nullptr, -17);
}
}
if(zone->watermap && zone->watermap->InLiquid(m_Position))
CheckIncreaseSkill(SkillSwimming, nullptr, -17);
return;
}
@ -6623,7 +6592,7 @@ void Client::Handle_OP_GroupFollow2(const EQApplicationPacket *app)
GroupGeneric_Struct* gf = (GroupGeneric_Struct*)app->pBuffer;
Mob* inviter = entity_list.GetClientByName(gf->name1);
// Inviter and Invitee are in the same zone
if (inviter != nullptr && inviter->IsClient())
{
@ -6638,7 +6607,7 @@ void Client::Handle_OP_GroupFollow2(const EQApplicationPacket *app)
{
// Inviter is in another zone - Remove merc from group now if any
LeaveGroup();
ServerPacket* pack = new ServerPacket(ServerOP_GroupFollow, sizeof(ServerGroupFollow_Struct));
ServerGroupFollow_Struct *sgfs = (ServerGroupFollow_Struct *)pack->pBuffer;
sgfs->CharacterID = CharacterID();
@ -8029,7 +7998,7 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app)
InspectResponse_Struct* insr = (InspectResponse_Struct*)outapp->pBuffer;
Mob* tmp = entity_list.GetMob(insr->TargetID);
const Item_Struct* item = nullptr;
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
for (int16 L = EmuConstants::EQUIPMENT_BEGIN; L <= MainWaist; L++) {
const ItemInst* inst = GetInv().GetItem(L);
@ -11706,7 +11675,7 @@ void Client::Handle_OP_Rewind(const EQApplicationPacket *app)
Message_StringID(MT_System, REWIND_WAIT);
}
else {
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), rewind_x, rewind_y, rewind_z, 0, 2, Rewind);
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_RewindLocation.m_X, m_RewindLocation.m_Y, m_RewindLocation.m_Z, 0, 2, Rewind);
rewind_timer.Start(30000, true);
}
}
@ -11830,29 +11799,29 @@ void Client::Handle_OP_SenseTraps(const EQApplicationPacket *app)
int uskill = GetSkill(SkillSenseTraps);
if ((zone->random.Int(0, 99) + uskill) >= (zone->random.Int(0, 99) + trap->skill*0.75))
{
float xdif = trap->x - GetX();
float ydif = trap->y - GetY();
if (xdif == 0 && ydif == 0)
auto diff = trap->m_Position - GetPosition();
if (diff.m_X == 0 && diff.m_Y == 0)
Message(MT_Skills, "You sense a trap right under your feet!");
else if (xdif > 10 && ydif > 10)
else if (diff.m_X > 10 && diff.m_Y > 10)
Message(MT_Skills, "You sense a trap to the NorthWest.");
else if (xdif < -10 && ydif > 10)
else if (diff.m_X < -10 && diff.m_Y > 10)
Message(MT_Skills, "You sense a trap to the NorthEast.");
else if (ydif > 10)
else if (diff.m_Y > 10)
Message(MT_Skills, "You sense a trap to the North.");
else if (xdif > 10 && ydif < -10)
else if (diff.m_X > 10 && diff.m_Y < -10)
Message(MT_Skills, "You sense a trap to the SouthWest.");
else if (xdif < -10 && ydif < -10)
else if (diff.m_X < -10 && diff.m_Y < -10)
Message(MT_Skills, "You sense a trap to the SouthEast.");
else if (ydif < -10)
else if (diff.m_Y < -10)
Message(MT_Skills, "You sense a trap to the South.");
else if (xdif > 10)
else if (diff.m_X > 10)
Message(MT_Skills, "You sense a trap to the West.");
else
Message(MT_Skills, "You sense a trap to the East.");
trap->detected = true;
float angle = CalculateHeadingToTarget(trap->x, trap->y);
float angle = CalculateHeadingToTarget(trap->m_Position.m_X, trap->m_Position.m_Y);
if (angle < 0)
angle = (256 + angle);
@ -12930,9 +12899,9 @@ void Client::Handle_OP_SwapSpell(const EQApplicationPacket *app)
m_pp.spell_book[swapspell->from_slot] = m_pp.spell_book[swapspell->to_slot];
m_pp.spell_book[swapspell->to_slot] = swapspelltemp;
/* Save Spell Swaps */
/* Save Spell Swaps */
if (!database.SaveCharacterSpell(this->CharacterID(), m_pp.spell_book[swapspell->from_slot], swapspell->from_slot)){
database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[swapspell->from_slot], swapspell->from_slot);
database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[swapspell->from_slot], swapspell->from_slot);
}
if (!database.SaveCharacterSpell(this->CharacterID(), swapspelltemp, swapspell->to_slot)){
database.DeleteCharacterSpell(this->CharacterID(), swapspelltemp, swapspell->to_slot);
@ -13718,7 +13687,7 @@ void Client::Handle_OP_Translocate(const EQApplicationPacket *app)
}
Translocate_Struct *its = (Translocate_Struct*)app->pBuffer;
if (!PendingTranslocate)
if (!PendingTranslocate)
return;
if ((RuleI(Spells, TranslocateTimeLimit) > 0) && (time(nullptr) > (TranslocateTime + RuleI(Spells, TranslocateTimeLimit)))) {
@ -13739,7 +13708,7 @@ void Client::Handle_OP_Translocate(const EQApplicationPacket *app)
// to the bind coords it has from the PlayerProfile, but with the X and Y reversed. I suspect they are
// reversed in the pp, and since spells like Gate are handled serverside, this has not mattered before.
if (((SpellID == 1422) || (SpellID == 1334) || (SpellID == 3243)) &&
(zone->GetZoneID() == PendingTranslocateData.zone_id &&
(zone->GetZoneID() == PendingTranslocateData.zone_id &&
zone->GetInstanceID() == PendingTranslocateData.instance_id))
{
PendingTranslocate = false;
@ -13750,7 +13719,7 @@ void Client::Handle_OP_Translocate(const EQApplicationPacket *app)
////Was sending the packet back to initiate client zone...
////but that could be abusable, so lets go through proper channels
MovePC(PendingTranslocateData.zone_id, PendingTranslocateData.instance_id,
PendingTranslocateData.x, PendingTranslocateData.y,
PendingTranslocateData.x, PendingTranslocateData.y,
PendingTranslocateData.z, PendingTranslocateData.heading, 0, ZoneSolicited);
}
}

View File

@ -174,7 +174,7 @@ bool Client::Process() {
GetMerc()->Save();
GetMerc()->Depop();
}
Raid *myraid = entity_list.GetRaidByClient(this);
if (myraid)
{
@ -340,41 +340,31 @@ bool Client::Process() {
if(aa_los_them_mob)
{
if(auto_attack_target != aa_los_them_mob ||
aa_los_me.x != GetX() ||
aa_los_me.y != GetY() ||
aa_los_me.z != GetZ() ||
aa_los_them.x != aa_los_them_mob->GetX() ||
aa_los_them.y != aa_los_them_mob->GetY() ||
aa_los_them.z != aa_los_them_mob->GetZ())
m_AutoAttackPosition.m_X != GetX() ||
m_AutoAttackPosition.m_Y != GetY() ||
m_AutoAttackPosition.m_Z != GetZ() ||
m_AutoAttackTargetLocation.m_X != aa_los_them_mob->GetX() ||
m_AutoAttackTargetLocation.m_Y != aa_los_them_mob->GetY() ||
m_AutoAttackTargetLocation.m_Z != aa_los_them_mob->GetZ())
{
aa_los_them_mob = auto_attack_target;
aa_los_me.x = GetX();
aa_los_me.y = GetY();
aa_los_me.z = GetZ();
aa_los_them.x = aa_los_them_mob->GetX();
aa_los_them.y = aa_los_them_mob->GetY();
aa_los_them.z = aa_los_them_mob->GetZ();
m_AutoAttackPosition = GetPosition();
m_AutoAttackTargetLocation = aa_los_them_mob->GetPosition();
los_status = CheckLosFN(auto_attack_target);
aa_los_me_heading = GetHeading();
los_status_facing = IsFacingMob(aa_los_them_mob);
}
// If only our heading changes, we can skip the CheckLosFN call
// but above we still need to update los_status_facing
if (aa_los_me_heading != GetHeading()) {
aa_los_me_heading = GetHeading();
if (m_AutoAttackPosition.m_Heading != GetHeading()) {
m_AutoAttackPosition.m_Heading = GetHeading();
los_status_facing = IsFacingMob(aa_los_them_mob);
}
}
else
{
aa_los_them_mob = auto_attack_target;
aa_los_me.x = GetX();
aa_los_me.y = GetY();
aa_los_me.z = GetZ();
aa_los_me_heading = GetHeading();
aa_los_them.x = aa_los_them_mob->GetX();
aa_los_them.y = aa_los_them_mob->GetY();
aa_los_them.z = aa_los_them_mob->GetZ();
m_AutoAttackPosition = GetPosition();
m_AutoAttackTargetLocation = aa_los_them_mob->GetPosition();
los_status = CheckLosFN(auto_attack_target);
los_status_facing = IsFacingMob(aa_los_them_mob);
}
@ -529,9 +519,7 @@ bool Client::Process() {
else
{
animation = 0;
delta_x = 0;
delta_y = 0;
delta_z = 0;
m_Delta = xyz_heading(0.0f, 0.0f, 0.0f, m_Delta.m_Heading);
SendPosUpdate(2);
}
}
@ -785,32 +773,32 @@ void Client::OnDisconnect(bool hard_disconnect) {
if (MyRaid)
MyRaid->MemberZoned(this);
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
/* QS: PlayerLogConnectDisconnect */
if (RuleB(QueryServ, PlayerLogConnectDisconnect)){
std::string event_desc = StringFormat("Disconnect :: in zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID());
QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc);
}
}
}
Mob *Other = trade->With();
Mob *Other = trade->With();
if(Other)
{
mlog(TRADING__CLIENT, "Client disconnected during a trade. Returning their items.");
mlog(TRADING__CLIENT, "Client disconnected during a trade. Returning their items.");
FinishTrade(this);
if(Other->IsClient())
Other->CastToClient()->FinishTrade(Other);
/* Reset both sides of the trade */
trade->Reset();
trade->Reset();
Other->trade->Reset();
}
database.SetFirstLogon(CharacterID(), 0); //We change firstlogon status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world.
/* Remove ourself from all proximities */
/* Remove ourself from all proximities */
ClearAllProximities();
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LogoutReply);
@ -1555,7 +1543,7 @@ void Client::OPMoveCoin(const EQApplicationPacket* app)
if (from_bucket == &m_pp.platinum_shared)
amount_to_add = 0 - amount_to_take;
database.SetSharedPlatinum(AccountID(),amount_to_add);
database.SetSharedPlatinum(AccountID(),amount_to_add);
}
}
else{
@ -1741,7 +1729,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
}
SetSkill(skill, t_level);
} else {
} else {
switch(skill) {
case SkillBrewing:
case SkillMakePoison:
@ -1943,7 +1931,7 @@ void Client::DoEnduranceUpkeep() {
int upkeep_sum = 0;
int cost_redux = spellbonuses.EnduranceReduction + itembonuses.EnduranceReduction + aabonuses.EnduranceReduction;
bool has_effect = false;
uint32 buffs_i;
uint32 buff_count = GetMaxTotalSlots();
@ -2129,9 +2117,9 @@ void Client::HandleRespawnFromHover(uint32 Option)
if (corpse)
{
x_pos = corpse->GetX();
y_pos = corpse->GetY();
z_pos = corpse->GetZ();
m_Position.m_X = corpse->GetX();
m_Position.m_Y = corpse->GetY();
m_Position.m_Z = corpse->GetZ();
}
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) + 10);
@ -2184,10 +2172,10 @@ void Client::HandleRespawnFromHover(uint32 Option)
SetMana(GetMaxMana());
SetEndurance(GetMaxEndurance());
x_pos = chosen->x;
y_pos = chosen->y;
z_pos = chosen->z;
heading = chosen->heading;
m_Position.m_X = chosen->x;
m_Position.m_Y = chosen->y;
m_Position.m_Z = chosen->z;
m_Position.m_Heading = chosen->heading;
ClearHover();
entity_list.RefreshClientXTargets(this);
@ -2197,7 +2185,7 @@ void Client::HandleRespawnFromHover(uint32 Option)
//After they've respawned into the same zone, trigger EVENT_RESPAWN
parse->EventPlayer(EVENT_RESPAWN, this, static_cast<std::string>(itoa(Option)), is_rez ? 1 : 0);
//Pop Rez option from the respawn options list;
//Pop Rez option from the respawn options list;
//easiest way to make sure it stays at the end and
//doesn't disrupt adding/removing scripted options
respawn_options.pop_back();

View File

@ -1839,14 +1839,7 @@ void command_itemtest(Client *c, const Seperator *sep)
void command_gassign(Client *c, const Seperator *sep)
{
if (sep->IsNumber(1) && c->GetTarget() && c->GetTarget()->IsNPC())
{
database.AssignGrid(
c,
(c->GetTarget()->CastToNPC()->org_x),
(c->GetTarget()->CastToNPC()->org_y),
atoi(sep->arg[1])
);
}
database.AssignGrid(c, c->GetTarget()->CastToNPC()->m_SpawnPoint, atoi(sep->arg[1]));
else
c->Message(0,"Usage: #gassign [num] - must have an npc target!");
}
@ -2019,7 +2012,7 @@ void command_dbspawn2(Client *c, const Seperator *sep)
if(sep->IsNumber(5))
cond_min = atoi(sep->arg[5]);
}
database.CreateSpawn2(c, atoi(sep->arg[1]), zone->GetShortName(), c->GetHeading(), c->GetX(), c->GetY(), c->GetZ(), atoi(sep->arg[2]), atoi(sep->arg[3]), cond, cond_min);
database.CreateSpawn2(c, atoi(sep->arg[1]), zone->GetShortName(), c->GetPosition(), atoi(sep->arg[2]), atoi(sep->arg[3]), cond, cond_min);
}
else {
c->Message(0, "Usage: #dbspawn2 spawngroup respawn variance [condition_id] [condition_min]");
@ -2098,10 +2091,12 @@ void command_wp(Client *c, const Seperator *sep)
if (wp == 0) //default to highest if it's left blank, or we enter 0
wp = database.GetHighestWaypoint(zone->GetZoneID(), atoi(sep->arg[2])) + 1;
if (strcasecmp("-h",sep->arg[5]) == 0) {
database.AddWP(c, atoi(sep->arg[2]),wp, c->GetX(), c->GetY(), c->GetZ(), atoi(sep->arg[3]),zone->GetZoneID(), c->GetHeading());
database.AddWP(c, atoi(sep->arg[2]),wp, c->GetPosition(), atoi(sep->arg[3]),zone->GetZoneID());
}
else {
database.AddWP(c, atoi(sep->arg[2]),wp, c->GetX(), c->GetY(), c->GetZ(), atoi(sep->arg[3]),zone->GetZoneID(), -1);
auto position = c->GetPosition();
position.m_Heading = -1;
database.AddWP(c, atoi(sep->arg[2]),wp, position, atoi(sep->arg[3]),zone->GetZoneID());
}
}
else if (strcasecmp("delete",sep->arg[1]) == 0)
@ -2469,7 +2464,7 @@ void command_spawn(Client *c, const Seperator *sep)
LogFile->write(EQEmuLog::Debug,"#spawn Spawning:");
#endif
NPC* npc = NPC::SpawnNPC(sep->argplus[1], c->GetX(), c->GetY(), c->GetZ(), c->GetHeading(), c);
NPC* npc = NPC::SpawnNPC(sep->argplus[1], c->GetPosition(), c);
if (!npc) {
c->Message(0, "Format: #spawn name race level material hp gender class priweapon secweapon merchantid bodytype - spawns a npc those parameters.");
c->Message(0, "Name Format: NPCFirstname_NPCLastname - All numbers in a name are stripped and \"_\" characters become a space.");
@ -2528,7 +2523,7 @@ void command_npctypespawn(Client *c, const Seperator *sep)
const NPCType* tmp = 0;
if ((tmp = database.GetNPCType(atoi(sep->arg[1])))) {
//tmp->fixedZ = 1;
NPC* npc = new NPC(tmp, 0, c->GetX(), c->GetY(), c->GetZ(), c->GetHeading(), FlyMode3);
NPC* npc = new NPC(tmp, 0, c->GetPosition(), FlyMode3);
if (npc && sep->IsNumber(2))
npc->SetNPCFactionID(atoi(sep->arg[2]));
@ -2591,7 +2586,7 @@ void command_peekinv(Client *c, const Seperator *sep)
peekTrade = 0x20,
peekWorld = 0x40
} ;
if (!c->GetTarget() || !c->GetTarget()->IsClient()) {
c->Message(0, "You must have a PC target selected for this command");
return;
@ -5420,8 +5415,7 @@ void command_wpadd(Client *c, const Seperator *sep)
{
int type1=0,
type2=0,
pause=0,
heading=-1; // Defaults for a new grid
pause=0; // Defaults for a new grid
Mob *t=c->GetTarget();
if (t && t->IsNPC())
@ -5444,9 +5438,11 @@ void command_wpadd(Client *c, const Seperator *sep)
return;
}
}
if (strcmp("-h",sep->arg[2]) == 0)
heading = c->GetHeading();
uint32 tmp_grid = database.AddWPForSpawn(c, s2info->GetID(), c->GetX(),c->GetY(),c->GetZ(), pause, type1, type2, zone->GetZoneID(), heading);
auto position = c->GetPosition();
if (strcmp("-h",sep->arg[2]) != 0)
position.m_Heading = -1;
uint32 tmp_grid = database.AddWPForSpawn(c, s2info->GetID(), position, pause, type1, type2, zone->GetZoneID());
if (tmp_grid)
t->CastToNPC()->SetGrid(tmp_grid);
@ -5563,9 +5559,8 @@ void command_givemoney(Client *c, const Seperator *sep)
void command_itemsearch(Client *c, const Seperator *sep)
{
if (sep->arg[1][0] == 0) {
if (sep->arg[1][0] == 0)
c->Message(0, "Usage: #itemsearch [search string]");
}
else
{
const char *search_criteria=sep->argplus[1];
@ -5620,6 +5615,7 @@ void command_itemsearch(Client *c, const Seperator *sep)
c->Message(0, "50 items shown...too many results.");
else
c->Message(0, "%i items found", count);
}
}
@ -7334,7 +7330,7 @@ void command_pf(Client *c, const Seperator *sep)
{
Mob *who = c->GetTarget();
c->Message(0, "POS: (%.2f, %.2f, %.2f)", who->GetX(), who->GetY(), who->GetZ());
c->Message(0, "WP: (%.2f, %.2f, %.2f) (%d/%d)", who->GetCWPX(), who->GetCWPY(), who->GetCWPZ(), who->GetCWP(), who->IsNPC()?who->CastToNPC()->GetMaxWp():-1);
c->Message(0, "WP: %s (%d/%d)", to_string(who->GetCurrentWayPoint()).c_str(), who->IsNPC()?who->CastToNPC()->GetMaxWp():-1);
c->Message(0, "TAR: (%.2f, %.2f, %.2f)", who->GetTarX(), who->GetTarY(), who->GetTarZ());
c->Message(0, "TARV: (%.2f, %.2f, %.2f)", who->GetTarVX(), who->GetTarVY(), who->GetTarVZ());
c->Message(0, "|TV|=%.2f index=%d", who->GetTarVector(), who->GetTarNDX());
@ -7376,16 +7372,18 @@ void command_bestz(Client *c, const Seperator *sep) {
if(c->GetTarget()) {
z=c->GetTarget()->GetZ();
RegionType = zone->watermap->ReturnRegionType(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z);
c->Message(0,"InWater returns %d", zone->watermap->InWater(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z));
c->Message(0,"InLava returns %d", zone->watermap->InLava(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z));
auto position = xyz_location(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z);
RegionType = zone->watermap->ReturnRegionType(position);
c->Message(0,"InWater returns %d", zone->watermap->InWater(position));
c->Message(0,"InLava returns %d", zone->watermap->InLava(position));
}
else {
z=c->GetZ();
RegionType = zone->watermap->ReturnRegionType(c->GetX(), c->GetY(), z);
c->Message(0,"InWater returns %d", zone->watermap->InWater(c->GetX(), c->GetY(), z));
c->Message(0,"InLava returns %d", zone->watermap->InLava(c->GetX(), c->GetY(), z));
auto position = xyz_location(c->GetX(), c->GetY(), z);
RegionType = zone->watermap->ReturnRegionType(position);
c->Message(0,"InWater returns %d", zone->watermap->InWater(position));
c->Message(0,"InLava returns %d", zone->watermap->InLava(position));
}
@ -8200,7 +8198,7 @@ void command_setgraveyard(Client *c, const Seperator *sep)
zoneid = database.GetZoneID(sep->arg[1]);
if(zoneid > 0) {
graveyard_id = database.CreateGraveyardRecord(zoneid, t->GetX(), t->GetY(), t->GetZ(), t->GetHeading());
graveyard_id = database.CreateGraveyardRecord(zoneid, t->GetPosition());
if(graveyard_id > 0) {
c->Message(0, "Successfuly added a new record for this graveyard!");
@ -8263,7 +8261,7 @@ void command_summonburriedplayercorpse(Client *c, const Seperator *sep)
return;
}
Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(t->CharacterID(), t->GetZoneID(), zone->GetInstanceID(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading());
Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(t->CharacterID(), t->GetZoneID(), zone->GetInstanceID(), t->GetPosition());
if(!PlayerCorpse)
c->Message(0, "Your target doesn't have any burried corpses.");

View File

@ -70,13 +70,13 @@ void Corpse::SendLootReqErrorPacket(Client* client, uint8 response) {
safe_delete(outapp);
}
Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, float in_x, float in_y, float in_z, float in_heading, std::string time_of_death, bool rezzed, bool was_at_graveyard){
Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const xyz_heading& position, std::string time_of_death, bool rezzed, bool was_at_graveyard) {
uint32 item_count = database.GetCharacterCorpseItemCount(in_dbid);
char *buffer = new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))];
PlayerCorpse_Struct *pcs = (PlayerCorpse_Struct*)buffer;
database.LoadCharacterCorpseData(in_dbid, pcs);
/* Load Items */
/* Load Items */
ItemList itemlist;
ServerLootItem_Struct* tmp = 0;
for (unsigned int i = 0; i < pcs->itemcount; i++) {
@ -95,10 +95,7 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
pcs->silver, // uint32 in_silver
pcs->gold, // uint32 in_gold
pcs->plat, // uint32 in_plat
in_x, // float in_x
in_y, // float in_y
in_z, // float in_z
in_heading, // float in_heading
position,
pcs->size, // float in_size
pcs->gender, // uint8 in_gender
pcs->race, // uint16 in_race
@ -110,9 +107,9 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
pcs->exp, // uint32 in_rezexp
was_at_graveyard // bool wasAtGraveyard
);
if (pcs->locked){
if (pcs->locked)
pc->Lock();
}
/* Load Item Tints */
pc->item_tint[0].color = pcs->item_tint[0].color;
@ -123,7 +120,7 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
pc->item_tint[5].color = pcs->item_tint[5].color;
pc->item_tint[6].color = pcs->item_tint[6].color;
pc->item_tint[7].color = pcs->item_tint[7].color;
pc->item_tint[8].color = pcs->item_tint[8].color;
pc->item_tint[8].color = pcs->item_tint[8].color;
/* Load Physical Appearance */
pc->haircolor = pcs->haircolor;
@ -145,57 +142,12 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
}
Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime)
: Mob("Unnamed_Corpse", // const char* in_name,
"", // const char* in_lastname,
0, // int32 in_cur_hp,
0, // int32 in_max_hp,
in_npc->GetGender(), // uint8 in_gender,
in_npc->GetRace(), // uint16 in_race,
in_npc->GetClass(), // uint8 in_class,
BT_Humanoid, // bodyType in_bodytype,
in_npc->GetDeity(), // uint8 in_deity,
in_npc->GetLevel(), // uint8 in_level,
in_npc->GetNPCTypeID(), // uint32 in_npctype_id,
in_npc->GetSize(), // float in_size,
0, // float in_runspeed,
in_npc->GetHeading(), // float in_heading,
in_npc->GetX(), // float in_x_pos,
in_npc->GetY(), // float in_y_pos,
in_npc->GetZ(), // float in_z_pos,
0, // uint8 in_light,
in_npc->GetTexture(), // uint8 in_texture,
in_npc->GetHelmTexture(), // uint8 in_helmtexture,
0, // uint16 in_ac,
0, // uint16 in_atk,
0, // uint16 in_str,
0, // uint16 in_sta,
0, // uint16 in_dex,
0, // uint16 in_agi,
0, // uint16 in_int,
0, // uint16 in_wis,
0, // uint16 in_cha,
0, // uint8 in_haircolor,
0, // uint8 in_beardcolor,
0, // uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye?
0, // uint8 in_eyecolor2,
0, // uint8 in_hairstyle,
0, // uint8 in_luclinface,
0, // uint8 in_beard,
0, // uint32 in_drakkin_heritage,
0, // uint32 in_drakkin_tattoo,
0, // uint32 in_drakkin_details,
0, // uint32 in_armor_tint[_MaterialCount],
0xff, // uint8 in_aa_title,
0, // uint8 in_see_invis, // see through invis/ivu
0, // uint8 in_see_invis_undead,
0, // uint8 in_see_hide,
0, // uint8 in_see_improved_hide,
0, // int32 in_hp_regen,
0, // int32 in_mana_regen,
0, // uint8 in_qglobal,
0, // uint8 in_maxlevel,
0 // uint32 in_scalerate
),
// vesuvias - appearence fix
: Mob("Unnamed_Corpse","",0,0,in_npc->GetGender(),in_npc->GetRace(),in_npc->GetClass(),BT_Humanoid,//bodytype added
in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0,
in_npc->GetPosition(), 0, in_npc->GetTexture(),in_npc->GetHelmTexture(),
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0xff,0,0,0,0,0,0,0,0,0),
corpse_decay_timer(in_decaytime),
corpse_rez_timer(0),
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
@ -224,7 +176,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
player_corpse_depop = false;
strcpy(corpse_name, in_npc->GetName());
strcpy(name, in_npc->GetName());
for(int count = 0; count < 100; count++) {
if ((level >= npcCorpseDecayTimes[count].minlvl) && (level <= npcCorpseDecayTimes[count].maxlvl)) {
corpse_decay_timer.SetTimer(npcCorpseDecayTimes[count].seconds*1000);
@ -235,7 +187,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
corpse_decay_timer.SetTimer(RuleI(NPC,EmptyNPCCorpseDecayTimeMS)+1000);
}
if(in_npc->HasPrivateCorpse()) {
corpse_delay_timer.SetTimer(corpse_decay_timer.GetRemainingTime() + 1000);
}
@ -260,10 +212,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
0, // uint32 in_npctype_id,
client->GetSize(), // float in_size,
0, // float in_runspeed,
client->GetHeading(), // float in_heading,
client->GetX(), // float in_x_pos,
client->GetY(), // float in_y_pos,
client->GetZ(), // float in_z_pos,
client->GetPosition(),
0, // uint8 in_light,
client->GetTexture(), // uint8 in_texture,
client->GetHelmTexture(), // uint8 in_helmtexture,
@ -297,15 +246,15 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
0, // uint8 in_qglobal,
0, // uint8 in_maxlevel,
0 // uint32 in_scalerate
),
),
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
corpse_graveyard_timer(RuleI(Zone, GraveyardTimeMS)),
loot_cooldown_timer(10)
loot_cooldown_timer(10)
{
int i;
PlayerProfile_Struct *pp = &client->GetPP();
ItemInst *item;
@ -335,7 +284,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
platinum = 0;
strcpy(corpse_name, pp->name);
strcpy(name, pp->name);
strcpy(name, pp->name);
/* become_npc was not being initialized which led to some pretty funky things with newly created corpses */
become_npc = false;
@ -343,8 +292,8 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
SetPlayerKillItemID(0);
/* Check Rule to see if we can leave corpses */
if(!RuleB(Character, LeaveNakedCorpses) ||
RuleB(Character, LeaveCorpses) &&
if(!RuleB(Character, LeaveNakedCorpses) ||
RuleB(Character, LeaveCorpses) &&
GetLevel() >= RuleI(Character, DeathItemLossLevel)) {
// cash
// Let's not move the cash when 'RespawnFromHover = true' && 'client->GetClientVersion() < EQClientSoF' since the client doesn't.
@ -485,59 +434,55 @@ std::list<uint32> Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16
return returnlist;
}
/* Called from Database Load */
Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, float in_x, float in_y, float in_z, float in_heading, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard)
: Mob("Unnamed_Corpse", // const char* in_name,
"", // const char* in_lastname,
0, // int32 in_cur_hp,
0, // int32 in_max_hp,
in_gender, // uint8 in_gender,
in_race, // uint16 in_race,
in_class, // uint8 in_class,
BT_Humanoid, // bodyType in_bodytype,
in_deity, // uint8 in_deity,
in_level, // uint8 in_level,
0, // uint32 in_npctype_id,
in_size, // float in_size,
0, // float in_runspeed,
in_heading, // float in_heading,
in_x, // float in_x_pos,
in_y, // float in_y_pos,
in_z, // float in_z_pos,
0, // uint8 in_light,
in_texture, // uint8 in_texture,
in_helmtexture, // uint8 in_helmtexture,
0, // uint16 in_ac,
0, // uint16 in_atk,
0, // uint16 in_str,
0, // uint16 in_sta,
0, // uint16 in_dex,
0, // uint16 in_agi,
0, // uint16 in_int,
0, // uint16 in_wis,
0, // uint16 in_cha,
0, // uint8 in_haircolor,
0, // uint8 in_beardcolor,
0, // uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye?
0, // uint8 in_eyecolor2,
0, // uint8 in_hairstyle,
0, // uint8 in_luclinface,
0, // uint8 in_beard,
0, // uint32 in_drakkin_heritage,
0, // uint32 in_drakkin_tattoo,
0, // uint32 in_drakkin_details,
0, // uint32 in_armor_tint[_MaterialCount],
0xff, // uint8 in_aa_title,
0, // uint8 in_see_invis, // see through invis/ivu
0, // uint8 in_see_invis_undead,
0, // uint8 in_see_hide,
0, // uint8 in_see_improved_hide,
0, // int32 in_hp_regen,
0, // int32 in_mana_regen,
0, // uint8 in_qglobal,
0, // uint8 in_maxlevel,
0), // uint32 in_scalerate
// To be called from LoadFromDBData
Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, const xyz_heading& position, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard)
: Mob("Unnamed_Corpse",
"",
0,
0,
in_gender,
in_race,
in_class,
BT_Humanoid,
in_deity,
in_level,
0,
in_size,
0,
position,
0,
in_texture,
in_helmtexture,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0xff,
0,
0,
0,
0,
0,
0,
0,
0,
0),
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
@ -547,9 +492,8 @@ Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemLi
LoadPlayerCorpseDecayTime(in_dbid);
if (!zone->HasGraveyard() || wasAtGraveyard){
if (!zone->HasGraveyard() || wasAtGraveyard)
corpse_graveyard_timer.Disable();
}
memset(item_tint, 0, sizeof(item_tint));
@ -652,18 +596,18 @@ bool Corpse::Save() {
ItemList::iterator cur, end;
cur = itemlist.begin();
end = itemlist.end();
for (; cur != end; ++cur) {
for (; cur != end; ++cur) {
ServerLootItem_Struct* item = *cur;
memcpy((char*)&dbpc->items[x++], (char*)item, sizeof(ServerLootItem_Struct));
}
/* Create New Corpse*/
if (corpse_db_id == 0) {
corpse_db_id = database.SaveCharacterCorpse(char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading);
corpse_db_id = database.SaveCharacterCorpse(char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, m_Position);
}
/* Update Corpse Data */
else{
corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading, IsRezzed());
corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, m_Position, IsRezzed());
}
safe_delete_array(dbpc);
@ -673,16 +617,15 @@ bool Corpse::Save() {
void Corpse::Delete() {
if (IsPlayerCorpse() && corpse_db_id != 0)
database.DeleteCharacterCorpse(corpse_db_id);
database.DeleteCharacterCorpse(corpse_db_id);
corpse_db_id = 0;
player_corpse_depop = true;
}
void Corpse::Bury() {
if (IsPlayerCorpse() && corpse_db_id != 0){
if (IsPlayerCorpse() && corpse_db_id != 0)
database.BuryCharacterCorpse(corpse_db_id);
}
corpse_db_id = 0;
player_corpse_depop = true;
}
@ -707,7 +650,7 @@ void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, ui
is_corpse_changed = true;
ServerLootItem_Struct* item = new ServerLootItem_Struct;
memset(item, 0, sizeof(ServerLootItem_Struct));
item->item_id = itemnum;
item->charges = charges;
@ -782,7 +725,7 @@ void Corpse::RemoveItem(uint16 lootslot) {
}
void Corpse::RemoveItem(ServerLootItem_Struct* item_data){
uint8 material;
uint8 material;
ItemList::iterator cur,end;
cur = itemlist.begin();
end = itemlist.end();
@ -827,14 +770,12 @@ bool Corpse::IsEmpty() const {
}
bool Corpse::Process() {
if (player_corpse_depop){
if (player_corpse_depop)
return false;
}
if (corpse_delay_timer.Check()) {
for (int i = 0; i < MAX_LOOTERS; i++){
for (int i = 0; i < MAX_LOOTERS; i++)
allowed_looters[i] = 0;
}
corpse_delay_timer.Disable();
return true;
}
@ -844,8 +785,7 @@ bool Corpse::Process() {
Save();
player_corpse_depop = true;
database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(),
(zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->graveyard_x(),
zone->graveyard_y(), zone->graveyard_z(), zone->graveyard_heading());
(zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->GetGraveyardPoint());
corpse_graveyard_timer.Disable();
ServerPacket* pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct));
SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer;
@ -911,15 +851,11 @@ bool Corpse::CanPlayerLoot(int charid) {
looters++;
}
if (allowed_looters[i] == charid){
if (allowed_looters[i] == charid)
return true;
}
}
/* If we have no looters, obviously client can loot */
if (looters == 0){
return true;
}
return false;
return looters == 0;
}
void Corpse::AllowPlayerLoot(Mob *them, uint8 slot) {
@ -952,21 +888,20 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
return;
}
if(being_looted_by == 0) {
being_looted_by = 0xFFFFFFFF;
}
if(being_looted_by == 0)
being_looted_by = 0xFFFFFFFF;
if(this->being_looted_by != 0xFFFFFFFF) {
// lets double check....
Entity* looter = entity_list.GetID(this->being_looted_by);
if(looter == 0) {
this->being_looted_by = 0xFFFFFFFF;
}
if(looter == 0)
this->being_looted_by = 0xFFFFFFFF;
}
uint8 Loot_Request_Type = 1;
bool loot_coin = false;
if(database.GetVariable("LootCoin", tmp, 9)) { loot_coin = (atoi(tmp) == 1); }
if(database.GetVariable("LootCoin", tmp, 9))
loot_coin = (atoi(tmp) == 1);
if (this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) {
SendLootReqErrorPacket(client, 0);
@ -1004,7 +939,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
d->unknown2 = 0xef;
/* Dont take the coin off if it's a gm peeking at the corpse */
if(Loot_Request_Type == 2 || (Loot_Request_Type >= 3 && loot_coin)) {
if(Loot_Request_Type == 2 || (Loot_Request_Type >= 3 && loot_coin)) {
if(!IsPlayerCorpse() && client->IsGrouped() && client->AutoSplitEnabled() && client->GetGroup()) {
d->copper = 0;
d->silver = 0;
@ -1022,7 +957,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
}
RemoveCash();
Save();
Save();
}
outapp->priority = 6;
@ -1251,7 +1186,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
/* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */
database.DeleteItemOffCharacterCorpse(this->corpse_db_id, item_data->equip_slot, item_data->item_id);
/* Delete Item Instance */
RemoveItem(item_data->lootslot);
RemoveItem(item_data->lootslot);
}
/* Remove Bag Contents */
@ -1259,9 +1194,9 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
for (int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) {
if (bag_item_data[i]) {
/* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */
database.DeleteItemOffCharacterCorpse(this->corpse_db_id, bag_item_data[i]->equip_slot, bag_item_data[i]->item_id);
database.DeleteItemOffCharacterCorpse(this->corpse_db_id, bag_item_data[i]->equip_slot, bag_item_data[i]->item_id);
/* Delete Item Instance */
RemoveItem(bag_item_data[i]);
RemoveItem(bag_item_data[i]);
}
}
}
@ -1333,7 +1268,7 @@ void Corpse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
ns->spawn.NPC = 2;
}
void Corpse::QueryLoot(Client* to) {
void Corpse::QueryLoot(Client* to) {
int x = 0, y = 0; // x = visible items, y = total items
to->Message(0, "Coin: %ip, %ig, %is, %ic", platinum, gold, silver, copper);

View File

@ -37,22 +37,19 @@ class Corpse : public Mob {
public:
static void SendEndLootErrorPacket(Client* client);
static void SendLootReqErrorPacket(Client* client, uint8 response = 2);
static void SendLootReqErrorPacket(Client* client, uint8 response = 2);
Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime = 600000);
Corpse(Client* client, int32 in_rezexp);
Corpse(uint32 in_corpseid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, float in_x, float in_y, float in_z, float in_heading, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture, uint32 in_rezexp, bool wasAtGraveyard = false);
~Corpse();
static Corpse* LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, float in_x, float in_y, float in_z, float in_heading, std::string time_of_death, bool rezzed, bool was_at_graveyard);
Corpse(uint32 in_corpseid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, const xyz_heading& position, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture, uint32 in_rezexp, bool wasAtGraveyard = false);
~Corpse();
static Corpse* LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const xyz_heading& position, std::string time_of_death, bool rezzed, bool was_at_graveyard);
/* Corpse: General */
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; }
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; }
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false,
bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) {
return false;
}
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; }
virtual bool HasRaid() { return false; }
virtual bool HasGroup() { return false; }
virtual Raid* GetRaid() { return 0; }
@ -73,7 +70,7 @@ class Corpse : public Mob {
uint32 GetDecayTime() { if (!corpse_decay_timer.Enabled()) return 0xFFFFFFFF; else return corpse_decay_timer.GetRemainingTime(); }
uint32 GetRezTime() { if (!corpse_rez_timer.Enabled()) return 0; else return corpse_rez_timer.GetRemainingTime(); }
void SetDecayTimer(uint32 decay_time);
void Delete();
void Bury();
void CalcCorpseName();
@ -81,9 +78,9 @@ class Corpse : public Mob {
/* Corpse: Items */
uint32 GetWornItem(int16 equipSlot) const;
ServerLootItem_Struct* GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data = 0);
ServerLootItem_Struct* GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data = 0);
void SetPlayerKillItemID(int32 pk_item_id) { player_kill_item = pk_item_id; }
int32 GetPlayerKillItem() { return player_kill_item; }
int32 GetPlayerKillItem() { return player_kill_item; }
void RemoveItem(uint16 lootslot);
void RemoveItem(ServerLootItem_Struct* item_data);
void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
@ -123,10 +120,10 @@ class Corpse : public Mob {
bool Summon(Client* client, bool spell, bool CheckDistance);
void Spawn();
char corpse_name[64];
char corpse_name[64];
uint32 GetEquipment(uint8 material_slot) const;
uint32 GetEquipmentColor(uint8 material_slot) const;
inline int GetRezExp() { return rez_experience; }
inline int GetRezExp() { return rez_experience; }
protected:
std::list<uint32> MoveItemToCorpse(Client *client, ItemInst *item, int16 equipslot);
@ -139,7 +136,7 @@ private:
uint32 corpse_db_id; /* Corpse Database ID (Player Corpse) */
uint32 char_id; /* Character ID */
ItemList itemlist; /* Internal Item list used for corpses */
uint32 copper;
uint32 copper;
uint32 silver;
uint32 gold;
uint32 platinum;
@ -152,7 +149,7 @@ private:
int allowed_looters[MAX_LOOTERS]; /* People allowed to loot the corpse, character id */
Timer corpse_decay_timer; /* The amount of time in millseconds in which a corpse will take to decay (Depop/Poof) */
Timer corpse_rez_timer; /* The amount of time in millseconds in which a corpse can be rezzed */
Timer corpse_delay_timer;
Timer corpse_delay_timer;
Timer corpse_graveyard_timer;
Timer loot_cooldown_timer; /* Delay between loot actions on the corpse entity */
Color_Struct item_tint[9];

View File

@ -39,17 +39,15 @@
extern EntityList entity_list;
extern WorldServer worldserver;
Doors::Doors(const Door* door)
: close_timer(5000)
Doors::Doors(const Door* door) :
close_timer(5000),
m_Position(door->pos_x, door->pos_y, door->pos_z, door->heading),
m_Destination(door->dest_x, door->dest_y, door->dest_z, door->dest_heading)
{
db_id = door->db_id;
door_id = door->door_id;
strn0cpy(zone_name,door->zone_name,32);
strn0cpy(door_name,door->door_name,32);
pos_x = door->pos_x;
pos_y = door->pos_y;
pos_z = door->pos_z;
heading = door->heading;
incline = door->incline;
opentype = door->opentype;
guild_id = door->guild_id;
@ -66,28 +64,22 @@ Doors::Doors(const Door* door)
close_timer.Disable();
strn0cpy(dest_zone,door->dest_zone,32);
strn0cpy(dest_zone,door->dest_zone,16);
dest_instance_id = door->dest_instance_id;
dest_x = door->dest_x;
dest_y = door->dest_y;
dest_z = door->dest_z;
dest_heading = door->dest_heading;
is_ldon_door = door->is_ldon_door;
client_version_mask = door->client_version_mask;
}
Doors::Doors(const char *dmodel, float dx, float dy, float dz, float dheading, uint8 dopentype, uint16 dsize)
: close_timer(5000)
Doors::Doors(const char *dmodel, const xyz_heading& position, uint8 dopentype, uint16 dsize) :
close_timer(5000),
m_Position(position),
m_Destination(xyz_heading::Origin())
{
db_id = database.GetDoorsCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion());
door_id = database.GetDoorsDBCountPlusOne(zone->GetShortName(), zone->GetInstanceVersion());
strn0cpy(zone_name,zone->GetShortName(),32);
strn0cpy(door_name,dmodel,32);
pos_x = dx;
pos_y = dy;
pos_z = dz;
heading = dheading;
incline = 0;
opentype = dopentype;
guild_id = 0;
@ -106,10 +98,6 @@ Doors::Doors(const char *dmodel, float dx, float dy, float dz, float dheading, u
strn0cpy(dest_zone,"NONE",32);
dest_instance_id = 0;
dest_x = 0;
dest_y = 0;
dest_z = 0;
dest_heading = 0;
is_ldon_door = 0;
client_version_mask = 4294967295u;
@ -144,9 +132,9 @@ bool Doors::Process()
void Doors::HandleClick(Client* sender, uint8 trigger)
{
//door debugging info dump
_log(DOORS__INFO, "%s clicked door %s (dbid %d, eqid %d) at (%.4f,%.4f,%.4f @%.4f)", sender->GetName(), door_name, db_id, door_id, pos_x, pos_y, pos_z, heading);
_log(DOORS__INFO, "%s clicked door %s (dbid %d, eqid %d) at %s", sender->GetName(), door_name, db_id, door_id, to_string(m_Position).c_str());
_log(DOORS__INFO, " incline %d, opentype %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", incline, opentype, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param);
_log(DOORS__INFO, " size %d, invert %d, dest: %s (%.4f,%.4f,%.4f @%.4f)", size, invert_state, dest_zone, dest_x, dest_y, dest_z, dest_heading);
_log(DOORS__INFO, " size %d, invert %d, dest: %s %s", size, invert_state, dest_zone, to_string(m_Destination).c_str());
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer;
@ -422,7 +410,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
{
sender->KeyRingAdd(playerkey);
}
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading);
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.m_X, m_Destination.m_Y, m_Destination.m_Z, m_Destination.m_Heading);
}
else if (( !IsDoorOpen() || opentype == 58 ) && (keyneeded && ((keyneeded == playerkey) || sender->GetGM())))
{
@ -432,22 +420,22 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
}
if(database.GetZoneID(dest_zone) == zone->GetZoneID())
{
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading);
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.m_X, m_Destination.m_Y, m_Destination.m_Z, m_Destination.m_Heading);
}
else
{
sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, dest_x, dest_y, dest_z, dest_heading);
sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.m_X, m_Destination.m_Y, m_Destination.m_Z, m_Destination.m_Heading);
}
}
if (( !IsDoorOpen() || opentype == 58 ) && (!keyneeded))
{
if(database.GetZoneID(dest_zone) == zone->GetZoneID())
{
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading);
sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.m_X, m_Destination.m_Y, m_Destination.m_Z, m_Destination.m_Heading);
}
else
{
sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, dest_x, dest_y, dest_z, dest_heading);
sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.m_X, m_Destination.m_Y, m_Destination.m_Z, m_Destination.m_Heading);
}
}
}
@ -560,14 +548,14 @@ void Doors::ToggleState(Mob *sender)
void Doors::DumpDoor(){
LogFile->write(EQEmuLog::Debug,
"db_id:%i door_id:%i zone_name:%s door_name:%s pos_x:%f pos_y:%f pos_z:%f heading:%f",
db_id, door_id, zone_name, door_name, pos_x, pos_y, pos_z, heading);
"db_id:%i door_id:%i zone_name:%s door_name:%s %s",
db_id, door_id, zone_name, door_name, to_string(m_Position).c_str());
LogFile->write(EQEmuLog::Debug,
"opentype:%i guild_id:%i lockpick:%i keyitem:%i nokeyring:%i trigger_door:%i trigger_type:%i door_param:%i open:%s",
opentype, guild_id, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param, (isopen) ? "open":"closed");
LogFile->write(EQEmuLog::Debug,
"dest_zone:%s dest_x:%f dest_y:%f dest_z:%f dest_heading:%f",
dest_zone, dest_x, dest_y, dest_z, dest_heading);
"dest_zone:%s destination:%s ",
dest_zone, to_string(m_Destination).c_str());
}
int32 ZoneDatabase::GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version) {
@ -709,30 +697,13 @@ bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name
void Doors::SetLocation(float x, float y, float z)
{
entity_list.DespawnAllDoors();
pos_x = x;
pos_y = y;
pos_z = z;
m_Position = xyz_location(x, y, z);
entity_list.RespawnAllDoors();
}
void Doors::SetX(float in) {
void Doors::SetPosition(const xyz_heading& position) {
entity_list.DespawnAllDoors();
pos_x = in;
entity_list.RespawnAllDoors();
}
void Doors::SetY(float in) {
entity_list.DespawnAllDoors();
pos_y = in;
entity_list.RespawnAllDoors();
}
void Doors::SetZ(float in) {
entity_list.DespawnAllDoors();
pos_z = in;
entity_list.RespawnAllDoors();
}
void Doors::SetHeading(float in) {
entity_list.DespawnAllDoors();
heading = in;
m_Position = position;
entity_list.RespawnAllDoors();
}
@ -767,6 +738,6 @@ void Doors::CreateDatabaseEntry()
{
return;
}
database.InsertDoor(GetDoorDBID(), GetDoorID(), GetDoorName(), GetX(), GetY(), GetZ(), GetHeading(), GetOpenType(), GetGuildID(), GetLockpick(), GetKeyItem(), GetDoorParam(), GetInvertState(), GetIncline(), GetSize());
database.InsertDoor(GetDoorDBID(), GetDoorID(), GetDoorName(), m_Position, GetOpenType(), GetGuildID(), GetLockpick(), GetKeyItem(), GetDoorParam(), GetInvertState(), GetIncline(), GetSize());
}

View File

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

View File

@ -32,7 +32,7 @@
#include "zone.h"
extern Zone* zone;
extern QueryServ* QServ;
extern QueryServ* QServ;
/*
@ -219,11 +219,9 @@ XS(XS__spawn)
int npc_type = (int)SvIV(ST(0));
int grid = (int)SvIV(ST(1));
int unused = (int)SvIV(ST(2));
float x = (float)SvNV(ST(3));
float y = (float)SvNV(ST(4));
float z = (float)SvNV(ST(5));
auto position = xyz_heading((float)SvNV(ST(3)), (float)SvNV(ST(4)), (float)SvNV(ST(5)), 0.0f);
Mob *r = quest_manager.spawn2(npc_type, grid, unused, x, y, z, 0);
Mob *r = quest_manager.spawn2(npc_type, grid, unused, position);
RETVAL = (r != nullptr) ? r->GetID() : 0;
XSprePUSH; PUSHu((UV)RETVAL);
@ -243,12 +241,9 @@ XS(XS__spawn2)
int npc_type = (int)SvIV(ST(0));
int grid = (int)SvIV(ST(1));
int unused = (int)SvIV(ST(2));
float x = (float)SvNV(ST(3));
float y = (float)SvNV(ST(4));
float z = (float)SvNV(ST(5));
float heading = (float)SvNV(ST(6));
auto position = xyz_heading((float)SvNV(ST(3)), (float)SvNV(ST(4)), (float)SvNV(ST(5)), (float)SvNV(ST(6)));
Mob *r = quest_manager.spawn2(npc_type, grid, unused, x, y, z, heading);
Mob *r = quest_manager.spawn2(npc_type, grid, unused, position);
RETVAL = (r != nullptr) ? r->GetID() : 0;
XSprePUSH; PUSHu((UV)RETVAL);
@ -275,7 +270,7 @@ XS(XS__unique_spawn)
if(items == 7)
heading = (float)SvNV(ST(6));
Mob *r = quest_manager.unique_spawn(npc_type, grid, unused, x, y, z, heading);
Mob *r = quest_manager.unique_spawn(npc_type, grid, unused, xyz_heading(x, y, z, heading));
RETVAL = (r != nullptr) ? r->GetID() : 0;
XSprePUSH; PUSHu((UV)RETVAL);
@ -1175,7 +1170,7 @@ XS(XS__createguild)
Perl_croak(aTHX_ "Usage: createguild(guild_name, leader)");
char * guild_name = (char *)SvPV_nolen(ST(0));
char * leader = (char *)SvPV_nolen(ST(1));
char * leader = (char *)SvPV_nolen(ST(1));
quest_manager.CreateGuild(guild_name, leader);
@ -1322,11 +1317,9 @@ XS(XS__rebind)
Perl_croak(aTHX_ "Usage: rebind(zoneid, x, y, z)");
int zoneid = (int)SvIV(ST(0));
float x = (float)SvNV(ST(1));
float y = (float)SvNV(ST(2));
float z = (float)SvNV(ST(3));
auto location = xyz_location((float)SvNV(ST(1)),(float)SvNV(ST(2)),(float)SvNV(ST(3)));
quest_manager.rebind(zoneid, x, y, z);
quest_manager.rebind(zoneid, location);
XSRETURN_EMPTY;
}
@ -1395,7 +1388,7 @@ XS(XS__moveto)
else
saveguard = false;
quest_manager.moveto(x, y, z, h, saveguard);
quest_manager.moveto(xyz_heading(x, y, z, h), saveguard);
XSRETURN_EMPTY;
}
@ -1750,12 +1743,9 @@ XS(XS__summonburriedplayercorpse)
bool RETVAL;
uint32 char_id = (int)SvIV(ST(0));
float dest_x = (float)SvIV(ST(1));
float dest_y = (float)SvIV(ST(2));
float dest_z = (float)SvIV(ST(3));
float dest_heading = (float)SvIV(ST(4));
auto position = xyz_heading((float)SvIV(ST(1)), (float)SvIV(ST(2)), (float)SvIV(ST(3)),(float)SvIV(ST(4)));
RETVAL = quest_manager.summonburriedplayercorpse(char_id, dest_x, dest_y, dest_z, dest_heading);
RETVAL = quest_manager.summonburriedplayercorpse(char_id, position);
ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0));
@ -1771,12 +1761,9 @@ XS(XS__summonallplayercorpses)
bool RETVAL;
uint32 char_id = (int)SvIV(ST(0));
float dest_x = (float)SvIV(ST(1));
float dest_y = (float)SvIV(ST(2));
float dest_z = (float)SvIV(ST(3));
float dest_heading = (float)SvIV(ST(4));
auto position = xyz_heading((float)SvIV(ST(1)),(float)SvIV(ST(2)),(float)SvIV(ST(3)),(float)SvIV(ST(4)));
RETVAL = quest_manager.summonallplayercorpses(char_id, dest_x, dest_y, dest_z, dest_heading);
RETVAL = quest_manager.summonallplayercorpses(char_id, position);
ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0));
@ -2673,10 +2660,10 @@ XS(XS__CreateGroundObject)
uint16 id = 0;
if(items == 5)
id = quest_manager.CreateGroundObject(itemid, x, y, z, heading);
id = quest_manager.CreateGroundObject(itemid, xyz_heading(x, y, z, heading));
else{
uint32 decay_time = (uint32)SvIV(ST(5));
id = quest_manager.CreateGroundObject(itemid, x, y, z, heading, decay_time);
id = quest_manager.CreateGroundObject(itemid, xyz_heading(x, y, z, heading), decay_time);
}
XSRETURN_IV(id);
@ -2704,7 +2691,7 @@ XS(XS__CreateGroundObjectFromModel)
if (items > 6)
decay_time = (uint32)SvIV(ST(6));
id = quest_manager.CreateGroundObjectFromModel(modelname, x, y, z, heading, type, decay_time);
id = quest_manager.CreateGroundObjectFromModel(modelname, xyz_heading(x, y, z, heading), type, decay_time);
XSRETURN_IV(id);
}
@ -2979,12 +2966,12 @@ XS(XS__MovePCInstance)
if (items == 4)
{
quest_manager.MovePCInstance(zoneid, instanceid, x, y, z, 0.0f);
quest_manager.MovePCInstance(zoneid, instanceid, xyz_heading(x, y, z, 0.0f));
}
else
{
float heading = (float)SvNV(ST(5));
quest_manager.MovePCInstance(zoneid, instanceid, x, y, z, heading);
quest_manager.MovePCInstance(zoneid, instanceid, xyz_heading(x, y, z, heading));
}
XSRETURN_EMPTY;
@ -3294,7 +3281,7 @@ XS(XS__GetZoneID)
char *zone = (char *)SvPV_nolen(ST(0));
int32 id = quest_manager.GetZoneID(zone);
XSRETURN_IV(id);
}
@ -3307,7 +3294,7 @@ XS(XS__GetZoneLongName)
dXSTARG;
char *zone = (char *)SvPV_nolen(ST(0));
Const_char* RETVAL = quest_manager.GetZoneLongName(zone);
sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
XSRETURN(1);
}
@ -3437,7 +3424,7 @@ XS(XS__clear_npctype_cache)
int32 npctype_id = (int32)SvIV(ST(0));
quest_manager.ClearNPCTypeCache(npctype_id);
}
XSRETURN_EMPTY;
}
@ -3460,11 +3447,11 @@ XS(XS__qs_player_event);
XS(XS__qs_player_event)
{
dXSARGS;
if (items != 2){
if (items != 2){
Perl_croak(aTHX_ "Usage: qs_player_event(char_id, event_desc)");
}
else{
int char_id = (int)SvIV(ST(0));
int char_id = (int)SvIV(ST(0));
std::string event_desc = (std::string)SvPV_nolen(ST(1));
QServ->PlayerLogEvent(Player_Log_Quest, char_id, event_desc);
}
@ -3499,7 +3486,7 @@ XS(XS__crosszonesignalnpcbynpctypeid)
if (items == 2) {
uint32 npctype_id = (uint32)SvIV(ST(0));
uint32 data = (uint32)SvIV(ST(1));
uint32 data = (uint32)SvIV(ST(1));
quest_manager.CrossZoneSignalNPCByNPCTypeID(npctype_id, data);
}

View File

@ -68,7 +68,7 @@ Entity::Entity()
Entity::~Entity()
{
}
Client *Entity::CastToClient()
@ -484,14 +484,14 @@ void EntityList::MobProcess()
while (it != mob_list.end()) {
uint16 id = it->first;
Mob *mob = it->second;
size_t sz = mob_list.size();
bool p_val = mob->Process();
size_t a_sz = mob_list.size();
if(a_sz > sz) {
//increased size can potentially screw with iterators so reset it to current value
//if buckets are re-orderered we may skip a process here and there but since
//if buckets are re-orderered we may skip a process here and there but since
//process happens so often it shouldn't matter much
it = mob_list.find(id);
++it;
@ -846,10 +846,11 @@ bool EntityList::MakeDoorSpawnPacket(EQApplicationPacket *app, Client *client)
strlen(door->GetDoorName()) > 3) {
memset(&nd, 0, sizeof(nd));
memcpy(nd.name, door->GetDoorName(), 32);
nd.xPos = door->GetX();
nd.yPos = door->GetY();
nd.zPos = door->GetZ();
nd.heading = door->GetHeading();
auto position = door->GetPosition();
nd.xPos = position.m_X;
nd.yPos = position.m_Y;
nd.zPos = position.m_Z;
nd.heading = position.m_Heading;
nd.incline = door->GetIncline();
nd.size = door->GetSize();
nd.doorId = door->GetDoorID();
@ -1551,16 +1552,14 @@ Client *EntityList::GetClientByWID(uint32 iWID)
return nullptr;
}
Client *EntityList::GetRandomClient(float x, float y, float z, float Distance, Client *ExcludeClient)
Client *EntityList::GetRandomClient(const xyz_location& location, float Distance, Client *ExcludeClient)
{
std::vector<Client *> ClientsInRange;
auto it = client_list.begin();
while (it != client_list.end()) {
if ((it->second != ExcludeClient) && (it->second->DistNoRoot(x, y, z) <= Distance))
for (auto it = client_list.begin();it != client_list.end(); ++it)
if ((it->second != ExcludeClient) && (it->second->DistNoRoot(location.m_X, location.m_Y, location.m_Z) <= Distance))
ClientsInRange.push_back(it->second);
++it;
}
if (ClientsInRange.empty())
return nullptr;
@ -3065,54 +3064,43 @@ void EntityList::AddHealAggro(Mob *target, Mob *caster, uint16 thedam)
void EntityList::OpenDoorsNear(NPC *who)
{
auto it = door_list.begin();
while (it != door_list.end()) {
for (auto it = door_list.begin();it != door_list.end(); ++it) {
Doors *cdoor = it->second;
if (cdoor && !cdoor->IsDoorOpen()) {
float zdiff = who->GetZ() - cdoor->GetZ();
if (zdiff < 0)
zdiff = 0 - zdiff;
float curdist = 0;
float tmp = who->GetX() - cdoor->GetX();
curdist += tmp * tmp;
tmp = who->GetY() - cdoor->GetY();
curdist += tmp * tmp;
if (zdiff < 10 && curdist <= 100)
cdoor->NPCOpen(who);
}
++it;
if (!cdoor || cdoor->IsDoorOpen())
continue;
auto diff = who->GetPosition() - cdoor->GetPosition();
diff.ABS_XYZ();
float curdist = diff.m_X * diff.m_X + diff.m_Y * diff.m_Y;
if (diff.m_Z * diff.m_Z < 10 && curdist <= 100)
cdoor->NPCOpen(who);
}
}
void EntityList::SendAlarm(Trap *trap, Mob *currenttarget, uint8 kos)
{
float val2 = trap->effectvalue * trap->effectvalue;
float preSquareDistance = trap->effectvalue * trap->effectvalue;
auto it = npc_list.begin();
while (it != npc_list.end()) {
for (auto it = npc_list.begin();it != npc_list.end(); ++it) {
NPC *cur = it->second;
float curdist = 0;
float tmp = cur->GetX() - trap->x;
curdist += tmp*tmp;
tmp = cur->GetY() - trap->y;
curdist += tmp*tmp;
tmp = cur->GetZ() - trap->z;
curdist += tmp*tmp;
if (!cur->GetOwner() &&
/*!cur->CastToMob()->dead && */
!cur->IsEngaged() &&
curdist <= val2 )
{
if (kos) {
uint8 factioncon = currenttarget->GetReverseFactionCon(cur);
if (factioncon == FACTION_THREATENLY || factioncon == FACTION_SCOWLS) {
cur->AddToHateList(currenttarget,1);
}
} else {
auto diff = cur->GetPosition() - trap->m_Position;
float curdist = diff.m_X * diff.m_X + diff.m_Y * diff.m_Y + diff.m_Z * diff.m_Z;
if (cur->GetOwner() || cur->IsEngaged() || curdist > preSquareDistance )
continue;
if (kos) {
uint8 factioncon = currenttarget->GetReverseFactionCon(cur);
if (factioncon == FACTION_THREATENLY || factioncon == FACTION_SCOWLS) {
cur->AddToHateList(currenttarget,1);
}
}
++it;
}
else
cur->AddToHateList(currenttarget,1);
}
}
@ -3149,7 +3137,7 @@ struct quest_proximity_event {
int area_type;
};
void EntityList::ProcessMove(Client *c, float x, float y, float z)
void EntityList::ProcessMove(Client *c, const xyz_location& location)
{
float last_x = c->ProximityX();
float last_y = c->ProximityY();
@ -3171,9 +3159,9 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z)
last_z < l->min_z || last_z > l->max_z) {
old_in = false;
}
if (x < l->min_x || x > l->max_x ||
y < l->min_y || y > l->max_y ||
z < l->min_z || z > l->max_z) {
if (location.m_X < l->min_x || location.m_X > l->max_x ||
location.m_Y < l->min_y || location.m_Y > l->max_y ||
location.m_Z < l->min_z || location.m_Z > l->max_z) {
new_in = false;
}
@ -3206,9 +3194,9 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z)
old_in = false;
}
if (x < a.min_x || x > a.max_x ||
y < a.min_y || y > a.max_y ||
z < a.min_z || z > a.max_z ) {
if (location.m_X < a.min_x || location.m_X > a.max_x ||
location.m_Y < a.min_y || location.m_Y > a.max_y ||
location.m_Z < a.min_z || location.m_Z > a.max_z ) {
new_in = false;
}
@ -3611,7 +3599,7 @@ int16 EntityList::CountTempPets(Mob *owner)
}
++it;
}
owner->SetTempPetCount(count);
return count;
@ -3802,51 +3790,54 @@ void EntityList::GroupMessage(uint32 gid, const char *from, const char *message)
}
}
uint16 EntityList::CreateGroundObject(uint32 itemid, float x, float y, float z,
float heading, uint32 decay_time)
uint16 EntityList::CreateGroundObject(uint32 itemid, const xyz_heading& position, uint32 decay_time)
{
const Item_Struct *is = database.GetItem(itemid);
if (is) {
ItemInst *i = new ItemInst(is, is->MaxCharges);
if (i) {
Object *object = new Object(i, x, y, z, heading,decay_time);
entity_list.AddObject(object, true);
if (!is)
return 0;
safe_delete(i);
if (object)
return object->GetID();
}
return 0; // fell through itemstruct
}
return 0; // fell through everything, this is bad/incomplete from perl
ItemInst *i = new ItemInst(is, is->MaxCharges);
if (!i)
return 0;
Object *object = new Object(i, position.m_X, position.m_Y, position.m_Z, position.m_Heading,decay_time);
entity_list.AddObject(object, true);
safe_delete(i);
if (!object)
return 0;
return object->GetID();
}
uint16 EntityList::CreateGroundObjectFromModel(const char *model, float x,
float y, float z, float heading, uint8 type, uint32 decay_time)
uint16 EntityList::CreateGroundObjectFromModel(const char *model, const xyz_heading& position, uint8 type, uint32 decay_time)
{
if (model) {
Object *object = new Object(model, x, y, z, heading, type);
entity_list.AddObject(object, true);
if (!model)
return 0;
if (object)
return object->GetID();
}
return 0; // fell through everything, this is bad/incomplete from perl
Object *object = new Object(model, position.m_X, position.m_Y, position.m_Z, position.m_Heading, type);
entity_list.AddObject(object, true);
if (!object)
return 0;
return object->GetID();
}
uint16 EntityList::CreateDoor(const char *model, float x, float y, float z,
float heading, uint8 opentype, uint16 size)
uint16 EntityList::CreateDoor(const char *model, const xyz_heading& position, uint8 opentype, uint16 size)
{
if (model) {
Doors *door = new Doors(model, x, y, z, heading, opentype, size);
RemoveAllDoors();
zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion());
entity_list.AddDoor(door);
entity_list.RespawnAllDoors();
if (!model)
return 0; // fell through everything, this is bad/incomplete from perl
Doors *door = new Doors(model, position, opentype, size);
RemoveAllDoors();
zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion());
entity_list.AddDoor(door);
entity_list.RespawnAllDoors();
if (door)
return door->GetEntityID();
if (door)
return door->GetEntityID();
}
return 0; // fell through everything, this is bad/incomplete from perl
}

View File

@ -27,6 +27,7 @@
#include "../common/bodytypes.h"
#include "../common/eq_constants.h"
#include "position.h"
#include "zonedump.h"
class Beacon;
@ -57,7 +58,7 @@ class Bot;
class BotRaids;
#endif
extern EntityList entity_list;
extern EntityList entity_list;
class Entity
{
@ -154,7 +155,7 @@ public:
Client *GetClientByCharID(uint32 iCharID);
Client *GetClientByWID(uint32 iWID);
Client *GetClient(uint32 ip, uint16 port);
Client *GetRandomClient(float x, float y, float z, float Distance, Client *ExcludeClient = nullptr);
Client *GetRandomClient(const xyz_location& location, float Distance, Client *ExcludeClient = nullptr);
Group *GetGroupByMob(Mob* mob);
Group *GetGroupByClient(Client* client);
Group *GetGroupByID(uint32 id);
@ -202,7 +203,7 @@ public:
void MobProcess();
void TrapProcess();
void BeaconProcess();
void ProcessMove(Client *c, float x, float y, float z);
void ProcessMove(Client *c, const xyz_location& location);
void ProcessMove(NPC *n, float x, float y, float z);
void AddArea(int id, int type, float min_x, float max_x, float min_y, float max_y, float min_z, float max_z);
void RemoveArea(int id);
@ -393,9 +394,9 @@ public:
void SaveAllClientsTaskState();
void ReloadAllClientsTaskState(int TaskID=0);
uint16 CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time = 300000);
uint16 CreateGroundObjectFromModel(const char *model, float x, float y, float z, float heading, uint8 type = 0x00, uint32 decay_time = 0);
uint16 CreateDoor(const char *model, float x, float y, float z, float heading, uint8 type = 0, uint16 size = 100);
uint16 CreateGroundObject(uint32 itemid, const xyz_heading& position, uint32 decay_time = 300000);
uint16 CreateGroundObjectFromModel(const char *model, const xyz_heading& position, uint8 type = 0x00, uint32 decay_time = 0);
uint16 CreateDoor(const char *model, const xyz_heading& position, uint8 type = 0, uint16 size = 100);
void ZoneWho(Client *c, Who_All_Struct* Who);
void UnMarkNPC(uint16 ID);

View File

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

View File

@ -174,7 +174,8 @@ bool Client::CanFish() {
}
if(zone->zonemap != nullptr && zone->watermap != nullptr && RuleB(Watermap, CheckForWaterWhenFishing)) {
float RodX, RodY, RodZ;
xyz_location rodPosition;
// Tweak Rod and LineLength if required
const float RodLength = RuleR(Watermap, FishingRodLength);
const float LineLength = RuleR(Watermap, FishingLineLength);
@ -183,25 +184,25 @@ bool Client::CanFish() {
HeadingDegrees = (int) ((GetHeading()*360)/256);
HeadingDegrees = HeadingDegrees % 360;
RodX = x_pos + RodLength * sin(HeadingDegrees * M_PI/180.0f);
RodY = y_pos + RodLength * cos(HeadingDegrees * M_PI/180.0f);
rodPosition.m_X = m_Position.m_X + RodLength * sin(HeadingDegrees * M_PI/180.0f);
rodPosition.m_Y = m_Position.m_Y + RodLength * cos(HeadingDegrees * M_PI/180.0f);
// Do BestZ to find where the line hanging from the rod intersects the water (if it is water).
// and go 1 unit into the water.
Map::Vertex dest;
dest.x = RodX;
dest.y = RodY;
dest.z = z_pos+10;
dest.x = rodPosition.m_X;
dest.y = rodPosition.m_Y;
dest.z = m_Position.m_Z+10;
RodZ = zone->zonemap->FindBestZ(dest, nullptr) + 4;
bool in_lava = zone->watermap->InLava(RodX, RodY, RodZ);
bool in_water = zone->watermap->InWater(RodX, RodY, RodZ) || zone->watermap->InVWater(RodX, RodY, RodZ);
rodPosition.m_Z = zone->zonemap->FindBestZ(dest, nullptr) + 4;
bool in_lava = zone->watermap->InLava(rodPosition);
bool in_water = zone->watermap->InWater(rodPosition) || zone->watermap->InVWater(rodPosition);
//Message(0, "Rod is at %4.3f, %4.3f, %4.3f, InWater says %d, InLava says %d", RodX, RodY, RodZ, in_water, in_lava);
if (in_lava) {
Message_StringID(MT_Skills, FISHING_LAVA); //Trying to catch a fire elemental or something?
return false;
}
if((!in_water) || (z_pos-RodZ)>LineLength) { //Didn't hit the water OR the water is too far below us
if((!in_water) || (m_Position.m_Z-rodPosition.m_Z)>LineLength) { //Didn't hit the water OR the water is too far below us
Message_StringID(MT_Skills, FISHING_LAND); //Trying to catch land sharks perhaps?
return false;
}
@ -272,7 +273,9 @@ void Client::GoFish()
if(npc_chance < zone->random.Int(0, 99)) {
const NPCType* tmp = database.GetNPCType(npc_id);
if(tmp != nullptr) {
NPC* npc = new NPC(tmp, nullptr, GetX()+3, GetY(), GetZ(), GetHeading(), FlyMode3);
auto positionNPC = GetPosition();
positionNPC.m_X = positionNPC.m_X + 3;
NPC* npc = new NPC(tmp, nullptr, positionNPC, FlyMode3);
npc->AddLootTable();
npc->AddToHateList(this, 1, 0, false); //no help yelling

View File

@ -308,8 +308,9 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center)
continue;
}
auto hateEntryPosition = xyz_location(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ());
if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
if (!zone->watermap->InLiquid(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ())) {
if (!zone->watermap->InLiquid(hateEntryPosition)) {
skipped_count++;
++iterator;
continue;
@ -434,7 +435,7 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center)
{
struct_HateList *cur = (*iterator);
if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
if (!zone->watermap->InLiquid(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ())) {
if (!zone->watermap->InLiquid(cur->entity_on_hatelist->GetPosition())) {
skipped_count++;
++iterator;
continue;

View File

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

View File

@ -29,7 +29,7 @@ struct NewSpawn_Struct;
class Horse : public NPC {
public:
Horse(Client *owner, uint16 spell_id, float x, float y, float z, float heading);
Horse(Client *owner, uint16 spell_id, const xyz_heading& position);
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);

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) {
Lua_Safe_Call_Void();
self->SetBindPoint(to_zone, to_instance, new_x);
self->SetBindPoint(to_zone, to_instance, xyz_location(new_x,0.0f,0.0f));
}
void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y) {
Lua_Safe_Call_Void();
self->SetBindPoint(to_zone, to_instance, new_x, new_y);
self->SetBindPoint(to_zone, to_instance, xyz_location(new_x, new_y, 0.0f));
}
void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y, float new_z) {
Lua_Safe_Call_Void();
self->SetBindPoint(to_zone, to_instance, new_x, new_y, new_z);
self->SetBindPoint(to_zone, to_instance, xyz_location(new_x, new_y, new_z));
}
float Lua_Client::GetBindX() {
@ -700,13 +700,13 @@ void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5);
}
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
bool attuned) {
Lua_Safe_Call_Void();
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned);
}
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
bool attuned, int to_slot) {
Lua_Safe_Call_Void();
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned, to_slot);
@ -1396,7 +1396,7 @@ luabind::scope lua_register_client() {
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem)
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32))&Lua_Client::SummonItem)
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool))&Lua_Client::SummonItem)
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool,int))&Lua_Client::SummonItem)
.def("SummonItem", (void(Lua_Client::*)(uint32,int,uint32,uint32,uint32,uint32,uint32,bool,int))&Lua_Client::SummonItem)
.def("SetStats", (void(Lua_Client::*)(int,int))&Lua_Client::SetStats)
.def("IncStats", (void(Lua_Client::*)(int,int))&Lua_Client::IncStats)
.def("DropItem", (void(Lua_Client::*)(int))&Lua_Client::DropItem)

View File

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

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_Safe_Call_Class(Lua_Client);
return self->GetRandomClient(x, y, z, dist);
return self->GetRandomClient(xyz_location(x, y, z), dist);
}
Lua_Client Lua_EntityList::GetRandomClient(float x, float y, float z, float dist, Lua_Client exclude) {
Lua_Safe_Call_Class(Lua_Client);
return self->GetRandomClient(x, y, z, dist, exclude);
return self->GetRandomClient(xyz_location(x, y, z), dist, exclude);
}
Lua_Mob_List Lua_EntityList::GetMobList() {

View File

@ -124,7 +124,7 @@ void register_event(std::string package_name, std::string name, int evt, luabind
e.encounter_name = name;
e.lua_reference = func;
e.event_id = static_cast<QuestEventID>(evt);
auto liter = lua_encounter_events_registered.find(package_name);
if(liter == lua_encounter_events_registered.end()) {
std::list<lua_registered_event> elist;
@ -201,7 +201,7 @@ void unregister_player_event(int evt) {
void register_item_event(std::string name, int evt, int item_id, luabind::adl::object func) {
std::string package_name = "item_";
package_name += std::to_string(static_cast<long long>(item_id));
if(luabind::type(func) == LUA_TFUNCTION) {
register_event(package_name, name, evt, func);
}
@ -251,13 +251,13 @@ void unregister_spell_event(int evt, int spell_id) {
}
Lua_Mob lua_spawn2(int npc_type, int grid, int unused, double x, double y, double z, double heading) {
return Lua_Mob(quest_manager.spawn2(npc_type, grid, unused,
static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(heading)));
auto position = xyz_heading(x, y, z, heading);
return Lua_Mob(quest_manager.spawn2(npc_type, grid, unused, position));
}
Lua_Mob lua_unique_spawn(int npc_type, int grid, int unused, double x, double y, double z, double heading = 0.0) {
return Lua_Mob(quest_manager.unique_spawn(npc_type, grid, unused,
static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(heading)));
auto position = xyz_heading(x,y,z,heading);
return Lua_Mob(quest_manager.unique_spawn(npc_type, grid, unused, position));
}
Lua_Mob lua_spawn_from_spawn2(uint32 spawn2_id) {
@ -421,15 +421,15 @@ void lua_pause(int duration) {
}
void lua_move_to(float x, float y, float z) {
quest_manager.moveto(x, y, z, 0, false);
quest_manager.moveto(xyz_heading(x, y, z, 0.0f), false);
}
void lua_move_to(float x, float y, float z, float h) {
quest_manager.moveto(x, y, z, h, false);
quest_manager.moveto(xyz_heading(x, y, z, h), false);
}
void lua_move_to(float x, float y, float z, float h, bool save_guard_spot) {
quest_manager.moveto(x, y, z, h, save_guard_spot);
quest_manager.moveto(xyz_heading(x, y, z, h), save_guard_spot);
}
void lua_path_resume() {
@ -485,11 +485,11 @@ void lua_toggle_spawn_event(int event_id, bool enable, bool strict, bool reset)
}
void lua_summon_burried_player_corpse(uint32 char_id, float x, float y, float z, float h) {
quest_manager.summonburriedplayercorpse(char_id, x, y, z, h);
quest_manager.summonburriedplayercorpse(char_id, xyz_heading(x, y, z, h));
}
void lua_summon_all_player_corpses(uint32 char_id, float x, float y, float z, float h) {
quest_manager.summonallplayercorpses(char_id, x, y, z, h);
quest_manager.summonallplayercorpses(char_id, xyz_heading(x, y, z, h));
}
int lua_get_player_burried_corpse_count(uint32 char_id) {
@ -685,23 +685,23 @@ int lua_get_level(int type) {
}
void lua_create_ground_object(uint32 item_id, float x, float y, float z, float h) {
quest_manager.CreateGroundObject(item_id, x, y, z, h);
quest_manager.CreateGroundObject(item_id, xyz_heading(x, y, z, h));
}
void lua_create_ground_object(uint32 item_id, float x, float y, float z, float h, uint32 decay_time) {
quest_manager.CreateGroundObject(item_id, x, y, z, h, decay_time);
quest_manager.CreateGroundObject(item_id, xyz_heading(x, y, z, h), decay_time);
}
void lua_create_ground_object_from_model(const char *model, float x, float y, float z, float h) {
quest_manager.CreateGroundObjectFromModel(model, x, y, z, h);
quest_manager.CreateGroundObjectFromModel(model, xyz_heading(x, y, z, h));
}
void lua_create_ground_object_from_model(const char *model, float x, float y, float z, float h, int type) {
quest_manager.CreateGroundObjectFromModel(model, x, y, z, h, type);
quest_manager.CreateGroundObjectFromModel(model, xyz_heading(x, y, z, h), type);
}
void lua_create_ground_object_from_model(const char *model, float x, float y, float z, float h, int type, uint32 decay_time) {
quest_manager.CreateGroundObjectFromModel(model, x, y, z, h, type, decay_time);
quest_manager.CreateGroundObjectFromModel(model, xyz_heading(x, y, z, h), type, decay_time);
}
void lua_create_door(const char *model, float x, float y, float z, float h, int open_type, int size) {
@ -1036,7 +1036,7 @@ void lua_add_spawn_point(luabind::adl::object table) {
int condition_min_value = 0;
bool enabled = true;
int animation = 0;
auto cur = table["spawn2_id"];
if(luabind::type(cur) != LUA_TNIL) {
try {
@ -1284,7 +1284,7 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
if(luabind::type(table) != LUA_TTABLE) {
return;
}
NPCType* npc_type = new NPCType;
memset(npc_type, 0, sizeof(NPCType));
@ -1391,7 +1391,7 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
LuaCreateNPCParse(raid_target, bool, false);
LuaCreateNPCParse(probability, uint8, 0);
NPC* npc = new NPC(npc_type, nullptr, x, y, z, heading, FlyMode3);
NPC* npc = new NPC(npc_type, nullptr, xyz_heading(x, y, z, heading), FlyMode3);
npc->GiveNPCTypeData(npc_type);
entity_list.AddNPC(npc);
}

View File

@ -631,7 +631,7 @@ double Lua_Mob::ResistSpell(int resist_type, int spell_id, Lua_Mob caster, bool
return self->ResistSpell(resist_type, spell_id, caster, use_resist_override, resist_override);
}
double Lua_Mob::ResistSpell(int resist_type, int spell_id, Lua_Mob caster, bool use_resist_override, int resist_override,
double Lua_Mob::ResistSpell(int resist_type, int spell_id, Lua_Mob caster, bool use_resist_override, int resist_override,
bool charisma_check) {
Lua_Safe_Call_Real();
return self->ResistSpell(resist_type, spell_id, caster, use_resist_override, resist_override, charisma_check);
@ -674,22 +674,22 @@ double Lua_Mob::GetHeading() {
double Lua_Mob::GetWaypointX() {
Lua_Safe_Call_Real();
return self->GetCWPX();
return self->GetCurrentWayPoint().m_X;
}
double Lua_Mob::GetWaypointY() {
Lua_Safe_Call_Real();
return self->GetCWPY();
return self->GetCurrentWayPoint().m_Y;
}
double Lua_Mob::GetWaypointZ() {
Lua_Safe_Call_Real();
return self->GetCWPZ();
return self->GetCurrentWayPoint().m_Z;
}
double Lua_Mob::GetWaypointH() {
Lua_Safe_Call_Real();
return self->GetCWPH();
return self->GetCurrentWayPoint().m_Heading;
}
double Lua_Mob::GetWaypointPause() {
@ -777,19 +777,19 @@ bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, in
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot));
}
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer,
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer,
int timer_duration) {
Lua_Safe_Call_Bool();
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
static_cast<uint32>(timer), static_cast<uint32>(timer_duration));
}
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer,
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer,
int timer_duration, int resist_adjust) {
Lua_Safe_Call_Bool();
int16 res = resist_adjust;
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
static_cast<uint32>(timer), static_cast<uint32>(timer_duration), 0, &res);
}
@ -841,7 +841,7 @@ Lua_Mob Lua_Mob::GetOwner() {
Lua_HateList Lua_Mob::GetHateList() {
Lua_Safe_Call_Class(Lua_HateList);
Lua_HateList ret;
auto h_list = self->GetHateList();
auto iter = h_list.begin();
while(iter != h_list.end()) {
@ -1222,7 +1222,7 @@ bool Lua_Mob::EntityVariableExists(const char *name) {
void Lua_Mob::Signal(uint32 id) {
Lua_Safe_Call_Void();
if(self->IsClient()) {
self->CastToClient()->Signal(id);
} else if(self->IsNPC()) {
@ -1255,7 +1255,7 @@ void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, in
self->DoSpecialAttackDamage(other, static_cast<SkillUseTypes>(skill), max_damage, min_damage, hate_override, reuse_time);
}
void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time,
void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time,
bool hit_chance) {
Lua_Safe_Call_Void();
self->DoSpecialAttackDamage(other, static_cast<SkillUseTypes>(skill), max_damage, min_damage, hate_override, reuse_time, hit_chance);
@ -1286,7 +1286,7 @@ void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_
self->DoThrowingAttackDmg(other, range_weapon, item, weapon_damage, chance_mod);
}
void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_Item item, int weapon_damage, int chance_mod,
void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_Item item, int weapon_damage, int chance_mod,
int focus) {
Lua_Safe_Call_Void();
self->DoThrowingAttackDmg(other, range_weapon, item, weapon_damage, chance_mod, focus);
@ -1337,7 +1337,7 @@ void Lua_Mob::DoArcheryAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_I
self->DoArcheryAttackDmg(other, range_weapon, ammo, weapon_damage, chance_mod);
}
void Lua_Mob::DoArcheryAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_ItemInst ammo, int weapon_damage, int chance_mod,
void Lua_Mob::DoArcheryAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_ItemInst ammo, int weapon_damage, int chance_mod,
int focus) {
Lua_Safe_Call_Void();
self->DoArcheryAttackDmg(other, range_weapon, ammo, weapon_damage, chance_mod, focus);
@ -1395,7 +1395,7 @@ void Lua_Mob::ProjectileAnimation(Lua_Mob to, int item_id, bool is_arrow, double
void Lua_Mob::ProjectileAnimation(Lua_Mob to, int item_id, bool is_arrow, double speed, double angle, double tilt, double arc) {
Lua_Safe_Call_Void();
self->ProjectileAnimation(to, item_id, is_arrow, static_cast<float>(speed), static_cast<float>(angle), static_cast<float>(tilt),
self->ProjectileAnimation(to, item_id, is_arrow, static_cast<float>(speed), static_cast<float>(angle), static_cast<float>(tilt),
static_cast<float>(arc));
}
@ -1635,7 +1635,7 @@ void Lua_Mob::SendSpellEffect(uint32 effect_id, uint32 duration, uint32 finish_d
self->SendSpellEffect(effect_id, duration, finish_delay, zone_wide, unk020, perm_effect);
}
void Lua_Mob::SendSpellEffect(uint32 effect_id, uint32 duration, uint32 finish_delay, bool zone_wide, uint32 unk020, bool perm_effect,
void Lua_Mob::SendSpellEffect(uint32 effect_id, uint32 duration, uint32 finish_delay, bool zone_wide, uint32 unk020, bool perm_effect,
Lua_Client c) {
Lua_Safe_Call_Void();
self->SendSpellEffect(effect_id, duration, finish_delay, zone_wide, unk020, perm_effect, c);

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

View File

@ -22,6 +22,7 @@
#ifndef ZONE_MAP_H
#define ZONE_MAP_H
#include "position.h"
#include <stdio.h>
#define BEST_Z_INVALID -99999
@ -35,10 +36,14 @@ public:
Vertex() : x(0.0f), y(0.0f), z(0.0f) { }
Vertex(float _x, float _y, float _z) : x(_x), y(_y), z(_z) { }
~Vertex() { }
bool operator==(const Vertex &v) const
bool operator==(const Vertex &v) const
{
return((v.x == x) && (v.y == y) && (v.z == z));
}
operator xyz_location() const
{
return xyz_location(x,y,z);
}
float x;
float y;
@ -48,7 +53,7 @@ public:
Map();
~Map();
float FindBestZ(Vertex &start, Vertex *result) const;
bool LineIntersectsZone(Vertex start, Vertex end, float step, Vertex *result) const;
bool LineIntersectsZoneNoZLeaps(Vertex start, Vertex end, float step_mag, Vertex *result) const;
@ -61,7 +66,7 @@ private:
void TranslateVertex(Vertex &v, float tx, float ty, float tz);
bool LoadV1(FILE *f);
bool LoadV2(FILE *f);
struct impl;
impl *imp;
};

View File

@ -20,7 +20,7 @@
extern volatile bool ZoneLoaded;
Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
: NPC(d, 0, x, y, z, heading, 0, false), endupkeep_timer(1000), rest_timer(1), confidence_timer(6000), check_target_timer(2000)
: NPC(d, nullptr, xyz_heading(x, y, z, heading), 0, false), endupkeep_timer(1000), rest_timer(1), confidence_timer(6000), check_target_timer(2000)
{
base_hp = d->max_hp;
base_mana = d->Mana;
@ -4722,11 +4722,11 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id,
if(merc_template)
{
//TODO: Maybe add a way of updating client merc stats in a seperate function? like, for example, on leveling up.
const NPCType* npc_type_to_copy = database.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel());
const NPCType* npc_type_to_copy = database.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel());
if(npc_type_to_copy != nullptr)
{
//This is actually a very terrible method of assigning stats, and should be changed at some point. See the comment in merc's deconstructor.
NPCType* npc_type = new NPCType;
NPCType* npc_type = new NPCType;
memset(npc_type, 0, sizeof(NPCType));
memcpy(npc_type, npc_type_to_copy, sizeof(NPCType));
if(c && !updateFromDB)
@ -4919,7 +4919,7 @@ bool Merc::Spawn(Client *owner) {
entity_list.AddMerc(this, true, true);
SendPosition();
if (MERC_DEBUG > 0)
owner->Message(7, "Mercenary Debug: Spawn.");
@ -4945,7 +4945,7 @@ void Client::SendMercResponsePackets(uint32 ResponseType)
break;
case 3: //Mercenary failed to spawn!
SendMercMerchantResponsePacket(3);
break;
break;
case 4: //Mercenaries are not allowed in raids!
SendMercMerchantResponsePacket(4);
break;
@ -5109,7 +5109,7 @@ void Client::UpdateMercTimer()
{
SendMercResponsePackets(16);
}
if (MERC_DEBUG > 0)
Message(7, "Mercenary Debug: UpdateMercTimer Complete.");
@ -5132,7 +5132,7 @@ bool Client::CheckCanHireMerc(Mob* merchant, uint32 template_id) {
MercTemplate* mercTemplate = zone->GetMercTemplate(template_id);
//check for suspended merc
if(GetMercInfo().mercid != 0 && GetMercInfo().IsSuspended) {
if(GetMercInfo().mercid != 0 && GetMercInfo().IsSuspended) {
SendMercResponsePackets(6);
return false;
}
@ -5163,7 +5163,7 @@ bool Client::CheckCanHireMerc(Mob* merchant, uint32 template_id) {
return false;
}
}
if (MERC_DEBUG > 0)
Message(7, "Mercenary Debug: CheckCanHireMerc True.");
@ -5237,7 +5237,7 @@ bool Client::CheckCanSpawnMerc(uint32 template_id) {
SendMercResponsePackets(9);
return false;
}
if (MERC_DEBUG > 0)
Message(7, "Mercenary Debug: CheckCanSpawnMerc True.");
@ -5260,7 +5260,7 @@ bool Client::CheckCanUnsuspendMerc() {
Message(0, "You must wait %i seconds before unsuspending your mercenary.", GetPTimers().GetRemainingTime(pTimerMercSuspend));
return false;
}
if (MERC_DEBUG > 0)
Message(7, "Mercenary Debug: CheckCanUnsuspendMerc True.");
@ -5413,7 +5413,7 @@ void Client::SendMercTimer(Merc* merc) {
}
void Client::SpawnMerc(Merc* merc, bool setMaxStats) {
void Client::SpawnMerc(Merc* merc, bool setMaxStats) {
if (!merc || !CheckCanSpawnMerc(merc->GetMercTemplateID()))
{
@ -5454,12 +5454,12 @@ bool Merc::Suspend() {
mercOwner->GetMercTimer()->Disable();
mercOwner->SendMercSuspendResponsePacket(mercOwner->GetMercInfo().SuspendedTime);
mercOwner->SendMercTimer(this);
Depop();
// Start the timer to send the packet that refreshes the Unsuspend Button
mercOwner->GetPTimers().Start(pTimerMercSuspend, RuleI(Mercs, SuspendIntervalS));
if (MERC_DEBUG > 0)
mercOwner->Message(7, "Mercenary Debug: Suspend Complete.");
@ -5556,7 +5556,7 @@ bool Client::DismissMerc(uint32 MercID) {
if (MERC_DEBUG > 0)
Message(7, "Mercenary Debug: Dismiss Successful.");
}
if (GetMerc())
{
GetMerc()->Depop();
@ -5724,7 +5724,7 @@ bool Merc::MercJoinClientGroup() {
if(MERC_DEBUG > 0)
mercOwner->Message(7, "Mercenary Debug: Mercenary disbanded new group.");
}
}
else if (AddMercToGroup(this, mercOwner->GetGroup()))
{

View File

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

View File

@ -22,6 +22,7 @@
#include "entity.h"
#include "hate_list.h"
#include "pathing.h"
#include "position.h"
#include <set>
#include <vector>
@ -77,10 +78,7 @@ public:
uint32 in_npctype_id,
float in_size,
float in_runspeed,
float in_heading,
float in_x_pos,
float in_y_pos,
float in_z_pos,
const xyz_heading& position,
uint8 in_light,
uint8 in_texture,
uint8 in_helmtexture,
@ -183,7 +181,7 @@ public:
bool IsInvisible(Mob* other = 0) const;
void SetInvisible(uint8 state);
bool AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* weapon);
//Song
bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1);
bool ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, uint16 slot);
@ -296,9 +294,9 @@ public:
inline virtual uint32 GetNimbusEffect2() const { return nimbus_effect2; }
inline virtual uint32 GetNimbusEffect3() const { return nimbus_effect3; }
void RemoveNimbusEffect(int effectid);
inline float GetTargetRingX() const { return targetring_x; }
inline float GetTargetRingY() const { return targetring_y; }
inline float GetTargetRingZ() const { return targetring_z; }
inline float GetTargetRingX() const { return m_TargetRing.m_X; }
inline float GetTargetRingY() const { return m_TargetRing.m_Y; }
inline float GetTargetRingZ() const { return m_TargetRing.m_Z; }
inline bool HasEndurUpkeep() const { return endur_upkeep; }
inline void SetEndurUpkeep(bool val) { endur_upkeep = val; }
@ -400,18 +398,19 @@ public:
((static_cast<float>(cur_mana) / max_mana) * 100); }
virtual int32 CalcMaxMana();
uint32 GetNPCTypeID() const { return npctype_id; }
inline const float GetX() const { return x_pos; }
inline const float GetY() const { return y_pos; }
inline const float GetZ() const { return z_pos; }
inline const float GetHeading() const { return heading; }
inline const xyz_heading GetPosition() const { return m_Position; }
inline const float GetX() const { return m_Position.m_X; }
inline const float GetY() const { return m_Position.m_Y; }
inline const float GetZ() const { return m_Position.m_Z; }
inline const float GetHeading() const { return m_Position.m_Heading; }
inline const float GetSize() const { return size; }
inline const float GetBaseSize() const { return base_size; }
inline const float GetTarX() const { return tarx; }
inline const float GetTarY() const { return tary; }
inline const float GetTarZ() const { return tarz; }
inline const float GetTarVX() const { return tar_vx; }
inline const float GetTarVY() const { return tar_vy; }
inline const float GetTarVZ() const { return tar_vz; }
inline const float GetTarX() const { return m_TargetLocation.m_X; }
inline const float GetTarY() const { return m_TargetLocation.m_Y; }
inline const float GetTarZ() const { return m_TargetLocation.m_Z; }
inline const float GetTarVX() const { return m_TargetV.m_X; }
inline const float GetTarVY() const { return m_TargetV.m_Y; }
inline const float GetTarVZ() const { return m_TargetV.m_Z; }
inline const float GetTarVector() const { return tar_vector; }
inline const uint8 GetTarNDX() const { return tar_ndx; }
bool IsBoat() const;
@ -426,9 +425,9 @@ public:
virtual inline int32 GetPrimaryFaction() const { return 0; }
//Movement
void Warp( float x, float y, float z );
void Warp(const xyz_location& location);
inline bool IsMoving() const { return moving; }
virtual void SetMoving(bool move) { moving = move; delta_x = 0; delta_y = 0; delta_z = 0; delta_heading = 0; }
virtual void SetMoving(bool move) { moving = move; m_Delta = xyz_heading::Origin(); }
virtual void GoToBind(uint8 bindnum = 0) { }
virtual void Gate();
float GetWalkspeed() const { return(_GetMovementSpeed(-47)); }
@ -438,15 +437,15 @@ public:
bool IsRunning() const { return m_is_running; }
void SetRunning(bool val) { m_is_running = val; }
virtual void GMMove(float x, float y, float z, float heading = 0.01, bool SendUpdate = true);
void SetDeltas(float delta_x, float delta_y, float delta_z, float delta_h);
void SetDelta(const xyz_heading& delta);
void SetTargetDestSteps(uint8 target_steps) { tar_ndx = target_steps; }
void SendPosUpdate(uint8 iSendToSelf = 0);
void MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct* spu);
void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu);
void SendPosition();
void SetFlyMode(uint8 flymode);
inline void Teleport(Map::Vertex NewPosition) { x_pos = NewPosition.x; y_pos = NewPosition.y;
z_pos = NewPosition.z; };
inline void Teleport(Map::Vertex NewPosition) { m_Position.m_X = NewPosition.x; m_Position.m_Y = NewPosition.y;
m_Position.m_Z = NewPosition.z; };
//AI
static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel);
@ -467,8 +466,8 @@ public:
bool IsEngaged() { return(!hate_list.IsHateListEmpty()); }
bool HateSummon();
void FaceTarget(Mob* MobToFace = 0);
void SetHeading(float iHeading) { if(heading != iHeading) { pLastChange = Timer::GetCurrentTime();
heading = iHeading; } }
void SetHeading(float iHeading) { if(m_Position.m_Heading != iHeading) { pLastChange = Timer::GetCurrentTime();
m_Position.m_Heading = iHeading; } }
void WipeHateList();
void AddFeignMemory(Client* attacker);
void RemoveFromFeignMemory(Client* attacker);
@ -575,10 +574,10 @@ public:
int16 CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus=false);
uint8 IsFocusEffect(uint16 spellid, int effect_index, bool AA=false,uint32 aa_effect=0);
void SendIllusionPacket(uint16 in_race, uint8 in_gender = 0xFF, uint8 in_texture = 0xFF, uint8 in_helmtexture = 0xFF,
uint8 in_haircolor = 0xFF, uint8 in_beardcolor = 0xFF, uint8 in_eyecolor1 = 0xFF, uint8 in_eyecolor2 = 0xFF,
uint8 in_hairstyle = 0xFF, uint8 in_luclinface = 0xFF, uint8 in_beard = 0xFF, uint8 in_aa_title = 0xFF,
uint32 in_drakkin_heritage = 0xFFFFFFFF, uint32 in_drakkin_tattoo = 0xFFFFFFFF,
void SendIllusionPacket(uint16 in_race, uint8 in_gender = 0xFF, uint8 in_texture = 0xFF, uint8 in_helmtexture = 0xFF,
uint8 in_haircolor = 0xFF, uint8 in_beardcolor = 0xFF, uint8 in_eyecolor1 = 0xFF, uint8 in_eyecolor2 = 0xFF,
uint8 in_hairstyle = 0xFF, uint8 in_luclinface = 0xFF, uint8 in_beard = 0xFF, uint8 in_aa_title = 0xFF,
uint32 in_drakkin_heritage = 0xFFFFFFFF, uint32 in_drakkin_tattoo = 0xFFFFFFFF,
uint32 in_drakkin_details = 0xFFFFFFFF, float in_size = -1.0f);
bool RandomizeFeatures(bool send_illusion = true, bool set_variables = true);
virtual void Stun(int duration);
@ -627,7 +626,7 @@ public:
bool CanBlockSpell() const { return(spellbonuses.BlockNextSpell); }
bool DoHPToManaCovert(uint16 mana_cost = 0);
int32 ApplySpellEffectiveness(Mob* caster, int16 spell_id, int32 value, bool IsBard = false);
int8 GetDecayEffectValue(uint16 spell_id, uint16 spelleffect);
int8 GetDecayEffectValue(uint16 spell_id, uint16 spelleffect);
int32 GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg);
void MeleeLifeTap(int32 damage);
bool PassCastRestriction(bool UseCastRestriction = true, int16 value = 0, bool IsDamage = true);
@ -688,9 +687,9 @@ public:
inline int16 GetTempPetCount() const { return count_TempPet; }
inline void SetTempPetCount(int16 i) { count_TempPet = i; }
bool HasPetAffinity() { if (aabonuses.GivePetGroupTarget || itembonuses.GivePetGroupTarget || spellbonuses.GivePetGroupTarget) return true; return false; }
inline bool IsPetOwnerClient() const { return pet_owner_client; }
inline bool IsPetOwnerClient() const { return pet_owner_client; }
inline void SetPetOwnerClient(bool value) { pet_owner_client = value; }
inline bool IsTempPet() const { return _IsTempPet; }
inline bool IsTempPet() const { return _IsTempPet; }
inline void SetTempPet(bool value) { _IsTempPet = value; }
inline const bodyType GetBodyType() const { return bodytype; }
@ -821,10 +820,10 @@ public:
void SetDontCureMeBefore(uint32 time) { pDontCureMeBefore = time; }
// calculate interruption of spell via movement of mob
void SaveSpellLoc() {spell_x = x_pos; spell_y = y_pos; spell_z = z_pos; }
inline float GetSpellX() const {return spell_x;}
inline float GetSpellY() const {return spell_y;}
inline float GetSpellZ() const {return spell_z;}
void SaveSpellLoc() {m_SpellLocation = m_Position; }
inline float GetSpellX() const {return m_SpellLocation.m_X;}
inline float GetSpellY() const {return m_SpellLocation.m_Y;}
inline float GetSpellZ() const {return m_SpellLocation.m_Z;}
inline bool IsGrouped() const { return isgrouped; }
void SetGrouped(bool v);
inline bool IsRaidGrouped() const { return israidgrouped; }
@ -875,11 +874,8 @@ public:
Shielders_Struct shielder[MAX_SHIELDERS];
Trade* trade;
inline float GetCWPX() const { return(cur_wp_x); }
inline float GetCWPY() const { return(cur_wp_y); }
inline float GetCWPZ() const { return(cur_wp_z); }
inline float GetCWPH() const { return(cur_wp_heading); }
inline xyz_heading GetCurrentWayPoint() const { return m_CurrentWayPoint; }
inline float GetCWPP() const { return(static_cast<float>(cur_wp_pause)); }
inline int GetCWP() const { return(cur_wp); }
void SetCurrentWP(uint16 waypoint) { cur_wp = waypoint; }
@ -1023,10 +1019,7 @@ protected:
uint8 level;
uint8 orig_level;
uint32 npctype_id;
float x_pos;
float y_pos;
float z_pos;
float heading;
xyz_heading m_Position;
uint16 animation;
float base_size;
float size;
@ -1075,10 +1068,7 @@ protected:
char clean_name[64];
char lastname[64];
int32 delta_heading;
float delta_x;
float delta_y;
float delta_z;
xyz_heading m_Delta;
uint8 light;
@ -1087,7 +1077,6 @@ protected:
uint8 pRunAnimSpeed;
bool m_is_running;
Timer attack_timer;
Timer attack_dw_timer;
Timer ranged_timer;
@ -1100,7 +1089,7 @@ protected:
//spell casting vars
Timer spellend_timer;
uint16 casting_spell_id;
float spell_x, spell_y, spell_z;
xyz_location m_SpellLocation;
int attacked_count;
bool delaytimer;
uint16 casting_spell_targetid;
@ -1119,9 +1108,8 @@ protected:
bool ActiveProjectileATK;
tProjatk ProjectileAtk[MAX_SPELL_PROJECTILE];
float rewind_x;
float rewind_y;
float rewind_z;
xyz_location m_RewindLocation;
Timer rewind_timer;
// Currently 3 max nimbus particle effects at a time
@ -1217,16 +1205,12 @@ protected:
int pausetype;
int cur_wp;
float cur_wp_x;
float cur_wp_y;
float cur_wp_z;
xyz_heading m_CurrentWayPoint;
int cur_wp_pause;
float cur_wp_heading;
int patrol;
float fear_walkto_x;
float fear_walkto_y;
float fear_walkto_z;
xyz_location m_FearWalkTarget;
bool curfp;
// Pathing
@ -1261,19 +1245,13 @@ protected:
bool pet_owner_client; //Flags regular and pets as belonging to a client
EGNode *_egnode; //the EG node we are in
float tarx;
float tary;
float tarz;
xyz_location m_TargetLocation;
uint8 tar_ndx;
float tar_vector;
float tar_vx;
float tar_vy;
float tar_vz;
xyz_location m_TargetV;
float test_vector;
float targetring_x;
float targetring_y;
float targetring_z;
xyz_location m_TargetRing;
uint32 m_spellHitsLeft[38]; // Used to track which spells will have their numhits incremented when spell finishes casting, 38 Buffslots
int flymode;

View File

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

View File

@ -25,10 +25,10 @@
#include "../common/spdat.h"
#include "../common/string_util.h"
#include "../common/clientversions.h"
#include "../common/features.h"
#include "../common/item.h"
#include "../common/item_struct.h"
#include "../common/linked_list.h"
#include "../common/features.h"
#include "../common/item.h"
#include "../common/item_struct.h"
#include "../common/linked_list.h"
#include "../common/servertalk.h"
#include "aa.h"
@ -56,7 +56,7 @@ extern Zone* zone;
extern volatile bool ZoneLoaded;
extern EntityList entity_list;
NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float heading, int iflymode, bool IsCorpse)
NPC::NPC(const NPCType* d, Spawn2* in_respawn, const xyz_heading& position, int iflymode, bool IsCorpse)
: Mob(d->name,
d->lastname,
d->max_hp,
@ -70,10 +70,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
d->npc_id,
d->size,
d->runspeed,
heading,
x,
y,
z,
position,
d->light,
d->texture,
d->helmtexture,
@ -115,7 +112,10 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
qglobal_purge_timer(30000),
sendhpupdate_timer(1000),
enraged_timer(1000),
taunt_timer(TauntReuseTime * 1000)
taunt_timer(TauntReuseTime * 1000),
m_SpawnPoint(position),
m_GuardPoint(-1,-1,-1,0),
m_GuardPointSaved(0,0,0,0)
{
//What is the point of this, since the names get mangled..
Mob* mob = entity_list.GetMob(name);
@ -205,14 +205,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
MerchantType = d->merchanttype;
merchant_open = GetClass() == MERCHANT;
adventure_template_id = d->adventure_template;
org_x = x;
org_y = y;
org_z = z;
flymode = iflymode;
guard_x = -1; //just some value we might be able to recongize as "unset"
guard_y = -1;
guard_z = -1;
guard_heading = 0;
guard_anim = eaStanding;
roambox_distance = 0;
roambox_max_x = -2;
@ -223,7 +216,6 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
roambox_movingto_y = -2;
roambox_min_delay = 1000;
roambox_delay = 1000;
org_heading = heading;
p_depop = false;
loottable_id = d->loottable_id;
@ -356,10 +348,6 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
reface_timer = new Timer(15000);
reface_timer->Disable();
qGlobals = nullptr;
guard_x_saved = 0;
guard_y_saved = 0;
guard_z_saved = 0;
guard_heading_saved = 0;
SetEmoteID(d->emoteid);
InitializeBuffSlots();
CalcBonuses();
@ -674,8 +662,8 @@ bool NPC::Process()
DoGravityEffect();
}
if(reface_timer->Check() && !IsEngaged() && (guard_x == GetX() && guard_y == GetY() && guard_z == GetZ())) {
SetHeading(guard_heading);
if(reface_timer->Check() && !IsEngaged() && (m_GuardPoint.m_X == GetX() && m_GuardPoint.m_Y == GetY() && m_GuardPoint.m_Z == GetZ())) {
SetHeading(m_GuardPoint.m_Heading);
SendPosition();
reface_timer->Disable();
}
@ -780,7 +768,7 @@ bool NPC::DatabaseCastAccepted(int spell_id) {
return false;
}
NPC* NPC::SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z, float in_heading, Client* client) {
NPC* NPC::SpawnNPC(const char* spawncommand, const xyz_heading& position, Client* client) {
if(spawncommand == 0 || spawncommand[0] == 0) {
return 0;
}
@ -939,7 +927,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z,
npc_type->prim_melee_type = 28;
npc_type->sec_melee_type = 28;
NPC* npc = new NPC(npc_type, 0, in_x, in_y, in_z, in_heading/8, FlyMode3);
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode3);
npc->GiveNPCTypeData(npc_type);
entity_list.AddNPC(npc);
@ -2433,7 +2421,7 @@ void NPC::DepopSwarmPets()
Mob* owner = entity_list.GetMobID(GetSwarmInfo()->owner_id);
if (owner)
owner->SetTempPetCount(owner->GetTempPetCount() - 1);
Depop();
return;
}

View File

@ -64,10 +64,10 @@ struct AISpells_Struct {
};
struct AISpellsEffects_Struct {
uint16 spelleffectid;
int32 base;
int32 limit;
int32 max;
uint16 spelleffectid;
int32 base;
int32 limit;
int32 max;
};
struct AISpellsVar_Struct {
@ -83,7 +83,7 @@ struct AISpellsVar_Struct {
uint32 idle_no_sp_recast_min;
uint32 idle_no_sp_recast_max;
uint8 idle_beneficial_chance;
};
};
class AA_SwarmPetInfo;
class Client;
@ -95,10 +95,10 @@ struct Item_Struct;
class NPC : public Mob
{
public:
static NPC* SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z, float in_heading = 0, Client* client = 0);
static NPC* SpawnNPC(const char* spawncommand, const xyz_heading& position, Client* client = nullptr);
static int8 GetAILevel(bool iForceReRead = false);
NPC(const NPCType* data, Spawn2* respawn, float x, float y, float z, float heading, int iflymode, bool IsCorpse = false);
NPC(const NPCType* data, Spawn2* respawn, const xyz_heading& position, int iflymode, bool IsCorpse = false);
virtual ~NPC();
@ -162,7 +162,7 @@ public:
FACTION_VALUE CheckNPCFactionAlly(int32 other_faction);
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther);
void GoToBind(uint8 bindnum = 0) { GMMove(org_x, org_y, org_z, org_heading); }
void GoToBind(uint8 bindnum = 0) { GMMove(m_SpawnPoint.m_X, m_SpawnPoint.m_Y, m_SpawnPoint.m_Z, m_SpawnPoint.m_Heading); }
void Gate();
void GetPetState(SpellBuff_Struct *buffs, uint32 *items, char *name);
@ -210,14 +210,8 @@ public:
uint32 GetSp2() const { return spawn_group; }
uint32 GetSpawnPointID() const;
float GetSpawnPointX() const { return org_x; }
float GetSpawnPointY() const { return org_y; }
float GetSpawnPointZ() const { return org_z; }
float GetSpawnPointH() const { return org_heading; }
float GetGuardPointX() const { return guard_x; }
float GetGuardPointY() const { return guard_y; }
float GetGuardPointZ() const { return guard_z; }
float GetGuardPointH() const { return guard_heading; }
xyz_heading const GetSpawnPoint() const { return m_SpawnPoint; }
xyz_heading const GetGuardPoint() const { return m_GuardPoint; }
EmuAppearance GetGuardPointAnim() const { return guard_anim; }
void SaveGuardPointAnim(EmuAppearance anim) { guard_anim = anim; }
@ -254,7 +248,7 @@ public:
void SetNPCFactionID(int32 in) { npc_faction_id = in; database.GetFactionIdsForNPC(npc_faction_id, &faction_list, &primary_faction); }
float org_x, org_y, org_z, org_heading;
xyz_heading m_SpawnPoint;
uint32 GetMaxDMG() const {return max_dmg;}
uint32 GetMinDMG() const {return min_dmg;}
@ -288,15 +282,15 @@ public:
void StopWandering();
void ResumeWandering();
void PauseWandering(int pausetime);
void MoveTo(float mtx, float mty, float mtz, float mth, bool saveguardspot);
void GetClosestWaypoint(std::list<wplist> &wp_list, int count, float m_x, float m_y, float m_z);
void MoveTo(const xyz_heading& position, bool saveguardspot);
void GetClosestWaypoint(std::list<wplist> &wp_list, int count, const xyz_location& location);
uint32 GetEquipment(uint8 material_slot) const; // returns item id
int32 GetEquipmentMaterial(uint8 material_slot) const;
void NextGuardPosition();
void SaveGuardSpot(bool iClearGuardSpot = false);
inline bool IsGuarding() const { return(guard_heading != 0); }
inline bool IsGuarding() const { return(m_GuardPoint.m_Heading != 0); }
void SaveGuardSpotCharm();
void RestoreGuardSpotCharm();
void AI_SetRoambox(float iDist, float iRoamDist, uint32 iDelay = 2500, uint32 iMinDelay = 2500);
@ -387,7 +381,7 @@ public:
inline void SetHealScale(float amt) { healscale = amt; }
inline float GetHealScale() { return healscale; }
inline void SetSpellFocusDMG(int32 NewSpellFocusDMG) {SpellFocusDMG = NewSpellFocusDMG;}
inline int32 GetSpellFocusDMG() const { return SpellFocusDMG;}
@ -408,7 +402,7 @@ public:
void SetHeroForgeModel(uint32 model) { herosforgemodel = model; }
bool IsRaidTarget() const { return raid_target; };
protected:
const NPCType* NPCTypedata;
@ -450,7 +444,6 @@ protected:
AISpellsVar_Struct AISpellVar;
int16 GetFocusEffect(focusType type, uint16 spell_id);
uint32 npc_spells_effects_id;
std::vector<AISpellsEffects_Struct> AIspellsEffects;
bool HasAISpellEffects;
@ -480,8 +473,8 @@ protected:
void _ClearWaypints();
int max_wp;
int save_wp;
float guard_x, guard_y, guard_z, guard_heading;
float guard_x_saved, guard_y_saved, guard_z_saved, guard_heading_saved;
xyz_heading m_GuardPoint;
xyz_heading m_GuardPointSaved;
EmuAppearance guard_anim;
float roambox_max_x;
float roambox_max_y;
@ -519,7 +512,7 @@ protected:
//mercenary stuff
std::list<MercType> mercTypeList;
std::list<MercData> mercDataList;
bool raid_target;
uint8 probability;

View File

@ -587,8 +587,8 @@ void PathManager::SpawnPathNodes()
npc_type->CHA = 150;
npc_type->findable = 1;
NPC* npc = new NPC(npc_type, 0, PathNodes[i].v.x, PathNodes[i].v.y, PathNodes[i].v.z, 0, FlyMode1);
auto position = xyz_heading(PathNodes[i].v.x, PathNodes[i].v.y, PathNodes[i].v.z, 0.0f);
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1);
npc->GiveNPCTypeData(npc_type);
entity_list.AddNPC(npc, true, true);
@ -1197,12 +1197,14 @@ bool PathManager::NoHazardsAccurate(Map::Vertex From, Map::Vertex To)
if (zone->watermap)
{
if (zone->watermap->InLiquid(From.x, From.y, From.z) || zone->watermap->InLiquid(To.x, To.y, To.z))
auto from = xyz_location(From.x, From.y, From.z);
auto to = xyz_location(To.x, To.y, To.z);
if (zone->watermap->InLiquid(from) || zone->watermap->InLiquid(to))
{
break;
}
if (zone->watermap->InLiquid(TestPoint.x, TestPoint.y, NewZ))
auto testPointNewZ = xyz_location(TestPoint.x, TestPoint.y, NewZ);
if (zone->watermap->InLiquid(testPointNewZ))
{
Map::Vertex TestPointWater(TestPoint.x, TestPoint.y, NewZ - 0.5f);
Map::Vertex TestPointWaterDest = TestPointWater;
@ -1574,7 +1576,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
npc_type->CHA = 150;
npc_type->findable = 1;
NPC* npc = new NPC(npc_type, 0, new_node.v.x, new_node.v.y, new_node.v.z, 0, FlyMode1);
auto position = xyz_heading(new_node.v.x, new_node.v.y, new_node.v.z, 0.0f);
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1);
npc->GiveNPCTypeData(npc_type);
entity_list.AddNPC(npc, true, true);
@ -1634,7 +1637,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
npc_type->CHA = 150;
npc_type->findable = 1;
NPC* npc = new NPC(npc_type, 0, new_node.v.x, new_node.v.y, new_node.v.z, 0, FlyMode1);
auto position = xyz_heading(new_node.v.x, new_node.v.y, new_node.v.z, 0.0f);
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1);
npc->GiveNPCTypeData(npc_type);
entity_list.AddNPC(npc, true, true);

View File

@ -1072,7 +1072,7 @@ XS(XS_Client_SetBindPoint)
new_z = (float)SvNV(ST(5));
}
THIS->SetBindPoint(to_zone, to_instance, new_x, new_y, new_z);
THIS->SetBindPoint(to_zone, to_instance, xyz_location(new_x, new_y, new_z));
}
XSRETURN_EMPTY;
}
@ -1277,7 +1277,7 @@ XS(XS_Client_MovePC)
#ifdef BOTS
else if (THIS->IsBot())
_log(CLIENT__ERROR, "Perl(XS_Client_MovePC) attempted to process a type Bot reference");
#endif
#endif
else
_log(CLIENT__ERROR, "Perl(XS_Client_MovePC) attempted to process an Unknown type reference");
@ -1327,7 +1327,7 @@ XS(XS_Client_MovePCInstance)
else
_log(CLIENT__ERROR, "Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference");
Perl_croak(aTHX_ "THIS is not of type Client");
Perl_croak(aTHX_ "THIS is not of type Client");
Perl_croak(aTHX_ "THIS is not of type Client");
}
@ -5094,7 +5094,7 @@ XS(XS_Client_GetTaskActivityDoneCount)
Perl_croak(aTHX_ "Usage: Client::GetTaskActivityDoneCount(THIS, TaskID, ActivityID)");
{
Client * THIS;
int RETVAL;
int RETVAL;
int TaskID = (int)SvIV(ST(1));
int ActivityID = (int)SvIV(ST(2));
dXSTARG;
@ -5108,7 +5108,7 @@ XS(XS_Client_GetTaskActivityDoneCount)
if (THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetTaskActivityDoneCountFromTaskID(TaskID, ActivityID);
XSprePUSH; PUSHi((IV)RETVAL);
}
@ -5952,7 +5952,7 @@ XS(XS_Client_SilentMessage)
{
Client * THIS;
dXSTARG;
if (sv_derived_from(ST(0), "Client")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(Client *,tmp);
@ -6351,7 +6351,7 @@ XS(boot_Client)
newXSproto(strcpy(buf, "SendMarqueeMessage"), XS_Client_SendMarqueeMessage, file, "$$$$$$$");
newXSproto(strcpy(buf, "SendColoredText"), XS_Client_SendColoredText, file, "$$$");
newXSproto(strcpy(buf, "SendSpellAnim"), XS_Client_SendSpellAnim, file, "$$$");
XSRETURN_YES;
}

View File

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

View File

@ -1875,7 +1875,7 @@ XS(XS_EntityList_GetRandomClient)
c = INT2PTR(Client *,tmp);
}
}
RETVAL = entity_list.GetRandomClient(x, y, z, d * d, c);
RETVAL = entity_list.GetRandomClient(xyz_location(x, y, z), d * d, c);
ST(0) = sv_newmortal();
sv_setref_pv(ST(0), "Client", (void*)RETVAL);
}

View File

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

View File

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

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
could get while it still looked good). I also noticed this can happen if an NPC is spawned on the same spot of another or in a related bad spot.*/
Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 power)
: NPC(type_data, 0, owner->GetX()+2, owner->GetY()+2, owner->GetZ(), owner->GetHeading(), FlyMode3)
: NPC(type_data, 0, owner->GetPosition() + xy_location(2, 2), FlyMode3)
{
GiveNPCTypeData(type_data);
typeofpet = type;

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);
}
Mob* QuestManager::spawn2(int npc_type, int grid, int unused, float x, float y, float z, float heading) {
Mob* QuestManager::spawn2(int npc_type, int grid, int unused, const xyz_heading& position) {
const NPCType* tmp = 0;
if (tmp = database.GetNPCType(npc_type))
{
NPC* npc = new NPC(tmp, 0, x, y, z, heading, FlyMode3);
NPC* npc = new NPC(tmp, nullptr, position, FlyMode3);
npc->AddLootTable();
entity_list.AddNPC(npc,true,true);
if(grid > 0)
@ -218,7 +218,7 @@ Mob* QuestManager::spawn2(int npc_type, int grid, int unused, float x, float y,
return nullptr;
}
Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading) {
Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, const xyz_heading& position) {
Mob *other = entity_list.GetMobByNpcTypeID(npc_type);
if(other != nullptr) {
return other;
@ -227,7 +227,7 @@ Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, flo
const NPCType* tmp = 0;
if (tmp = database.GetNPCType(npc_type))
{
NPC* npc = new NPC(tmp, 0, x, y, z, heading, FlyMode3);
NPC* npc = new NPC(tmp, nullptr, position, FlyMode3);
npc->AddLootTable();
entity_list.AddNPC(npc,true,true);
if(grid > 0)
@ -300,8 +300,8 @@ Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id)
database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0);
found_spawn->SetCurrentNPCID(npcid);
NPC* npc = new NPC(tmp, found_spawn, found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(),
found_spawn->GetHeading(), FlyMode3);
auto position = xyz_heading(found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(), found_spawn->GetHeading());
NPC* npc = new NPC(tmp, found_spawn, position, FlyMode3);
found_spawn->SetNPCPointer(npc);
npc->AddLootTable();
@ -923,7 +923,7 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) {
spells[curspell].skill != 52 &&
( !RuleB(Spells, UseCHAScribeHack) || spells[curspell].effectid[EFFECT_COUNT - 1] != 10 )
)
{
{
if(IsDiscipline(curspell)){
//we may want to come up with a function like Client::GetNextAvailableSpellBookSlot() to help speed this up a little
for(uint32 r = 0; r < MAX_PP_DISCIPLINES; r++) {
@ -937,12 +937,12 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) {
SpellGlobalCheckResult = initiator->SpellGlobalCheck(curspell, Char_ID);
if (SpellGlobalCheckResult) {
initiator->GetPP().disciplines.values[r] = curspell;
database.SaveCharacterDisc(Char_ID, r, curspell);
database.SaveCharacterDisc(Char_ID, r, curspell);
initiator->SendDisciplineUpdate();
initiator->Message(0, "You have learned a new discipline!");
count++; //success counter
}
break; //continue the 1st loop
break; //continue the 1st loop
}
else {
initiator->GetPP().disciplines.values[r] = curspell;
@ -1486,10 +1486,10 @@ void QuestManager::ding() {
}
void QuestManager::rebind(int zoneid, float x, float y, float z) {
void QuestManager::rebind(int zoneid, const xyz_location& location) {
QuestManagerCurrentQuestVars();
if(initiator && initiator->IsClient()) {
initiator->SetBindPoint(zoneid, x, y, z);
initiator->SetBindPoint(zoneid, 0, location);
}
}
@ -1517,12 +1517,12 @@ void QuestManager::pause(int duration) {
owner->CastToNPC()->PauseWandering(duration);
}
void QuestManager::moveto(float x, float y, float z, float h, bool saveguardspot) {
void QuestManager::moveto(const xyz_heading& position, bool saveguardspot) {
QuestManagerCurrentQuestVars();
if (!owner || !owner->IsNPC())
return;
owner->CastToNPC()->MoveTo(x, y, z, h, saveguardspot);
owner->CastToNPC()->MoveTo(position, saveguardspot);
}
void QuestManager::resume() {
@ -1563,26 +1563,20 @@ void QuestManager::setnextinchpevent(int at) {
owner->SetNextIncHPEvent(at);
}
void QuestManager::respawn(int npc_type, int grid) {
void QuestManager::respawn(int npcTypeID, int grid) {
QuestManagerCurrentQuestVars();
if (!owner || !owner->IsNPC())
return;
float x,y,z,h;
x = owner->GetX();
y = owner->GetY();
z = owner->GetZ();
h = owner->GetHeading();
running_quest e = quests_running_.top();
e.depop_npc = true;
quests_running_.pop();
quests_running_.push(e);
const NPCType* tmp = 0;
if ((tmp = database.GetNPCType(npc_type)))
const NPCType* npcType = nullptr;
if ((npcType = database.GetNPCType(npcTypeID)))
{
owner = new NPC(tmp, 0, x, y, z, h, FlyMode3);
owner = new NPC(npcType, nullptr, owner->GetPosition(), FlyMode3);
owner->CastToNPC()->AddLootTable();
entity_list.AddNPC(owner->CastToNPC(),true,true);
if(grid > 0)
@ -1704,27 +1698,28 @@ void QuestManager::sethp(int hpperc) {
owner->Damage(owner, newhp, SPELL_UNKNOWN, SkillHandtoHand, false, 0, false);
}
bool QuestManager::summonburriedplayercorpse(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading) {
bool QuestManager::summonburriedplayercorpse(uint32 char_id, const xyz_heading& position) {
bool Result = false;
if(char_id > 0) {
Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(char_id, zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading);
if(PlayerCorpse) {
Result = true;
}
}
return Result;
if(char_id <= 0)
return false;
Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(char_id, zone->GetZoneID(), zone->GetInstanceID(), position);
if(!PlayerCorpse)
return false;
return true;
}
bool QuestManager::summonallplayercorpses(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading) {
bool Result = false;
bool QuestManager::summonallplayercorpses(uint32 char_id, const xyz_heading& position) {
if(char_id > 0) {
Client* c = entity_list.GetClientByCharID(char_id);
c->SummonAllCorpses(dest_x, dest_y, dest_z, dest_heading);
Result = true;
}
return Result;
if(char_id <= 0)
return false;
Client* c = entity_list.GetClientByCharID(char_id);
c->SummonAllCorpses(position);
return true;
}
uint32 QuestManager::getplayerburriedcorpsecount(uint32 char_id) {
@ -2312,17 +2307,17 @@ int QuestManager::getlevel(uint8 type)
return 0;
}
uint16 QuestManager::CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time)
uint16 QuestManager::CreateGroundObject(uint32 itemid, const xyz_heading& position, uint32 decay_time)
{
uint16 entid = 0; //safety check
entid = entity_list.CreateGroundObject(itemid, x, y, z, heading, decay_time);
entid = entity_list.CreateGroundObject(itemid, position, decay_time);
return entid;
}
uint16 QuestManager::CreateGroundObjectFromModel(const char *model, float x, float y, float z, float heading, uint8 type, uint32 decay_time)
uint16 QuestManager::CreateGroundObjectFromModel(const char *model, const xyz_heading& position, uint8 type, uint32 decay_time)
{
uint16 entid = 0; //safety check
entid = entity_list.CreateGroundObjectFromModel(model, x, y, z, heading, type, decay_time);
entid = entity_list.CreateGroundObjectFromModel(model, position, type, decay_time);
return entid;
}
@ -2587,12 +2582,12 @@ void QuestManager::RemoveAllFromInstance(uint16 instance_id)
}
}
void QuestManager::MovePCInstance(int zone_id, int instance_id, float x, float y, float z, float heading)
void QuestManager::MovePCInstance(int zone_id, int instance_id, const xyz_heading& position)
{
QuestManagerCurrentQuestVars();
if(initiator)
{
initiator->MovePC(zone_id, instance_id, x, y, z, heading);
initiator->MovePC(zone_id, instance_id, position.m_X, position.m_Y, position.m_Z, position.m_Heading);
}
}
@ -2841,7 +2836,7 @@ void QuestManager::SendMail(const char *to, const char *from, const char *subjec
uint16 QuestManager::CreateDoor(const char* model, float x, float y, float z, float heading, uint8 opentype, uint16 size)
{
uint16 entid = 0; //safety check
entid = entity_list.CreateDoor(model, x, y, z, heading, opentype, size);
entid = entity_list.CreateDoor(model, xyz_heading(x, y, z, heading), opentype, size);
return entid;
}
@ -2884,7 +2879,7 @@ void QuestManager::CrossZoneSignalPlayerByName(const char *CharName, uint32 data
CZSC->data = data;
worldserver.SendPacket(pack);
safe_delete(pack);
}
}
void QuestManager::CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message){
uint32 message_len = strlen(CharName) + 1;
@ -2894,7 +2889,7 @@ void QuestManager::CrossZoneMessagePlayerByName(uint32 Type, const char *CharNam
CZSC->Type = Type;
strn0cpy(CZSC->CharName, CharName, 64);
strn0cpy(CZSC->Message, Message, 512);
worldserver.SendPacket(pack);
worldserver.SendPacket(pack);
safe_delete(pack);
}
@ -2904,7 +2899,7 @@ void QuestManager::CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, cons
ServerPacket* pack = new ServerPacket(ServerOP_CZSetEntityVariableByNPCTypeID, sizeof(CZSetEntVarByNPCTypeID_Struct) + message_len + message_len2);
CZSetEntVarByNPCTypeID_Struct* CZSNBYNID = (CZSetEntVarByNPCTypeID_Struct*)pack->pBuffer;
CZSNBYNID->npctype_id = npctype_id;
strn0cpy(CZSNBYNID->id, id, 256);
strn0cpy(CZSNBYNID->id, id, 256);
strn0cpy(CZSNBYNID->m_var, m_var, 256);
worldserver.SendPacket(pack);
safe_delete(pack);

View File

@ -57,8 +57,8 @@ public:
void me(const char *str);
void summonitem(uint32 itemid, int16 charges = -1);
void write(const char *file, const char *str);
Mob* spawn2(int npc_type, int grid, int unused, float x, float y, float z, float heading);
Mob* unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading = 0);
Mob* spawn2(int npc_type, int grid, int unused, const xyz_heading& position);
Mob* unique_spawn(int npc_type, int grid, int unused, const xyz_heading& position);
Mob* spawn_from_spawn2(uint32 spawn2_id);
void enable_spawn2(uint32 spawn2_id);
void disable_spawn2(uint32 spawn2_id);
@ -132,11 +132,11 @@ public:
void targlobal(const char *varname, const char *value, const char *duration, int npcid, int charid, int zoneid);
void delglobal(const char *varname);
void ding();
void rebind(int zoneid, float x, float y, float z);
void rebind(int zoneid, const xyz_location& location);
void start(int wp);
void stop();
void pause(int duration);
void moveto(float x, float y, float z, float h, bool saveguardspot);
void moveto(const xyz_heading& position, bool saveguardspot);
void resume();
void addldonpoints(int32 points, uint32 theme);
void addldonwin(int32 wins, uint32 theme);
@ -157,8 +157,8 @@ public:
void set_zone_flag(int zone_id);
void clear_zone_flag(int zone_id);
void sethp(int hpperc);
bool summonburriedplayercorpse(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading);
bool summonallplayercorpses(uint32 char_id, float dest_x, float dest_y, float dest_z, float dest_heading);
bool summonburriedplayercorpse(uint32 char_id, const xyz_heading& position);
bool summonallplayercorpses(uint32 char_id, const xyz_heading& position);
uint32 getplayerburriedcorpsecount(uint32 char_id);
bool buryplayercorpse(uint32 char_id);
void forcedooropen(uint32 doorid, bool altmode);
@ -208,8 +208,8 @@ public:
void enabletitle(int titleset);
bool checktitle(int titlecheck);
void removetitle(int titlecheck);
uint16 CreateGroundObject(uint32 itemid, float x, float y, float z, float heading, uint32 decay_time = 300000);
uint16 CreateGroundObjectFromModel(const char* model, float x, float y, float z, float heading, uint8 type = 0x00, uint32 decay_time = 0);
uint16 CreateGroundObject(uint32 itemid, const xyz_heading& position, uint32 decay_time = 300000);
uint16 CreateGroundObjectFromModel(const char* model, const xyz_heading& position, uint8 type = 0x00, uint32 decay_time = 0);
void ModifyNPCStat(const char *identifier, const char *newValue);
void UpdateSpawnTimer(uint32 id, uint32 newTime);
void MerchantSetItem(uint32 NPCid, uint32 itemid, uint32 quantity = 0);
@ -224,7 +224,7 @@ public:
//void RemoveGroupFromInstance(uint16 instance_id); //potentially useful but not implmented at this time.
//void RemoveRaidFromInstance(uint16 instance_id); //potentially useful but not implmented at this time.
void RemoveAllFromInstance(uint16 instance_id);
void MovePCInstance(int zone_id, int instance_id, float x, float y, float z, float heading);
void MovePCInstance(int zone_id, int instance_id, const xyz_heading& position);
void FlagInstanceByGroupLeader(uint32 zone, int16 version);
void FlagInstanceByRaidLeader(uint32 zone, int16 version);
const char* varlink(char* perltext, int item_id);
@ -241,7 +241,7 @@ public:
uint16 CreateDoor( const char* model, float x, float y, float z, float heading, uint8 opentype, uint16 size);
int32 GetZoneID(const char *zone);
const char *GetZoneLongName(const char *zone);
void CrossZoneSignalPlayerByCharID(int charid, uint32 data);
void CrossZoneSignalPlayerByCharID(int charid, uint32 data);
void CrossZoneSignalNPCByNPCTypeID(uint32 npctype_id, uint32 data);
void CrossZoneSignalPlayerByName(const char *CharName, uint32 data);
void CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, const char *id, const char *m_var);

View File

@ -218,7 +218,7 @@ bool Spawn2::Process() {
database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0);
currentnpcid = npcid;
NPC* npc = new NPC(tmp, this, x, y, z, heading, FlyMode3);
NPC* npc = new NPC(tmp, this, xyz_heading(x, y, z, heading), FlyMode3);
npc->mod_prespawn(this);
@ -414,13 +414,13 @@ Spawn2* ZoneDatabase::LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2
return newSpawn;
}
bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value)
bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* zone, const xyz_heading& position, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value)
{
std::string query = StringFormat("INSERT INTO spawn2 (spawngroupID, zone, x, y, z, heading, "
"respawntime, variance, _condition, cond_value) "
"VALUES (%i, '%s', %f, %f, %f, %f, %i, %i, %u, %i)",
spawngroup, zone, x, y, z, heading,
spawngroup, zone, position.m_X, position.m_Y, position.m_Z, position.m_Heading,
respawn, variance, condition, cond_value);
auto results = QueryDatabase(query);
if (!results.Success()) {

View File

@ -309,7 +309,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
sprintf(temp, "%d", spell_id);
parse->EventNPC(EVENT_CAST_BEGIN, CastToNPC(), nullptr, temp, 0);
}
//To prevent NPC ghosting when spells are cast from scripts
if (IsNPC() && IsMoving() && cast_time > 0)
SendPosition();
@ -362,7 +362,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
casting_spell_type = type;
SaveSpellLoc();
mlog(SPELLS__CASTING, "Casting %d Started at (%.3f,%.3f,%.3f)", spell_id, spell_x, spell_y, spell_z);
mlog(SPELLS__CASTING, "Casting %d Started at (%.3f,%.3f,%.3f)", spell_id, m_SpellLocation.m_X, m_SpellLocation.m_Y, m_SpellLocation.m_Z);
// if this spell doesn't require a target, or if it's an optional target
// and a target wasn't provided, then it's us; unless TGB is on and this
@ -533,8 +533,8 @@ bool Mob::DoCastingChecks()
return false;
}
if (zone->IsSpellBlocked(spell_id, GetX(), GetY(), GetZ())) {
const char *msg = zone->GetSpellBlockedMessage(spell_id, GetX(), GetY(), GetZ());
if (zone->IsSpellBlocked(spell_id, GetPosition())) {
const char *msg = zone->GetSpellBlockedMessage(spell_id, GetPosition());
if (msg) {
Message(13, msg);
return false;
@ -1626,7 +1626,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
{
if(!spell_target)
return false;
ae_center = spell_target;
CastAction = AETarget;
}
@ -1645,7 +1645,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
{
if(!spell_target)
return false;
ae_center = spell_target;
CastAction = AETarget;
}
@ -1918,8 +1918,8 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
if(IsClient() && !CastToClient()->GetGM()){
if(zone->IsSpellBlocked(spell_id, GetX(), GetY(), GetZ())){
const char *msg = zone->GetSpellBlockedMessage(spell_id, GetX(), GetY(), GetZ());
if(zone->IsSpellBlocked(spell_id, GetPosition())){
const char *msg = zone->GetSpellBlockedMessage(spell_id, GetPosition());
if(msg){
Message(13, msg);
return false;
@ -2097,7 +2097,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
} else {
// regular PB AE or targeted AE spell - spell_target is null if PB
if(spell_target) // this must be an AETarget spell
{
{
bool cast_on_target = true;
if (spells[spell_id].targettype == ST_TargetAENoPlayersPets && spell_target->IsPetOwnerClient())
cast_on_target = false;
@ -2206,7 +2206,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
ConeDirectional(spell_id, resist_adjust);
break;
}
case Beam:
{
BeamDirectional(spell_id, resist_adjust);
@ -3729,7 +3729,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r
if (IsValidSpell(spells[spell_id].RecourseLink))
SpellFinished(spells[spell_id].RecourseLink, this, 10, 0, -1, spells[spells[spell_id].RecourseLink].ResistDiff);
if (IsDetrimentalSpell(spell_id)) {
CheckNumHitsRemaining(NumHit::OutgoingSpells);
@ -3856,9 +3856,9 @@ void Corpse::CastRezz(uint16 spellid, Mob* Caster)
rezz->zone_id = zone->GetZoneID();
rezz->instance_id = zone->GetInstanceID();
rezz->spellid = spellid;
rezz->x = this->x_pos;
rezz->y = this->y_pos;
rezz->z = this->z_pos;
rezz->x = this->m_Position.m_X;
rezz->y = this->m_Position.m_Y;
rezz->z = this->m_Position.m_Z;
rezz->unknown000 = 0x00000000;
rezz->unknown020 = 0x00000000;
rezz->unknown088 = 0x00000000;
@ -4522,7 +4522,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
if(partial_modifier <= 0)
{
return 100;
}
}
else if(partial_modifier >= 100)
{
return 0;
@ -4840,7 +4840,7 @@ void Client::UnmemSpell(int slot, bool update_client)
m_pp.mem_spells[slot] = 0xFFFFFFFF;
database.DeleteCharacterMemorizedSpell(this->CharacterID(), m_pp.mem_spells[slot], slot);
if(update_client)
{
MemorizeSpell(slot, m_pp.mem_spells[slot], memSpellForget);
@ -4884,8 +4884,8 @@ void Client::UnscribeSpell(int slot, bool update_client)
mlog(CLIENT__SPELLS, "Spell %d erased from spell book slot %d", m_pp.spell_book[slot], slot);
m_pp.spell_book[slot] = 0xFFFFFFFF;
database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[slot], slot);
database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[slot], slot);
if(update_client)
{
EQApplicationPacket* outapp = new EQApplicationPacket(OP_DeleteSpell, sizeof(DeleteSpell_Struct));
@ -4913,7 +4913,7 @@ void Client::UntrainDisc(int slot, bool update_client)
if(slot >= MAX_PP_DISCIPLINES || slot < 0)
return;
mlog(CLIENT__SPELLS, "Discipline %d untrained from slot %d", m_pp.disciplines.values[slot], slot);
mlog(CLIENT__SPELLS, "Discipline %d untrained from slot %d", m_pp.disciplines.values[slot], slot);
m_pp.disciplines.values[slot] = 0;
database.DeleteCharacterDisc(this->CharacterID(), slot);
@ -5462,27 +5462,27 @@ void Mob::BeamDirectional(uint16 spell_id, int16 resist_adjust)
if (IsBeneficialSpell(spell_id) && IsClient())
beneficial_targets = true;
std::list<Mob*> targets_in_range;
std::list<Mob*>::iterator iter;
entity_list.GetTargetsForConeArea(this, spells[spell_id].min_range, spells[spell_id].range, spells[spell_id].range / 2, targets_in_range);
iter = targets_in_range.begin();
float dX = 0;
float dY = 0;
float dZ = 0;
CalcDestFromHeading(GetHeading(), spells[spell_id].range, 5, GetX(), GetY(), dX, dY, dZ);
dZ = GetZ();
//FIND SLOPE: Put it into the form y = mx + b
float m = (dY - GetY()) / (dX - GetX());
float b = (GetY() * dX - dY * GetX()) / (dX - GetX());
while(iter != targets_in_range.end())
{
if (!(*iter) || (beneficial_targets && ((*iter)->IsNPC() && !(*iter)->IsPetOwnerClient()))
if (!(*iter) || (beneficial_targets && ((*iter)->IsNPC() && !(*iter)->IsPetOwnerClient()))
|| (*iter)->BehindMob(this, (*iter)->GetX(),(*iter)->GetY())){
++iter;
continue;
@ -5490,7 +5490,7 @@ void Mob::BeamDirectional(uint16 spell_id, int16 resist_adjust)
//# shortest distance from line to target point
float d = abs( (*iter)->GetY() - m * (*iter)->GetX() - b) / sqrt(m * m + 1);
if (d <= spells[spell_id].aoerange)
{
if(CheckLosFN((*iter)) || spells[spell_id].npc_no_los) {
@ -5537,7 +5537,7 @@ void Mob::ConeDirectional(uint16 spell_id, int16 resist_adjust)
}
float heading_to_target = (CalculateHeadingToTarget((*iter)->GetX(), (*iter)->GetY()) * 360.0f / 256.0f);
while(heading_to_target < 0.0f)
heading_to_target += 360.0f;

View File

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

View File

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

View File

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

View File

@ -6,31 +6,31 @@ WaterMapV2::WaterMapV2() {
WaterMapV2::~WaterMapV2() {
}
WaterRegionType WaterMapV2::ReturnRegionType(float y, float x, float z) const {
WaterRegionType WaterMapV2::ReturnRegionType(const xyz_location& location) const {
size_t sz = regions.size();
for(size_t i = 0; i < sz; ++i) {
auto const &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 RegionTypeNormal;
}
bool WaterMapV2::InWater(float y, float x, float z) const {
return ReturnRegionType(y, x, z) == RegionTypeWater;
bool WaterMapV2::InWater(const xyz_location& location) const {
return ReturnRegionType(location) == RegionTypeWater;
}
bool WaterMapV2::InVWater(float y, float x, float z) const {
return ReturnRegionType(y, x, z) == RegionTypeVWater;
bool WaterMapV2::InVWater(const xyz_location& location) const {
return ReturnRegionType(location) == RegionTypeVWater;
}
bool WaterMapV2::InLava(float y, float x, float z) const {
return ReturnRegionType(y, x, z) == RegionTypeLava;
bool WaterMapV2::InLava(const xyz_location& location) const {
return ReturnRegionType(location) == RegionTypeLava;
}
bool WaterMapV2::InLiquid(float y, float x, float z) const {
return InWater(y, x, z) || InLava(y, x, z);
bool WaterMapV2::InLiquid(const xyz_location& location) const {
return InWater(location) || InLava(location);
}
bool WaterMapV2::Load(FILE *fp) {
@ -106,7 +106,7 @@ bool WaterMapV2::Load(FILE *fp) {
return false;
}
regions.push_back(std::make_pair((WaterRegionType)region_type,
regions.push_back(std::make_pair((WaterRegionType)region_type,
OrientedBoundingBox(glm::vec3(x, y, z), glm::vec3(x_rot, y_rot, z_rot), glm::vec3(x_scale, y_scale, z_scale), glm::vec3(x_extent, y_extent, z_extent))));
}

View File

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

View File

@ -120,7 +120,7 @@ void NPC::ResumeWandering()
return;
}
if (cur_wp_x == GetX() && cur_wp_y == GetY())
if (m_CurrentWayPoint.m_X == GetX() && m_CurrentWayPoint.m_Y == GetY())
{ // are we we at a waypoint? if so, trigger event and start to next
char temp[100];
itoa(cur_wp,temp,10); //do this before updating to next waypoint
@ -159,7 +159,7 @@ void NPC::PauseWandering(int pausetime)
return;
}
void NPC::MoveTo(float mtx, float mty, float mtz, float mth, bool saveguardspot)
void NPC::MoveTo(const xyz_heading& position, bool saveguardspot)
{ // makes mob walk to specified location
if (IsNPC() && GetGrid() != 0)
{ // he is on a grid
@ -174,36 +174,30 @@ void NPC::MoveTo(float mtx, float mty, float mtz, float mth, bool saveguardspot)
save_wp=cur_wp; // save the current waypoint
cur_wp=-1; // flag this move as quest controlled
}
mlog(AI__WAYPOINTS, "MoveTo (%.3f, %.3f, %.3f), pausing regular grid wandering. Grid %d, save_wp %d", mtx, mty, mtz, -GetGrid(), save_wp);
mlog(AI__WAYPOINTS, "MoveTo %s, pausing regular grid wandering. Grid %d, save_wp %d",to_string(static_cast<xyz_location>(position)).c_str(), -GetGrid(), save_wp);
}
else
{ // not on a grid
roamer=true;
save_wp=0;
cur_wp=-2; // flag as quest controlled w/no grid
mlog(AI__WAYPOINTS, "MoveTo (%.3f, %.3f, %.3f) without a grid.", mtx, mty, mtz);
mlog(AI__WAYPOINTS, "MoveTo %s without a grid.", to_string(static_cast<xyz_location>(position)).c_str());
}
if (saveguardspot)
{
guard_x = mtx;
guard_y = mty;
guard_z = mtz;
guard_heading = mth;
m_GuardPoint = position;
if(guard_heading == 0)
guard_heading = 0.0001; //hack to make IsGuarding simpler
if(m_GuardPoint.m_Heading == 0)
m_GuardPoint.m_Heading = 0.0001; //hack to make IsGuarding simpler
if(guard_heading == -1)
guard_heading = this->CalculateHeadingToTarget(mtx, mty);
if(m_GuardPoint.m_Heading == -1)
m_GuardPoint.m_Heading = this->CalculateHeadingToTarget(position.m_X, position.m_Y);
mlog(AI__WAYPOINTS, "Setting guard position to (%.3f, %.3f, %.3f)", guard_x, guard_y, guard_z);
mlog(AI__WAYPOINTS, "Setting guard position to %s", to_string(static_cast<xyz_location>(m_GuardPoint)).c_str());
}
cur_wp_x = mtx;
cur_wp_y = mty;
cur_wp_z = mtz;
m_CurrentWayPoint = position;
cur_wp_pause = 0;
cur_wp_heading = mth;
pLastFightingDelayMoving = 0;
if(AIwalking_timer->Enabled())
AIwalking_timer->Start(100);
@ -219,26 +213,23 @@ void NPC::UpdateWaypoint(int wp_index)
cur = Waypoints.begin();
cur += wp_index;
cur_wp_x = cur->x;
cur_wp_y = cur->y;
cur_wp_z = cur->z;
m_CurrentWayPoint = xyz_heading(cur->x, cur->y, cur->z, cur->heading);
cur_wp_pause = cur->pause;
cur_wp_heading = cur->heading;
mlog(AI__WAYPOINTS, "Next waypoint %d: (%.3f, %.3f, %.3f, %.3f)", wp_index, cur_wp_x, cur_wp_y, cur_wp_z, cur_wp_heading);
mlog(AI__WAYPOINTS, "Next waypoint %d: (%.3f, %.3f, %.3f, %.3f)", wp_index, m_CurrentWayPoint.m_X, m_CurrentWayPoint.m_Y, m_CurrentWayPoint.m_Z, m_CurrentWayPoint.m_Heading);
//fix up pathing Z
if(zone->HasMap() && RuleB(Map, FixPathingZAtWaypoints))
{
if(!RuleB(Watermap, CheckForWaterAtWaypoints) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(cur_wp_x, cur_wp_y, cur_wp_z)))
(zone->HasWaterMap() && !zone->watermap->InWater(m_CurrentWayPoint)))
{
Map::Vertex dest(cur_wp_x, cur_wp_y, cur_wp_z);
Map::Vertex dest(m_CurrentWayPoint.m_X, m_CurrentWayPoint.m_Y, m_CurrentWayPoint.m_Z);
float newz = zone->zonemap->FindBestZ(dest, nullptr);
if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaWaypoint))
cur_wp_z = newz + 1;
m_CurrentWayPoint.m_Z = newz + 1;
}
}
@ -267,7 +258,7 @@ void NPC::CalculateNewWaypoint()
case 1: //10 closest
{
std::list<wplist> closest;
GetClosestWaypoint(closest, 10, GetX(), GetY(), GetZ());
GetClosestWaypoint(closest, 10, GetPosition());
std::list<wplist>::iterator iter = closest.begin();
if(closest.size() != 0)
{
@ -323,7 +314,7 @@ void NPC::CalculateNewWaypoint()
case 5: //pick random closest 5 and pick one that's in sight
{
std::list<wplist> closest;
GetClosestWaypoint(closest, 5, GetX(), GetY(), GetZ());
GetClosestWaypoint(closest, 5, GetPosition());
std::list<wplist>::iterator iter = closest.begin();
while(iter != closest.end())
@ -364,7 +355,7 @@ bool wp_distance_pred(const wp_distance& left, const wp_distance& right)
return left.dist < right.dist;
}
void NPC::GetClosestWaypoint(std::list<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();
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;
for(int i = 0; i < Waypoints.size(); ++i)
{
float cur_x = (Waypoints[i].x - m_x);
float cur_x = (Waypoints[i].x - location.m_X);
cur_x *= cur_x;
float cur_y = (Waypoints[i].y - m_y);
float cur_y = (Waypoints[i].y - location.m_Y);
cur_y *= cur_y;
float cur_z = (Waypoints[i].z - m_z);
float cur_z = (Waypoints[i].z - location.m_Z);
cur_z *= cur_z;
float cur_dist = cur_x + cur_y + cur_z;
wp_distance w_dist;
@ -431,28 +422,23 @@ void NPC::SetWaypointPause()
void NPC::SaveGuardSpot(bool iClearGuardSpot) {
if (iClearGuardSpot) {
mlog(AI__WAYPOINTS, "Clearing guard order.");
guard_x = 0;
guard_y = 0;
guard_z = 0;
guard_heading = 0;
m_GuardPoint = xyz_heading(0, 0, 0, 0);
}
else {
guard_x = x_pos;
guard_y = y_pos;
guard_z = z_pos;
guard_heading = heading;
if(guard_heading == 0)
guard_heading = 0.0001; //hack to make IsGuarding simpler
mlog(AI__WAYPOINTS, "Setting guard position to (%.3f, %.3f, %.3f)", guard_x, guard_y, guard_z);
m_GuardPoint = m_Position;
if(m_GuardPoint.m_Heading == 0)
m_GuardPoint.m_Heading = 0.0001; //hack to make IsGuarding simpler
mlog(AI__WAYPOINTS, "Setting guard position to %s", to_string(static_cast<xyz_location>(m_GuardPoint)).c_str());
}
}
void NPC::NextGuardPosition() {
if (!CalculateNewPosition2(guard_x, guard_y, guard_z, GetMovespeed())) {
SetHeading(guard_heading);
if (!CalculateNewPosition2(m_GuardPoint.m_X, m_GuardPoint.m_Y, m_GuardPoint.m_Z, GetMovespeed())) {
SetHeading(m_GuardPoint.m_Heading);
mlog(AI__WAYPOINTS, "Unable to move to next guard position. Probably rooted.");
}
else if((x_pos == guard_x) && (y_pos == guard_y) && (z_pos == guard_z))
else if((m_Position.m_X == m_GuardPoint.m_X) && (m_Position.m_Y == m_GuardPoint.m_Y) && (m_Position.m_Z == m_GuardPoint.m_Z))
{
if(moved)
{
@ -480,7 +466,7 @@ void Mob::SaveSpawnSpot() {
}*/
float Mob::CalculateDistance(float x, float y, float z) {
return (float)sqrtf( ((x_pos-x)*(x_pos-x)) + ((y_pos-y)*(y_pos-y)) + ((z_pos-z)*(z_pos-z)) );
return (float)sqrtf( ((m_Position.m_X-x)*(m_Position.m_X-x)) + ((m_Position.m_Y-y)*(m_Position.m_Y-y)) + ((m_Position.m_Z-z)*(m_Position.m_Z-z)) );
}
/*
@ -491,13 +477,13 @@ uint8 NPC::CalculateHeadingToNextWaypoint() {
float Mob::CalculateHeadingToTarget(float in_x, float in_y) {
float angle;
if (in_x-x_pos > 0)
angle = - 90 + atan((float)(in_y-y_pos) / (float)(in_x-x_pos)) * 180 / M_PI;
else if (in_x-x_pos < 0)
angle = + 90 + atan((float)(in_y-y_pos) / (float)(in_x-x_pos)) * 180 / M_PI;
if (in_x-m_Position.m_X > 0)
angle = - 90 + atan((float)(in_y-m_Position.m_Y) / (float)(in_x-m_Position.m_X)) * 180 / M_PI;
else if (in_x-m_Position.m_X < 0)
angle = + 90 + atan((float)(in_y-m_Position.m_Y) / (float)(in_x-m_Position.m_X)) * 180 / M_PI;
else // Added?
{
if (in_y-y_pos > 0)
if (in_y-m_Position.m_Y > 0)
angle = 0;
else
angle = 180;
@ -513,16 +499,16 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
if(GetID()==0)
return true;
if ((x_pos-x == 0) && (y_pos-y == 0)) {//spawn is at target coords
if(z_pos-z != 0) {
z_pos = z;
if ((m_Position.m_X-x == 0) && (m_Position.m_Y-y == 0)) {//spawn is at target coords
if(m_Position.m_Z-z != 0) {
m_Position.m_Z = z;
mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z);
return true;
}
mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater);
return false;
}
else if ((ABS(x_pos - x) < 0.1) && (ABS(y_pos - y) < 0.1))
else if ((ABS(m_Position.m_X - x) < 0.1) && (ABS(m_Position.m_Y - y) < 0.1))
{
mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f): X/Y difference <0.1, Jumping to target.", x, y, z);
@ -530,27 +516,27 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
entity_list.ProcessMove(CastToNPC(), x, y, z);
}
x_pos = x;
y_pos = y;
z_pos = z;
m_Position.m_X = x;
m_Position.m_Y = y;
m_Position.m_Z = z;
return true;
}
int compare_steps = IsBoat() ? 1 : 20;
if(tar_ndx < compare_steps && tarx==x && tary==y) {
if(tar_ndx < compare_steps && m_TargetLocation.m_X==x && m_TargetLocation.m_Y==y) {
float new_x = x_pos + tar_vx*tar_vector;
float new_y = y_pos + tar_vy*tar_vector;
float new_z = z_pos + tar_vz*tar_vector;
float new_x = m_Position.m_X + m_TargetV.m_X*tar_vector;
float new_y = m_Position.m_Y + m_TargetV.m_Y*tar_vector;
float new_z = m_Position.m_Z + m_TargetV.m_Z*tar_vector;
if(IsNPC()) {
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
}
x_pos = new_x;
y_pos = new_y;
z_pos = new_z;
m_Position.m_X = new_x;
m_Position.m_Y = new_y;
m_Position.m_Z = new_z;
mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), old vector (%.3f, %.3f, %.3f)", x, y, z, tar_vx, tar_vy, tar_vz);
mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), old vector (%.3f, %.3f, %.3f)", x, y, z, m_TargetV.m_X, m_TargetV.m_Y, m_TargetV.m_Z);
uint8 NPCFlyMode = 0;
@ -563,25 +549,25 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving))
{
if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
(zone->HasWaterMap() && !zone->watermap->InWater(m_Position.m_X)))
{
Map::Vertex dest(x_pos, y_pos, z_pos);
Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z);
float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f;
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z);
if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
{
if((ABS(x - x_pos) < 0.5) && (ABS(y - y_pos) < 0.5))
if((ABS(x - m_Position.m_X) < 0.5) && (ABS(y - m_Position.m_Y) < 0.5))
{
if(ABS(z-z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving))
z_pos = z;
if(ABS(z-m_Position.m_Z) <= RuleR(Map, FixPathingZMaxDeltaMoving))
m_Position.m_Z = z;
else
z_pos = newz + 1;
m_Position.m_Z = newz + 1;
}
else
z_pos = newz + 1;
m_Position.m_Z = newz + 1;
}
}
}
@ -596,28 +582,26 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
} else {
tar_ndx=0;
}
tarx=x;
tary=y;
tarz=z;
m_TargetLocation = xyz_location(x, y, z);
float nx = this->x_pos;
float ny = this->y_pos;
float nz = this->z_pos;
float nx = this->m_Position.m_X;
float ny = this->m_Position.m_Y;
float nz = this->m_Position.m_Z;
// float nh = this->heading;
tar_vx = x - nx;
tar_vy = y - ny;
tar_vz = z - nz;
m_TargetV.m_X = x - nx;
m_TargetV.m_Y = y - ny;
m_TargetV.m_Z = z - nz;
//pRunAnimSpeed = (int8)(speed*NPC_RUNANIM_RATIO);
//speed *= NPC_SPEED_MULTIPLIER;
mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), new vector (%.3f, %.3f, %.3f) rate %.3f, RAS %d", x, y, z, tar_vx, tar_vy, tar_vz, speed, pRunAnimSpeed);
mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), new vector (%.3f, %.3f, %.3f) rate %.3f, RAS %d", x, y, z, m_TargetV.m_X, m_TargetV.m_Y, m_TargetV.m_Z, speed, pRunAnimSpeed);
// --------------------------------------------------------------------------
// 2: get unit vector
// --------------------------------------------------------------------------
float mag = sqrtf (tar_vx*tar_vx + tar_vy*tar_vy + tar_vz*tar_vz);
float mag = sqrtf (m_TargetV.m_X*m_TargetV.m_X + m_TargetV.m_Y*m_TargetV.m_Y + m_TargetV.m_Z*m_TargetV.m_Z);
tar_vector = speed / mag;
// mob move fix
@ -630,24 +614,24 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
{
if (numsteps>1)
{
tar_vector=1.0f ;
tar_vx = tar_vx/numsteps;
tar_vy = tar_vy/numsteps;
tar_vz = tar_vz/numsteps;
tar_vector=1.0f ;
m_TargetV.m_X = m_TargetV.m_X/numsteps;
m_TargetV.m_Y = m_TargetV.m_Y/numsteps;
m_TargetV.m_Z = m_TargetV.m_Z/numsteps;
float new_x = x_pos + tar_vx;
float new_y = y_pos + tar_vy;
float new_z = z_pos + tar_vz;
float new_x = m_Position.m_X + m_TargetV.m_X;
float new_y = m_Position.m_Y + m_TargetV.m_Y;
float new_z = m_Position.m_Z + m_TargetV.m_Z;
if(IsNPC()) {
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
}
x_pos = new_x;
y_pos = new_y;
z_pos = new_z;
m_Position.m_X = new_x;
m_Position.m_Y = new_y;
m_Position.m_Z = new_z;
m_Position.m_Heading = CalculateHeadingToTarget(x, y);
tar_ndx=22-numsteps;
heading = CalculateHeadingToTarget(x, y);
mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", x_pos, y_pos, z_pos, numsteps);
mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.m_X, m_Position.m_Y, m_Position.m_Z, numsteps);
}
else
{
@ -655,9 +639,9 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
entity_list.ProcessMove(CastToNPC(), x, y, z);
}
x_pos = x;
y_pos = y;
z_pos = z;
m_Position.m_X = x;
m_Position.m_Y = y;
m_Position.m_Z = z;
mlog(AI__WAYPOINTS, "Only a single step to get there... jumping.");
@ -667,18 +651,18 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
else {
tar_vector/=20;
float new_x = x_pos + tar_vx*tar_vector;
float new_y = y_pos + tar_vy*tar_vector;
float new_z = z_pos + tar_vz*tar_vector;
float new_x = m_Position.m_X + m_TargetV.m_X*tar_vector;
float new_y = m_Position.m_Y + m_TargetV.m_Y*tar_vector;
float new_z = m_Position.m_Z + m_TargetV.m_Z*tar_vector;
if(IsNPC()) {
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
}
x_pos = new_x;
y_pos = new_y;
z_pos = new_z;
heading = CalculateHeadingToTarget(x, y);
mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", x_pos, y_pos, z_pos, numsteps);
m_Position.m_X = new_x;
m_Position.m_Y = new_y;
m_Position.m_Z = new_z;
m_Position.m_Heading = CalculateHeadingToTarget(x, y);
mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.m_X, m_Position.m_Y, m_Position.m_Z, numsteps);
}
uint8 NPCFlyMode = 0;
@ -692,25 +676,25 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) {
if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
(zone->HasWaterMap() && !zone->watermap->InWater(m_Position)))
{
Map::Vertex dest(x_pos, y_pos, z_pos);
Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z);
float newz = zone->zonemap->FindBestZ(dest, nullptr);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z);
if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
{
if(ABS(x - x_pos) < 0.5 && ABS(y - y_pos) < 0.5)
if(ABS(x - m_Position.m_X) < 0.5 && ABS(y - m_Position.m_Y) < 0.5)
{
if(ABS(z - z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving))
z_pos = z;
if(ABS(z - m_Position.m_Z) <= RuleR(Map, FixPathingZMaxDeltaMoving))
m_Position.m_Z = z;
else
z_pos = newz + 1;
m_Position.m_Z = newz + 1;
}
else
z_pos = newz+1;
m_Position.m_Z = newz+1;
}
}
}
@ -718,10 +702,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
SetMoving(true);
moved=true;
delta_x=x_pos-nx;
delta_y=y_pos-ny;
delta_z=z_pos-nz;
delta_heading=0;
m_Delta = xyz_heading(m_Position.m_X - nx, m_Position.m_Y - ny, m_Position.m_Z - nz, 0.0f);
if (IsClient())
SendPosUpdate(1);
@ -746,9 +727,9 @@ bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool chec
if(GetID()==0)
return true;
float nx = x_pos;
float ny = y_pos;
float nz = z_pos;
float nx = m_Position.m_X;
float ny = m_Position.m_Y;
float nz = m_Position.m_Z;
// if NPC is rooted
if (speed == 0.0) {
@ -764,46 +745,46 @@ bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool chec
}
float old_test_vector=test_vector;
tar_vx = x - nx;
tar_vy = y - ny;
tar_vz = z - nz;
m_TargetV.m_X = x - nx;
m_TargetV.m_Y = y - ny;
m_TargetV.m_Z = z - nz;
if (tar_vx == 0 && tar_vy == 0)
if (m_TargetV.m_X == 0 && m_TargetV.m_Y == 0)
return false;
pRunAnimSpeed = (uint8)(speed*NPC_RUNANIM_RATIO);
speed *= NPC_SPEED_MULTIPLIER;
mlog(AI__WAYPOINTS, "Calculating new position to (%.3f, %.3f, %.3f) vector (%.3f, %.3f, %.3f) rate %.3f RAS %d", x, y, z, tar_vx, tar_vy, tar_vz, speed, pRunAnimSpeed);
mlog(AI__WAYPOINTS, "Calculating new position to (%.3f, %.3f, %.3f) vector (%.3f, %.3f, %.3f) rate %.3f RAS %d", x, y, z, m_TargetV.m_X, m_TargetV.m_Y, m_TargetV.m_Z, speed, pRunAnimSpeed);
// --------------------------------------------------------------------------
// 2: get unit vector
// --------------------------------------------------------------------------
test_vector=sqrtf (x*x + y*y + z*z);
tar_vector = speed / sqrtf (tar_vx*tar_vx + tar_vy*tar_vy + tar_vz*tar_vz);
heading = CalculateHeadingToTarget(x, y);
tar_vector = speed / sqrtf (m_TargetV.m_X*m_TargetV.m_X + m_TargetV.m_Y*m_TargetV.m_Y + m_TargetV.m_Z*m_TargetV.m_Z);
m_Position.m_Heading = CalculateHeadingToTarget(x, y);
if (tar_vector >= 1.0) {
if(IsNPC()) {
entity_list.ProcessMove(CastToNPC(), x, y, z);
}
x_pos = x;
y_pos = y;
z_pos = z;
m_Position.m_X = x;
m_Position.m_Y = y;
m_Position.m_Z = z;
mlog(AI__WAYPOINTS, "Close enough, jumping to waypoint");
}
else {
float new_x = x_pos + tar_vx*tar_vector;
float new_y = y_pos + tar_vy*tar_vector;
float new_z = z_pos + tar_vz*tar_vector;
float new_x = m_Position.m_X + m_TargetV.m_X*tar_vector;
float new_y = m_Position.m_Y + m_TargetV.m_Y*tar_vector;
float new_z = m_Position.m_Z + m_TargetV.m_Z*tar_vector;
if(IsNPC()) {
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
}
x_pos = new_x;
y_pos = new_y;
z_pos = new_z;
mlog(AI__WAYPOINTS, "Next position (%.3f, %.3f, %.3f)", x_pos, y_pos, z_pos);
m_Position.m_X = new_x;
m_Position.m_Y = new_y;
m_Position.m_Z = new_z;
mlog(AI__WAYPOINTS, "Next position (%.3f, %.3f, %.3f)", m_Position.m_X, m_Position.m_Y, m_Position.m_Z);
}
uint8 NPCFlyMode = 0;
@ -817,25 +798,25 @@ bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool chec
if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving))
{
if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
(zone->HasWaterMap() && !zone->watermap->InWater(m_Position)))
{
Map::Vertex dest(x_pos, y_pos, z_pos);
Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z);
float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f;
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z);
if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
{
if(ABS(x - x_pos) < 0.5 && ABS(y - y_pos) < 0.5)
if(ABS(x - m_Position.m_X) < 0.5 && ABS(y - m_Position.m_Y) < 0.5)
{
if(ABS(z - z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving))
z_pos = z;
if(ABS(z - m_Position.m_Z) <= RuleR(Map, FixPathingZMaxDeltaMoving))
m_Position.m_Z = z;
else
z_pos = newz + 1;
m_Position.m_Z = newz + 1;
}
else
z_pos = newz+1;
m_Position.m_Z = newz+1;
}
}
}
@ -845,10 +826,7 @@ bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool chec
tar_ndx=0;
this->SetMoving(true);
moved=true;
delta_x=(x_pos-nx);
delta_y=(y_pos-ny);
delta_z=(z_pos-nz);
delta_heading=0;//(heading-nh)*8;
m_Delta = xyz_heading(m_Position.m_X - nx, m_Position.m_Y - ny, m_Position.m_Z - nz, 0.0f);
SendPosUpdate();
}
tar_ndx++;
@ -914,8 +892,9 @@ void NPC::AssignWaypoints(int32 grid) {
if(zone->HasMap() && RuleB(Map, FixPathingZWhenLoading) )
{
auto positon = xyz_location(newwp.x,newwp.y,newwp.z);
if(!RuleB(Watermap, CheckWaypointsInWaterWhenLoading) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(newwp.x, newwp.y, newwp.z)))
(zone->HasWaterMap() && !zone->watermap->InWater(positon)))
{
Map::Vertex dest(newwp.x, newwp.y, newwp.z);
@ -948,9 +927,9 @@ void Mob::SendTo(float new_x, float new_y, float new_z) {
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
}
x_pos = new_x;
y_pos = new_y;
z_pos = new_z;
m_Position.m_X = new_x;
m_Position.m_Y = new_y;
m_Position.m_Z = new_z;
mlog(AI__WAYPOINTS, "Sent To (%.3f, %.3f, %.3f)", new_x, new_y, new_z);
if(flymode == FlyMode1)
@ -961,20 +940,20 @@ void Mob::SendTo(float new_x, float new_y, float new_z) {
if(zone->HasMap() && RuleB(Map, FixPathingZOnSendTo) )
{
if(!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
(zone->HasWaterMap() && !zone->watermap->InWater(m_Position)))
{
Map::Vertex dest(x_pos, y_pos, z_pos);
Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z);
float newz = zone->zonemap->FindBestZ(dest, nullptr);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z);
if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaSendTo)) // Sanity check.
z_pos = newz + 1;
m_Position.m_Z = newz + 1;
}
}
else
z_pos += 0.1;
m_Position.m_Z += 0.1;
}
void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
@ -982,9 +961,9 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z + 0.1);
}
x_pos = new_x;
y_pos = new_y;
z_pos = new_z + 0.1;
m_Position.m_X = new_x;
m_Position.m_Y = new_y;
m_Position.m_Z = new_z + 0.1;
//fix up pathing Z, this shouldent be needed IF our waypoints
//are corrected instead
@ -992,16 +971,16 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
if(zone->HasMap() && RuleB(Map, FixPathingZOnSendTo))
{
if(!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
(zone->HasWaterMap() && !zone->watermap->InWater(m_Position)))
{
Map::Vertex dest(x_pos, y_pos, z_pos);
Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z);
float newz = zone->zonemap->FindBestZ(dest, nullptr);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z);
if( (newz > -2000) && ABS(newz-dest.z) < RuleR(Map, FixPathingZMaxDeltaSendTo)) // Sanity check.
z_pos = newz + 1;
m_Position.m_Z = newz + 1;
}
}
}
@ -1067,15 +1046,14 @@ bool ZoneDatabase::GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist*
return true;
}
void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid)
void ZoneDatabase::AssignGrid(Client *client, const xy_location& location, uint32 grid)
{
int matches = 0, fuzzy = 0, spawn2id = 0;
float dbx = 0, dby = 0;
// looks like most of the stuff in spawn2 is straight integers
// so let's try that first
std::string query = StringFormat("SELECT id, x, y FROM spawn2 WHERE zone = '%s' AND x = %i AND y = %i",
zone->GetShortName(), (int)x, (int)y);
zone->GetShortName(), (int)location.m_X, (int)location.m_Y);
auto results = QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEmuLog::Error, "Error querying spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
@ -1089,7 +1067,7 @@ void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid)
query = StringFormat("SELECT id,x,y FROM spawn2 WHERE zone='%s' AND "
"ABS( ABS(x) - ABS(%f) ) < %f AND "
"ABS( ABS(y) - ABS(%f) ) < %f",
zone->GetShortName(), x, _GASSIGN_TOLERANCE, y, _GASSIGN_TOLERANCE);
zone->GetShortName(), location.m_X, _GASSIGN_TOLERANCE, location.m_Y, _GASSIGN_TOLERANCE);
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEmuLog::Error, "Error querying fuzzy spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
@ -1115,8 +1093,7 @@ void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid)
auto row = results.begin();
spawn2id = atoi(row[0]);
dbx = atof(row[1]);
dby = atof(row[2]);
xy_location dbLocation = xy_location(atof(row[1]), atof(row[2]));
query = StringFormat("UPDATE spawn2 SET pathgrid = %d WHERE id = %d", grid, spawn2id);
results = QueryDatabase(query);
@ -1141,7 +1118,7 @@ void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid)
return;
}
float difference = sqrtf(pow(fabs(x - dbx) , 2) + pow(fabs(y - dby), 2));
float difference = sqrtf(pow(fabs(location.m_X - dbLocation.m_X) , 2) + pow(fabs(location.m_Y - dbLocation.m_Y), 2));
client->Message(0, "Grid assign: spawn2 id = %d updated - fuzzy match: deviation %f", spawn2id, difference);
}
@ -1189,11 +1166,11 @@ void ZoneDatabase::ModifyGrid(Client *client, bool remove, uint32 id, uint8 type
/**************************************
* AddWP - Adds a new waypoint to a specific grid for a specific zone.
*/
void ZoneDatabase::AddWP(Client *client, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading)
void ZoneDatabase::AddWP(Client *client, uint32 gridid, uint32 wpnum, const xyz_heading& position, uint32 pause, uint16 zoneid)
{
std::string query = StringFormat("INSERT INTO grid_entries (gridid, zoneid, `number`, x, y, z, pause, heading) "
"VALUES (%i, %i, %i, %f, %f, %f, %i, %f)",
gridid, zoneid, wpnum, xpos, ypos, zpos, pause, heading);
gridid, zoneid, wpnum, position.m_X, position.m_Y, position.m_Z, pause, position.m_Heading);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEmuLog::Error, "Error adding waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
@ -1238,7 +1215,7 @@ void ZoneDatabase::DeleteWaypoint(Client *client, uint32 grid_num, uint32 wp_num
* Returns 0 if the function didn't have to create a new grid. If the function had to create a new grid for the spawn, then the ID of
* the created grid is returned.
*/
uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading) {
uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, const xyz_heading& position, uint32 pause, int type1, int type2, uint16 zoneid) {
uint32 grid_num; // The grid number the spawn is assigned to (if spawn has no grid, will be the grid number we end up creating)
uint32 next_wp_num; // The waypoint number we should be assigning to the new waypoint
@ -1301,7 +1278,7 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos,
query = StringFormat("INSERT INTO grid_entries(gridid, zoneid, `number`, x, y, z, pause, heading) "
"VALUES (%i, %i, %i, %f, %f, %f, %i, %f)",
grid_num, zoneid, next_wp_num, xpos, ypos, zpos, pause, heading);
grid_num, zoneid, next_wp_num, position.m_X, position.m_Y, position.m_Z, pause, position.m_Heading);
results = QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEmuLog::Error, "Error adding grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
@ -1349,16 +1326,10 @@ int ZoneDatabase::GetHighestWaypoint(uint32 zoneid, uint32 gridid) {
void NPC::SaveGuardSpotCharm()
{
guard_x_saved = guard_x;
guard_y_saved = guard_y;
guard_z_saved = guard_z;
guard_heading_saved = guard_heading;
m_GuardPointSaved = m_GuardPoint;
}
void NPC::RestoreGuardSpotCharm()
{
guard_x = guard_x_saved;
guard_y = guard_y_saved;
guard_z = guard_z_saved;
guard_heading = guard_heading_saved;
m_GuardPoint = m_GuardPointSaved;
}

View File

@ -97,7 +97,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
}
zone->zonemap = Map::LoadMapFile(zone->map_name);
zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name);
zone->pathing = PathManager::LoadPathFile(zone->map_name);
zone->pathing = PathManager::LoadPathFile(zone->map_name);
char tmp[10];
if (database.GetVariable("loglevel",tmp, 9)) {
@ -482,14 +482,14 @@ void Zone::GetMerchantDataForZoneLoad() {
"WHERE nt.merchant_id = ml.merchantid AND nt.id = se.npcid "
"AND se.spawngroupid = s2.spawngroupid AND s2.zone = '%s' AND s2.version = %i "
"ORDER BY ml.slot ", GetShortName(), GetInstanceVersion());
auto results = database.QueryDatabase(query);
auto results = database.QueryDatabase(query);
std::map<uint32, std::list<MerchantList> >::iterator cur;
uint32 npcid = 0;
if (results.RowCount() == 0) {
LogFile->write(EQEmuLog::Debug, "No Merchant Data found for %s.", GetShortName());
return;
}
for (auto row = results.begin(); row != results.end(); ++row) {
for (auto row = results.begin(); row != results.end(); ++row) {
MerchantList ml;
ml.id = atoul(row[0]);
if (npcid != ml.id) {
@ -736,7 +736,9 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
clientauth_timer(AUTHENTICATION_TIMEOUT * 1000),
spawn2_timer(1000),
qglobal_purge_timer(30000),
hotzone_timer(120000)
hotzone_timer(120000),
m_SafePoint(0.0f,0.0f,0.0f),
m_Graveyard(0.0f,0.0f,0.0f,0.0f)
{
zoneid = in_zoneid;
instanceid = in_instanceid;
@ -762,28 +764,20 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
memset(file_name, 0, sizeof(file_name));
long_name = 0;
aggroedmobs =0;
psafe_x = 0;
psafe_y = 0;
psafe_z = 0;
pgraveyard_id = 0;
pgraveyard_zoneid = 0;
pgraveyard_x = 0;
pgraveyard_y = 0;
pgraveyard_z = 0;
pgraveyard_heading = 0;
pMaxClients = 0;
pQueuedMerchantsWorkID = 0;
pvpzone = false;
if(database.GetServerType() == 1)
pvpzone = true;
database.GetZoneLongName(short_name, &long_name, file_name, &psafe_x, &psafe_y, &psafe_z, &pgraveyard_id, &pMaxClients);
database.GetZoneLongName(short_name, &long_name, file_name, &m_SafePoint.m_X, &m_SafePoint.m_Y, &m_SafePoint.m_Z, &pgraveyard_id, &pMaxClients);
if(graveyard_id() > 0)
{
LogFile->write(EQEmuLog::Debug, "Graveyard ID is %i.", graveyard_id());
bool GraveYardLoaded = database.GetZoneGraveyard(graveyard_id(), &pgraveyard_zoneid, &pgraveyard_x, &pgraveyard_y, &pgraveyard_z, &pgraveyard_heading);
bool GraveYardLoaded = database.GetZoneGraveyard(graveyard_id(), &pgraveyard_zoneid, &m_Graveyard.m_X, &m_Graveyard.m_Y, &m_Graveyard.m_Z, &m_Graveyard.m_Heading);
if(GraveYardLoaded)
LogFile->write(EQEmuLog::Debug, "Loaded a graveyard for zone %s: graveyard zoneid is %u x is %f y is %f z is %f heading is %f.", short_name, graveyard_zoneid(), graveyard_x(), graveyard_y(), graveyard_z(), graveyard_heading());
LogFile->write(EQEmuLog::Debug, "Loaded a graveyard for zone %s: graveyard zoneid is %u at %s.", short_name, graveyard_zoneid(), to_string(m_Graveyard).c_str());
else
LogFile->write(EQEmuLog::Error, "Unable to load the graveyard id %i for zone %s.", graveyard_id(), short_name);
}
@ -1520,7 +1514,7 @@ void Zone::SetTime(uint8 hour, uint8 minute)
}
}
ZonePoint* Zone::GetClosestZonePoint(float x, float y, float z, uint32 to, Client* client, float max_distance) {
ZonePoint* Zone::GetClosestZonePoint(const xyz_location& location, uint32 to, Client* client, float max_distance) {
LinkedListIterator<ZonePoint*> iterator(zone_point_list);
ZonePoint* closest_zp = 0;
float closest_dist = FLT_MAX;
@ -1538,14 +1532,10 @@ ZonePoint* Zone::GetClosestZonePoint(float x, float y, float z, uint32 to, Clien
if (zp->target_zone_id == to)
{
float delta_x = zp->x - x;
float delta_y = zp->y - y;
if(zp->x == 999999 || zp->x == -999999)
delta_x = 0;
if(zp->y == 999999 || zp->y == -999999)
delta_y = 0;
auto dist = Distance(xy_location(zp->x,zp->y), location);
if ((zp->x == 999999 || zp->x == -999999) && (zp->y == 999999 || zp->y == -999999))
dist = 0;
float dist = sqrt(delta_x * delta_x + delta_y * delta_y);
if (dist < closest_dist)
{
closest_zp = zp;
@ -1558,24 +1548,24 @@ ZonePoint* Zone::GetClosestZonePoint(float x, float y, float z, uint32 to, Clien
if(closest_dist > 400.0f && closest_dist < max_distance2)
{
if(client)
client->CheatDetected(MQZoneUnknownDest, x, y, z); // Someone is trying to use /zone
client->CheatDetected(MQZoneUnknownDest, location.m_X, location.m_Y, location.m_Z); // Someone is trying to use /zone
LogFile->write(EQEmuLog::Status, "WARNING: Closest zone point for zone id %d is %f, you might need to update your zone_points table if you dont arrive at the right spot.", to, closest_dist);
LogFile->write(EQEmuLog::Status, "<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)
closest_zp = nullptr;
if(!closest_zp)
closest_zp = GetClosestZonePointWithoutZone(x, y, z, client);
closest_zp = GetClosestZonePointWithoutZone(location.m_X, location.m_Y, location.m_Z, client);
return closest_zp;
}
ZonePoint* Zone::GetClosestZonePoint(float x, float y, float z, const char* to_name, Client* client, float max_distance) {
ZonePoint* Zone::GetClosestZonePoint(const xyz_location& location, const char* to_name, Client* client, float max_distance) {
if(to_name == nullptr)
return GetClosestZonePointWithoutZone(x,y,z, client, max_distance);
return GetClosestZonePoint(x, y, z, database.GetZoneID(to_name), client, max_distance);
return GetClosestZonePointWithoutZone(location.m_X, location.m_Y, location.m_Z, client, max_distance);
return GetClosestZonePoint(location, database.GetZoneID(to_name), client, max_distance);
}
ZonePoint* Zone::GetClosestZonePointWithoutZone(float x, float y, float z, Client* client, float max_distance) {
@ -1823,12 +1813,9 @@ bool Zone::HasGraveyard() {
return Result;
}
void Zone::SetGraveyard(uint32 zoneid, uint32 x, uint32 y, uint32 z, uint32 heading) {
void Zone::SetGraveyard(uint32 zoneid, const xyz_heading& graveyardPosition) {
pgraveyard_zoneid = zoneid;
pgraveyard_x = x;
pgraveyard_y = y;
pgraveyard_z = z;
pgraveyard_heading = heading;
m_Graveyard = graveyardPosition;
}
void Zone::LoadBlockedSpells(uint32 zoneid)
@ -1855,7 +1842,7 @@ void Zone::ClearBlockedSpells()
}
}
bool Zone::IsSpellBlocked(uint32 spell_id, float nx, float ny, float nz)
bool Zone::IsSpellBlocked(uint32 spell_id, const xyz_location& location)
{
if (blocked_spells)
{
@ -1905,12 +1892,8 @@ bool Zone::IsSpellBlocked(uint32 spell_id, float nx, float ny, float nz)
}
case 2:
{
if ((( nx >= (blocked_spells[x].x-blocked_spells[x].xdiff)) && (nx <= (blocked_spells[x].x+blocked_spells[x].xdiff))) &&
(( ny >= (blocked_spells[x].y-blocked_spells[x].ydiff)) && (ny <= (blocked_spells[x].y+blocked_spells[x].ydiff))) &&
(( nz >= (blocked_spells[x].z-blocked_spells[x].zdiff)) && (nz <= (blocked_spells[x].z+blocked_spells[x].zdiff))))
{
if (!IsWithinAxisAlignedBox(location, blocked_spells[x].m_Location - blocked_spells[x].m_Difference, blocked_spells[x].m_Location + blocked_spells[x].m_Difference))
return true;
}
break;
}
default:
@ -1925,7 +1908,7 @@ bool Zone::IsSpellBlocked(uint32 spell_id, float nx, float ny, float nz)
return false;
}
const char* Zone::GetSpellBlockedMessage(uint32 spell_id, float nx, float ny, float nz)
const char* Zone::GetSpellBlockedMessage(uint32 spell_id, const xyz_location& location)
{
if(blocked_spells)
{
@ -1943,12 +1926,8 @@ const char* Zone::GetSpellBlockedMessage(uint32 spell_id, float nx, float ny, fl
}
case 2:
{
if((( nx > (blocked_spells[x].x-blocked_spells[x].xdiff)) && (nx < (blocked_spells[x].x+blocked_spells[x].xdiff))) &&
(( ny > (blocked_spells[x].y-blocked_spells[x].ydiff)) && (ny < (blocked_spells[x].y+blocked_spells[x].ydiff))) &&
(( nz > (blocked_spells[x].z-blocked_spells[x].zdiff)) && (nz < (blocked_spells[x].z+blocked_spells[x].zdiff))))
{
if(!IsWithinAxisAlignedBox(location, blocked_spells[x].m_Location - blocked_spells[x].m_Difference, blocked_spells[x].m_Location + blocked_spells[x].m_Difference))
return blocked_spells[x].message;
}
break;
}
default:
@ -2185,7 +2164,7 @@ void Zone::DoAdventureActions()
const NPCType* tmp = database.GetNPCType(ds->data_id);
if(tmp)
{
NPC* npc = new NPC(tmp, 0, ds->assa_x, ds->assa_y, ds->assa_z, ds->assa_h, FlyMode3);
NPC* npc = new NPC(tmp, nullptr, xyz_heading(ds->assa_x, ds->assa_y, ds->assa_z, ds->assa_h), FlyMode3);
npc->AddLootTable();
entity_list.AddNPC(npc);
npc->Shout("Rarrrgh!");

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
#include "../common/shareddb.h"
#include "../common/eq_packet_structs.h"
#include "position.h"
#include "../common/faction.h"
class Client;
@ -129,12 +130,8 @@ struct PetInfo {
struct ZoneSpellsBlocked {
uint32 spellid;
int8 type;
float x;
float y;
float z;
float xdiff;
float ydiff;
float zdiff;
xyz_location m_Location;
xyz_location m_Difference;
char message[256];
};
@ -235,7 +232,7 @@ public:
/* Traders */
void SaveTraderItem(uint32 char_id,uint32 itemid,uint32 uniqueid, int32 charges,uint32 itemcost,uint8 slot);
void UpdateTraderItemCharges(int char_id, uint32 ItemInstID, int32 charges);
void UpdateTraderItemPrice(int CharID, uint32 ItemID, uint32 Charges, uint32 NewPrice);
void UpdateTraderItemPrice(int CharID, uint32 ItemID, uint32 Charges, uint32 NewPrice);
void DeleteTraderItem(uint32 char_id);
void DeleteTraderItem(uint32 char_id,uint16 slot_id);
@ -276,7 +273,7 @@ public:
bool LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp);
/* Character Data Saves */
bool SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, float x, float y, float z, float heading, uint8 is_home);
bool SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, const xyz_heading& position, uint8 is_home);
bool SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
bool SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp);
bool SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level);
@ -308,24 +305,24 @@ public:
uint32 GetCharacterCorpseItemCount(uint32 corpse_id);
bool LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs);
Corpse* LoadCharacterCorpse(uint32 player_corpse_id);
Corpse* SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading);
Corpse* SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, const xyz_heading& position);
void MarkCorpseAsRezzed(uint32 dbid);
bool GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes);
bool GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes);
bool BuryCharacterCorpse(uint32 dbid);
bool BuryAllCharacterCorpses(uint32 charid);
bool DeleteCharacterCorpse(uint32 dbid);
bool SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading);
bool SummonAllGraveyardCorpses(uint32 cur_zoneid, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading);
bool UnburyCharacterCorpse(uint32 dbid, uint32 new_zoneid, uint16 dest_instanceid, float new_x, float new_y, float new_z, float new_heading);
bool LoadCharacterCorpses(uint32 iZoneID, uint16 iInstanceID);
bool DeleteCharacterCorpse(uint32 dbid);
bool SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, const xyz_heading& position);
bool SummonAllGraveyardCorpses(uint32 cur_zoneid, uint32 dest_zoneid, uint16 dest_instanceid, const xyz_heading& position);
bool UnburyCharacterCorpse(uint32 dbid, uint32 new_zoneid, uint16 dest_instanceid, const xyz_heading& position);
bool LoadCharacterCorpses(uint32 iZoneID, uint16 iInstanceID);
bool DeleteGraveyard(uint32 zone_id, uint32 graveyard_id);
uint32 GetCharacterCorpseDecayTimer(uint32 corpse_db_id);
uint32 GetCharacterBuriedCorpseCount(uint32 char_id);
uint32 SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zoneid, uint16 instanceid, float x, float y, float z, float heading);
uint32 CreateGraveyardRecord(uint32 graveyard_zoneid, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading);
uint32 SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zoneid, uint16 instanceid, const xyz_heading& position);
uint32 CreateGraveyardRecord(uint32 graveyard_zoneid, const xyz_heading& position);
uint32 AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id);
uint32 SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading);
uint32 UpdateCharacterCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading, bool rezzed = false);
uint32 SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const xyz_heading& position);
uint32 UpdateCharacterCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const xyz_heading& position, bool rezzed = false);
uint32 GetFirstCorpseID(uint32 char_id);
uint32 GetCharacterCorpseCount(uint32 char_id);
uint32 GetCharacterCorpseID(uint32 char_id, uint8 corpse);
@ -356,7 +353,7 @@ public:
bool GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct *data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city, bool &is_hotzone, bool &allow_mercs, uint8 &zone_type, int &ruleset, char **map_filename);
bool SaveZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct* zd);
bool LoadStaticZonePoints(LinkedList<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();
int getZoneShutDownDelay(uint32 zoneID, uint32 version);
@ -365,7 +362,7 @@ public:
bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list);
bool PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay = 0);
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);
uint32 GetSpawnTimeLeft(uint32 id, uint16 instance_id);
void UpdateSpawn2Status(uint32 id, uint8 new_status);
@ -374,19 +371,19 @@ public:
uint32 GetFreeGrid(uint16 zoneid);
void DeleteGrid(Client *c, uint32 sg2, uint32 grid_num, bool grid_too, uint16 zoneid);
void DeleteWaypoint(Client *c, uint32 grid_num, uint32 wp_num, uint16 zoneid);
void AddWP(Client *c, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading);
uint32 AddWPForSpawn(Client *c, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading);
void AddWP(Client *c, uint32 gridid, uint32 wpnum, const xyz_heading& position, uint32 pause, uint16 zoneid);
uint32 AddWPForSpawn(Client *c, uint32 spawn2id, const xyz_heading& position, uint32 pause, int type1, int type2, uint16 zoneid);
void ModifyGrid(Client *c, bool remove, uint32 id, uint8 type = 0, uint8 type2 = 0, uint16 zoneid = 0);
void ModifyWP(Client *c, uint32 grid_id, uint32 wp_num, float xpos, float ypos, float zpos, uint32 script = 0, uint16 zoneid = 0);
void ModifyWP(Client *c, uint32 grid_id, uint32 wp_num, const xyz_location& location, uint32 script = 0, uint16 zoneid = 0);
uint8 GetGridType(uint32 grid, uint32 zoneid);
uint8 GetGridType2(uint32 grid, uint16 zoneid);
bool GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp);
void AssignGrid(Client *client, float x, float y, uint32 id);
void AssignGrid(Client *client, const xy_location& location, uint32 id);
int GetHighestGrid(uint32 zoneid);
int GetHighestWaypoint(uint32 zoneid, uint32 gridid);
/* NPCs */
uint32 NPCSpawnDB(uint8 command, const char* zone, uint32 zone_version, Client *c, NPC* spawn = 0, uint32 extra = 0); // 0 = Create 1 = Add; 2 = Update; 3 = Remove; 4 = Delete
uint32 CreateNewNPCCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 extra);
uint32 AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime);
@ -453,7 +450,7 @@ public:
int32 GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version);
int32 GetDoorsCountPlusOne(const char *zone_name, int16 version);
int32 GetDoorsDBCountPlusOne(const char *zone_name, int16 version);
void InsertDoor(uint32 did, uint16 ddoorid, const char* ddoor_name, float dxpos, float dypos, float dzpos, float dheading, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize);
void InsertDoor(uint32 did, uint16 ddoorid, const char* ddoor_name, const xyz_heading& position, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize);
/* Blocked Spells */
int32 GetBlockedSpellsCount(uint32 zoneid);

View File

@ -124,7 +124,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
return;
}
zone_point = zone->GetClosestZonePoint(GetX(), GetY(), GetZ(), target_zone_id, this, ZONEPOINT_ZONE_RANGE);
zone_point = zone->GetClosestZonePoint(GetPosition(), target_zone_id, this, ZONEPOINT_ZONE_RANGE);
//if we didnt get a zone point, or its to a different zone,
//then we assume this is invalid.
if(!zone_point || zone_point->target_zone_id != target_zone_id) {
@ -198,9 +198,9 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
dest_z = safe_z;
break;
case GMSummon:
dest_x = zonesummon_x;
dest_y = zonesummon_y;
dest_z = zonesummon_z;
dest_x = m_ZoneSummonLocation.m_X;
dest_y = m_ZoneSummonLocation.m_Y;
dest_z = m_ZoneSummonLocation.m_Z;
ignorerestrictions = 1;
break;
case GateToBindPoint:
@ -216,9 +216,9 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
break;
case ZoneSolicited: //we told the client to zone somewhere, so we know where they are going.
//recycle zonesummon variables
dest_x = zonesummon_x;
dest_y = zonesummon_y;
dest_z = zonesummon_z;
dest_x = m_ZoneSummonLocation.m_X;
dest_y = m_ZoneSummonLocation.m_Y;
dest_z = m_ZoneSummonLocation.m_Z;
break;
case ZoneUnsolicited: //client came up with this on its own.
//client requested a zoning... what are the cases when this could happen?
@ -350,16 +350,16 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc
//set the player's coordinates in the new zone so they have them
//when they zone into it
x_pos = dest_x; //these coordinates will now be saved when ~client is called
y_pos = dest_y;
z_pos = dest_z;
heading = dest_h; // Cripp: fix for zone heading
m_Position.m_X = dest_x; //these coordinates will now be saved when ~client is called
m_Position.m_Y = dest_y;
m_Position.m_Z = dest_z;
m_Position.m_Heading = dest_h; // Cripp: fix for zone heading
m_pp.heading = dest_h;
m_pp.zone_id = zone_id;
m_pp.zoneInstance = instance_id;
//Force a save so its waiting for them when they zone
Save(2);
Save(2);
if (zone_id == zone->GetZoneID() && instance_id == zone->GetInstanceID()) {
// No need to ask worldserver if we're zoning to ourselves (most
@ -394,9 +394,7 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc
//reset to unsolicited.
zone_mode = ZoneUnsolicited;
zonesummon_x = 0;
zonesummon_y = 0;
zonesummon_z = 0;
m_ZoneSummonLocation = xyz_location::Origin();
zonesummon_id = 0;
zonesummon_ignorerestrictions = 0;
}
@ -493,59 +491,53 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z
return;
}
iZoneNameLength = strlen(pZoneName);
xyz_heading safePoint;
switch(zm) {
case EvacToSafeCoords:
case ZoneToSafeCoords:
x = zone->safe_x();
y = zone->safe_y();
z = zone->safe_z();
safePoint = zone->GetSafePoint();
x = safePoint.m_X;
y = safePoint.m_Y;
z = safePoint.m_Z;
SetHeading(heading);
break;
case GMSummon:
zonesummon_x = x_pos = x;
zonesummon_y = y_pos = y;
zonesummon_z = z_pos = z;
m_ZoneSummonLocation = m_Position = xyz_heading(x,y,z,heading);
SetHeading(heading);
zonesummon_id = zoneID;
zonesummon_ignorerestrictions = 1;
break;
case ZoneSolicited:
zonesummon_x = x;
zonesummon_y = y;
zonesummon_z = z;
m_ZoneSummonLocation = xyz_location(x,y,z);
SetHeading(heading);
zonesummon_id = zoneID;
zonesummon_ignorerestrictions = ignorerestrictions;
break;
case GateToBindPoint:
x = x_pos = m_pp.binds[0].x;
y = y_pos = m_pp.binds[0].y;
z = z_pos = m_pp.binds[0].z;
x = m_Position.m_X = m_pp.binds[0].x;
y = m_Position.m_Y = m_pp.binds[0].y;
z = m_Position.m_Z = m_pp.binds[0].z;
heading = m_pp.binds[0].heading;
break;
case ZoneToBindPoint:
x = x_pos = m_pp.binds[0].x;
y = y_pos = m_pp.binds[0].y;
z = z_pos = m_pp.binds[0].z;
x = m_Position.m_X = m_pp.binds[0].x;
y = m_Position.m_Y = m_pp.binds[0].y;
z = m_Position.m_Z = m_pp.binds[0].z;
heading = m_pp.binds[0].heading;
zonesummon_ignorerestrictions = 1;
LogFile->write(EQEmuLog::Debug, "Player %s has died and will be zoned to bind point in zone: %s at LOC x=%f, y=%f, z=%f, heading=%f", GetName(), pZoneName, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, m_pp.binds[0].heading);
break;
case SummonPC:
zonesummon_x = x_pos = x;
zonesummon_y = y_pos = y;
zonesummon_z = z_pos = z;
m_ZoneSummonLocation = m_Position = xyz_location(x, y, z);
SetHeading(heading);
break;
case Rewind:
LogFile->write(EQEmuLog::Debug, "%s has requested a /rewind from %f, %f, %f, to %f, %f, %f in %s", GetName(), x_pos, y_pos, z_pos, rewind_x, rewind_y, rewind_z, zone->GetShortName());
zonesummon_x = x_pos = x;
zonesummon_y = y_pos = y;
zonesummon_z = z_pos = z;
LogFile->write(EQEmuLog::Debug, "%s has requested a /rewind from %f, %f, %f, to %f, %f, %f in %s", GetName(), m_Position.m_X, m_Position.m_Y, m_Position.m_Z, m_RewindLocation.m_X, m_RewindLocation.m_Y, m_RewindLocation.m_Z, zone->GetShortName());
m_ZoneSummonLocation = m_Position = xyz_location(x, y, z);
SetHeading(heading);
break;
default:
@ -655,10 +647,8 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z
else {
if(zoneID == GetZoneID()) {
//properly handle proximities
entity_list.ProcessMove(this, x_pos, y_pos, z_pos);
proximity_x = x_pos;
proximity_y = y_pos;
proximity_z = z_pos;
entity_list.ProcessMove(this, m_Position);
m_Proximity = m_Position;
//send out updates to people in zone.
SendPosition();
@ -687,9 +677,7 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z
{
if(zm != EvacToSafeCoords && zm != ZoneToSafeCoords && zm != ZoneToBindPoint)
{
zonesummon_x = 0;
zonesummon_y = 0;
zonesummon_z = 0;
m_ZoneSummonLocation = xyz_location::Origin();
zonesummon_id = 0;
zonesummon_ignorerestrictions = 0;
zone_mode = ZoneUnsolicited;
@ -722,22 +710,23 @@ void NPC::Gate() {
Mob::Gate();
}
void Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y, float new_z) {
void Client::SetBindPoint(int to_zone, int to_instance, const xyz_location& location) {
if (to_zone == -1) {
m_pp.binds[0].zoneId = zone->GetZoneID();
m_pp.binds[0].instance_id = (zone->GetInstanceID() != 0 && zone->IsInstancePersistent()) ? zone->GetInstanceID() : 0;
m_pp.binds[0].x = x_pos;
m_pp.binds[0].y = y_pos;
m_pp.binds[0].z = z_pos;
m_pp.binds[0].x = m_Position.m_X;
m_pp.binds[0].y = m_Position.m_Y;
m_pp.binds[0].z = m_Position.m_Z;
}
else {
m_pp.binds[0].zoneId = to_zone;
m_pp.binds[0].instance_id = to_instance;
m_pp.binds[0].x = new_x;
m_pp.binds[0].y = new_y;
m_pp.binds[0].z = new_z;
m_pp.binds[0].x = location.m_X;
m_pp.binds[0].y = location.m_Y;
m_pp.binds[0].z = location.m_Z;
}
database.SaveCharacterBindPoint(this->CharacterID(), m_pp.binds[0].zoneId, m_pp.binds[0].instance_id, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0, 0);
auto regularBindPoint = xyz_heading(m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0.0f);
database.SaveCharacterBindPoint(this->CharacterID(), m_pp.binds[0].zoneId, m_pp.binds[0].instance_id, regularBindPoint, 0);
}
void Client::GoToBind(uint8 bindnum) {