Merge remote-tracking branch 'remotes/origin/master' into logging_changes

Conflicts:
	world/client.cpp
	world/worlddb.cpp
	zone/aggro.cpp
	zone/bot.cpp
	zone/client.cpp
	zone/client_packet.cpp
	zone/client_process.cpp
	zone/doors.cpp
	zone/entity.cpp
	zone/inventory.cpp
	zone/mob_ai.cpp
	zone/perl_client.cpp
	zone/spells.cpp
	zone/waypoints.cpp
	zone/zone.cpp
	zone/zonedb.cpp
	zone/zoning.cpp
This commit is contained in:
Akkadius 2015-01-21 17:29:30 -06:00
commit c5447778a6
109 changed files with 2543 additions and 2939 deletions

View File

@ -1,5 +1,11 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 01/20/2015 ==
Uleat: Fix for Inventory::_HasItemByUse(bucket) using the parent container when searching for bag container items.
== 01/19/2015 ==
Uleat: Changed 'enum EQClientVersion' to 'enum class ClientVersion.' Other light modifications were made to accommodate this namespace. Added 'RoF2' to the lua client version enumeration.
== 01/15/2015 ==
Uleat: Attempted fix for elusive inventory bug:
- Removed 'iter_queue' typedef and converted lcast to explicit or auto defines

View File

@ -19,59 +19,58 @@ static const uint32 BIT_RoFAndLater = 0xFFFFFFE0;
static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0;
static const uint32 BIT_AllClients = 0xFFFFFFFF;
typedef enum
enum class ClientVersion
{
EQClientUnknown = 0,
EQClient62, // Build: 'Aug 4 2005 15:40:59'
EQClientTitanium, // Build: 'Oct 31 2005 10:33:37'
EQClientSoF, // Build: 'Sep 7 2007 09:11:49'
EQClientSoD, // Build: 'Dec 19 2008 15:22:49'
EQClientUnderfoot, // Build: 'Jun 8 2010 16:44:32'
EQClientRoF, // Build: 'Dec 10 2012 17:35:44'
EQClientRoF2, // Build: 'May 10 2013 23:30:08'
Unknown = 0,
Client62, // Build: 'Aug 4 2005 15:40:59'
Tit, // Build: 'Oct 31 2005 10:33:37'
SoF, // Build: 'Sep 7 2007 09:11:49'
SoD, // Build: 'Dec 19 2008 15:22:49'
Und, // Build: 'Jun 8 2010 16:44:32'
RoF, // Build: 'Dec 10 2012 17:35:44'
RoF2, // Build: 'May 10 2013 23:30:08'
_EQClientCount, // place new clients before this point (preferably, in release/attribute order)
MobNPC,
MobMerc,
MobBot,
MobPet,
};
// Values below are not implemented, as yet...
#define CLIENT_VERSION_COUNT 12
#define LAST_PC_CLIENT ClientVersion::RoF2
#define LAST_NPC_CLIENT ClientVersion::MobPet
EmuNPC = _EQClientCount,
EmuMerc,
EmuBot,
EmuPet,
_EmuClientCount // array size for EQLimits
} EQClientVersion;
static const char* EQClientVersionName(EQClientVersion version)
static const char* ClientVersionName(ClientVersion version)
{
switch (version)
{
case EQClientUnknown:
return "EQClientUnknown";
case EQClient62:
return "EQClient62";
case EQClientTitanium:
return "EQClientTitanium";
case EQClientSoF:
return "EQClientSoF";
case EQClientSoD:
return "EQClientSoD";
case EQClientUnderfoot:
return "EQClientUnderfoot";
case EQClientRoF:
return "EQClientRoF";
case EQClientRoF2:
return "EQClientRoF2";
case EmuNPC:
return "EmuNPC";
case EmuMerc:
return "EmuMerc";
case EmuBot:
return "EmuBot";
case EmuPet:
return "EmuPet";
case ClientVersion::Unknown:
return "ClientVersion::Unknown";
case ClientVersion::Client62:
return "ClientVersion::Client62";
case ClientVersion::Tit:
return "ClientVersion::Tit";
case ClientVersion::SoF:
return "ClientVersion::SoF";
case ClientVersion::SoD:
return "ClientVersion::SoD";
case ClientVersion::Und:
return "ClientVersion::Und";
case ClientVersion::RoF:
return "ClientVersion::RoF";
case ClientVersion::RoF2:
return "ClientVersion::RoF2";
case ClientVersion::MobNPC:
return "ClientVersion::MobNPC";
case ClientVersion::MobMerc:
return "ClientVersion::MobMerc";
case ClientVersion::MobBot:
return "ClientVersion::MobBot";
case ClientVersion::MobPet:
return "ClientVersion::MobPet";
default:
return "ERROR: Invalid EQClientVersion";
return "<ERROR> Invalid ClientVersion";
};
}

View File

@ -25,8 +25,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// class EmuConstants
//
uint16 EmuConstants::InventoryMapSize(int16 map) {
switch (map) {
uint16 EmuConstants::InventoryMapSize(int16 indexMap) {
switch (indexMap) {
case MapPossessions:
return MAP_POSSESSIONS_SIZE;
case MapBank:
@ -91,8 +91,8 @@ std::string EmuConstants::InventoryLocationName(Location_Struct location) {
}
*/
std::string EmuConstants::InventoryMapName(int16 map) {
switch (map) {
std::string EmuConstants::InventoryMapName(int16 indexMap) {
switch (indexMap) {
case INVALID_INDEX:
return "Invalid Map";
case MapPossessions:
@ -150,8 +150,8 @@ std::string EmuConstants::InventoryMapName(int16 map) {
}
}
std::string EmuConstants::InventoryMainName(int16 main) {
switch (main) {
std::string EmuConstants::InventoryMainName(int16 indexMain) {
switch (indexMain) {
case INVALID_INDEX:
return "Invalid Main";
case MainCharm:
@ -229,293 +229,83 @@ std::string EmuConstants::InventoryMainName(int16 main) {
}
}
std::string EmuConstants::InventorySubName(int16 sub) {
if (sub == INVALID_INDEX)
std::string EmuConstants::InventorySubName(int16 indexSub) {
if (indexSub == INVALID_INDEX)
return "Invalid Sub";
if ((uint16)sub >= ITEM_CONTAINER_SIZE)
if ((uint16)indexSub >= ITEM_CONTAINER_SIZE)
return "Unknown Sub";
std::string ret_str;
ret_str = StringFormat("Container %i", (sub + 1)); // zero-based index..but, count starts at one
ret_str = StringFormat("Container %i", (indexSub + 1)); // zero-based index..but, count starts at one
return ret_str;
}
std::string EmuConstants::InventoryAugName(int16 aug) {
if (aug == INVALID_INDEX)
std::string EmuConstants::InventoryAugName(int16 indexAug) {
if (indexAug == INVALID_INDEX)
return "Invalid Aug";
if ((uint16)aug >= ITEM_COMMON_SIZE)
if ((uint16)indexAug >= ITEM_COMMON_SIZE)
return "Unknown Aug";
std::string ret_str;
ret_str = StringFormat("Augment %i", (aug + 1)); // zero-based index..but, count starts at one
ret_str = StringFormat("Augment %i", (indexAug + 1)); // zero-based index..but, count starts at one
return ret_str;
}
// legacy-related functions
//
// these should work for the first-stage coversions..but, once the new system is up and going..conversions will be incompatible
// without limiting server functions and other aspects, such as augment control, bag size, etc. A complete remapping will be
// required when bag sizes over 10 and direct manipulation of augments are implemented, due to the massive increase in range usage.
//
// (current personal/cursor bag range {251..340}, or 90 slots ... conversion translated range would be {10000..12804}, or 2805 slots...
// these would have to be hard-coded into all perl code to allow access to full range of the new system - actual limits would be
// less, based on bag size..but, the range must be full and consistent to avoid translation issues -- similar changes to other ranges
// (240 versus 6120 slots for bank bags, for example...))
/*
int EmuConstants::ServerToPerlSlot(int server_slot) { // set r/s
switch (server_slot) {
case legacy::SLOT_CURSOR_END:
return legacy::SLOT_CURSOR_END;
case INVALID_INDEX:
return legacy::SLOT_INVALID;
case MainPowerSource:
return legacy::SLOT_POWER_SOURCE;
case MainAmmo:
return legacy::SLOT_AMMO;
case MainCursor:
return legacy::SLOT_CURSOR;
case legacy::SLOT_TRADESKILL:
return legacy::SLOT_TRADESKILL;
case legacy::SLOT_AUGMENT:
return legacy::SLOT_AUGMENT;
default:
int perl_slot = legacy::SLOT_INVALID;
// activate the internal checks as needed
if (server_slot >= EmuConstants::EQUIPMENT_BEGIN && server_slot <= MainWaist) {
perl_slot = server_slot;
}
else if (server_slot >= EmuConstants::GENERAL_BEGIN && server_slot <= EmuConstants::GENERAL_END) {
perl_slot = server_slot;// + legacy::SLOT_PERSONAL_BEGIN - EmuConstants::GENERAL_BEGIN;
//if (perl_slot < legacy::SLOT_PERSONAL_BEGIN || perl_slot > legacy::SLOT_PERSONAL_END)
// perl_slot = legacy::SLOT_INVALID;
}
else if (server_slot >= EmuConstants::GENERAL_BAGS_BEGIN && server_slot <= EmuConstants::GENERAL_BAGS_END) {
perl_slot = server_slot;// + legacy::SLOT_PERSONAL_BAGS_BEGIN - EmuConstants::GENERAL_BAGS_BEGIN;
//if (perl_slot < legacy::SLOT_PERSONAL_BAGS_BEGIN || perl_slot > legacy::SLOT_PERSONAL_BAGS_END)
// perl_slot = legacy::SLOT_INVALID;
}
else if (server_slot >= EmuConstants::CURSOR_BAG_BEGIN && server_slot <= EmuConstants::CURSOR_BAG_END) {
perl_slot = server_slot;// + legacy::SLOT_CURSOR_BAG_BEGIN - EmuConstants::CURSOR_BAG_BEGIN;
//if (perl_slot < legacy::SLOT_CURSOR_BAG_BEGIN || perl_slot > legacy::SLOT_CURSOR_BAG_END)
// perl_slot = legacy::SLOT_INVALID;
}
else if (server_slot >= EmuConstants::TRIBUTE_BEGIN && server_slot <= EmuConstants::TRIBUTE_END) {
perl_slot = server_slot;// + legacy::SLOT_TRIBUTE_BEGIN - EmuConstants::TRADE_BEGIN;
//if (perl_slot < legacy::SLOT_TRIBUTE_BEGIN || perl_slot > legacy::SLOT_TRIBUTE_END)
// perl_slot = legacy::SLOT_INVALID;
}
else if (server_slot >= EmuConstants::BANK_BEGIN && server_slot <= EmuConstants::BANK_END) {
perl_slot = server_slot;// + legacy::SLOT_BANK_BEGIN - EmuConstants::BANK_BEGIN;
//if (perl_slot < legacy::SLOT_BANK_BEGIN || perl_slot > legacy::SLOT_BANK_END)
// perl_slot = legacy::SLOT_INVALID;
}
else if (server_slot >= EmuConstants::BANK_BAGS_BEGIN && server_slot <= EmuConstants::BANK_BAGS_END) {
perl_slot = server_slot;// + legacy::SLOT_BANK_BAGS_BEGIN - EmuConstants::BANK_BAGS_BEGIN;
//if (perl_slot < legacy::SLOT_BANK_BAGS_BEGIN || perl_slot > legacy::SLOT_BANK_BAGS_END)
// perl_slot = legacy::SLOT_INVALID;
}
else if (server_slot >= EmuConstants::SHARED_BANK_BEGIN && server_slot <= EmuConstants::SHARED_BANK_END) {
perl_slot = server_slot;// + legacy::SLOT_SHARED_BANK_BEGIN - EmuConstants::SHARED_BANK_BEGIN;
//if (perl_slot < legacy::SLOT_SHARED_BANK_BEGIN || perl_slot > legacy::SLOT_SHARED_BANK_END)
// perl_slot = legacy::SLOT_INVALID;
}
else if (server_slot >= EmuConstants::SHARED_BANK_BAGS_BEGIN && server_slot <= EmuConstants::SHARED_BANK_BAGS_END) {
perl_slot = server_slot;// + legacy::SLOT_SHARED_BANK_BAGS_BEGIN - EmuConstants::SHARED_BANK_BAGS_BEGIN;
//if (perl_slot < legacy::SLOT_SHARED_BANK_BAGS_BEGIN || perl_slot > legacy::SLOT_SHARED_BANK_BAGS_END)
// perl_slot = legacy::SLOT_INVALID;
}
else if (server_slot >= EmuConstants::TRADE_BEGIN && server_slot <= EmuConstants::TRADE_END) {
perl_slot = server_slot;// + legacy::SLOT_TRADE_BEGIN - EmuConstants::TRADE_BEGIN;
//if (perl_slot < legacy::SLOT_TRADE_BEGIN || perl_slot > legacy::SLOT_TRADE_END)
// perl_slot = legacy::SLOT_INVALID;
}
else if (server_slot >= EmuConstants::TRADE_BAGS_BEGIN && server_slot <= EmuConstants::TRADE_BAGS_END) {
perl_slot = server_slot;// + legacy::SLOT_TRADE_BAGS_BEGIN - EmuConstants::TRADE_BAGS_BEGIN;
//if (perl_slot < legacy::SLOT_TRADE_BAGS_BEGIN || perl_slot > legacy::SLOT_TRADE_BAGS_END)
// perl_slot = legacy::SLOT_INVALID;
}
else if (server_slot >= EmuConstants::WORLD_BEGIN && server_slot <= EmuConstants::WORLD_END) {
perl_slot = server_slot;// + legacy::SLOT_WORLD_BEGIN - EmuConstants::WORLD_BEGIN;
//if (perl_slot < legacy::SLOT_WORLD_BEGIN || perl_slot > legacy::SLOT_WORLD_END)
// perl_slot = legacy::SLOT_INVALID;
}
else if (server_slot >= 8000 && server_slot <= 8999) { // this range may be limited to 36 in the future (client size)
perl_slot = server_slot;
}
return perl_slot;
}
}
*/
/*
int EmuConstants::PerlToServerSlot(int perl_slot) { // set r/s
switch (perl_slot) {
case legacy::SLOT_CURSOR_END:
return legacy::SLOT_CURSOR_END;
case legacy::SLOT_INVALID:
return INVALID_INDEX;
case legacy::SLOT_POWER_SOURCE:
return MainPowerSource;
case legacy::SLOT_AMMO:
return MainAmmo;
case legacy::SLOT_CURSOR:
return MainCursor;
case legacy::SLOT_TRADESKILL:
return legacy::SLOT_TRADESKILL;
case legacy::SLOT_AUGMENT:
return legacy::SLOT_AUGMENT;
default:
int server_slot = INVALID_INDEX;
// activate the internal checks as needed
if (perl_slot >= legacy::SLOT_EQUIPMENT_BEGIN && perl_slot <= legacy::SLOT_WAIST) {
server_slot = perl_slot;
}
else if (perl_slot >= legacy::SLOT_PERSONAL_BEGIN && perl_slot <= legacy::SLOT_PERSONAL_END) {
server_slot = perl_slot;// + EmuConstants::GENERAL_BEGIN - legacy::SLOT_PERSONAL_BEGIN;
//if (server_slot < EmuConstants::GENERAL_BEGIN || server_slot > EmuConstants::GENERAL_END)
// server_slot = INVALID_INDEX;
}
else if (perl_slot >= legacy::SLOT_PERSONAL_BAGS_BEGIN && perl_slot <= legacy::SLOT_PERSONAL_BAGS_END) {
server_slot = perl_slot;// + EmuConstants::GENERAL_BAGS_BEGIN - legacy::SLOT_PERSONAL_BAGS_BEGIN;
//if (server_slot < EmuConstants::GENERAL_BAGS_BEGIN || server_slot > EmuConstants::GENERAL_BAGS_END)
// server_slot = INVALID_INDEX;
}
else if (perl_slot >= legacy::SLOT_CURSOR_BAG_BEGIN && perl_slot <= legacy::SLOT_CURSOR_BAG_END) {
server_slot = perl_slot;// + EmuConstants::CURSOR_BAG_BEGIN - legacy::SLOT_CURSOR_BAG_BEGIN;
//if (server_slot < EmuConstants::CURSOR_BAG_BEGIN || server_slot > EmuConstants::CURSOR_BAG_END)
// server_slot = INVALID_INDEX;
}
else if (perl_slot >= legacy::SLOT_TRIBUTE_BEGIN && perl_slot <= legacy::SLOT_TRIBUTE_END) {
server_slot = perl_slot;// + EmuConstants::TRIBUTE_BEGIN - legacy::SLOT_TRIBUTE_BEGIN;
//if (server_slot < EmuConstants::TRIBUTE_BEGIN || server_slot > EmuConstants::TRIBUTE_END)
// server_slot = INVALID_INDEX;
}
else if (perl_slot >= legacy::SLOT_BANK_BEGIN && perl_slot <= legacy::SLOT_BANK_END) {
server_slot = perl_slot;// + EmuConstants::BANK_BEGIN - legacy::SLOT_BANK_BEGIN;
//if (server_slot < EmuConstants::BANK_BEGIN || server_slot > EmuConstants::BANK_END)
// server_slot = INVALID_INDEX;
}
else if (perl_slot >= legacy::SLOT_BANK_BAGS_BEGIN && perl_slot <= legacy::SLOT_BANK_BAGS_END) {
server_slot = perl_slot;// + EmuConstants::BANK_BAGS_BEGIN - legacy::SLOT_BANK_BAGS_BEGIN;
//if (server_slot < EmuConstants::BANK_BAGS_BEGIN || server_slot > EmuConstants::BANK_BAGS_END)
// server_slot = INVALID_INDEX;
}
else if (perl_slot >= legacy::SLOT_SHARED_BANK_BEGIN && perl_slot <= legacy::SLOT_SHARED_BANK_END) {
server_slot = perl_slot;// + EmuConstants::SHARED_BANK_BEGIN - legacy::SLOT_SHARED_BANK_BEGIN;
//if (server_slot < EmuConstants::SHARED_BANK_BEGIN || server_slot > EmuConstants::SHARED_BANK_END)
// server_slot = INVALID_INDEX;
}
else if (perl_slot >= legacy::SLOT_SHARED_BANK_BAGS_BEGIN && perl_slot <= legacy::SLOT_SHARED_BANK_BAGS_END) {
server_slot = perl_slot;// + EmuConstants::SHARED_BANK_BAGS_BEGIN - legacy::SLOT_SHARED_BANK_BAGS_END;
//if (server_slot < EmuConstants::SHARED_BANK_BAGS_BEGIN || server_slot > EmuConstants::SHARED_BANK_BAGS_END)
// server_slot = INVALID_INDEX;
}
else if (perl_slot >= legacy::SLOT_TRADE_BEGIN && perl_slot <= legacy::SLOT_TRADE_END) {
server_slot = perl_slot;// + EmuConstants::TRADE_BEGIN - legacy::SLOT_TRADE_BEGIN;
//if (server_slot < EmuConstants::TRADE_BEGIN || server_slot > EmuConstants::TRADE_END)
// server_slot = INVALID_INDEX;
}
else if (perl_slot >= legacy::SLOT_TRADE_BAGS_BEGIN && perl_slot <= legacy::SLOT_TRADE_BAGS_END) {
server_slot = perl_slot;// + EmuConstants::TRADE_BAGS_BEGIN - legacy::SLOT_TRADE_BAGS_BEGIN;
//if (server_slot < EmuConstants::TRADE_BAGS_BEGIN || server_slot > EmuConstants::TRADE_BAGS_END)
// server_slot = INVALID_INDEX;
}
else if (perl_slot >= legacy::SLOT_WORLD_BEGIN && perl_slot <= legacy::SLOT_WORLD_END) {
server_slot = perl_slot;// + EmuConstants::WORLD_BEGIN - legacy::SLOT_WORLD_BEGIN;
//if (server_slot < EmuConstants::WORLD_BEGIN || server_slot > EmuConstants::WORLD_END)
// server_slot = INVALID_INDEX;
}
else if (perl_slot >= 8000 && perl_slot <= 8999) { // this range may be limited to 36 in the future (client size)
server_slot = perl_slot;
}
return server_slot;
}
}
*/
//
// class EQLimits
//
// client validation
bool EQLimits::IsValidClientVersion(uint32 version) {
if (version < _EQClientCount)
bool EQLimits::IsValidPCClientVersion(ClientVersion clientVersion) {
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT)
return true;
return false;
}
uint32 EQLimits::ValidateClientVersion(uint32 version) {
if (version < _EQClientCount)
return version;
ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion) {
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT)
return clientVersion;
return EQClientUnknown;
}
EQClientVersion EQLimits::ValidateClientVersion(EQClientVersion version) {
if (version >= EQClientUnknown)
if (version < _EQClientCount)
return version;
return EQClientUnknown;
return ClientVersion::Unknown;
}
// npc validation
bool EQLimits::IsValidNPCVersion(uint32 version) {
if (version >= _EQClientCount)
if (version < _EmuClientCount)
return true;
return false;
}
uint32 EQLimits::ValidateNPCVersion(uint32 version) {
if (version >= _EQClientCount)
if (version < _EmuClientCount)
return version;
return EQClientUnknown;
}
EQClientVersion EQLimits::ValidateNPCVersion(EQClientVersion version) {
if (version >= _EQClientCount)
if (version < _EmuClientCount)
return version;
return EQClientUnknown;
}
// mob validation
bool EQLimits::IsValidMobVersion(uint32 version) {
if (version < _EmuClientCount)
bool EQLimits::IsValidNPCClientVersion(ClientVersion clientVersion) {
if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT)
return true;
return false;
}
uint32 EQLimits::ValidateMobVersion(uint32 version) {
if (version < _EmuClientCount)
return version;
ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion) {
if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT)
return clientVersion;
return EQClientUnknown;
return ClientVersion::Unknown;
}
EQClientVersion EQLimits::ValidateMobVersion(EQClientVersion version) {
if (version >= EQClientUnknown)
if (version < _EmuClientCount)
return version;
// mob validation
bool EQLimits::IsValidMobClientVersion(ClientVersion clientVersion) {
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT)
return true;
return EQClientUnknown;
return false;
}
ClientVersion EQLimits::ValidateMobClientVersion(ClientVersion clientVersion) {
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT)
return clientVersion;
return ClientVersion::Unknown;
}
// inventory
uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) {
uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion) {
// not all maps will have an instantiated container..some are references for queue generators (i.e., bazaar, mail, etc...)
// a zero '0' indicates a needed value..otherwise, change to '_NOTUSED' for a null value so indices requiring research can be identified
// ALL of these values need to be verified before pushing to live
@ -527,7 +317,7 @@ uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) {
//
// when setting NPC-based values, try to adhere to an EmuConstants::<property> or NOT_USED value to avoid unnecessary issues
static const uint16 local[_MapCount][_EmuClientCount] = {
static const uint16 local[_MapCount][CLIENT_VERSION_COUNT] = {
// server and database are sync'd to current MapPossessions's client as set in 'using namespace RoF::slots;' and
// 'EmuConstants::MAP_POSSESSIONS_SIZE' - use/update EquipmentBitmask(), GeneralBitmask() and CursorBitmask()
// for partial range validation checks and 'EmuConstants::MAP_POSSESSIONS_SIZE' for full range iterations
@ -908,19 +698,19 @@ uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) {
}
};
if ((uint16)map < _MapCount)
return local[map][ValidateMobVersion(version)];
if ((uint16)indexMap < _MapCount)
return local[indexMap][static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
return NOT_USED;
}
uint64 EQLimits::PossessionsBitmask(uint32 version) {
uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion) {
// these are for the new inventory system (RoF)..not the current (Ti) one...
// 0x0000000000200000 is SlotPowerSource (SoF+)
// 0x0000000080000000 is SlotGeneral9 (RoF+)
// 0x0000000100000000 is SlotGeneral10 (RoF+)
static const uint64 local[_EmuClientCount] = {
static const uint64 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x000000027FDFFFFF,
/*Titanium*/ 0x000000027FDFFFFF,
@ -937,11 +727,11 @@ uint64 EQLimits::PossessionsBitmask(uint32 version) {
};
return NOT_USED;
//return local[ValidateMobVersion(version)];
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint64 EQLimits::EquipmentBitmask(uint32 version) {
static const uint64 local[_EmuClientCount] = {
uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion) {
static const uint64 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x00000000005FFFFF,
/*Titanium*/ 0x00000000005FFFFF,
@ -958,11 +748,11 @@ uint64 EQLimits::EquipmentBitmask(uint32 version) {
};
return NOT_USED;
//return local[ValidateMobVersion(version)];
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint64 EQLimits::GeneralBitmask(uint32 version) {
static const uint64 local[_EmuClientCount] = {
uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion) {
static const uint64 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x000000007F800000,
/*Titanium*/ 0x000000007F800000,
@ -979,11 +769,11 @@ uint64 EQLimits::GeneralBitmask(uint32 version) {
};
return NOT_USED;
//return local[ValidateMobVersion(version)];
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint64 EQLimits::CursorBitmask(uint32 version) {
static const uint64 local[_EmuClientCount] = {
uint64 EQLimits::CursorBitmask(ClientVersion clientVersion) {
static const uint64 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x0000000200000000,
/*Titanium*/ 0x0000000200000000,
@ -1000,11 +790,11 @@ uint64 EQLimits::CursorBitmask(uint32 version) {
};
return NOT_USED;
//return local[ValidateMobVersion(version)];
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
bool EQLimits::AllowsEmptyBagInBag(uint32 version) {
static const bool local[_EmuClientCount] = {
bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion) {
static const bool local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ false,
/*62*/ false,
/*Titanium*/ Titanium::limits::ALLOWS_EMPTY_BAG_IN_BAG,
@ -1021,11 +811,11 @@ bool EQLimits::AllowsEmptyBagInBag(uint32 version) {
};
return false; // not implemented
//return local[ValidateMobVersion(version)];
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
bool EQLimits::AllowsClickCastFromBag(uint32 version) {
static const bool local[_EmuClientCount] = {
bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion) {
static const bool local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ false,
/*62*/ false,
/*Titanium*/ Titanium::limits::ALLOWS_CLICK_CAST_FROM_BAG,
@ -1041,12 +831,12 @@ bool EQLimits::AllowsClickCastFromBag(uint32 version) {
/*Pet*/ false
};
return local[ValidateMobVersion(version)];
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
// items
uint16 EQLimits::ItemCommonSize(uint32 version) {
static const uint16 local[_EmuClientCount] = {
uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion) {
static const uint16 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::ITEM_COMMON_SIZE,
/*Titanium*/ EmuConstants::ITEM_COMMON_SIZE,
@ -1062,11 +852,11 @@ uint16 EQLimits::ItemCommonSize(uint32 version) {
/*Pet*/ EmuConstants::ITEM_COMMON_SIZE
};
return local[ValidateMobVersion(version)];
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint16 EQLimits::ItemContainerSize(uint32 version) {
static const uint16 local[_EmuClientCount] = {
uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion) {
static const uint16 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*Titanium*/ EmuConstants::ITEM_CONTAINER_SIZE,
@ -1082,11 +872,11 @@ uint16 EQLimits::ItemContainerSize(uint32 version) {
/*Pet*/ EmuConstants::ITEM_CONTAINER_SIZE
};
return local[ValidateMobVersion(version)];
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
bool EQLimits::CoinHasWeight(uint32 version) {
static const bool local[_EmuClientCount] = {
bool EQLimits::CoinHasWeight(ClientVersion clientVersion) {
static const bool local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ true,
/*62*/ true,
/*Titanium*/ Titanium::limits::COIN_HAS_WEIGHT,
@ -1102,11 +892,11 @@ bool EQLimits::CoinHasWeight(uint32 version) {
/*Pet*/ true
};
return local[ValidateMobVersion(version)];
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint32 EQLimits::BandoliersCount(uint32 version) {
static const uint32 local[_EmuClientCount] = {
uint32 EQLimits::BandoliersCount(ClientVersion clientVersion) {
static const uint32 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::BANDOLIERS_COUNT,
/*Titanium*/ EmuConstants::BANDOLIERS_COUNT,
@ -1122,11 +912,11 @@ uint32 EQLimits::BandoliersCount(uint32 version) {
/*Pet*/ NOT_USED
};
return local[ValidateMobVersion(version)];
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint32 EQLimits::BandolierSize(uint32 version) {
static const uint32 local[_EmuClientCount] = {
uint32 EQLimits::BandolierSize(ClientVersion clientVersion) {
static const uint32 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::BANDOLIER_SIZE,
/*Titanium*/ EmuConstants::BANDOLIER_SIZE,
@ -1142,11 +932,11 @@ uint32 EQLimits::BandolierSize(uint32 version) {
/*Pet*/ NOT_USED
};
return local[ValidateMobVersion(version)];
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint32 EQLimits::PotionBeltSize(uint32 version) {
static const uint32 local[_EmuClientCount] = {
uint32 EQLimits::PotionBeltSize(ClientVersion clientVersion) {
static const uint32 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::POTION_BELT_SIZE,
/*Titanium*/ EmuConstants::POTION_BELT_SIZE,
@ -1162,5 +952,5 @@ uint32 EQLimits::PotionBeltSize(uint32 version) {
/*Pet*/ NOT_USED
};
return local[ValidateMobVersion(version)];
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}

View File

@ -46,15 +46,15 @@ class EmuConstants {
// an immutable value is required to initialize arrays, etc... use this class as a repository for those
public:
// database
static const EQClientVersion CHARACTER_CREATION_CLIENT = EQClientRoF; // adjust according to starting item placement and target client
static const ClientVersion CHARACTER_CREATION_CLIENT = ClientVersion::RoF2; // adjust according to starting item placement and target client
// inventory
static uint16 InventoryMapSize(int16 map);
static uint16 InventoryMapSize(int16 indexMap);
//static std::string InventoryLocationName(Location_Struct location);
static std::string InventoryMapName(int16 map);
static std::string InventoryMainName(int16 main);
static std::string InventorySubName(int16 sub);
static std::string InventoryAugName(int16 aug);
static std::string InventoryMapName(int16 indexMap);
static std::string InventoryMainName(int16 indexMain);
static std::string InventorySubName(int16 indexSub);
static std::string InventoryAugName(int16 indexAug);
// these are currently hard-coded for existing inventory system..do not use in place of special client version handlers until ready
static const uint16 MAP_POSSESSIONS_SIZE = _MainCount;
@ -163,44 +163,41 @@ class EQLimits {
public:
// client version validation (checks to avoid crashing zone server when accessing reference arrays)
// use this inside of class Client (limits to actual clients)
static bool IsValidClientVersion(uint32 version);
static uint32 ValidateClientVersion(uint32 version);
static EQClientVersion ValidateClientVersion(EQClientVersion version);
static bool IsValidPCClientVersion(ClientVersion clientVersion);
static ClientVersion ValidatePCClientVersion(ClientVersion clientVersion);
// basically..any non-client classes - do not when setting a valid client
static bool IsValidNPCVersion(uint32 version);
static uint32 ValidateNPCVersion(uint32 version);
static EQClientVersion ValidateNPCVersion(EQClientVersion version);
static bool IsValidNPCClientVersion(ClientVersion clientVersion);
static ClientVersion ValidateNPCClientVersion(ClientVersion clientVersion);
// these are 'universal' - do not when setting a valid client
static bool IsValidMobVersion(uint32 version);
static uint32 ValidateMobVersion(uint32 version);
static EQClientVersion ValidateMobVersion(EQClientVersion version);
static bool IsValidMobClientVersion(ClientVersion clientVersion);
static ClientVersion ValidateMobClientVersion(ClientVersion clientVersion);
// inventory
static uint16 InventoryMapSize(int16 map, uint32 version);
static uint64 PossessionsBitmask(uint32 version);
static uint64 EquipmentBitmask(uint32 version);
static uint64 GeneralBitmask(uint32 version);
static uint64 CursorBitmask(uint32 version);
static uint16 InventoryMapSize(int16 indexMap, ClientVersion clientVersion);
static uint64 PossessionsBitmask(ClientVersion clientVersion);
static uint64 EquipmentBitmask(ClientVersion clientVersion);
static uint64 GeneralBitmask(ClientVersion clientVersion);
static uint64 CursorBitmask(ClientVersion clientVersion);
static bool AllowsEmptyBagInBag(uint32 version);
static bool AllowsClickCastFromBag(uint32 version);
static bool AllowsEmptyBagInBag(ClientVersion clientVersion);
static bool AllowsClickCastFromBag(ClientVersion clientVersion);
// items
static uint16 ItemCommonSize(uint32 version);
static uint16 ItemContainerSize(uint32 version);
static uint16 ItemCommonSize(ClientVersion clientVersion);
static uint16 ItemContainerSize(ClientVersion clientVersion);
// player profile
static bool CoinHasWeight(uint32 version);
static bool CoinHasWeight(ClientVersion clientVersion);
static uint32 BandoliersCount(uint32 version);
static uint32 BandolierSize(uint32 version);
static uint32 BandoliersCount(ClientVersion clientVersion);
static uint32 BandolierSize(ClientVersion clientVersion);
static uint32 PotionBeltSize(uint32 version);
static uint32 PotionBeltSize(ClientVersion clientVersion);
};
#endif /* EQ_LIMITS_H */
#endif /* EQ_DICTIONARY_H */
/*
Working Notes:

View File

@ -35,7 +35,7 @@ public:
virtual const uint32 GetBytesRecieved() const { return 0; }
virtual const uint32 GetBytesSentPerSecond() const { return 0; }
virtual const uint32 GetBytesRecvPerSecond() const { return 0; }
virtual const EQClientVersion ClientVersion() const { return EQClientUnknown; }
virtual const ClientVersion GetClientVersion() const { return ClientVersion::Unknown; }
};
#endif /*EQSTREAMINTF_H_*/

View File

@ -22,9 +22,9 @@ std::string EQStreamProxy::Describe() const {
return(m_structs->Describe());
}
const EQClientVersion EQStreamProxy::ClientVersion() const
const ClientVersion EQStreamProxy::GetClientVersion() const
{
return m_structs->ClientVersion();
return m_structs->GetClientVersion();
}
void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {

View File

@ -27,7 +27,7 @@ public:
virtual void RemoveData();
virtual bool CheckState(EQStreamState state);
virtual std::string Describe() const;
virtual const EQClientVersion ClientVersion() const;
virtual const ClientVersion GetClientVersion() const;
virtual const uint32 GetBytesSent() const;
virtual const uint32 GetBytesRecieved() const;

View File

@ -1259,7 +1259,7 @@ int16 Inventory::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, ui
if (!inst->IsType(ItemClassContainer)) { continue; }
for (auto bag_iter = bucket.begin(); bag_iter != bucket.end(); ++bag_iter) {
for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) {
auto bag_inst = bag_iter->second;
if (bag_inst == nullptr) { continue; }
@ -1710,9 +1710,17 @@ void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent)
end = m_contents.end();
for (; cur != end;) {
ItemInst* inst = cur->second;
if (inst == nullptr)
if (inst == nullptr) {
cur = m_contents.erase(cur);
continue;
}
const Item_Struct* item = inst->GetItem();
if (item == nullptr) {
cur = m_contents.erase(cur);
continue;
}
del = cur;
++cur;
@ -1723,6 +1731,7 @@ void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent)
m_contents.erase(del->first);
continue;
}
// no 'break;' deletes 'byFlagNotSet' type - can't add at the moment because it really *breaks* the process somewhere
case byFlagNotSet:
if (item->NoDrop != 0) {
safe_delete(inst);
@ -1740,6 +1749,7 @@ void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent)
m_contents.erase(del->first);
continue;
}
// no 'break;' deletes 'byFlagNotSet' type - can't add at the moment because it really *breaks* the process somewhere
case byFlagNotSet:
if (item->NoRent != 0) {
safe_delete(inst);

View File

@ -117,11 +117,11 @@ public:
// Public Methods
///////////////////////////////
Inventory() { m_version = EQClientUnknown; m_versionset = false; }
Inventory() { m_version = ClientVersion::Unknown; m_versionset = false; }
~Inventory();
// Inventory v2 creep
bool SetInventoryVersion(EQClientVersion version) {
bool SetInventoryVersion(ClientVersion version) {
if (!m_versionset) {
m_version = version;
return (m_versionset = true);
@ -131,7 +131,7 @@ public:
}
}
EQClientVersion GetInventoryVersion() { return m_version; }
ClientVersion GetInventoryVersion() { return m_version; }
static void CleanDirty();
static void MarkDirty(ItemInst *inst);
@ -252,7 +252,7 @@ protected:
private:
// Active inventory version
EQClientVersion m_version;
ClientVersion m_version;
bool m_versionset;
};

View File

@ -115,9 +115,9 @@ namespace RoF
return(r);
}
const EQClientVersion Strategy::ClientVersion() const
const ClientVersion Strategy::GetClientVersion() const
{
return EQClientRoF;
return ClientVersion::RoF;
}
#include "ss_define.h"

View File

@ -23,7 +23,7 @@ namespace RoF {
protected:
virtual std::string Describe() const;
virtual const EQClientVersion ClientVersion() const;
virtual const ClientVersion GetClientVersion() const;
//magic macro to declare our opcode processors
#include "ss_declare.h"

View File

@ -115,9 +115,9 @@ namespace RoF2
return(r);
}
const EQClientVersion Strategy::ClientVersion() const
const ClientVersion Strategy::GetClientVersion() const
{
return EQClientRoF2;
return ClientVersion::RoF2;
}
#include "ss_define.h"

View File

@ -23,7 +23,7 @@ namespace RoF2 {
protected:
virtual std::string Describe() const;
virtual const EQClientVersion ClientVersion() const;
virtual const ClientVersion GetClientVersion() const;
//magic macro to declare our opcode processors
#include "ss_declare.h"

View File

@ -113,9 +113,9 @@ namespace SoD
return(r);
}
const EQClientVersion Strategy::ClientVersion() const
const ClientVersion Strategy::GetClientVersion() const
{
return EQClientSoD;
return ClientVersion::SoD;
}
#include "ss_define.h"

View File

@ -23,7 +23,7 @@ namespace SoD {
protected:
virtual std::string Describe() const;
virtual const EQClientVersion ClientVersion() const;
virtual const ClientVersion GetClientVersion() const;
//magic macro to declare our opcode processors
#include "ss_declare.h"

View File

@ -113,9 +113,9 @@ namespace SoF
return(r);
}
const EQClientVersion Strategy::ClientVersion() const
const ClientVersion Strategy::GetClientVersion() const
{
return EQClientSoF;
return ClientVersion::SoF;
}
#include "ss_define.h"

View File

@ -23,7 +23,7 @@ namespace SoF {
protected:
virtual std::string Describe() const;
virtual const EQClientVersion ClientVersion() const;
virtual const ClientVersion GetClientVersion() const;
//magic macro to declare our opcode processors
#include "ss_declare.h"

View File

@ -111,9 +111,9 @@ namespace Titanium
return(r);
}
const EQClientVersion Strategy::ClientVersion() const
const ClientVersion Strategy::GetClientVersion() const
{
return EQClientTitanium;
return ClientVersion::Tit;
}
#include "ss_define.h"

View File

@ -23,7 +23,7 @@ namespace Titanium {
protected:
virtual std::string Describe() const;
virtual const EQClientVersion ClientVersion() const;
virtual const ClientVersion GetClientVersion() const;
//magic macro to declare our opcode processors
#include "ss_declare.h"

View File

@ -113,9 +113,9 @@ namespace Underfoot
return(r);
}
const EQClientVersion Strategy::ClientVersion() const
const ClientVersion Strategy::GetClientVersion() const
{
return EQClientUnderfoot;
return ClientVersion::Und;
}
#include "ss_define.h"

View File

@ -23,7 +23,7 @@ namespace Underfoot {
protected:
virtual std::string Describe() const;
virtual const EQClientVersion ClientVersion() const;
virtual const ClientVersion GetClientVersion() const;
//magic macro to declare our opcode processors
#include "ss_declare.h"

View File

@ -165,6 +165,7 @@ RULE_INT ( World, ExemptAccountLimitStatus, -1 ) //Min status required to be exe
RULE_BOOL ( World, GMAccountIPList, false) // Check ip list against GM Accounts, AntiHack GM Accounts.
RULE_INT ( World, MinGMAntiHackStatus, 1 ) //Minimum GM status to check against AntiHack list
RULE_INT ( World, SoFStartZoneID, -1 ) //Sets the Starting Zone for SoF Clients separate from Titanium Clients (-1 is disabled)
RULE_INT ( World, TitaniumStartZoneID, -1) //Sets the Starting Zone for Titanium Clients (-1 is disabled). Replaces the old method.
RULE_INT ( World, ExpansionSettings, 16383) // Sets the expansion settings for the server, This is sent on login to world and affects client expansion settings. Defaults to all expansions enabled up to TSS.
RULE_INT ( World, PVPSettings, 0) // Sets the PVP settings for the server, 1 = Rallos Zek RuleSet, 2 = Tallon/Vallon Zek Ruleset, 4 = Sullon Zek Ruleset, 6 = Discord Ruleset, anything above 6 is the Discord Ruleset without the no-drop restrictions removed. TODO: Edit IsAttackAllowed in Zone to accomodate for these rules.
RULE_BOOL (World, IsGMPetitionWindowEnabled, false)
@ -600,4 +601,4 @@ RULE_CATEGORY_END()
#undef RULE_INT
#undef RULE_REAL
#undef RULE_BOOL
#undef RULE_CATEGORY_END
#undef RULE_CATEGORY_END

View File

@ -24,7 +24,7 @@ public:
void Decode(EQApplicationPacket *p) const;
virtual std::string Describe() const = 0;
virtual const EQClientVersion ClientVersion() const = 0;
virtual const ClientVersion GetClientVersion() const = 0;
protected:
//some common coders:

View File

@ -24,7 +24,7 @@
extern ErrorLog *server_log;
extern LoginServer server;
Client::Client(EQStream *c, ClientVersion v)
Client::Client(EQStream *c, LSClientVersion v)
{
connection = c;
version = v;

View File

@ -30,13 +30,13 @@
using namespace std;
enum ClientVersion
enum LSClientVersion
{
cv_titanium,
cv_sod
};
enum ClientStatus
enum LSClientStatus
{
cs_not_sent_session_ready,
cs_waiting_for_login,
@ -59,7 +59,7 @@ public:
/**
* Constructor, sets our connection to c and version to v
*/
Client(EQStream *c, ClientVersion v);
Client(EQStream *c, LSClientVersion v);
/**
* Destructor.
@ -134,8 +134,8 @@ public:
EQEmu::Random random;
private:
EQStream *connection;
ClientVersion version;
ClientStatus status;
LSClientVersion version;
LSClientStatus status;
string account_name;
unsigned int account_id;

View File

@ -89,7 +89,8 @@ Client::Client(EQStreamInterface* ieqs)
ClientVersionBit = 0;
numclients++;
ClientVersionBit = 1 << (eqs->ClientVersion() - 1);
if (eqs->GetClientVersion() != ClientVersion::Unknown)
ClientVersionBit = 1 << (static_cast<unsigned int>(eqs->GetClientVersion()) - 1);
}
Client::~Client() {
@ -1433,33 +1434,27 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
pp.pvp = database.GetServerType() == 1 ? 1 : 0;
/* If it is an SoF Client and the SoF Start Zone rule is set, send new chars there */
if (ClientVersionBit & BIT_SoFAndLater && RuleI(World, SoFStartZoneID) > 0) {
if (ClientVersionBit & BIT_SoFAndLater) {
Log.Out(Logs::Detail, Logs::World_Server,"Found 'SoFStartZoneID' rule setting: %i", RuleI(World, SoFStartZoneID));
pp.zone_id = RuleI(World, SoFStartZoneID);
if (pp.zone_id)
database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z);
else
Log.Out(Logs::Detail, Logs::World_Server,"Error getting zone id for Zone ID %i", RuleI(World, SoFStartZoneID));
} else {
/* if there's a startzone variable put them in there */
if (database.GetVariable("startzone", startzone, 50)) {
Log.Out(Logs::Detail, Logs::World_Server,"Found 'startzone' variable setting: %s", startzone);
pp.zone_id = database.GetZoneID(startzone);
if (pp.zone_id)
database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z);
else
Log.Out(Logs::Detail, Logs::World_Server,"Error getting zone id for '%s'", startzone);
} else { /* otherwise use normal starting zone logic */
bool ValidStartZone = false;
if (ClientVersionBit & BIT_TitaniumAndEarlier)
ValidStartZone = database.GetStartZone(&pp, cc);
else
ValidStartZone = database.GetStartZoneSoF(&pp, cc);
if (!ValidStartZone)
return false;
if (RuleI(World, SoFStartZoneID) > 0) {
pp.zone_id = RuleI(World, SoFStartZoneID);
cc->start_zone = pp.zone_id;
}
}
else {
clog(WORLD__CLIENT, "Found 'TitaniumStartZoneID' rule setting: %i", RuleI(World, TitaniumStartZoneID));
if (RuleI(World, TitaniumStartZoneID) > 0) { /* if there's a startzone variable put them in there */
pp.zone_id = RuleI(World, TitaniumStartZoneID);
cc->start_zone = pp.zone_id;
}
}
/* use normal starting zone logic to either get defaults, or if startzone was set, load that from the db table.*/
bool ValidStartZone = database.GetStartZone(&pp, cc, ClientVersionBit & BIT_TitaniumAndEarlier);
if (!ValidStartZone){
return false;
}
/* just in case */
if (!pp.zone_id) {

View File

@ -282,116 +282,34 @@ int WorldDatabase::MoveCharacterToBind(int CharID, uint8 bindnum) {
return zone_id;
}
bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc,bool isTitanium)
{
// SoF doesn't send the player_choice field in character creation, it now sends the real zoneID instead.
//
// For SoF, search for an entry in start_zones with a matching zone_id, class, race and deity.
//
// For now, if no row matching row is found, send them to Crescent Reach, as that is probably the most likely
// reason for no match being found.
//
if(!in_pp || !in_cc)
return false;
in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = in_pp->binds[0].instance_id = 0;
std::string query = StringFormat("SELECT x, y, z, heading, zone_id, bind_id "
"FROM start_zones WHERE player_choice = % i "
"AND player_class = %i AND player_deity = %i "
"AND player_race = %i",
in_cc->start_zone, in_cc->class_, in_cc->deity,
in_cc->race);
// see if we have an entry for start_zone. We can support both titanium & SOF+ by having two entries per class/race/deity combo with different zone_ids
std::string query = StringFormat("SELECT x, y, z, heading, start_zone, bind_id FROM start_zones WHERE zone_id = %i "
"AND player_class = %i AND player_deity = %i AND player_race = %i",
in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race);
auto results = QueryDatabase(query);
if(!results.Success()) {
return false;
}
Log.Out(Logs::General, Logs::Status, "Start zone query: %s\n", query.c_str());
Log.Out(Logs::General, Logs::Status, "SoF Start zone query: %s\n", query.c_str());
if (results.RowCount() == 0) {
printf("No start_zones entry in database, using defaults\n");
switch(in_cc->start_zone)
{
case 0:
{
in_pp->zone_id = 24; // erudnext
in_pp->binds[0].zoneId = 38; // tox
break;
}
case 1:
{
in_pp->zone_id = 2; // qeynos2
in_pp->binds[0].zoneId = 2; // qeynos2
break;
}
case 2:
{
in_pp->zone_id = 29; // halas
in_pp->binds[0].zoneId = 30; // everfrost
break;
}
case 3:
{
in_pp->zone_id = 19; // rivervale
in_pp->binds[0].zoneId = 20; // kithicor
break;
}
case 4:
{
in_pp->zone_id = 9; // freportw
in_pp->binds[0].zoneId = 9; // freportw
break;
}
case 5:
{
in_pp->zone_id = 40; // neriaka
in_pp->binds[0].zoneId = 25; // nektulos
break;
}
case 6:
{
in_pp->zone_id = 52; // gukta
in_pp->binds[0].zoneId = 46; // innothule
break;
}
case 7:
{
in_pp->zone_id = 49; // oggok
in_pp->binds[0].zoneId = 47; // feerrott
break;
}
case 8:
{
in_pp->zone_id = 60; // kaladima
in_pp->binds[0].zoneId = 68; // butcher
break;
}
case 9:
{
in_pp->zone_id = 54; // gfaydark
in_pp->binds[0].zoneId = 54; // gfaydark
break;
}
case 10:
{
in_pp->zone_id = 61; // felwithea
in_pp->binds[0].zoneId = 54; // gfaydark
break;
}
case 11:
{
in_pp->zone_id = 55; // akanon
in_pp->binds[0].zoneId = 56; // steamfont
break;
}
case 12:
{
in_pp->zone_id = 82; // cabwest
in_pp->binds[0].zoneId = 78; // fieldofbone
break;
}
case 13:
{
in_pp->zone_id = 155; // sharvahl
in_pp->binds[0].zoneId = 155; // sharvahl
break;
}
}
isTitanium ? SetTitaniumDefaultStartZone(in_pp, in_cc) : SetSoFDefaultStartZone(in_pp, in_cc);
}
else {
Log.Out(Logs::General, Logs::Status, "Found starting location in start_zones");
@ -412,64 +330,108 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct*
return true;
}
bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
{
// SoF doesn't send the player_choice field in character creation, it now sends the real zoneID instead.
//
// For SoF, search for an entry in start_zones with a matching zone_id, class, race and deity.
//
// For now, if no row matching row is found, send them to Crescent Reach, as that is probably the most likely
// reason for no match being found.
//
if(!in_pp || !in_cc)
return false;
in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = in_pp->binds[0].instance_id = 0;
std::string query = StringFormat("SELECT x, y, z, heading, bind_id FROM start_zones WHERE zone_id = %i "
"AND player_class = %i AND player_deity = %i AND player_race = %i",
in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race);
auto results = QueryDatabase(query);
if(!results.Success()) {
return false;
}
Log.Out(Logs::General, Logs::Status, "SoF Start zone query: %s\n", query.c_str());
if (results.RowCount() == 0) {
printf("No start_zones entry in database, using defaults\n");
if(in_cc->start_zone == RuleI(World, TutorialZoneID))
in_pp->zone_id = in_cc->start_zone;
else {
in_pp->x = in_pp->binds[0].x = -51;
in_pp->y = in_pp->binds[0].y = -20;
in_pp->z = in_pp->binds[0].z = 0.79;
in_pp->zone_id = in_pp->binds[0].zoneId = 394; // Crescent Reach.
}
}
else {
Log.Out(Logs::General, Logs::Status, "Found starting location in start_zones");
auto row = results.begin();
in_pp->x = atof(row[0]);
in_pp->y = atof(row[1]);
in_pp->z = atof(row[2]);
in_pp->heading = atof(row[3]);
void WorldDatabase::SetSoFDefaultStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc){
if (in_cc->start_zone == RuleI(World, TutorialZoneID)) {
in_pp->zone_id = in_cc->start_zone;
in_pp->binds[0].zoneId = atoi(row[4]);
}
else {
in_pp->x = in_pp->binds[0].x = -51;
in_pp->y = in_pp->binds[0].y = -20;
in_pp->z = in_pp->binds[0].z = 0.79;
in_pp->zone_id = in_pp->binds[0].zoneId = 394; // Crescent Reach.
}
if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0)
database.GetSafePoints(in_pp->zone_id, 0, &in_pp->x, &in_pp->y, &in_pp->z);
if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0)
database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z);
return true;
}
void WorldDatabase::SetTitaniumDefaultStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
{
switch (in_cc->start_zone)
{
case 0:
{
in_pp->zone_id = 24; // erudnext
in_pp->binds[0].zoneId = 38; // tox
break;
}
case 1:
{
in_pp->zone_id = 2; // qeynos2
in_pp->binds[0].zoneId = 2; // qeynos2
break;
}
case 2:
{
in_pp->zone_id = 29; // halas
in_pp->binds[0].zoneId = 30; // everfrost
break;
}
case 3:
{
in_pp->zone_id = 19; // rivervale
in_pp->binds[0].zoneId = 20; // kithicor
break;
}
case 4:
{
in_pp->zone_id = 9; // freportw
in_pp->binds[0].zoneId = 9; // freportw
break;
}
case 5:
{
in_pp->zone_id = 40; // neriaka
in_pp->binds[0].zoneId = 25; // nektulos
break;
}
case 6:
{
in_pp->zone_id = 52; // gukta
in_pp->binds[0].zoneId = 46; // innothule
break;
}
case 7:
{
in_pp->zone_id = 49; // oggok
in_pp->binds[0].zoneId = 47; // feerrott
break;
}
case 8:
{
in_pp->zone_id = 60; // kaladima
in_pp->binds[0].zoneId = 68; // butcher
break;
}
case 9:
{
in_pp->zone_id = 54; // gfaydark
in_pp->binds[0].zoneId = 54; // gfaydark
break;
}
case 10:
{
in_pp->zone_id = 61; // felwithea
in_pp->binds[0].zoneId = 54; // gfaydark
break;
}
case 11:
{
in_pp->zone_id = 55; // akanon
in_pp->binds[0].zoneId = 56; // steamfont
break;
}
case 12:
{
in_pp->zone_id = 82; // cabwest
in_pp->binds[0].zoneId = 78; // fieldofbone
break;
}
case 13:
{
in_pp->zone_id = 155; // sharvahl
in_pp->binds[0].zoneId = 155; // sharvahl
break;
}
}
}
void WorldDatabase::GetLauncherList(std::vector<std::string> &rl) {
rl.clear();

View File

@ -28,9 +28,7 @@ struct CharacterSelect_Struct;
class WorldDatabase : public SharedDatabase {
public:
bool GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
bool GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
bool GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc, bool isTitanium);
void GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*, uint32 ClientVersion);
int MoveCharacterToBind(int CharID, uint8 bindnum = 0);
@ -40,8 +38,9 @@ public:
bool LoadCharacterCreateAllocations();
bool LoadCharacterCreateCombos();
protected:
private:
void SetTitaniumDefaultStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
void SetSoFDefaultStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
};
extern WorldDatabase database;

View File

@ -15,7 +15,7 @@ SET(zone_sources
command.cpp
corpse.cpp
doors.cpp
effects.cpp
effects.cpp
embparser.cpp
embparser_api.cpp
embperl.cpp
@ -91,6 +91,7 @@ SET(zone_sources
perlpacket.cpp
petitions.cpp
pets.cpp
position.cpp
qglobals.cpp
queryserv.cpp
questmgr.cpp
@ -180,6 +181,7 @@ SET(zone_headers
perlpacket.h
petitions.h
pets.h
position.h
qglobals.h
quest_interface.h
queryserv.h

View File

@ -269,10 +269,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 */
@ -547,12 +547,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] = {
xy_location(5, 5), xy_location(-5, 5), xy_location(5, -5), xy_location(-5, -5),
xy_location(10, 10), xy_location(-10, 10), xy_location(10, -10), xy_location(-10, -10),
xy_location(8, 8), xy_location(-8, 8), xy_location(8, -8), xy_location(-8, -8)
};
while(summon_count > 0) {
int pet_duration = pet.duration;
if(duration_override > 0)
@ -569,8 +569,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());
@ -644,12 +644,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] = {
xy_location(5, 5), xy_location(-5, 5), xy_location(5, -5), xy_location(-5, -5),
xy_location(10, 10), xy_location(-10, 10), xy_location(10, -10), xy_location(-10, -10),
xy_location(8, 8), xy_location(-8, 8), xy_location(8, -8), xy_location(-8, -8)
};;
while(summon_count > 0) {
int pet_duration = pet.duration;
@ -667,8 +666,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());
@ -854,7 +853,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;
@ -1018,7 +1017,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)){
@ -1039,7 +1038,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

@ -89,7 +89,7 @@ void EntityList::DescribeAggro(Client *towho, NPC *from_who, float d, bool verbo
if (mob->IsClient()) //also ensures that mob != around
continue;
if (mob->DistNoRoot(*from_who) > d2)
if (ComparativeDistance(mob->GetPosition(), from_who->GetPosition()) > d2)
continue;
if (engaged) {
@ -151,7 +151,8 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) {
return;
}
float dist2 = mob->DistNoRoot(*this);
float dist2 = ComparativeDistance(mob->GetPosition(), m_Position);
float iAggroRange2 = iAggroRange*iAggroRange;
if( dist2 > iAggroRange2 ) {
towho->Message(0, "...%s is out of range. %.3f > %.3f ", mob->GetName(),
@ -296,7 +297,7 @@ bool Mob::CheckWillAggro(Mob *mob) {
return(false);
}
float dist2 = mob->DistNoRoot(*this);
float dist2 = ComparativeDistance(mob->GetPosition(), m_Position);
float iAggroRange2 = iAggroRange*iAggroRange;
if( dist2 > iAggroRange2 ) {
@ -410,7 +411,7 @@ int EntityList::GetHatedCount(Mob *attacker, Mob *exclude)
AggroRange *= AggroRange;
if (mob->DistNoRoot(*attacker) > AggroRange)
if (ComparativeDistance(mob->GetPosition(), attacker->GetPosition()) > AggroRange)
continue;
Count++;
@ -440,7 +441,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
// && !mob->IsCorpse()
// && mob->IsAIControlled()
&& mob->GetPrimaryFaction() != 0
&& mob->DistNoRoot(*sender) <= r
&& ComparativeDistance(mob->GetPosition(), sender->GetPosition()) <= r
&& !mob->IsEngaged()
&& ((!mob->IsPet()) || (mob->IsPet() && mob->GetOwner() && !mob->GetOwner()->IsClient()))
// If we're a pet we don't react to any calls for help if our owner is a client
@ -467,7 +468,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
if(mob->CheckLosFN(sender)) {
#if (EQDEBUG>=5)
Log.Out(Logs::General, Logs::None, "AIYellForHelp(\"%s\",\"%s\") %s attacking %s Dist %f Z %f",
sender->GetName(), attacker->GetName(), mob->GetName(), attacker->GetName(), mob->DistNoRoot(*sender), fabs(sender->GetZ()+mob->GetZ()));
sender->GetName(), attacker->GetName(), mob->GetName(), attacker->GetName(), ComparativeDistance(mob->GetPosition(), sender->GetPosition()), fabs(sender->GetZ()+mob->GetZ()));
#endif
mob->AddToHateList(attacker, 1, 0, false);
}
@ -874,7 +875,7 @@ bool Mob::CombatRange(Mob* other)
if (size_mod > 10000)
size_mod = size_mod / 7;
float _DistNoRoot = DistNoRoot(*other);
float _DistNoRoot = ComparativeDistance(m_Position, other->GetPosition());
if (GetSpecialAbility(NPC_CHASE_DISTANCE)){

View File

@ -2462,7 +2462,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;
}
}
@ -3339,7 +3339,7 @@ int32 Mob::ReduceAllDamage(int32 damage)
}
}
CheckNumHitsRemaining(NUMHIT_IncomingDamage);
CheckNumHitsRemaining(NumHit::IncomingDamage);
return(damage);
}
@ -3455,10 +3455,10 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
}
if (spell_id == SPELL_UNKNOWN && skill_used) {
CheckNumHitsRemaining(NUMHIT_IncomingHitAttempts);
CheckNumHitsRemaining(NumHit::IncomingHitAttempts);
if (attacker)
attacker->CheckNumHitsRemaining(NUMHIT_OutgoingHitAttempts);
attacker->CheckNumHitsRemaining(NumHit::OutgoingHitAttempts);
}
if(attacker){
@ -3535,7 +3535,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
}
if (skill_used)
CheckNumHitsRemaining(NUMHIT_IncomingHitSuccess);
CheckNumHitsRemaining(NumHit::IncomingHitSuccess);
if(IsClient() && CastToClient()->sneaking){
CastToClient()->sneaking = false;
@ -3908,7 +3908,8 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
float chance = ProcChance * (static_cast<float>(DefensiveProcs[i].chance)/100.0f);
if (zone->random.Roll(chance)) {
ExecWeaponProc(nullptr, DefensiveProcs[i].spellID, on);
CheckNumHitsRemaining(NUMHIT_DefensiveSpellProcs,0,DefensiveProcs[i].base_spellID);
CheckNumHitsRemaining(NumHit::DefensiveSpellProcs, 0,
DefensiveProcs[i].base_spellID);
}
}
}
@ -4084,7 +4085,8 @@ void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on,
"Spell proc %d procing spell %d (%.2f percent chance)",
i, SpellProcs[i].spellID, chance);
ExecWeaponProc(nullptr, SpellProcs[i].spellID, on);
CheckNumHitsRemaining(NUMHIT_OffensiveSpellProcs, 0, SpellProcs[i].base_spellID);
CheckNumHitsRemaining(NumHit::OffensiveSpellProcs, 0,
SpellProcs[i].base_spellID);
} else {
Log.Out(Logs::Detail, Logs::Combat,
"Spell proc %d failed to proc %d (%.2f percent chance)",
@ -4100,7 +4102,8 @@ void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on,
"Ranged proc %d procing spell %d (%.2f percent chance)",
i, RangedProcs[i].spellID, chance);
ExecWeaponProc(nullptr, RangedProcs[i].spellID, on);
CheckNumHitsRemaining(NUMHIT_OffensiveSpellProcs, 0, RangedProcs[i].base_spellID);
CheckNumHitsRemaining(NumHit::OffensiveSpellProcs, 0,
RangedProcs[i].base_spellID);
} else {
Log.Out(Logs::Detail, Logs::Combat,
"Ranged proc %d failed to proc %d (%.2f percent chance)",
@ -4517,7 +4520,8 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
float final_chance = chance * (ProcMod / 100.0f);
if (zone->random.Roll(final_chance)) {
ExecWeaponProc(nullptr, proc_spell_id, on);
CheckNumHitsRemaining(NUMHIT_OffensiveSpellProcs,0, base_spell_id);
CheckNumHitsRemaining(NumHit::OffensiveSpellProcs, 0,
base_spell_id);
CanProc = false;
break;
}
@ -4763,7 +4767,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, int32 &damage, SkillUseTypes s
ApplyMeleeDamageBonus(skillInUse, damage);
damage += (damage * defender->GetSkillDmgTaken(skillInUse) / 100) + (GetSkillDmgAmt(skillInUse) + defender->GetFcDamageAmtIncoming(this, 0, true, skillInUse));
TryCriticalHit(defender, skillInUse, damage);
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
}
void Mob::CommonBreakInvisible()

View File

@ -35,7 +35,7 @@ class Zone;
#include "../common/races.h"
#include "beacon.h"
#include "entity.h"
#include "mob.h"
#include "mob.h"
#ifdef BOTS
@ -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,26 +67,13 @@ 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();
}
#ifdef SOLAR
entity_list.Message(0, 0, "Beacon being created at %0.2f %0.2f %0.2f heading %0.2f lifetime %d", GetX(), GetY(), GetZ(), GetHeading(), lifetime);
#endif
}
Beacon::~Beacon()
{
#ifdef SOLAR
entity_list.Message(0, 0, "Beacon %d being removed at %0.2f %0.2f %0.2f heading %0.2f", GetID(), GetX(), GetY(), GetZ(), GetHeading());
#endif
}
bool Beacon::Process()

View File

@ -155,7 +155,7 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
}
//Power Source Slot
if (GetClientVersion() >= EQClientSoF)
if (GetClientVersion() >= ClientVersion::SoF)
{
const ItemInst* inst = m_inv[MainPowerSource];
if(inst)
@ -3082,7 +3082,7 @@ void Client::CalcItemScale() {
changed = true;
//Power Source Slot
if (GetClientVersion() >= EQClientSoF)
if (GetClientVersion() >= ClientVersion::SoF)
{
if(CalcItemScale(MainPowerSource, MainPowerSource))
changed = true;
@ -3176,7 +3176,7 @@ void Client::DoItemEnterZone() {
changed = true;
//Power Source Slot
if (GetClientVersion() >= EQClientSoF)
if (GetClientVersion() >= ClientVersion::SoF)
{
if(DoItemEnterZone(MainPowerSource, MainPowerSource))
changed = true;

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) {
@ -1375,7 +1375,7 @@ int32 Bot::GenerateBaseHitPoints()
uint32 Post255;
uint32 NormalSTA = GetSTA();
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= EQClientSoD && RuleB(Character, SoDClientUseSoDHPManaEnd))
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd))
{
float SoDPost255;
@ -3184,7 +3184,7 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
return;
if (damage > 0)
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
if((skillinuse == SkillDragonPunch) && GetAA(aaDragonPunch) && zone->random.Int(0, 99) < 25){
SpellFinished(904, other, 10, 0, -1, spells[904].ResistDiff);
@ -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())) || (ComparativeDistanceNoZ(static_cast<xyz_location>(m_Position), m_PreSummonLocation) < 10)) {
if(GetTarget())
FaceTarget(GetTarget());
SetHasBeenSummoned(false);
@ -3363,8 +3363,8 @@ void Bot::AI_Process() {
if(GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this)
{
Log.Out(Logs::Detail, Logs::AI, "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;
}
}
@ -3505,7 +3505,7 @@ void Bot::AI_Process() {
if(IsBotCasterCombatRange(GetTarget()))
atCombatRange = true;
}
else if(DistNoRoot(*GetTarget()) <= meleeDistance) {
else if(ComparativeDistance(m_Position, GetTarget()->GetPosition()) <= meleeDistance) {
atCombatRange = true;
}
@ -3533,7 +3533,7 @@ void Bot::AI_Process() {
return;
}
}
else if(!IsMoving() && GetClass() != ROGUE && (DistNoRootNoZ(*GetTarget()) < GetTarget()->GetSize())) {
else if(!IsMoving() && GetClass() != ROGUE && (ComparativeDistanceNoZ(m_Position, GetTarget()->GetPosition()) < GetTarget()->GetSize())) {
// If we are not a rogue trying to backstab, let's try to adjust our melee range so we don't appear to be bunched up
float newX = 0;
float newY = 0;
@ -3732,7 +3732,7 @@ void Bot::AI_Process() {
Mob* follow = entity_list.GetMob(GetFollowID());
if(follow) {
float dist = DistNoRoot(*follow);
float dist = ComparativeDistance(m_Position, follow->GetPosition());
float speed = follow->GetRunspeed();
if(dist < GetFollowDistance() + 1000)
@ -3865,7 +3865,7 @@ void Bot::PetAIProcess() {
return;
}
}
else if(botPet->DistNoRootNoZ(*botPet->GetTarget()) < botPet->GetTarget()->GetSize()) {
else if(ComparativeDistanceNoZ(botPet->GetPosition(), botPet->GetTarget()->GetPosition()) < botPet->GetTarget()->GetSize()) {
// Let's try to adjust our melee range so we don't appear to be bunched up
bool isBehindMob = false;
bool moveBehindMob = false;
@ -4003,7 +4003,7 @@ void Bot::PetAIProcess() {
switch(pStandingPetOrder) {
case SPO_Follow:
{
float dist = botPet->DistNoRoot(*botPet->GetTarget());
float dist = ComparativeDistance(botPet->GetPosition(), botPet->GetTarget()->GetPosition());
botPet->SetRunAnimSpeed(0);
if(dist > 184) {
botPet->CalculateNewPosition2(botPet->GetTarget()->GetX(), botPet->GetTarget()->GetY(), botPet->GetTarget()->GetZ(), botPet->GetTarget()->GetRunspeed());
@ -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);
@ -6249,7 +6249,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
MeleeLifeTap(damage);
if (damage > 0)
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
//break invis when you attack
if(invisible) {
@ -7705,7 +7705,7 @@ void Bot::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
if (HasDied()) return;
if (max_damage > 0)
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
//[AA Dragon Punch] value[0] = 100 for 25%, chance value[1] = skill
if(aabonuses.SpecialAttackKBProc[0] && aabonuses.SpecialAttackKBProc[1] == skill){
@ -8418,7 +8418,7 @@ void Bot::ProcessBotOwnerRefDelete(Mob* botOwner) {
std::list<Bot*> BotList = entity_list.GetBotsByBotOwnerCharacterID(botOwner->CastToClient()->CharacterID());
if(!BotList.empty()) {
for(std::list<Bot*>::iterator botListItr = BotList.begin(); botListItr != BotList.end(); botListItr++) {
for(std::list<Bot*>::iterator botListItr = BotList.begin(); botListItr != BotList.end(); ++botListItr) {
Bot* tempBot = *botListItr;
if(tempBot) {
@ -9074,7 +9074,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())) {
Log.Out(Logs::Detail, Logs::Spells, "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);
@ -9330,7 +9330,7 @@ int32 Bot::GenerateBaseManaPoints()
{
case 'I':
WisInt = INT;
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= EQClientSoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if(WisInt > 100) {
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
if(WisInt > 201) {
@ -9373,7 +9373,7 @@ int32 Bot::GenerateBaseManaPoints()
case 'W':
WisInt = WIS;
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= EQClientSoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if(WisInt > 100) {
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
if(WisInt > 201) {
@ -9612,7 +9612,7 @@ int32 Bot::GetMaxStat() {
if (level < 61) {
base = 255;
}
else if (GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= EQClientSoF) {
else if (GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= ClientVersion::SoF) {
base = 255 + 5 * (level - 60);
}
else if (level < 71) {
@ -10232,7 +10232,7 @@ int32 Bot::CalcBaseEndurance()
int32 sta_end = 0;
int Stats = 0;
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= EQClientSoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
int HeroicStats = 0;
Stats = ((GetSTR() + GetSTA() + GetDEX() + GetAGI()) / 4);
@ -10385,7 +10385,7 @@ bool Bot::IsArcheryRange(Mob *target) {
range *= range;
float targetDistance = DistNoRootNoZ(*target);
float targetDistance = ComparativeDistanceNoZ(m_Position, target->GetPosition());
float minRuleDistance = RuleI(Combat, MinRangedAttackDist) * RuleI(Combat, MinRangedAttackDist);
@ -10409,7 +10409,7 @@ bool Bot::IsBotCasterCombatRange(Mob *target) {
// half the max so the bot doesn't always stop at max range to allow combat movement
range *= .5;
float targetDistance = DistNoRootNoZ(*target);
float targetDistance = ComparativeDistanceNoZ(m_Position, target->GetPosition());
if(targetDistance > range)
result = false;
@ -10661,12 +10661,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());
}
}
}
@ -11675,7 +11675,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());
}
}
}
@ -15739,47 +15739,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.");
}
}
@ -15817,7 +15809,7 @@ void EntityList::ShowSpawnWindow(Client* client, int Distance, bool NamedOnly) {
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
curMob = it->second;
if (curMob && curMob->DistNoZ(*client)<=Distance) {
if (curMob && DistanceNoZ(curMob->GetPosition(), client->GetPosition()) <= Distance) {
if(curMob->IsTrackable()) {
Mob* cur_entity = curMob;
int Extras = (cur_entity->IsBot() || cur_entity->IsPet() || cur_entity->IsFamiliar() || cur_entity->IsClient());
@ -16166,11 +16158,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

@ -898,7 +898,7 @@ bool Bot::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain
if (AIspells[i].type & SpellType_Escape) {
dist2 = 0;
} else
dist2 = DistNoRoot(*tar);
dist2 = ComparativeDistance(m_Position, tar->GetPosition());
if (((((spells[AIspells[i].spellid].targettype==ST_GroupTeleport && AIspells[i].type==2)
|| spells[AIspells[i].spellid].targettype==ST_AECaster
@ -1755,7 +1755,7 @@ Mob* Bot::GetFirstIncomingMobToMez(Bot* botCaster, BotSpell botSpell) {
for(std::list<NPC*>::iterator itr = npc_list.begin(); itr != npc_list.end(); ++itr) {
NPC* npc = *itr;
if(npc->DistNoRootNoZ(*botCaster) <= botCaster->GetActSpellRange(botSpell.SpellId, spells[botSpell.SpellId].range)) {
if(ComparativeDistanceNoZ(npc->GetPosition(), botCaster->GetPosition()) <= botCaster->GetActSpellRange(botSpell.SpellId, spells[botSpell.SpellId].range)) {
if(!npc->IsMezzed()) {
if(botCaster->HasGroup()) {
Group* g = botCaster->GetGroup();

View File

@ -41,6 +41,7 @@ extern volatile bool RunLoops;
#include "../common/rulesys.h"
#include "../common/string_util.h"
#include "../common/data_verification.h"
#include "position.h"
#include "net.h"
#include "worldserver.h"
#include "zonedb.h"
@ -76,10 +77,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
@ -145,7 +143,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;
@ -191,16 +193,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;
@ -251,7 +247,7 @@ Client::Client(EQStreamInterface* ieqs)
GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS));
AttemptedMessages = 0;
TotalKarma = 0;
ClientVersion = EQClientUnknown;
m_ClientVersion = ClientVersion::Unknown;
ClientVersionBit = 0;
AggroCount = 0;
RestRegenHP = 0;
@ -269,13 +265,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;
@ -382,9 +371,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
@ -508,11 +497,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) {
@ -529,8 +518,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);
@ -995,7 +986,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
CheckEmoteHail(GetTarget(), message);
if(DistNoRootNoZ(*GetTarget()) <= 200) {
if(ComparativeDistanceNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
NPC *tar = GetTarget()->CastToNPC();
parse->EventNPC(EVENT_SAY, tar->CastToNPC(), this, message, language);
@ -1007,7 +998,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
}
}
else {
if (DistNoRootNoZ(*GetTarget()) <= 200) {
if (ComparativeDistanceNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
parse->EventNPC(EVENT_AGGRO_SAY, GetTarget()->CastToNPC(), this, message, language);
}
}
@ -1441,7 +1432,7 @@ void Client::UpdateWho(uint8 remove) {
else if (m_pp.anon >= 2)
scl->anon = 2;
scl->ClientVersion = GetClientVersion();
scl->ClientVersion = static_cast<unsigned int>(GetClientVersion());
scl->tellsoff = tellsoff;
scl->guild_id = guild_id;
scl->LFG = LFG;
@ -1697,7 +1688,7 @@ void Client::SendManaUpdatePacket() {
if (!Connected() || IsCasting())
return;
if (GetClientVersion() >= EQClientSoD) {
if (GetClientVersion() >= ClientVersion::SoD) {
SendManaUpdate();
SendEnduranceUpdate();
}
@ -1732,7 +1723,7 @@ void Client::SendManaUpdatePacket() {
for(int i = 0; i < MAX_GROUP_MEMBERS; ++i)
if(g->members[i] && g->members[i]->IsClient() && (g->members[i] != this) && (g->members[i]->CastToClient()->GetClientVersion() >= EQClientSoD))
if(g->members[i] && g->members[i]->IsClient() && (g->members[i] != this) && (g->members[i]->CastToClient()->GetClientVersion() >= ClientVersion::SoD))
{
g->members[i]->CastToClient()->QueuePacket(outapp);
g->members[i]->CastToClient()->QueuePacket(outapp2);
@ -1912,7 +1903,7 @@ void Client::ReadBook(BookRequest_Struct *book) {
BookText_Struct *out = (BookText_Struct *) outapp->pBuffer;
out->window = book->window;
if(GetClientVersion() >= EQClientSoF)
if(GetClientVersion() >= ClientVersion::SoF)
{
const ItemInst *inst = m_inv[book->invslot];
if(inst)
@ -2538,7 +2529,7 @@ bool Client::BindWound(Mob* bindmob, bool start, bool fail){
}
else {
if (!GetFeigned() && (bindmob->DistNoRoot(*this) <= 400)) {
if (!GetFeigned() && (ComparativeDistance(bindmob->GetPosition(), m_Position) <= 400)) {
// send bindmob bind done
if(!bindmob->IsAIControlled() && bindmob != this ) {
@ -3177,7 +3168,7 @@ void Client::Insight(uint32 t_id)
Message(0,"This ability can only be used on NPCs.");
return;
}
if (Dist(*who) > 200)
if (Distance(static_cast<xyz_location>(m_Position), static_cast<xyz_location>(who->GetPosition())) > 200)
{
Message(0,"You must get closer to your target!");
return;
@ -3672,7 +3663,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];
@ -4060,7 +4051,7 @@ bool Client::GroupFollow(Client* inviter) {
group->UpdateGroupAAs();
//Invite the inviter into the group first.....dont ask
if (inviter->GetClientVersion() < EQClientSoD)
if (inviter->GetClientVersion() < ClientVersion::SoD)
{
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
GroupJoin_Struct* outgj = (GroupJoin_Struct*)outapp->pBuffer;
@ -4106,13 +4097,13 @@ bool Client::GroupFollow(Client* inviter) {
return false;
}
if (GetClientVersion() >= EQClientSoD)
if (GetClientVersion() >= ClientVersion::SoD)
{
SendGroupJoinAcknowledge();
}
// Temporary hack for SoD, as things seem to work quite differently
if (inviter->IsClient() && inviter->GetClientVersion() >= EQClientSoD)
if (inviter->IsClient() && inviter->GetClientVersion() >= ClientVersion::SoD)
{
database.RefreshGroupFromDB(inviter);
}
@ -4122,7 +4113,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.
@ -4346,7 +4337,7 @@ void Client::IncrementAggroCount() {
if (AggroCount == 1)
SavedRaidRestTimer = rest_timer.GetRemainingTime();
if(GetClientVersion() >= EQClientSoF) {
if(GetClientVersion() >= ClientVersion::SoF) {
EQApplicationPacket *outapp = new EQApplicationPacket(OP_RestState, 1);
char *Buffer = (char *)outapp->pBuffer;
@ -4391,7 +4382,7 @@ void Client::DecrementAggroCount() {
rest_timer.Start(time_until_rest);
if(GetClientVersion() >= EQClientSoF) {
if(GetClientVersion() >= ClientVersion::SoF) {
EQApplicationPacket *outapp = new EQApplicationPacket(OP_RestState, 5);
char *Buffer = (char *)outapp->pBuffer;
@ -4548,7 +4539,7 @@ void Client::HandleLDoNOpen(NPC *target)
return;
}
if(DistNoRootNoZ(*target) > RuleI(Adventure, LDoNTrapDistanceUse))
if(ComparativeDistanceNoZ(m_Position, target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse))
{
Log.Out(Logs::General, Logs::None, "%s tried to open %s but %s was out of range",
GetName(), target->GetName(), target->GetName());
@ -4786,8 +4777,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.");
@ -4802,13 +4792,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));
@ -4824,12 +4812,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()
@ -5738,14 +5721,14 @@ void Client::GuildBankAck()
FastQueuePacket(&outapp);
}
void Client::GuildBankDepositAck(bool Fail)
void Client::GuildBankDepositAck(bool Fail, int8 action)
{
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildBank, sizeof(GuildBankDepositAck_Struct));
GuildBankDepositAck_Struct *gbdas = (GuildBankDepositAck_Struct*) outapp->pBuffer;
gbdas->Action = GuildBankDeposit;
gbdas->Action = action;
gbdas->Fail = Fail ? 1 : 0;
@ -6184,7 +6167,7 @@ void Client::DragCorpses()
Mob *corpse = entity_list.GetMob(It->second);
if (corpse && corpse->IsPlayerCorpse() &&
(DistNoRootNoZ(*corpse) <= RuleR(Character, DragCorpseDistance)))
(ComparativeDistanceNoZ(m_Position, corpse->GetPosition()) <= RuleR(Character, DragCorpseDistance)))
continue;
if (!corpse || !corpse->IsPlayerCorpse() ||
@ -6271,8 +6254,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] = {
xy_location(5, 5), xy_location(-5, 5), xy_location(5, -5), xy_location(-5, -5),
xy_location(10, 10), xy_location(-10, 10), xy_location(10, -10), xy_location(-10, -10),
xy_location(8, 8), xy_location(-8, 8), xy_location(8, -8), xy_location(-8, -8)
};
while(summon_count > 0) {
NPCType *npc_dup = nullptr;
@ -6284,8 +6270,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;
@ -6799,7 +6785,7 @@ void Client::SendStatsWindow(Client* client, bool use_window)
if(use_window) {
if(final_stats.size() < 4096)
{
uint32 Buttons = (client->GetClientVersion() < EQClientSoD) ? 0 : 1;
uint32 Buttons = (client->GetClientVersion() < ClientVersion::SoD) ? 0 : 1;
client->SendWindow(0, POPUPID_UPDATE_SHOWSTATSWINDOW, Buttons, "Cancel", "Update", 0, 1, this, "", "%s", final_stats.c_str());
goto Extra_Info;
}
@ -6835,7 +6821,7 @@ void Client::SendStatsWindow(Client* client, bool use_window)
}
void Client::SendAltCurrencies() {
if(GetClientVersion() >= EQClientSoF) {
if(GetClientVersion() >= ClientVersion::SoF) {
uint32 count = zone->AlternateCurrencies.size();
if(count == 0) {
return;
@ -7313,7 +7299,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)
@ -7326,7 +7312,7 @@ void Client::SendMercPersonalInfo()
if(mercData)
{
if (GetClientVersion() >= EQClientRoF)
if (GetClientVersion() >= ClientVersion::RoF)
{
if (mercCount > 0)
{
@ -7415,7 +7401,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);
@ -1019,8 +1019,9 @@ public:
inline int ActiveTasksInSet(int TaskSet) { return (taskstate ? taskstate->ActiveTasksInSet(TaskSet) :0); }
inline int CompletedTasksInSet(int TaskSet) { return (taskstate ? taskstate->CompletedTasksInSet(TaskSet) :0); }
inline const EQClientVersion GetClientVersion() const { return ClientVersion; }
inline const ClientVersion GetClientVersion() const { return m_ClientVersion; }
inline const uint32 GetClientVersionBit() const { return ClientVersionBit; }
inline void SetClientVersion(ClientVersion in) { m_ClientVersion = in; }
/** Adventure Stuff **/
void SendAdventureError(const char *error);
@ -1078,7 +1079,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();
@ -1097,7 +1098,7 @@ public:
QGlobalCache *GetQGlobals() { return qGlobals; }
QGlobalCache *CreateQGlobals() { qGlobals = new QGlobalCache(); return qGlobals; }
void GuildBankAck();
void GuildBankDepositAck(bool Fail);
void GuildBankDepositAck(bool Fail, int8 action);
inline bool IsGuildBanker() { return GuildBanker; }
void ClearGuildBank();
void SendGroupCreatePacket();
@ -1267,11 +1268,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 +1424,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 +1464,7 @@ private:
Timer RespawnFromHoverTimer;
Timer merc_timer;
float proximity_x;
float proximity_y;
float proximity_z;
xyz_location m_Proximity;
void BulkSendInventoryItems();
@ -1511,7 +1507,7 @@ private:
Timer *GlobalChatLimiterTimer; //60 seconds
uint32 AttemptedMessages;
EQClientVersion ClientVersion;
ClientVersion m_ClientVersion;
uint32 ClientVersionBit;
int XPRate;

View File

@ -44,7 +44,7 @@ int32 Client::GetMaxStat() const {
if (level < 61) {
base = 255;
}
else if (GetClientVersion() >= EQClientSoF) {
else if (GetClientVersion() >= ClientVersion::SoF) {
base = 255 + 5 * (level - 60);
}
else if (level < 71) {
@ -368,7 +368,7 @@ uint32 Mob::GetClassLevelFactor(){
int32 Client::CalcBaseHP()
{
if(GetClientVersion() >= EQClientSoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if(GetClientVersion() >= ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
int stats = GetSTA();
if(stats > 255) {
stats = (stats - 255) / 2;
@ -974,7 +974,7 @@ int32 Client::CalcBaseMana()
case 'I':
WisInt = GetINT();
if (GetClientVersion() >= EQClientSoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if (GetClientVersion() >= ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if (WisInt > 100) {
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
@ -1009,7 +1009,7 @@ int32 Client::CalcBaseMana()
case 'W':
WisInt = GetWIS();
if (GetClientVersion() >= EQClientSoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if (GetClientVersion() >= ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if (WisInt > 100) {
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
@ -1173,7 +1173,7 @@ uint32 Client::CalcCurrentWeight() {
*/
// SoD+ client has no weight for coin
if (EQLimits::CoinHasWeight(ClientVersion))
if (EQLimits::CoinHasWeight(GetClientVersion()))
Total += (m_pp.platinum + m_pp.gold + m_pp.silver + m_pp.copper) / 4;
float Packrat = (float)spellbonuses.Packrat + (float)aabonuses.Packrat + (float)itembonuses.Packrat;
@ -1926,7 +1926,7 @@ int32 Client::CalcBaseEndurance()
{
int32 base_end = 0;
if(GetClientVersion() >= EQClientSoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if(GetClientVersion() >= ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
double heroic_stats = (GetHeroicSTR() + GetHeroicSTA() + GetHeroicDEX() + GetHeroicAGI()) / 4.0f;
double stats = (GetSTR() + GetSTA() + GetDEX() + GetAGI()) / 4.0f;

View File

@ -510,7 +510,7 @@ void Client::CompleteConnect()
if (IsInAGuild()){
uint8 rank = GuildRank();
if (GetClientVersion() >= EQClientRoF)
if (GetClientVersion() >= ClientVersion::RoF)
{
switch (rank) {
case 0: { rank = 5; break; } // GUILD_MEMBER 0
@ -824,7 +824,7 @@ void Client::CompleteConnect()
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks)
GuildBanks->SendGuildBank(this);
if (GetClientVersion() >= EQClientSoD)
if (GetClientVersion() >= ClientVersion::SoD)
entity_list.SendFindableNPCList(this);
if (IsInAGuild()) {
@ -1036,7 +1036,7 @@ void Client::Handle_Connect_OP_ReqClientSpawn(const EQApplicationPacket *app)
outapp = new EQApplicationPacket(OP_SendExpZonein, 0);
FastQueuePacket(&outapp);
if (GetClientVersion() >= EQClientRoF)
if (GetClientVersion() >= ClientVersion::RoF)
{
outapp = new EQApplicationPacket(OP_ClientReady, 0);
FastQueuePacket(&outapp);
@ -1310,14 +1310,12 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
conn_state = ReceivedZoneEntry;
ClientVersion = Connection()->ClientVersion();
if (ClientVersion != EQClientUnknown)
ClientVersionBit = 1 << (ClientVersion - 1);
else
ClientVersionBit = 0;
SetClientVersion(Connection()->GetClientVersion());
if (m_ClientVersion != ClientVersion::Unknown)
ClientVersionBit = 1 << (static_cast<unsigned int>(m_ClientVersion) - 1);
bool siv = m_inv.SetInventoryVersion(ClientVersion);
Log.Out(Logs::General, Logs::None, "%s inventory version to %s(%i)", (siv ? "Succeeded in setting" : "Failed to set"), EQClientVersionName(ClientVersion), ClientVersion);
bool siv = m_inv.SetInventoryVersion(m_ClientVersion);
Log.Out(Logs::General, Logs::None, "%s inventory version to %s(%i)", (siv ? "Succeeded in setting" : "Failed to set"), ClientVersionName(m_ClientVersion), m_ClientVersion);
/* Antighost code
tmp var is so the search doesnt find this object
@ -1456,9 +1454,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);
@ -1468,10 +1467,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;
@ -1499,7 +1498,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
m_pp.guild_id = GuildID();
uint8 rank = guild_mgr.GetDisplayedRank(GuildID(), GuildRank(), CharacterID());
// FIXME: RoF guild rank
if (GetClientVersion() >= EQClientRoF) {
if (GetClientVersion() >= ClientVersion::RoF) {
switch (rank) {
case 0:
rank = 5;
@ -1850,7 +1849,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
/* Task Packets */
LoadClientTaskState();
if (GetClientVersion() >= EQClientRoF) {
if (GetClientVersion() >= ClientVersion::RoF) {
outapp = new EQApplicationPacket(OP_ReqNewZone, 0);
Handle_Connect_OP_ReqNewZone(outapp);
safe_delete(outapp);
@ -2029,7 +2028,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app)
return;
//you have to be somewhat close to them to be properly using them
if (DistNoRoot(*tmp) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, tmp->GetPosition()) > USE_NPC_RANGE2)
return;
merchantid = tmp->CastToNPC()->MerchantType;
@ -2204,7 +2203,7 @@ void Client::Handle_OP_AdventureMerchantRequest(const EQApplicationPacket *app)
return;
//you have to be somewhat close to them to be properly using them
if (DistNoRoot(*tmp) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, tmp->GetPosition()) > USE_NPC_RANGE2)
return;
merchantid = tmp->CastToNPC()->MerchantType;
@ -2295,7 +2294,7 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app)
return;
}
if (DistNoRoot(*vendor) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, vendor->GetPosition()) > USE_NPC_RANGE2)
{
Message(13, "Vendor is out of range.");
return;
@ -2553,7 +2552,7 @@ void Client::Handle_OP_AltCurrencyMerchantRequest(const EQApplicationPacket *app
NPC* tar = entity_list.GetNPCByID(*((uint32*)app->pBuffer));
if (tar) {
if (DistNoRoot(*tar) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, tar->GetPosition()) > USE_NPC_RANGE2)
return;
if (tar->GetClass() != ALT_CURRENCY_MERCHANT) {
@ -2632,7 +2631,7 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app)
AltCurrencyPurchaseItem_Struct *purchase = (AltCurrencyPurchaseItem_Struct*)app->pBuffer;
NPC* tar = entity_list.GetNPCByID(purchase->merchant_entity_id);
if (tar) {
if (DistNoRoot(*tar) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, tar->GetPosition())> USE_NPC_RANGE2)
return;
if (tar->GetClass() != ALT_CURRENCY_MERCHANT) {
@ -2769,7 +2768,7 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app)
NPC* tar = entity_list.GetNPCByID(sell->merchant_entity_id);
if (tar) {
if (DistNoRoot(*tar) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, tar->GetPosition()) > USE_NPC_RANGE2)
return;
if (tar->GetClass() != ALT_CURRENCY_MERCHANT) {
@ -2866,7 +2865,7 @@ void Client::Handle_OP_AltCurrencySellSelection(const EQApplicationPacket *app)
AltCurrencySelectItem_Struct *select = (AltCurrencySelectItem_Struct*)app->pBuffer;
NPC* tar = entity_list.GetNPCByID(select->merchant_entity_id);
if (tar) {
if (DistNoRoot(*tar) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, tar->GetPosition()) > USE_NPC_RANGE2)
return;
if (tar->GetClass() != ALT_CURRENCY_MERCHANT) {
@ -3024,7 +3023,7 @@ void Client::Handle_OP_Assist(const EQApplicationPacket *app)
if (assistee->GetTarget()) {
Mob *new_target = assistee->GetTarget();
if (new_target && (GetGM() ||
Dist(*assistee) <= TARGETING_RANGE)) {
Distance(m_Position, assistee->GetPosition()) <= TARGETING_RANGE)) {
SetAssistExemption(true);
eid->entity_id = new_target->GetID();
}
@ -3078,7 +3077,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
// Delegate to tradeskill object to perform combine
AugmentItem_Struct* in_augment = (AugmentItem_Struct*)app->pBuffer;
bool deleteItems = false;
if (GetClientVersion() >= EQClientRoF)
if (GetClientVersion() >= ClientVersion::RoF)
{
ItemInst *itemOneToPush = nullptr, *itemTwoToPush = nullptr;
@ -3240,13 +3239,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 +3254,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;
@ -3998,9 +3982,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
Log.Out(Logs::General, Logs::None, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[0], castspell->cs_unknown[0]);
@ -4032,9 +4014,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);
}
@ -4378,7 +4358,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;
@ -4394,9 +4375,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);
@ -4539,51 +4520,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;
@ -4603,13 +4574,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;
@ -4621,13 +4593,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;
}
@ -5190,7 +5157,7 @@ void Client::Handle_OP_DeleteItem(const EQApplicationPacket *app)
int16 AlcoholTolerance = GetSkill(SkillAlcoholTolerance);
int16 IntoxicationIncrease;
if (GetClientVersion() < EQClientSoD)
if (GetClientVersion() < ClientVersion::SoD)
IntoxicationIncrease = (200 - AlcoholTolerance) * 30 / 200 + 10;
else
IntoxicationIncrease = (270 - AlcoholTolerance) * 0.111111108 + 10;
@ -5507,7 +5474,7 @@ void Client::Handle_OP_EndLootRequest(const EQApplicationPacket *app)
Entity* entity = entity_list.GetID(*((uint16*)app->pBuffer));
if (entity == 0) {
Message(13, "Error: OP_EndLootRequest: Corpse not found (ent = 0)");
if (GetClientVersion() >= EQClientSoD)
if (GetClientVersion() >= ClientVersion::SoD)
Corpse::SendEndLootErrorPacket(this);
else
Corpse::SendLootReqErrorPacket(this);
@ -6617,7 +6584,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())
{
@ -6632,7 +6599,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();
@ -6868,13 +6835,28 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
char *Buffer = (char *)app->pBuffer;
uint32 Action = VARSTRUCT_DECODE_TYPE(uint32, Buffer);
uint32 sentAction = Action;
if (GetClientVersion() >= ClientVersion::RoF)
{
Action += 1;
/*
// Need to find all of the action types for RoF and switch case here
switch(Action)
{
case 4:
Action = 5;
break;
}
*/
}
if (!IsInAGuild())
{
Message(13, "You must be in a Guild to use the Guild Bank.");
if (Action == GuildBankDeposit)
GuildBankDepositAck(true);
GuildBankDepositAck(true, sentAction);
else
GuildBankAck();
@ -6901,7 +6883,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
{
Message_StringID(13, GUILD_BANK_FULL);
GuildBankDepositAck(true);
GuildBankDepositAck(true, sentAction);
return;
}
@ -6950,7 +6932,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
{
Message_StringID(13, GUILD_BANK_FULL);
GuildBankDepositAck(true);
GuildBankDepositAck(true, sentAction);
return;
}
@ -6963,7 +6945,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
{
Message(13, "No Item on the cursor.");
GuildBankDepositAck(true);
GuildBankDepositAck(true, sentAction);
return;
}
@ -6994,14 +6976,14 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
if (!Allowed)
{
Message_StringID(13, GUILD_BANK_CANNOT_DEPOSIT);
GuildBankDepositAck(true);
GuildBankDepositAck(true, sentAction);
return;
}
if (GuildBanks->AddItem(GuildID(), GuildBankDepositArea, CursorItem->ID, CursorItemInst->GetCharges(), GetName(), GuildBankBankerOnly, ""))
{
GuildBankDepositAck(false);
GuildBankDepositAck(false, sentAction);
DeleteItemInInventory(MainCursor, 0, false);
}
@ -7416,7 +7398,7 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app)
GuildInviteAccept_Struct* gj = (GuildInviteAccept_Struct*)app->pBuffer;
if (GetClientVersion() >= EQClientRoF)
if (GetClientVersion() >= ClientVersion::RoF)
{
if (gj->response > 9)
{
@ -7476,7 +7458,7 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app)
uint32 guildrank = gj->response;
if (GetClientVersion() >= EQClientRoF)
if (GetClientVersion() >= ClientVersion::RoF)
{
if (gj->response == 8)
{
@ -8010,7 +7992,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);
@ -8078,7 +8060,7 @@ void Client::Handle_OP_InspectRequest(const EQApplicationPacket *app)
Mob* tmp = entity_list.GetMob(ins->TargetID);
if (tmp != 0 && tmp->IsClient()) {
if (tmp->CastToClient()->GetClientVersion() < EQClientSoF) { tmp->CastToClient()->QueuePacket(app); } // Send request to target
if (tmp->CastToClient()->GetClientVersion() < ClientVersion::SoF) { tmp->CastToClient()->QueuePacket(app); } // Send request to target
// Inspecting an SoF or later client will make the server handle the request
else { ProcessInspectRequest(tmp->CastToClient(), this); }
}
@ -8598,7 +8580,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
}
else
{
if (GetClientVersion() >= EQClientSoD && !inst->IsEquipable(GetBaseRace(), GetClass()))
if (GetClientVersion() >= ClientVersion::SoD && !inst->IsEquipable(GetBaseRace(), GetClass()))
{
if (item->ItemType != ItemTypeFood && item->ItemType != ItemTypeDrink && item->ItemType != ItemTypeAlcohol)
{
@ -8719,7 +8701,7 @@ void Client::Handle_OP_LDoNDisarmTraps(const EQApplicationPacket *app)
{
if (HasSkill(SkillDisarmTraps))
{
if (DistNoRootNoZ(*target) > RuleI(Adventure, LDoNTrapDistanceUse))
if (ComparativeDistanceNoZ(m_Position, target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse))
{
Message(13, "%s is too far away.", target->GetCleanName());
return;
@ -8752,7 +8734,7 @@ void Client::Handle_OP_LDoNPickLock(const EQApplicationPacket *app)
{
if (HasSkill(SkillPickLock))
{
if (DistNoRootNoZ(*target) > RuleI(Adventure, LDoNTrapDistanceUse))
if (ComparativeDistanceNoZ(m_Position, target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse))
{
Message(13, "%s is too far away.", target->GetCleanName());
return;
@ -8771,7 +8753,7 @@ void Client::Handle_OP_LDoNSenseTraps(const EQApplicationPacket *app)
{
if (HasSkill(SkillSenseTraps))
{
if (DistNoRootNoZ(*target) > RuleI(Adventure, LDoNTrapDistanceUse))
if (ComparativeDistanceNoZ(m_Position, target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse))
{
Message(13, "%s is too far away.", target->GetCleanName());
return;
@ -9192,7 +9174,7 @@ void Client::Handle_OP_LootRequest(const EQApplicationPacket *app)
{
SetLooting(ent->GetID()); //store the entity we are looting
Corpse *ent_corpse = ent->CastToCorpse();
if (DistNoRootNoZ(ent_corpse->GetX(), ent_corpse->GetY()) > 625)
if (ComparativeDistanceNoZ(m_Position, ent_corpse->GetPosition()) > 625)
{
Message(13, "Corpse too far away.");
Corpse::SendLootReqErrorPacket(this);
@ -9424,21 +9406,21 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app)
int mercTypeCount = 0;
int mercCount = 0;
if (DistNoRoot(*tar) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, tar->GetPosition()) > USE_NPC_RANGE2)
return;
if (tar->GetClass() != MERCERNARY_MASTER) {
return;
}
mercTypeCount = tar->GetNumMercTypes(GetClientVersion());
mercCount = tar->GetNumMercs(GetClientVersion());
mercTypeCount = tar->GetNumMercTypes(static_cast<unsigned int>(GetClientVersion()));
mercCount = tar->GetNumMercs(static_cast<unsigned int>(GetClientVersion()));
if (mercCount > MAX_MERC)
return;
std::list<MercType> mercTypeList = tar->GetMercTypesList(GetClientVersion());
std::list<MercData> mercDataList = tar->GetMercsList(GetClientVersion());
std::list<MercType> mercTypeList = tar->GetMercTypesList(static_cast<unsigned int>(GetClientVersion()));
std::list<MercData> mercDataList = tar->GetMercsList(static_cast<unsigned int>(GetClientVersion()));
int i = 0;
int StanceCount = 0;
@ -9805,7 +9787,7 @@ void Client::Handle_OP_OpenGuildTributeMaster(const EQApplicationPacket *app)
StartTribute_Struct* st = (StartTribute_Struct*)app->pBuffer;
Mob* tribmast = entity_list.GetMob(st->tribute_master_id);
if (tribmast && tribmast->IsNPC() && tribmast->GetClass() == GUILD_TRIBUTE_MASTER
&& DistNoRoot(*tribmast) <= USE_NPC_RANGE2) {
&& ComparativeDistance(m_Position, tribmast->GetPosition()) <= USE_NPC_RANGE2) {
st->response = 1;
QueuePacket(app);
tribute_master_id = st->tribute_master_id;
@ -9836,7 +9818,7 @@ void Client::Handle_OP_OpenTributeMaster(const EQApplicationPacket *app)
StartTribute_Struct* st = (StartTribute_Struct*)app->pBuffer;
Mob* tribmast = entity_list.GetMob(st->tribute_master_id);
if (tribmast && tribmast->IsNPC() && tribmast->GetClass() == TRIBUTE_MASTER
&& DistNoRoot(*tribmast) <= USE_NPC_RANGE2) {
&& ComparativeDistance(m_Position, tribmast->GetPosition()) <= USE_NPC_RANGE2) {
st->response = 1;
QueuePacket(app);
tribute_master_id = st->tribute_master_id;
@ -9931,7 +9913,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
}
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
if (GetTarget() != this && mypet->DistNoRootNoZ(*GetTarget()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
if (GetTarget() != this && ComparativeDistanceNoZ(mypet->GetPosition(), GetTarget()->GetPosition()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
if (mypet->IsHeld()) {
if (!mypet->IsFocused()) {
mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
@ -9966,7 +9948,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
}
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
if (GetTarget() != this && mypet->DistNoRootNoZ(*GetTarget()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
if (GetTarget() != this && ComparativeDistanceNoZ(mypet->GetPosition(), GetTarget()->GetPosition()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
zone->AddAggroMob();
mypet->AddToHateList(GetTarget(), 1);
Message_StringID(MT_PetResponse, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName());
@ -11336,7 +11318,7 @@ void Client::Handle_OP_ReadBook(const EQApplicationPacket *app)
}
BookRequest_Struct* book = (BookRequest_Struct*)app->pBuffer;
ReadBook(book);
if (GetClientVersion() >= EQClientSoF)
if (GetClientVersion() >= ClientVersion::SoF)
{
EQApplicationPacket EndOfBook(OP_FinishWindow, 0);
QueuePacket(&EndOfBook);
@ -11683,7 +11665,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);
}
}
@ -11805,29 +11787,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);
@ -12107,7 +12089,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
if (mp->quantity < 1) return;
//you have to be somewhat close to them to be properly using them
if (DistNoRoot(*tmp) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, tmp->GetPosition()) > USE_NPC_RANGE2)
return;
merchantid = tmp->CastToNPC()->MerchantType;
@ -12356,7 +12338,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
return;
//you have to be somewhat close to them to be properly using them
if (DistNoRoot(*vendor) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, vendor->GetPosition()) > USE_NPC_RANGE2)
return;
uint32 price = 0;
@ -12515,7 +12497,7 @@ void Client::Handle_OP_ShopRequest(const EQApplicationPacket *app)
return;
//you have to be somewhat close to them to be properly using them
if (DistNoRoot(*tmp) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, tmp->GetPosition()) > USE_NPC_RANGE2)
return;
merchantid = tmp->CastToNPC()->MerchantType;
@ -12650,7 +12632,7 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app)
{
if (!HasSkill(SkillHide) && GetSkill(SkillHide) == 0)
{
if (GetClientVersion() < EQClientSoF)
if (GetClientVersion() < ClientVersion::SoF)
{
char *hack_str = nullptr;
MakeAnyLenString(&hack_str, "Player sent OP_SpawnAppearance with AT_Invis: %i", sa->parameter);
@ -12904,9 +12886,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);
@ -13011,7 +12993,7 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app)
// For /target, send reject or success packet
if (app->GetOpcode() == OP_TargetCommand) {
if (GetTarget() && !GetTarget()->CastToMob()->IsInvisible(this) && (DistNoRoot(*GetTarget()) <= TARGETING_RANGE*TARGETING_RANGE || GetGM())) {
if (GetTarget() && !GetTarget()->CastToMob()->IsInvisible(this) && (ComparativeDistance(m_Position, GetTarget()->GetPosition()) <= TARGETING_RANGE*TARGETING_RANGE || GetGM())) {
if (GetTarget()->GetBodyType() == BT_NoTarget2 || GetTarget()->GetBodyType() == BT_Special
|| GetTarget()->GetBodyType() == BT_NoTarget)
{
@ -13100,9 +13082,9 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app)
}
else if (GetBindSightTarget())
{
if (GetBindSightTarget()->DistNoRoot(*GetTarget()) > (zone->newzone_data.maxclip*zone->newzone_data.maxclip))
if (ComparativeDistance(GetBindSightTarget()->GetPosition(), GetTarget()->GetPosition()) > (zone->newzone_data.maxclip*zone->newzone_data.maxclip))
{
if (DistNoRoot(*GetTarget()) > (zone->newzone_data.maxclip*zone->newzone_data.maxclip))
if (ComparativeDistance(m_Position, GetTarget()->GetPosition()) > (zone->newzone_data.maxclip*zone->newzone_data.maxclip))
{
char *hacker_str = nullptr;
MakeAnyLenString(&hacker_str, "%s attempting to target something beyond the clip plane of %.2f units,"
@ -13116,7 +13098,7 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app)
}
}
}
else if (DistNoRoot(*GetTarget()) > (zone->newzone_data.maxclip*zone->newzone_data.maxclip))
else if (ComparativeDistance(m_Position, GetTarget()->GetPosition()) > (zone->newzone_data.maxclip*zone->newzone_data.maxclip))
{
char *hacker_str = nullptr;
MakeAnyLenString(&hacker_str, "%s attempting to target something beyond the clip plane of %.2f units,"
@ -13486,7 +13468,7 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
this->Trader_StartTrader();
if (GetClientVersion() >= EQClientRoF)
if (GetClientVersion() >= ClientVersion::RoF)
{
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Trader, sizeof(TraderStatus_Struct));
TraderStatus_Struct* tss = (TraderStatus_Struct*)outapp->pBuffer;
@ -13687,7 +13669,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)))) {
@ -13708,7 +13690,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;
@ -13719,7 +13701,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);
}
}
@ -13742,7 +13724,7 @@ void Client::Handle_OP_TributeItem(const EQApplicationPacket *app)
Mob* tribmast = entity_list.GetMob(t->tribute_master_id);
if (!tribmast || !tribmast->IsNPC() || tribmast->GetClass() != TRIBUTE_MASTER)
return;
if (DistNoRoot(*tribmast) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, tribmast->GetPosition()) > USE_NPC_RANGE2)
return;
t->tribute_points = TributeItem(t->slot, t->quantity);
@ -13769,7 +13751,7 @@ void Client::Handle_OP_TributeMoney(const EQApplicationPacket *app)
Mob* tribmast = entity_list.GetMob(t->tribute_master_id);
if (!tribmast || !tribmast->IsNPC() || tribmast->GetClass() != TRIBUTE_MASTER)
return;
if (DistNoRoot(*tribmast) > USE_NPC_RANGE2)
if (ComparativeDistance(m_Position, tribmast->GetPosition()) > USE_NPC_RANGE2)
return;
t->tribute_points = TributeMoney(t->platinum);

View File

@ -126,7 +126,7 @@ bool Client::Process() {
HandleRespawnFromHover(0);
}
if(IsTracking() && (GetClientVersion() >= EQClientSoD) && TrackingTimer.Check())
if(IsTracking() && (GetClientVersion() >= ClientVersion::SoD) && TrackingTimer.Check())
DoTracking();
if(hpupdate_timer.Check())
@ -176,7 +176,7 @@ bool Client::Process() {
GetMerc()->Save();
GetMerc()->Depop();
}
Raid *myraid = entity_list.GetRaidByClient(this);
if (myraid)
{
@ -342,41 +342,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);
}
@ -531,9 +521,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);
}
}
@ -787,16 +775,16 @@ 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)
{
Log.Out(Logs::Detail, Logs::Trading, "Client disconnected during a trade. Returning their items.");
@ -806,13 +794,13 @@ void Client::OnDisconnect(bool hard_disconnect) {
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);
@ -885,7 +873,7 @@ void Client::BulkSendInventoryItems() {
}
// Power Source
if(GetClientVersion() >= EQClientSoF) {
if(GetClientVersion() >= ClientVersion::SoF) {
const ItemInst* inst = m_inv[MainPowerSource];
if(inst) {
std::string packet = inst->Serialize(MainPowerSource);
@ -1557,7 +1545,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{
@ -1615,7 +1603,7 @@ void Client::OPGMTraining(const EQApplicationPacket *app)
return;
//you have to be somewhat close to a trainer to be properly using them
if(DistNoRoot(*pTrainer) > USE_NPC_RANGE2)
if(ComparativeDistance(m_Position,pTrainer->GetPosition()) > USE_NPC_RANGE2)
return;
// if this for-loop acts up again (crashes linux), try enabling the before and after #pragmas
@ -1663,7 +1651,7 @@ void Client::OPGMEndTraining(const EQApplicationPacket *app)
return;
//you have to be somewhat close to a trainer to be properly using them
if(DistNoRoot(*pTrainer) > USE_NPC_RANGE2)
if(ComparativeDistance(m_Position, pTrainer->GetPosition()) > USE_NPC_RANGE2)
return;
// goodbye message
@ -1692,7 +1680,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
return;
//you have to be somewhat close to a trainer to be properly using them
if(DistNoRoot(*pTrainer) > USE_NPC_RANGE2)
if(ComparativeDistance(m_Position, pTrainer->GetPosition()) > USE_NPC_RANGE2)
return;
if (gmskill->skillbank == 0x01)
@ -1743,7 +1731,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
}
SetSkill(skill, t_level);
} else {
} else {
switch(skill) {
case SkillBrewing:
case SkillMakePoison:
@ -1806,7 +1794,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
}
}
if(GetClientVersion() >= EQClientSoF) {
if(GetClientVersion() >= ClientVersion::SoF) {
// The following packet decreases the skill points left in the Training Window and
// produces the 'You have increased your skill / learned the basics of' message.
//
@ -1945,7 +1933,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();
@ -2131,9 +2119,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);
@ -2186,10 +2174,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);
@ -2199,7 +2187,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

@ -1785,14 +1785,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!");
}
@ -1965,7 +1958,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]");
@ -2044,10 +2037,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)
@ -2415,7 +2410,7 @@ void command_spawn(Client *c, const Seperator *sep)
Log.LogDebug(Logs::General,"#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.");
@ -2474,7 +2469,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]));
@ -2537,7 +2532,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;
@ -2583,7 +2578,7 @@ void command_peekinv(Client *c, const Seperator *sep)
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
}
if ((scopeWhere & peekWorn) && (targetClient->GetClientVersion() >= EQClientSoF)) {
if ((scopeWhere & peekWorn) && (targetClient->GetClientVersion() >= ClientVersion::SoF)) {
inst_main = targetClient->GetInv().GetItem(MainPowerSource);
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main);
@ -4859,7 +4854,7 @@ void command_manaburn(Client *c, const Seperator *sep)
c->Message(0, "#Manaburn needs a target.");
else {
int cur_level=c->GetAA(MANA_BURN);//ManaBurn ID
if (c->DistNoRootNoZ(*target) > 200)
if (ComparativeDistance(c->GetPosition(), target->GetPosition()) > 200)
c->Message(0,"You are too far away from your target.");
else {
if(cur_level == 1) {
@ -5366,8 +5361,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())
@ -5390,9 +5384,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);
@ -5509,9 +5505,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];
@ -5566,6 +5561,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);
}
}
@ -7217,7 +7213,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());
@ -7259,16 +7255,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));
}
@ -7923,7 +7921,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!");
@ -7986,7 +7984,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.");
@ -9908,7 +9906,7 @@ void command_distance(Client *c, const Seperator *sep) {
if(c && c->GetTarget()) {
Mob* target = c->GetTarget();
c->Message(0, "Your target, %s, is %1.1f units from you.", c->GetTarget()->GetName(), c->Dist(*target));
c->Message(0, "Your target, %s, is %1.1f units from you.", c->GetTarget()->GetName(), Distance(c->GetPosition(), target->GetPosition()));
}
}
@ -10030,7 +10028,7 @@ void command_disarmtrap(Client *c, const Seperator *sep)
{
if(c->HasSkill(SkillDisarmTraps))
{
if(c->DistNoRootNoZ(*target) > RuleI(Adventure, LDoNTrapDistanceUse))
if(ComparativeDistanceNoZ(c->GetPosition(), target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse))
{
c->Message(13, "%s is too far away.", target->GetCleanName());
return;
@ -10055,7 +10053,7 @@ void command_sensetrap(Client *c, const Seperator *sep)
{
if(c->HasSkill(SkillSenseTraps))
{
if(c->DistNoRootNoZ(*target) > RuleI(Adventure, LDoNTrapDistanceUse))
if(ComparativeDistanceNoZ(c->GetPosition(), target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse))
{
c->Message(13, "%s is too far away.", target->GetCleanName());
return;
@ -10080,7 +10078,7 @@ void command_picklock(Client *c, const Seperator *sep)
{
if(c->HasSkill(SkillPickLock))
{
if(c->DistNoRootNoZ(*target) > RuleI(Adventure, LDoNTrapDistanceUse))
if(ComparativeDistanceNoZ(c->GetPosition(), target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse))
{
c->Message(13, "%s is too far away.", target->GetCleanName());
return;
@ -10679,4 +10677,4 @@ void command_logs(Client *c, const Seperator *sep){
c->Message(0, "--- #logs list_settings - Shows current log settings and categories");
c->Message(0, "--- #logs set [console|file|gmsay] <category_id> <debug_level (1-3)> - Sets log settings during the lifetime of the zone");
}
}
}

View File

@ -158,18 +158,18 @@ enum TradeState {
TradeCompleting
};
enum { //Numhits type
NUMHIT_IncomingHitAttempts = 1, //Attempted incoming melee attacks (hit or miss) on YOU.
NUMHIT_OutgoingHitAttempts = 2, //Attempted outgoing melee attacks (hit or miss) on YOUR TARGET.
NUMHIT_IncomingSpells = 3, //Incoming detrimental spells
NUMHIT_OutgoingSpells = 4, //Outgoing deterimental spells
NUMHIT_OutgoingHitSuccess = 5, //Successful outgoing melee attack HIT on YOUR TARGET.
NUMHIT_IncomingHitSuccess = 6, //Successful incoming melee attack HIT on YOU.
NUMHIT_MatchingSpells = 7, //Any casted spell matching/triggering a focus effect.
NUMHIT_IncomingDamage = 8, //Successful incoming spell or melee dmg attack on YOU
NUMHIT_ReflectSpell = 9, //Incoming Reflected spells.
NUMHIT_DefensiveSpellProcs = 10, //Defensive buff procs
NUMHIT_OffensiveSpellProcs = 11 //Offensive buff procs
enum class NumHit { // Numhits type
IncomingHitAttempts = 1, // Attempted incoming melee attacks (hit or miss) on YOU.
OutgoingHitAttempts = 2, // Attempted outgoing melee attacks (hit or miss) on YOUR TARGET.
IncomingSpells = 3, // Incoming detrimental spells
OutgoingSpells = 4, // Outgoing detrimental spells
OutgoingHitSuccess = 5, // Successful outgoing melee attack HIT on YOUR TARGET.
IncomingHitSuccess = 6, // Successful incoming melee attack HIT on YOU.
MatchingSpells = 7, // Any casted spell matching/triggering a focus effect.
IncomingDamage = 8, // Successful incoming spell or melee dmg attack on YOU
ReflectSpell = 9, // Incoming Reflected spells.
DefensiveSpellProcs = 10, // Defensive buff procs
OffensiveSpellProcs = 11 // Offensive buff procs
};
//this is our internal representation of the BUFF struct, can put whatever we want in it

View File

@ -71,13 +71,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++) {
@ -96,10 +96,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
@ -111,9 +108,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;
@ -124,7 +121,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;
@ -146,57 +143,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)),
@ -225,7 +177,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);
@ -236,7 +188,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);
}
@ -261,10 +213,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,
@ -298,15 +247,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;
@ -336,7 +285,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;
@ -344,13 +293,13 @@ 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.
// (change to first client that supports 'death hover' mode, if not SoF.)
if (!RuleB(Character, RespawnFromHover) || client->GetClientVersion() < EQClientSoF) {
if (!RuleB(Character, RespawnFromHover) || client->GetClientVersion() < ClientVersion::SoF) {
SetCash(pp->copper, pp->silver, pp->gold, pp->platinum);
pp->copper = 0;
pp->silver = 0;
@ -369,7 +318,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
std::list<uint32> removed_list;
//bool cursor = false;
for(i = MAIN_BEGIN; i < EmuConstants::MAP_POSSESSIONS_SIZE; i++) {
if(i == MainAmmo && client->GetClientVersion() >= EQClientSoF) {
if(i == MainAmmo && client->GetClientVersion() >= ClientVersion::SoF) {
item = client->GetInv().GetItem(MainPowerSource);
if((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) {
std::list<uint32> slot_list = MoveItemToCorpse(client, item, MainPowerSource);
@ -486,59 +435,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)),
@ -548,9 +493,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));
@ -653,18 +597,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);
@ -674,16 +618,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;
}
@ -708,7 +651,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;
@ -783,7 +726,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();
@ -828,14 +771,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;
}
@ -845,8 +786,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;
@ -912,15 +852,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) {
@ -953,21 +889,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);
@ -1005,7 +940,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;
@ -1023,7 +958,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
}
RemoveCash();
Save();
Save();
}
outapp->priority = 6;
@ -1107,7 +1042,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
// This is required for the 'Loot All' feature to work for SoD clients. I expect it is to tell the client that the
// server has now sent all the items on the corpse.
if(client->GetClientVersion() >= EQClientSoD) { SendLootReqErrorPacket(client, 6); }
if(client->GetClientVersion() >= ClientVersion::SoD) { SendLootReqErrorPacket(client, 6); }
}
void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
@ -1252,7 +1187,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 */
@ -1260,9 +1195,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]);
}
}
}
@ -1334,7 +1269,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);
@ -1394,7 +1329,7 @@ bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) {
client->Message(13, "That corpse is locked by a GM.");
return false;
}
if (!CheckDistance || (DistNoRootNoZ(*client) <= dist2)) {
if (!CheckDistance || (ComparativeDistanceNoZ(m_Position, client->GetPosition()) <= dist2)) {
GMMove(client->GetX(), client->GetY(), client->GetZ());
is_corpse_changed = true;
}
@ -1409,7 +1344,7 @@ bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) {
std::list<std::string>::iterator itr;
for(itr = client->consent_list.begin(); itr != client->consent_list.end(); ++itr) {
if(strcmp(this->GetOwnerName(), itr->c_str()) == 0) {
if (!CheckDistance || (DistNoRootNoZ(*client) <= dist2)) {
if (!CheckDistance || (ComparativeDistanceNoZ(m_Position, client->GetPosition()) <= dist2)) {
GMMove(client->GetX(), client->GetY(), client->GetZ());
is_corpse_changed = true;
}

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

@ -40,17 +40,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;
@ -67,28 +65,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;
@ -107,10 +99,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;
@ -145,9 +133,9 @@ bool Doors::Process()
void Doors::HandleClick(Client* sender, uint8 trigger)
{
//door debugging info dump
Log.Out(Logs::Detail, Logs::Doors, "%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.Out(Logs::Detail, Logs::Doors, "%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.Out(Logs::Detail, Logs::Doors, " 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.Out(Logs::Detail, Logs::Doors, " size %d, invert %d, dest: %s (%.4f,%.4f,%.4f @%.4f)", size, invert_state, dest_zone, dest_x, dest_y, dest_z, dest_heading);
Log.Out(Logs::Detail, Logs::Doors, " 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;
@ -423,7 +411,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())))
{
@ -433,22 +421,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);
}
}
}
@ -561,14 +549,14 @@ void Doors::ToggleState(Mob *sender)
void Doors::DumpDoor(){
Log.Out(Logs::General, Logs::None,
"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());
Log.Out(Logs::General, Logs::None,
"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");
Log.Out(Logs::General, Logs::None,
"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) {
@ -706,30 +694,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();
}
@ -764,6 +735,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

@ -27,6 +27,7 @@
#include "string_ids.h"
#include "worldserver.h"
#include "zonedb.h"
#include "position.h"
float Mob::GetActSpellRange(uint16 spell_id, float range, bool IsBard)
{
@ -674,7 +675,7 @@ void EntityList::AETaunt(Client* taunter, float range)
zdiff *= -1;
if (zdiff < 10
&& taunter->IsAttackAllowed(them)
&& taunter->DistNoRootNoZ(*them) <= range) {
&& ComparativeDistanceNoZ(taunter->GetPosition(), them->GetPosition()) <= range) {
if (taunter->CheckLosFN(them)) {
taunter->Taunt(them, true);
}
@ -721,10 +722,10 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
continue;
if (spells[spell_id].targettype == ST_Ring) {
dist_targ = curmob->DistNoRoot(caster->GetTargetRingX(), caster->GetTargetRingY(), caster->GetTargetRingZ());
dist_targ = ComparativeDistance(static_cast<xyz_location>(curmob->GetPosition()), caster->GetTargetRingLocation());
}
else if (center) {
dist_targ = center->DistNoRoot(*curmob);
dist_targ = ComparativeDistance(curmob->GetPosition(), center->GetPosition());
}
if (dist_targ > dist2) //make sure they are in range
@ -796,7 +797,7 @@ void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool a
continue;
if (curmob == caster && !affect_caster) //watch for caster too
continue;
if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
if (ComparativeDistance(center->GetPosition(), curmob->GetPosition()) > dist2) //make sure they are in range
continue;
//Only npcs mgb should hit are client pets...
@ -838,7 +839,7 @@ void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool aff
continue;
if (curmob == caster && !affect_caster) //watch for caster too
continue;
if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
if (ComparativeDistance(center->GetPosition(), curmob->GetPosition()) > dist2) //make sure they are in range
continue;
if (isnpc && curmob->IsNPC()) { //check npc->npc casting
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
@ -888,7 +889,7 @@ void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool I
&& curmob != attacker //this is not needed unless NPCs can use this
&&(attacker->IsAttackAllowed(curmob))
&& curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */
&& (curmob->DistNoRoot(*attacker) <= dist2)
&& (ComparativeDistance(curmob->GetPosition(), attacker->GetPosition()) <= dist2)
) {
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
hit++;

View File

@ -1143,7 +1143,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
ItemInst *inst = EQEmu::any_cast<ItemInst*>(extra_pointers->at(i));
std::string var_name = "item";
var_name += std::to_string(static_cast<long long>(i + 1));
var_name += std::to_string(i + 1);
if(inst) {
ExportVar(package_name.c_str(), var_name.c_str(), inst->GetItem()->ID);

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()
@ -466,14 +466,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;
@ -828,10 +828,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();
@ -1100,7 +1101,7 @@ void EntityList::ChannelMessage(Mob *from, uint8 chan_num, uint8 language,
filter = FilterAuctions;
//
// Only say is limited in range
if (chan_num != 8 || client->Dist(*from) < 200)
if (chan_num != 8 || Distance(client->GetPosition(), from->GetPosition()) < 200)
if (filter == FilterNone || client->GetFilter(filter) != FilterHide)
client->ChannelMessageSend(from->GetName(), 0, chan_num, language, lang_skill, buffer);
++it;
@ -1423,7 +1424,7 @@ void EntityList::QueueCloseClients(Mob *sender, const EQApplicationPacket *app,
|| (filter2 == FilterShowGroupOnly && (sender == ent ||
(ent->GetGroup() && ent->GetGroup()->IsGroupMember(sender))))
|| (filter2 == FilterShowSelfOnly && ent == sender))
&& (ent->DistNoRoot(*sender) <= dist2)) {
&& (ComparativeDistance(ent->GetPosition(), sender->GetPosition()) <= dist2)) {
ent->QueuePacket(app, ackreq, Client::CLIENT_CONNECTED);
}
}
@ -1533,16 +1534,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) && (ComparativeDistance(static_cast<xyz_location>(it->second->GetPosition()), location) <= Distance))
ClientsInRange.push_back(it->second);
++it;
}
if (ClientsInRange.empty())
return nullptr;
@ -1567,7 +1566,7 @@ Corpse *EntityList::GetCorpseByOwnerWithinRange(Client *client, Mob *center, int
auto it = corpse_list.begin();
while (it != corpse_list.end()) {
if (it->second->IsPlayerCorpse())
if (center->DistNoRootNoZ(*it->second) < range &&
if (ComparativeDistanceNoZ(center->GetPosition(), it->second->GetPosition()) < range &&
strcasecmp(it->second->GetOwnerName(), client->GetName()) == 0)
return it->second;
++it;
@ -1904,7 +1903,7 @@ void EntityList::MessageClose_StringID(Mob *sender, bool skipsender, float dist,
for (auto it = client_list.begin(); it != client_list.end(); ++it) {
c = it->second;
if(c && c->DistNoRoot(*sender) <= dist2 && (!skipsender || c != sender))
if(c && ComparativeDistance(c->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || c != sender))
c->Message_StringID(type, string_id, message1, message2, message3, message4, message5, message6, message7, message8, message9);
}
}
@ -1920,7 +1919,7 @@ void EntityList::FilteredMessageClose_StringID(Mob *sender, bool skipsender,
for (auto it = client_list.begin(); it != client_list.end(); ++it) {
c = it->second;
if (c && c->DistNoRoot(*sender) <= dist2 && (!skipsender || c != sender))
if (c && ComparativeDistance(c->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || c != sender))
c->FilteredMessage_StringID(sender, type, filter, string_id,
message1, message2, message3, message4, message5,
message6, message7, message8, message9);
@ -1968,7 +1967,7 @@ void EntityList::MessageClose(Mob* sender, bool skipsender, float dist, uint32 t
auto it = client_list.begin();
while (it != client_list.end()) {
if (it->second->DistNoRoot(*sender) <= dist2 && (!skipsender || it->second != sender))
if (ComparativeDistance(it->second->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || it->second != sender))
it->second->Message(type, buffer);
++it;
}
@ -2443,7 +2442,7 @@ void EntityList::SendPositionUpdates(Client *client, uint32 cLastUpdate,
//bool Grouped = client->HasGroup() && mob->IsClient() && (client->GetGroup() == mob->CastToClient()->GetGroup());
//if (range == 0 || (iterator.GetData() == alwayssend) || Grouped || (mob->DistNoRootNoZ(*client) <= range)) {
if (range == 0 || (it->second == alwayssend) || mob->IsClient() || (mob->DistNoRoot(*client) <= range)) {
if (range == 0 || (it->second == alwayssend) || mob->IsClient() || (ComparativeDistance(mob->GetPosition(), client->GetPosition()) <= range)) {
mob->MakeSpawnUpdate(ppu);
}
if(mob && mob->IsClient() && mob->GetID()>0) {
@ -2925,7 +2924,7 @@ bool EntityList::MakeTrackPacket(Client *client)
it->second->IsInvisible(client))
continue;
MobDistance = it->second->DistNoZ(*client);
MobDistance = DistanceNoZ(it->second->GetPosition(), client->GetPosition());
if (MobDistance > distance)
continue;
@ -2974,7 +2973,8 @@ void EntityList::MessageGroup(Mob *sender, bool skipclose, uint32 type, const ch
auto it = client_list.begin();
while (it != client_list.end()) {
if (it->second != sender && (it->second->Dist(*sender) <= dist2 || it->second->GetGroup() == sender->CastToClient()->GetGroup())) {
if (it->second != sender &&
(Distance(it->second->GetPosition(), sender->GetPosition()) <= dist2 || it->second->GetGroup() == sender->CastToClient()->GetGroup())) {
it->second->Message(type, buffer);
}
++it;
@ -3047,54 +3047,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);
}
}
@ -3131,7 +3120,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();
@ -3153,9 +3142,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;
}
@ -3188,9 +3177,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;
}
@ -3520,6 +3509,32 @@ bool EntityList::LimitCheckName(const char *npc_name)
return true;
}
void EntityList::RadialSetLogging(Mob *around, bool enabled, bool clients,
bool non_clients, float range)
{
float range2 = range * range;
auto it = mob_list.begin();
while (it != mob_list.end()) {
Mob *mob = it->second;
++it;
if (mob->IsClient()) {
if (!clients)
continue;
} else {
if (!non_clients)
continue;
}
if (ComparativeDistance(around->GetPosition(), mob->GetPosition()) > range2)
continue;
}
}
void EntityList::UpdateHoTT(Mob *target)
{
auto it = client_list.begin();
@ -3564,7 +3579,7 @@ int16 EntityList::CountTempPets(Mob *owner)
}
++it;
}
owner->SetTempPetCount(count);
return count;
@ -3630,7 +3645,7 @@ void EntityList::QuestJournalledSayClose(Mob *sender, Client *QuestInitiator,
// Use the old method for all other nearby clients
for (auto it = client_list.begin(); it != client_list.end(); ++it) {
c = it->second;
if(c && (c != QuestInitiator) && c->DistNoRoot(*sender) <= dist2)
if(c && (c != QuestInitiator) && ComparativeDistance(c->GetPosition(), sender->GetPosition()) <= dist2)
c->Message_StringID(10, GENERIC_SAY, mobname, message);
}
}
@ -3755,51 +3770,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
}
@ -3829,7 +3847,7 @@ Mob *EntityList::GetTargetForMez(Mob *caster)
continue;
}
if (caster->DistNoRoot(*d) > 22250) { //only pick targets within 150 range
if (ComparativeDistance(caster->GetPosition(), d->GetPosition()) > 22250) { //only pick targets within 150 range
++it;
continue;
}
@ -4339,7 +4357,7 @@ void EntityList::UpdateFindableNPCState(NPC *n, bool Remove)
auto it = client_list.begin();
while (it != client_list.end()) {
Client *c = it->second;
if (c && (c->GetClientVersion() >= EQClientSoD))
if (c && (c->GetClientVersion() >= ClientVersion::SoD))
c->QueuePacket(outapp);
++it;

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);
@ -391,9 +392,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;
Log.Out(Logs::Detail, Logs::None, "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

@ -173,7 +173,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);
@ -182,25 +183,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;
}
@ -271,7 +272,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

@ -394,7 +394,7 @@ void Group::SendHPPacketsTo(Mob *member)
{
members[i]->CreateHPPacket(&hpapp);
member->CastToClient()->QueuePacket(&hpapp, false);
if(member->CastToClient()->GetClientVersion() >= EQClientSoD)
if(member->CastToClient()->GetClientVersion() >= ClientVersion::SoD)
{
outapp.SetOpcode(OP_MobManaUpdate);
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
@ -425,7 +425,7 @@ void Group::SendHPPacketsFrom(Mob *member)
if(members[i] && members[i] != member && members[i]->IsClient())
{
members[i]->CastToClient()->QueuePacket(&hp_app);
if(members[i]->CastToClient()->GetClientVersion() >= EQClientSoD)
if(members[i]->CastToClient()->GetClientVersion() >= ClientVersion::SoD)
{
outapp.SetOpcode(OP_MobManaUpdate);
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
@ -565,7 +565,7 @@ bool Group::DelMemberOOZ(const char *Name) {
if(GroupCount() < 3)
{
UnDelegateMarkNPC(NPCMarkerName.c_str());
if(GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->GetClientVersion() < EQClientSoD) {
if(GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->GetClientVersion() < ClientVersion::SoD) {
UnDelegateMainAssist(MainAssistName.c_str());
}
ClearAllNPCMarks();
@ -723,7 +723,7 @@ bool Group::DelMember(Mob* oldmember, bool ignoresender)
if(GroupCount() < 3)
{
UnDelegateMarkNPC(NPCMarkerName.c_str());
if(GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->GetClientVersion() < EQClientSoD) {
if(GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->GetClientVersion() < ClientVersion::SoD) {
UnDelegateMainAssist(MainAssistName.c_str());
}
ClearAllNPCMarks();
@ -759,7 +759,7 @@ void Group::CastGroupSpell(Mob* caster, uint16 spell_id) {
}
else if(members[z] != nullptr)
{
distance = caster->DistNoRoot(*members[z]);
distance = ComparativeDistance(caster->GetPosition(), members[z]->GetPosition());
if(distance <= range2 && distance >= min_range2) {
members[z]->CalcSpellPowerDistanceMod(spell_id, distance);
caster->SpellOnTarget(spell_id, members[z]);
@ -799,7 +799,7 @@ void Group::GroupBardPulse(Mob* caster, uint16 spell_id) {
}
else if(members[z] != nullptr)
{
distance = caster->DistNoRoot(*members[z]);
distance = ComparativeDistance(caster->GetPosition(), members[z]->GetPosition());
if(distance <= range2) {
members[z]->BardPulse(spell_id, caster);
#ifdef GROUP_BUFF_PETS
@ -1198,7 +1198,7 @@ void Group::HealGroup(uint32 heal_amt, Mob* caster, float range)
for(; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi]){
distance = caster->DistNoRoot(*members[gi]);
distance = ComparativeDistance(caster->GetPosition(), members[gi]->GetPosition());
if(distance <= range2){
numMem += 1;
}
@ -1209,7 +1209,7 @@ void Group::HealGroup(uint32 heal_amt, Mob* caster, float range)
for(gi = 0; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi]){
distance = caster->DistNoRoot(*members[gi]);
distance = ComparativeDistance(caster->GetPosition(), members[gi]->GetPosition());
if(distance <= range2){
members[gi]->HealDamage(heal_amt, caster);
members[gi]->SendHPUpdate();
@ -1236,7 +1236,7 @@ void Group::BalanceHP(int32 penalty, float range, Mob* caster, int32 limit)
for(; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi]){
distance = caster->DistNoRoot(*members[gi]);
distance = ComparativeDistance(caster->GetPosition(), members[gi]->GetPosition());
if(distance <= range2){
dmgtaken_tmp = members[gi]->GetMaxHP() - members[gi]->GetHP();
@ -1254,7 +1254,7 @@ void Group::BalanceHP(int32 penalty, float range, Mob* caster, int32 limit)
for(gi = 0; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi]){
distance = caster->DistNoRoot(*members[gi]);
distance = ComparativeDistance(caster->GetPosition(), members[gi]->GetPosition());
if(distance <= range2){
if((members[gi]->GetMaxHP() - dmgtaken) < 1){ //this way the ability will never kill someone
members[gi]->SetHP(1); //but it will come darn close
@ -1285,7 +1285,7 @@ void Group::BalanceMana(int32 penalty, float range, Mob* caster, int32 limit)
for(; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi] && (members[gi]->GetMaxMana() > 0)){
distance = caster->DistNoRoot(*members[gi]);
distance = ComparativeDistance(caster->GetPosition(), members[gi]->GetPosition());
if(distance <= range2){
manataken_tmp = members[gi]->GetMaxMana() - members[gi]->GetMana();
@ -1307,7 +1307,7 @@ void Group::BalanceMana(int32 penalty, float range, Mob* caster, int32 limit)
for(gi = 0; gi < MAX_GROUP_MEMBERS; gi++)
{
if(members[gi]){
distance = caster->DistNoRoot(*members[gi]);
distance = ComparativeDistance(caster->GetPosition(), members[gi]->GetPosition());
if(distance <= range2){
if((members[gi]->GetMaxMana() - manataken) < 1){
members[gi]->SetMana(1);
@ -1568,7 +1568,7 @@ void Group::NotifyMainTank(Client *c, uint8 toggle)
if(!MainTankName.size())
return;
if(c->GetClientVersion() < EQClientSoD)
if(c->GetClientVersion() < ClientVersion::SoD)
{
if(toggle)
c->Message(0, "%s is now Main Tank.", MainTankName.c_str());
@ -1608,7 +1608,7 @@ void Group::NotifyMainAssist(Client *c, uint8 toggle)
if(!MainAssistName.size())
return;
if(c->GetClientVersion() < EQClientSoD)
if(c->GetClientVersion() < ClientVersion::SoD)
{
EQApplicationPacket *outapp = new EQApplicationPacket(OP_DelegateAbility, sizeof(DelegateAbility_Struct));
@ -1663,7 +1663,7 @@ void Group::NotifyPuller(Client *c, uint8 toggle)
if(!PullerName.size())
return;
if(c->GetClientVersion() < EQClientSoD)
if(c->GetClientVersion() < ClientVersion::SoD)
{
if(toggle)
c->Message(0, "%s is now Puller.", PullerName.c_str());
@ -2229,7 +2229,7 @@ void Group::ChangeLeader(Mob* newleader)
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (members[i] && members[i]->IsClient())
{
if(members[i]->CastToClient()->GetClientVersion() >= EQClientSoD)
if(members[i]->CastToClient()->GetClientVersion() >= ClientVersion::SoD)
members[i]->CastToClient()->SendGroupLeaderChangePacket(newleader->GetName());
members[i]->CastToClient()->QueuePacket(outapp);

View File

@ -63,7 +63,7 @@ void Client::SendGuildMOTD(bool GetGuildMOTDReply) {
void Client::SendGuildURL()
{
if(GetClientVersion() < EQClientSoF)
if(GetClientVersion() < ClientVersion::SoF)
return;
if(IsInAGuild())
@ -84,7 +84,7 @@ void Client::SendGuildURL()
void Client::SendGuildChannel()
{
if(GetClientVersion() < EQClientSoF)
if(GetClientVersion() < ClientVersion::SoF)
return;
if(IsInAGuild())
@ -106,7 +106,7 @@ void Client::SendGuildChannel()
void Client::SendGuildRanks()
{
if(GetClientVersion() < EQClientRoF)
if(GetClientVersion() < ClientVersion::RoF)
return;
int permissions = 30 + 1; //Static number of permissions in all EQ clients as of May 2014
@ -149,7 +149,7 @@ void Client::SendGuildSpawnAppearance() {
uint8 rank = guild_mgr.GetDisplayedRank(GuildID(), GuildRank(), CharacterID());
Log.Out(Logs::Detail, Logs::Guilds, "Sending spawn appearance for guild %d at rank %d", GuildID(), rank);
SendAppearancePacket(AT_GuildID, GuildID());
if(GetClientVersion() >= EQClientRoF)
if(GetClientVersion() >= ClientVersion::RoF)
{
switch (rank) {
case 0: { rank = 5; break; } // GUILD_MEMBER 0

View File

@ -322,7 +322,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
else if(c != nullptr && s->guild_id != GUILD_NONE) {
//char is in zone, and has changed into a new guild, send MOTD.
c->SendGuildMOTD();
if(c->GetClientVersion() >= EQClientRoF)
if(c->GetClientVersion() >= ClientVersion::RoF)
{
c->SendGuildRanks();
}

View File

@ -158,7 +158,7 @@ Mob* HateList::GetClosestEntOnHateList(Mob *hater) {
auto iterator = list.begin();
while (iterator != list.end()) {
this_distance = (*iterator)->entity_on_hatelist->DistNoRootNoZ(*hater);
this_distance = ComparativeDistanceNoZ((*iterator)->entity_on_hatelist->GetPosition(), hater->GetPosition());
if ((*iterator)->entity_on_hatelist != nullptr && this_distance <= close_distance) {
close_distance = this_distance;
close_entity = (*iterator)->entity_on_hatelist;
@ -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;
@ -591,7 +592,7 @@ void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_cent
struct_HateList *h = (*iterator);
if (range > 0)
{
dist_targ = center->DistNoRoot(*h->entity_on_hatelist);
dist_targ = ComparativeDistance(center->GetPosition(), h->entity_on_hatelist->GetPosition());
if (dist_targ <= range && dist_targ >= min_range2)
{
id_list.push_back(h->entity_on_hatelist->GetID());

View File

@ -29,8 +29,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

@ -56,7 +56,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
x++;
}
if (GetClientVersion() >= EQClientSoF)
if (GetClientVersion() >= ClientVersion::SoF)
DeleteItemInInventory(MainPowerSource, 0, true);
else
DeleteItemInInventory(MainPowerSource, 0, false); // Prevents Titanium crash
@ -684,7 +684,7 @@ void Client::SendCursorBuffer() {
// Temporary work-around for the RoF+ Client Buffer
// Instead of dealing with client moving items in cursor buffer,
// we can just send the next item in the cursor buffer to the cursor.
if (GetClientVersion() >= EQClientRoF)
if (GetClientVersion() >= ClientVersion::RoF)
{
if (!GetInv().CursorEmpty())
{
@ -938,7 +938,7 @@ bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_curs
for (int16 i = EmuConstants::EQUIPMENT_BEGIN; i < MainPowerSource; i++) { // originally (i < 22)
if (i == EmuConstants::GENERAL_BEGIN) {
// added power source check for SoF+ clients
if (this->GetClientVersion() >= EQClientSoF)
if (this->GetClientVersion() >= ClientVersion::SoF)
i = MainPowerSource;
else
break;
@ -2084,7 +2084,7 @@ void Client::RemoveNoRent(bool client_update)
auto inst = m_inv[MainPowerSource];
if (inst && !inst->GetItem()->NoRent) {
Log.Out(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, MainPowerSource);
DeleteItemInInventory(MainPowerSource, 0, (GetClientVersion() >= EQClientSoF) ? client_update : false); // Ti slot non-existent
DeleteItemInInventory(MainPowerSource, 0, (GetClientVersion() >= ClientVersion::SoF) ? client_update : false); // Ti slot non-existent
}
}
@ -2302,7 +2302,7 @@ void Client::MoveSlotNotAllowed(bool client_update)
bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false;
int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size, is_arrow);
Log.Out(Logs::Detail, Logs::Inventory, "Slot Assignment Error: Moving %s from slot %i to %i", inst->GetItem()->Name, MainPowerSource, free_slot_id);
PutItemInInventory(free_slot_id, *inst, (GetClientVersion() >= EQClientSoF) ? client_update : false);
PutItemInInventory(free_slot_id, *inst, (GetClientVersion() >= ClientVersion::SoF) ? client_update : false);
database.SaveInventory(character_id, nullptr, MainPowerSource);
safe_delete(inst);
}

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);
@ -834,7 +834,7 @@ void Lua_Client::SetAATitle(const char *title) {
int Lua_Client::GetClientVersion() {
Lua_Safe_Call_Int();
return self->GetClientVersion();
return static_cast<unsigned int>(self->GetClientVersion());
}
uint32 Lua_Client::GetClientVersionBit() {
@ -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;
@ -200,8 +200,8 @@ 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));
package_name += std::to_string(item_id);
if(luabind::type(func) == LUA_TFUNCTION) {
register_event(package_name, name, evt, func);
}
@ -214,7 +214,7 @@ void register_item_event(int evt, int item_id, luabind::adl::object func) {
void unregister_item_event(std::string name, int evt, int item_id) {
std::string package_name = "item_";
package_name += std::to_string(static_cast<long long>(item_id));
package_name += std::to_string(item_id);
unregister_event(package_name, name, evt);
}
@ -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));
@ -1356,7 +1356,7 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
LuaCreateNPCParseString(special_abilities, 512, "");
LuaCreateNPCParse(d_melee_texture1, uint16, 0);
LuaCreateNPCParse(d_melee_texture2, uint16, 0);
LuaCreateNPCParseString(ammo_idfile, 32, "");
LuaCreateNPCParseString(ammo_idfile, 30, "");
LuaCreateNPCParse(prim_melee_type, uint8, 0);
LuaCreateNPCParse(sec_melee_type, uint8, 0);
LuaCreateNPCParse(ranged_type, uint8, 0);
@ -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);
}
@ -1758,12 +1758,15 @@ luabind::scope lua_register_client_version() {
return luabind::class_<ClientVersions>("ClientVersion")
.enum_("constants")
[
luabind::value("Unknown", static_cast<int>(EQClientUnknown)),
luabind::value("Titanium", static_cast<int>(EQClientTitanium)),
luabind::value("SoF", static_cast<int>(EQClientSoF)),
luabind::value("SoD", static_cast<int>(EQClientSoD)),
luabind::value("Underfoot", static_cast<int>(EQClientUnderfoot)),
luabind::value("RoF", static_cast<int>(EQClientRoF))
luabind::value("Unknown", static_cast<int>(ClientVersion::Unknown)),
luabind::value("Titanium", static_cast<int>(ClientVersion::Tit)), // deprecated
luabind::value("Tit", static_cast<int>(ClientVersion::Tit)),
luabind::value("SoF", static_cast<int>(ClientVersion::SoF)),
luabind::value("SoD", static_cast<int>(ClientVersion::SoD)),
luabind::value("Underfoot", static_cast<int>(ClientVersion::Und)), // deprecated
luabind::value("Und", static_cast<int>(ClientVersion::Und)),
luabind::value("RoF", static_cast<int>(ClientVersion::RoF)),
luabind::value("RoF2", static_cast<int>(ClientVersion::RoF2))
];
}

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

@ -235,7 +235,7 @@ int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data,
return 0;
}
std::string package_name = "npc_" + std::to_string(static_cast<long long>(npc->GetNPCTypeID()));
std::string package_name = "npc_" + std::to_string(npc->GetNPCTypeID());
return _EventNPC(package_name, evt, npc, init, data, extra_data, extra_pointers);
}
@ -425,7 +425,7 @@ int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *
}
std::string package_name = "item_";
package_name += std::to_string(static_cast<long long>(item->GetID()));
package_name += std::to_string(item->GetID());
return _EventItem(package_name, evt, client, item, mob, data, extra_data, extra_pointers);
}
@ -499,12 +499,12 @@ int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spe
return 0;
}
std::string package_name = "spell_" + std::to_string(static_cast<long long>(spell_id));
std::string package_name = "spell_" + std::to_string(spell_id);
if(!SpellHasQuestSub(spell_id, evt)) {
return 0;
}
return _EventSpell(package_name, evt, npc, client, spell_id, extra_data, extra_pointers);
}
@ -646,7 +646,7 @@ bool LuaParser::HasQuestSub(uint32 npc_id, QuestEventID evt) {
return false;
}
std::string package_name = "npc_" + std::to_string(static_cast<long long>(npc_id));
std::string package_name = "npc_" + std::to_string(npc_id);
const char *subname = LuaEvents[evt];
return HasFunction(subname, package_name);
@ -688,7 +688,7 @@ bool LuaParser::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) {
return false;
}
std::string package_name = "spell_" + std::to_string(static_cast<long long>(spell_id));
std::string package_name = "spell_" + std::to_string(spell_id);
const char *subname = LuaEvents[evt];
return HasFunction(subname, package_name);
@ -704,7 +704,7 @@ bool LuaParser::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) {
}
std::string package_name = "item_";
package_name += std::to_string(static_cast<long long>(itm->GetID()));
package_name += std::to_string(itm->GetID());
const char *subname = LuaEvents[evt];
return HasFunction(subname, package_name);
@ -723,7 +723,7 @@ bool LuaParser::EncounterHasQuestSub(std::string encounter_name, QuestEventID ev
}
void LuaParser::LoadNPCScript(std::string filename, int npc_id) {
std::string package_name = "npc_" + std::to_string(static_cast<long long>(npc_id));
std::string package_name = "npc_" + std::to_string(npc_id);
LoadScript(filename, package_name);
}
@ -744,13 +744,13 @@ void LuaParser::LoadItemScript(std::string filename, ItemInst *item) {
if (item == nullptr)
return;
std::string package_name = "item_";
package_name += std::to_string(static_cast<long long>(item->GetID()));
package_name += std::to_string(item->GetID());
LoadScript(filename, package_name);
}
void LuaParser::LoadSpellScript(std::string filename, uint32 spell_id) {
std::string package_name = "spell_" + std::to_string(static_cast<long long>(spell_id));
std::string package_name = "spell_" + std::to_string(spell_id);
LoadScript(filename, package_name);
}
@ -1011,8 +1011,8 @@ int LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::stri
if(!npc)
return 0;
std::string package_name = "npc_" + std::to_string(static_cast<long long>(npc->GetNPCTypeID()));
int ret = 0;
std::string package_name = "npc_" + std::to_string(npc->GetNPCTypeID());
int ret = 0;
auto iter = lua_encounter_events_registered.find(package_name);
if(iter != lua_encounter_events_registered.end()) {
@ -1085,11 +1085,11 @@ int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *ite
if(!item)
return 0;
std::string package_name = "item_";
package_name += std::to_string(static_cast<long long>(item->GetID()));
int ret = 0;
package_name += std::to_string(item->GetID());
int ret = 0;
auto iter = lua_encounter_events_registered.find(package_name);
if(iter != lua_encounter_events_registered.end()) {
auto riter = iter->second.begin();
@ -1129,7 +1129,7 @@ int LuaParser::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, ui
return 0;
}
std::string package_name = "spell_" + std::to_string(static_cast<long long>(spell_id));
std::string package_name = "spell_" + std::to_string(spell_id);
int ret = 0;
auto iter = lua_encounter_events_registered.find(package_name);

View File

@ -56,7 +56,7 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *
if(extra_pointers) {
size_t sz = extra_pointers->size();
for(size_t i = 0; i < sz; ++i) {
std::string prefix = "item" + std::to_string(static_cast<long long>(i + 1));
std::string prefix = "item" + std::to_string(i + 1);
ItemInst *inst = EQEmu::any_cast<ItemInst*>(extra_pointers->at(i));
Lua_ItemInst l_inst = inst;

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

@ -21,7 +21,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;
@ -42,7 +42,7 @@ Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
_baseFR = d->FR;
_basePR = d->PR;
_baseCorrup = d->Corrup;
_OwnerClientVersion = EQClientTitanium;
_OwnerClientVersion = static_cast<unsigned int>(ClientVersion::Tit);
RestRegenHP = 0;
RestRegenMana = 0;
RestRegenEndurance = 0;
@ -1009,7 +1009,7 @@ int32 Merc::CalcBaseEndurance()
int32 sta_end = 0;
int Stats = 0;
if(GetClientVersion() >= EQClientSoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
if(GetClientVersion() >= static_cast<unsigned int>(ClientVersion::SoD) && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
int HeroicStats = 0;
Stats = ((GetSTR() + GetSTA() + GetDEX() + GetAGI()) / 4);
@ -1319,7 +1319,7 @@ bool Merc::IsMercCasterCombatRange(Mob *target) {
// half the max so the merc doesn't always stop at max range to allow combat movement
range *= .5;
float targetDistance = DistNoRootNoZ(*target);
float targetDistance = ComparativeDistanceNoZ(m_Position, target->GetPosition());
if(targetDistance > range)
result = false;
@ -1337,7 +1337,7 @@ void Merc::AI_Process() {
if(IsCasting())
return;
// A bot wont start its AI if not grouped
// A merc wont start its AI if not grouped
if(!HasGroup()) {
return;
}
@ -1481,7 +1481,7 @@ void Merc::AI_Process() {
if(IsMercCasterCombatRange(GetTarget()))
atCombatRange = true;
}
else if(DistNoRoot(*GetTarget()) <= meleeDistance) {
else if(ComparativeDistance(m_Position, GetTarget()->GetPosition()) <= meleeDistance) {
atCombatRange = true;
}
@ -1514,7 +1514,7 @@ void Merc::AI_Process() {
return;
}
}
else if(!IsMoving() && GetClass() != ROGUE && (DistNoRootNoZ(*GetTarget()) < GetTarget()->GetSize()))
else if(!IsMoving() && GetClass() != ROGUE && (ComparativeDistanceNoZ(m_Position, GetTarget()->GetPosition()) < GetTarget()->GetSize()))
{
// If we are not a rogue trying to backstab, let's try to adjust our melee range so we don't appear to be bunched up
float newX = 0;
@ -1702,7 +1702,7 @@ void Merc::AI_Process() {
if(follow)
{
float dist = DistNoRoot(*follow);
float dist = ComparativeDistance(m_Position, follow->GetPosition());
float speed = GetRunspeed();
if(dist < GetFollowDistance() + 1000)
@ -1939,7 +1939,7 @@ bool Merc::AIDoSpellCast(uint16 spellid, Mob* tar, int32 mana_cost, uint32* oDon
if (mercSpell.type & SpellType_Escape) {
dist2 = 0;
} else
dist2 = DistNoRoot(*tar);
dist2 = ComparativeDistance(m_Position, tar->GetPosition());
if (((((spells[spellid].targettype==ST_GroupTeleport && mercSpell.type==SpellType_Heal)
|| spells[spellid].targettype==ST_AECaster
@ -2436,7 +2436,7 @@ void Merc::CheckHateList() {
if(MercOwner && MercOwner->GetTarget() && MercOwner->GetTarget()->IsNPC() && (MercOwner->GetTarget()->GetHateAmount(MercOwner) || MercOwner->CastToClient()->AutoAttackEnabled()) && IsAttackAllowed(MercOwner->GetTarget())) {
float range = g->HasRole(MercOwner, RolePuller) ? RuleI(Mercs, AggroRadiusPuller) : RuleI(Mercs, AggroRadius);
range = range * range;
if(MercOwner->GetTarget()->DistNoRootNoZ(*this) < range) {
if(ComparativeDistanceNoZ(m_Position, MercOwner->GetTarget()->GetPosition()) < range) {
AddToHateList(MercOwner->GetTarget(), 1);
}
}
@ -2446,7 +2446,7 @@ void Merc::CheckHateList() {
for(std::list<NPC*>::iterator itr = npc_list.begin(); itr != npc_list.end(); ++itr) {
NPC* npc = *itr;
float dist = npc->DistNoRootNoZ(*this);
float dist = ComparativeDistanceNoZ(m_Position, npc->GetPosition());
int radius = RuleI(Mercs, AggroRadius);
radius *= radius;
if(dist <= radius) {
@ -2458,7 +2458,7 @@ void Merc::CheckHateList() {
if(!hate_list.IsEntOnHateList(npc)) {
float range = g->HasRole(groupMember, RolePuller) ? RuleI(Mercs, AggroRadiusPuller) : RuleI(Mercs, AggroRadius);
range *= range;
if(npc->DistNoRootNoZ(*this) < range) {
if(ComparativeDistanceNoZ(m_Position, npc->GetPosition()) < range) {
hate_list.AddEntToHateList(npc, 1);
}
}
@ -2500,7 +2500,7 @@ bool Merc::CheckAENuke(Merc* caster, Mob* tar, uint16 spell_id, uint8 &numTarget
for(std::list<NPC*>::iterator itr = npc_list.begin(); itr != npc_list.end(); ++itr) {
NPC* npc = *itr;
if(npc->DistNoRootNoZ(*tar) <= spells[spell_id].aoerange * spells[spell_id].aoerange) {
if(ComparativeDistanceNoZ(npc->GetPosition(), tar->GetPosition()) <= spells[spell_id].aoerange * spells[spell_id].aoerange) {
if(!npc->IsMezzed()) {
numTargets++;
}
@ -4099,7 +4099,7 @@ bool Merc::CheckAETaunt() {
for(std::list<NPC*>::iterator itr = npc_list.begin(); itr != npc_list.end(); ++itr) {
NPC* npc = *itr;
float dist = npc->DistNoRootNoZ(*this);
float dist = ComparativeDistanceNoZ(m_Position, npc->GetPosition());
int range = GetActSpellRange(mercSpell.spellid, spells[mercSpell.spellid].range);
range *= range;
@ -4202,7 +4202,7 @@ bool Merc::CheckConfidence() {
AggroRange = AggroRange * AggroRange;
if(mob->DistNoRoot(*this) > AggroRange) continue;
if(ComparativeDistance(m_Position, mob->GetPosition()) > AggroRange) continue;
CurrentCon = this->GetLevelCon(mob->GetLevel());
switch(CurrentCon) {
@ -4723,11 +4723,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)
@ -4920,7 +4920,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;
@ -4956,109 +4956,109 @@ void Client::SendMercResponsePackets(uint32 ResponseType)
SendMercMerchantResponsePacket(6);
break;
case 7: //You must dismiss your suspended mercenary before purchasing a new one!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
SendMercMerchantResponsePacket(7);
else
//You have the maximum number of mercenaries. You must dismiss one before purchasing a new one!
SendMercMerchantResponsePacket(6);
break;
case 8: //You can not purchase a mercenary because your group is full!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
SendMercMerchantResponsePacket(8);
else
SendMercMerchantResponsePacket(7);
break;
case 9: //You can not purchase a mercenary because you are in combat!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
//Mercenary failed to spawn!
SendMercMerchantResponsePacket(3);
else
SendMercMerchantResponsePacket(8);
break;
case 10: //You have recently dismissed a mercenary and must wait a few more seconds before you can purchase a new one!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
//Mercenary failed to spawn!
SendMercMerchantResponsePacket(3);
else
SendMercMerchantResponsePacket(9);
break;
case 11: //An error occurred created your mercenary!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
SendMercMerchantResponsePacket(9);
else
SendMercMerchantResponsePacket(10);
break;
case 12: //Upkeep Charge Message
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
SendMercMerchantResponsePacket(10);
else
SendMercMerchantResponsePacket(11);
break;
case 13: // ???
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
SendMercMerchantResponsePacket(11);
else
SendMercMerchantResponsePacket(12);
break;
case 14: //You ran out of funds to pay for your mercenary!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
SendMercMerchantResponsePacket(12);
else
SendMercMerchantResponsePacket(13);
break;
case 15: // ???
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
SendMercMerchantResponsePacket(13);
else
SendMercMerchantResponsePacket(14);
break;
case 16: //Your mercenary is about to be suspended due to insufficient funds!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
SendMercMerchantResponsePacket(14);
else
SendMercMerchantResponsePacket(15);
break;
case 17: //There is no mercenary liaison nearby!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
SendMercMerchantResponsePacket(15);
else
SendMercMerchantResponsePacket(16);
break;
case 18: //You are too far from the liaison!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
SendMercMerchantResponsePacket(16);
else
SendMercMerchantResponsePacket(17);
break;
case 19: //You do not meet the requirements for that mercenary!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
SendMercMerchantResponsePacket(17);
else
SendMercMerchantResponsePacket(18);
break;
case 20: //You are unable to interact with the liaison!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
//You are too far from the liaison!
SendMercMerchantResponsePacket(16);
else
SendMercMerchantResponsePacket(19);
break;
case 21: //You do not have a high enough membership level to purchase this mercenary!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
//You do not meet the requirements for that mercenary!
SendMercMerchantResponsePacket(17);
else
SendMercMerchantResponsePacket(20);
break;
case 22: //Your purchase has failed because this mercenary requires a Gold membership!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
//You do not meet the requirements for that mercenary!
SendMercMerchantResponsePacket(17);
else
SendMercMerchantResponsePacket(21);
break;
case 23: //Your purchase has failed because this mercenary requires at least a Silver membership!
if (GetClientVersion() < EQClientRoF)
if (GetClientVersion() < ClientVersion::RoF)
//You do not meet the requirements for that mercenary!
SendMercMerchantResponsePacket(17);
else
@ -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;
}
@ -5150,7 +5150,7 @@ bool Client::CheckCanHireMerc(Mob* merchant, uint32 template_id) {
}
//check for merchant too far away
if(DistNoRoot(*merchant) > USE_NPC_RANGE2) {
if(ComparativeDistance(m_Position, merchant->GetPosition()) > USE_NPC_RANGE2) {
SendMercResponsePackets(18);
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.");
@ -5211,7 +5211,7 @@ bool Client::CheckCanSpawnMerc(uint32 template_id) {
}
// Check client version
if(GetClientVersion() < mercTemplate->ClientVersion)
if(static_cast<unsigned int>(GetClientVersion()) < mercTemplate->ClientVersion)
{
SendMercResponsePackets(3);
return false;
@ -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.");
@ -5474,7 +5474,7 @@ bool Client::MercOnlyOrNoGroup() {
}
if (GetMerc())
{
if (GetMerc()->HasGroup() && GetMerc()->GetGroup() == GetGroup())
if (GetMerc()->GetGroup() == GetGroup())
{
if (GetGroup()->GroupCount() < 3)
{
@ -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()))
{
@ -5904,7 +5904,7 @@ void Client::UpdateMercLevel() {
void Client::SendMercMerchantResponsePacket(int32 response_type) {
// This response packet brings up the Mercenary Manager window
if(GetClientVersion() >= EQClientSoD)
if(GetClientVersion() >= ClientVersion::SoD)
{
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryHire, sizeof(MercenaryMerchantResponse_Struct));
MercenaryMerchantResponse_Struct* mmr = (MercenaryMerchantResponse_Struct*)outapp->pBuffer;

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)
@ -1554,7 +1524,6 @@ void Mob::SendIllusionPacket(uint16 in_race, uint8 in_gender, uint8 in_texture,
}
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Illusion, sizeof(Illusion_Struct));
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
Illusion_Struct* is = (Illusion_Struct*) outapp->pBuffer;
is->spawnid = GetID();
strcpy(is->charname, GetCleanName());
@ -1919,7 +1888,6 @@ void Mob::SendTargetable(bool on, Client *specific_target) {
void Mob::QuestReward(Client *c, uint32 silver, uint32 gold, uint32 platinum) {
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Sound, sizeof(QuestReward_Struct));
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
QuestReward_Struct* qr = (QuestReward_Struct*) outapp->pBuffer;
qr->from_mob = GetID(); // Entity ID for the from mob name
@ -1939,7 +1907,6 @@ void Mob::CameraEffect(uint32 duration, uint32 intensity, Client *c, bool global
if(global == true)
{
ServerPacket* pack = new ServerPacket(ServerOP_CameraShake, sizeof(ServerCameraShake_Struct));
memset(pack->pBuffer, 0, sizeof(pack->pBuffer));
ServerCameraShake_Struct* scss = (ServerCameraShake_Struct*) pack->pBuffer;
scss->duration = duration;
scss->intensity = intensity;
@ -1949,7 +1916,6 @@ void Mob::CameraEffect(uint32 duration, uint32 intensity, Client *c, bool global
}
EQApplicationPacket* outapp = new EQApplicationPacket(OP_CameraEffect, sizeof(Camera_Struct));
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
Camera_Struct* cs = (Camera_Struct*) outapp->pBuffer;
cs->duration = duration; // Duration in milliseconds
cs->intensity = ((intensity * 6710886) + 1023410176); // Intensity ranges from 1023410176 to 1090519040, so simplify it from 0 to 10.
@ -1965,7 +1931,6 @@ void Mob::CameraEffect(uint32 duration, uint32 intensity, Client *c, bool global
void Mob::SendSpellEffect(uint32 effectid, uint32 duration, uint32 finish_delay, bool zone_wide, uint32 unk020, bool perm_effect, Client *c) {
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpellEffect, sizeof(SpellEffect_Struct));
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
SpellEffect_Struct* se = (SpellEffect_Struct*) outapp->pBuffer;
se->EffectID = effectid; // ID of the Particle Effect
se->EntityID = GetID();
@ -2017,7 +1982,6 @@ void Mob::TempName(const char *newname)
// Send the new name to all clients
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MobRename, sizeof(MobRename_Struct));
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
MobRename_Struct* mr = (MobRename_Struct*) outapp->pBuffer;
strn0cpy(mr->old_name, old_name, 64);
strn0cpy(mr->old_name_again, old_name, 64);
@ -2302,59 +2266,7 @@ bool Mob::CanThisClassBlock(void) const
return(CastToClient()->HasSkill(SkillBlock));
}
}
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;
return sqrtf( (xDiff * xDiff)
+ (yDiff * yDiff)
+ (zDiff * zDiff) );
}
float Mob::DistNoZ(const Mob &other) const {
float xDiff = other.x_pos - x_pos;
float yDiff = other.y_pos - y_pos;
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;
return ( (xDiff * xDiff)
+ (yDiff * yDiff)
+ (zDiff * zDiff) );
}
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;
return ( (xDiff * xDiff)
+ (yDiff * yDiff)
+ (zDiff * zDiff) );
}
float Mob::DistNoRootNoZ(float x, float y) const {
float xDiff = x - x_pos;
float yDiff = y - y_pos;
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;
return ( (xDiff * xDiff) + (yDiff * yDiff) );
}
/*
float Mob::GetReciprocalHeading(Mob* target) {
float Result = 0;
@ -2371,7 +2283,7 @@ float Mob::GetReciprocalHeading(Mob* target) {
return Result;
}
*/
bool Mob::PlotPositionAroundTarget(Mob* target, float &x_dest, float &y_dest, float &z_dest, bool lookForAftArc) {
bool Result = false;
@ -2379,7 +2291,7 @@ bool Mob::PlotPositionAroundTarget(Mob* target, float &x_dest, float &y_dest, fl
float look_heading = 0;
if(lookForAftArc)
look_heading = GetReciprocalHeading(target);
look_heading = GetReciprocalHeading(target->GetPosition());
else
look_heading = target->GetHeading();
@ -2495,20 +2407,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;
@ -2686,7 +2596,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
@ -2797,14 +2707,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;
}
@ -2926,20 +2832,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();
}
@ -3024,7 +2926,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) {
@ -3059,7 +2961,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;
@ -3151,9 +3054,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)
@ -3171,9 +3074,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)
@ -3268,11 +3171,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)
@ -3381,7 +3281,7 @@ void Mob::TriggerOnCast(uint32 focus_spell, uint32 spell_id, bool aa_trigger)
if(IsValidSpell(trigger_spell_id) && GetTarget()){
SpellFinished(trigger_spell_id, GetTarget(),10, 0, -1, spells[trigger_spell_id].ResistDiff);
CheckNumHitsRemaining(NUMHIT_MatchingSpells,-1, focus_spell);
CheckNumHitsRemaining(NumHit::MatchingSpells, -1, focus_spell);
}
}
}
@ -3613,7 +3513,7 @@ int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
value += tmp_focus;
if (tmp_buffslot >= 0)
CheckNumHitsRemaining(NUMHIT_MatchingSpells, tmp_buffslot);
CheckNumHitsRemaining(NumHit::MatchingSpells, tmp_buffslot);
}
return value;
}
@ -3718,7 +3618,7 @@ void Mob::TrySympatheticProc(Mob *target, uint32 spell_id)
SpellFinished(focus_trigger, target, 10, 0, -1, spells[focus_trigger].ResistDiff);
}
CheckNumHitsRemaining(NUMHIT_MatchingSpells, -1, focus_spell);
CheckNumHitsRemaining(NumHit::MatchingSpells, -1, focus_spell);
}
}

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);
@ -282,7 +280,7 @@ public:
int16 GetBuffSlotFromType(uint16 type);
uint16 GetSpellIDFromSlot(uint8 slot);
int CountDispellableBuffs();
void CheckNumHitsRemaining(uint8 type, int32 buff_slot=-1, uint16 spell_id=SPELL_UNKNOWN);
void CheckNumHitsRemaining(NumHit type, int32 buff_slot = -1, uint16 spell_id = SPELL_UNKNOWN);
bool HasNumhits() const { return has_numhits; }
inline void Numhits(bool val) { has_numhits = val; }
bool HasMGB() const { return has_MGB; }
@ -296,9 +294,10 @@ 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 const xyz_location& GetTargetRingLocation() const { return m_TargetRing; }
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 +399,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 +426,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 +438,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 +467,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);
@ -511,13 +511,6 @@ public:
void ShowStats(Client* client);
void ShowBuffs(Client* client);
void ShowBuffList(Client* client);
float Dist(const Mob &) const;
float DistNoZ(const Mob &) const;
float DistNoRoot(const Mob &) const;
float DistNoRoot(float x, float y, float z) const;
float DistNoRootNoZ(float x, float y) const;
float DistNoRootNoZ(const Mob &) const;
static float GetReciprocalHeading(Mob* target);
bool PlotPositionAroundTarget(Mob* target, float &x_dest, float &y_dest, float &z_dest,
bool lookForAftArc = true);
@ -569,10 +562,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);
@ -621,7 +614,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);
@ -682,9 +675,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; }
@ -815,10 +808,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; }
@ -869,11 +862,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; }
@ -1017,10 +1007,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;
@ -1069,10 +1056,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;
@ -1081,7 +1065,6 @@ protected:
uint8 pRunAnimSpeed;
bool m_is_running;
Timer attack_timer;
Timer attack_dw_timer;
Timer ranged_timer;
@ -1094,7 +1077,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;
@ -1113,9 +1096,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
@ -1211,16 +1193,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
@ -1255,19 +1233,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

@ -67,7 +67,7 @@ bool NPC::AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes) {
dist2 = 0; //DistNoRoot(*this); //WTF was up with this...
}
else
dist2 = DistNoRoot(*tar);
dist2 = ComparativeDistance(m_Position, tar->GetPosition());
bool checked_los = false; //we do not check LOS until we are absolutely sure we need to, and we only do it once.
@ -401,7 +401,7 @@ bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float
if (t1 > iRange
|| t2 > iRange
|| t3 > iRange
|| mob->DistNoRoot(*caster) > iRange2
|| ComparativeDistance(mob->GetPosition(), caster->GetPosition()) > iRange2
//this call should seem backwards:
|| !mob->CheckLosFN(caster)
|| mob->GetReverseFactionCon(caster) >= FACTION_KINDLY
@ -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();
}
@ -625,7 +622,7 @@ void Client::AI_SpellCast()
if(!targ)
return;
float dist = DistNoRootNoZ(*targ);
float dist = ComparativeDistanceNoZ(m_Position, targ->GetPosition());
std::vector<uint32> valid_spells;
std::vector<uint32> slots;
@ -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)
@ -1000,7 +997,7 @@ void Client::AI_Process()
if(owner == nullptr)
return;
float dist = DistNoRoot(*owner);
float dist = ComparativeDistance(m_Position, owner->GetPosition());
if (dist >= 100)
{
float speed = dist >= 225 ? GetRunspeed() : GetWalkspeed();
@ -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(ComparativeDistanceNoZ(m_Position, npcSpawnPoint) > 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(ComparativeDistanceNoZ(m_Position, npcSpawnPoint) > 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();
@ -1493,7 +1492,7 @@ void Mob::AI_Process() {
//if(owner->IsClient())
// printf("Pet start pos: (%f, %f, %f)\n", GetX(), GetY(), GetZ());
float dist = DistNoRoot(*owner);
float dist = ComparativeDistance(m_Position, owner->GetPosition());
if (dist >= 400)
{
float speed = GetWalkspeed();
@ -1548,7 +1547,7 @@ void Mob::AI_Process() {
if (!follow) SetFollowID(0);
else
{
float dist2 = DistNoRoot(*follow);
float dist2 = ComparativeDistance(m_Position, follow->GetPosition());
int followdist = GetFollowDistance();
if (dist2 >= followdist) // Default follow distance is 100
@ -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
Log.Out(Logs::Detail, Logs::AI, "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) {
Log.Out(Logs::Detail, Logs::AI, "Reached guard point (%.3f,%.3f,%.3f)", guard_x, guard_y, guard_z);
Log.Out(Logs::Detail, Logs::AI, "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 )
if (GetTarget() == nullptr || ComparativeDistance(m_Position, GetTarget()->GetPosition()) >= 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();
@ -673,8 +661,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();
}
@ -779,7 +767,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;
}
@ -938,7 +926,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);
@ -2424,7 +2412,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

@ -117,7 +117,7 @@ Object::Object(Client* client, const ItemInst* inst)
m_data.heading = client->GetHeading();
m_data.x = client->GetX();
m_data.y = client->GetY();
if (client->GetClientVersion() >= EQClientRoF2)
if (client->GetClientVersion() >= ClientVersion::RoF2)
{
// RoF2 places items at player's Z, which is 0.625 of their height.
m_data.z = client->GetZ() - (client->GetSize() * 0.625f);

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.Out(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Bot reference");
#endif
#endif
else
Log.Out(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process an Unknown type reference");
@ -1327,7 +1327,7 @@ XS(XS_Client_MovePCInstance)
else
Log.Out(Logs::Detail, Logs::None, "[CLIENT] 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");
}
@ -3899,7 +3899,7 @@ XS(XS_Client_GetClientVersion)
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetClientVersion();
RETVAL = static_cast<unsigned int>(THIS->GetClientVersion());
XSprePUSH; PUSHu((UV)RETVAL);
}
XSRETURN(1);
@ -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);
@ -5963,7 +5963,7 @@ XS(XS_Client_SilentMessage)
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
if(THIS->GetTarget() != NULL){
if(THIS->GetTarget()->IsNPC()){
if (THIS->DistNoRootNoZ(*THIS->GetTarget()) <= 200) {
if (ComparativeDistanceNoZ(THIS->GetPosition(), THIS->GetTarget()->GetPosition()) <= 200) {
if(THIS->GetTarget()->CastToNPC()->IsMoving() && !THIS->GetTarget()->CastToNPC()->IsOnHatelist(THIS->GetTarget()))
THIS->GetTarget()->CastToNPC()->PauseWandering(RuleI(NPC, SayPauseTimeInSec));
THIS->ChannelMessageReceived(8, 0, 100, SvPV_nolen(ST(1)));
@ -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

@ -429,7 +429,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;

254
zone/position.cpp Normal file
View File

@ -0,0 +1,254 @@
#include <string>
#include <cmath>
#include "position.h"
#include "../common/string_util.h"
#include <algorithm>
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 non square root'ed distance between the two points.
*/
float ComparativeDistance(const xyz_heading& point1, const xyz_heading& point2) {
return ComparativeDistance(static_cast<xyz_location>(point1), static_cast<xyz_location>(point2));
}
/**
* 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.
*/
float Distance(const xyz_heading& point1, const xyz_heading& point2) {
return Distance(static_cast<xyz_location>(point1), static_cast<xyz_location>(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 distance between the two points within the XY plane.
*/
float DistanceNoZ(const xyz_heading& point1, const xyz_heading& 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));
}
/**
* Produces the non square root'ed distance between the two points within the XY plane.
*/
float ComparativeDistanceNoZ(const xyz_heading& point1, const xyz_heading& 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;
}
/**
* Gives the heading directly 180 degrees from the
* current heading.
* Takes the EQfloat from the xyz_heading and returns
* an EQFloat.
*/
float GetReciprocalHeading(const xyz_heading& point1) {
return GetReciprocalHeading(point1.m_Heading);
}
/**
* Gives the heading directly 180 degrees from the
* current heading.
* Takes an EQfloat and returns an EQFloat.
*/
float GetReciprocalHeading(const float heading) {
float result = 0;
// Convert to radians
float h = (heading / 256.0f) * 6.283184f;
// Calculate the reciprocal heading in radians
result = h + 3.141592f;
// Convert back to eq heading from radians
result = (result / 6.283184f) * 256.0f;
return result;
}

105
zone/position.h Normal file
View File

@ -0,0 +1,105 @@
/* 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);
float ComparativeDistance(const xyz_heading& point1, const xyz_heading& point2);
float Distance(const xyz_heading& point1, const xyz_heading& point2);
float DistanceNoZ(const xyz_heading& point1, const xyz_heading& point2);
float ComparativeDistanceNoZ(const xyz_heading& point1, const xyz_heading& point2);
float GetReciprocalHeading(const xyz_heading& point1);
float GetReciprocalHeading(const float heading);
#endif

View File

@ -206,11 +206,11 @@ bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) {
std::string item_script;
if(itm->GetItem()->ScriptFileID != 0) {
item_script = "script_";
item_script += std::to_string(static_cast<long long>(itm->GetItem()->ScriptFileID));
item_script += std::to_string(itm->GetItem()->ScriptFileID);
} else if(strlen(itm->GetItem()->CharmFile) > 0) {
item_script = itm->GetItem()->CharmFile;
} else {
item_script = std::to_string(static_cast<long long>(itm->GetID()));
item_script = std::to_string(itm->GetID());
}
uint32 item_id = itm->GetID();
@ -358,11 +358,11 @@ int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst
std::string item_script;
if(item->GetItem()->ScriptFileID != 0) {
item_script = "script_";
item_script += std::to_string(static_cast<long long>(item->GetItem()->ScriptFileID));
item_script += std::to_string(item->GetItem()->ScriptFileID);
} else if(strlen(item->GetItem()->CharmFile) > 0) {
item_script = item->GetItem()->CharmFile;
} else {
item_script = std::to_string(static_cast<long long>(item->GetID()));
item_script = std::to_string(item->GetID());
}
uint32 item_id = item->GetID();

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

@ -489,7 +489,7 @@ void Raid::CastGroupSpell(Mob* caster, uint16 spellid, uint32 gid)
else if(members[x].member != nullptr)
{
if(members[x].GroupNumber == gid){
distance = caster->DistNoRoot(*members[x].member);
distance = ComparativeDistance(caster->GetPosition(), members[x].member->GetPosition());
if(distance <= range2){
caster->SpellOnTarget(spellid, members[x].member);
#ifdef GROUP_BUFF_PETS
@ -537,7 +537,7 @@ void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, float range)
if(members[gi].member){
if(members[gi].GroupNumber == gid)
{
distance = caster->DistNoRoot(*members[gi].member);
distance = ComparativeDistance(caster->GetPosition(), members[gi].member->GetPosition());
if(distance <= range2){
numMem += 1;
}
@ -551,7 +551,7 @@ void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, float range)
if(members[gi].member){
if(members[gi].GroupNumber == gid)
{
distance = caster->DistNoRoot(*members[gi].member);
distance = ComparativeDistance(caster->GetPosition(), members[gi].member->GetPosition());
if(distance <= range2){
members[gi].member->SetHP(members[gi].member->GetHP() + heal_amt);
members[gi].member->SendHPUpdate();
@ -581,7 +581,7 @@ void Raid::BalanceHP(int32 penalty, uint32 gid, float range, Mob* caster, int32
if(members[gi].member){
if(members[gi].GroupNumber == gid)
{
distance = caster->DistNoRoot(*members[gi].member);
distance = ComparativeDistance(caster->GetPosition(), members[gi].member->GetPosition());
if(distance <= range2){
dmgtaken_tmp = members[gi].member->GetMaxHP() - members[gi].member->GetHP();
@ -602,7 +602,7 @@ void Raid::BalanceHP(int32 penalty, uint32 gid, float range, Mob* caster, int32
if(members[gi].member){
if(members[gi].GroupNumber == gid)
{
distance = caster->DistNoRoot(*members[gi].member);
distance = ComparativeDistance(caster->GetPosition(), members[gi].member->GetPosition());
if(distance <= range2){
if((members[gi].member->GetMaxHP() - dmgtaken) < 1){//this way the ability will never kill someone
members[gi].member->SetHP(1); //but it will come darn close
@ -637,7 +637,7 @@ void Raid::BalanceMana(int32 penalty, uint32 gid, float range, Mob* caster, int3
if(members[gi].GroupNumber == gid)
{
if (members[gi].member->GetMaxMana() > 0) {
distance = caster->DistNoRoot(*members[gi].member);
distance = ComparativeDistance(caster->GetPosition(), members[gi].member->GetPosition());
if(distance <= range2){
manataken_tmp = members[gi].member->GetMaxMana() - members[gi].member->GetMana();
@ -660,7 +660,7 @@ void Raid::BalanceMana(int32 penalty, uint32 gid, float range, Mob* caster, int3
if(members[gi].member){
if(members[gi].GroupNumber == gid)
{
distance = caster->DistNoRoot(*members[gi].member);
distance = ComparativeDistance(caster->GetPosition(), members[gi].member->GetPosition());
if(distance <= range2){
if((members[gi].member->GetMaxMana() - manataken) < 1){
members[gi].member->SetMana(1);
@ -791,7 +791,7 @@ void Raid::GroupBardPulse(Mob* caster, uint16 spellid, uint32 gid){
else if(members[z].member != nullptr)
{
if(members[z].GroupNumber == gid){
distance = caster->DistNoRoot(*members[z].member);
distance = ComparativeDistance(caster->GetPosition(), members[z].member->GetPosition());
if(distance <= range2) {
members[z].member->BardPulse(spellid, caster);
#ifdef GROUP_BUFF_PETS
@ -1529,7 +1529,7 @@ void Raid::SendHPPacketsTo(Client *c)
{
members[x].member->CreateHPPacket(&hpapp);
c->QueuePacket(&hpapp, false);
if(c->GetClientVersion() >= EQClientSoD)
if(c->GetClientVersion() >= ClientVersion::SoD)
{
outapp.SetOpcode(OP_MobManaUpdate);
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
@ -1565,7 +1565,7 @@ void Raid::SendHPPacketsFrom(Mob *m)
if(!m->IsClient() || ((members[x].member != m->CastToClient()) && (members[x].GroupNumber == gid)))
{
members[x].member->QueuePacket(&hpapp, false);
if(members[x].member->GetClientVersion() >= EQClientSoD)
if(members[x].member->GetClientVersion() >= ClientVersion::SoD)
{
outapp.SetOpcode(OP_MobManaUpdate);
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;

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);
@ -411,13 +411,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

@ -769,7 +769,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
float range = RangeItem->Range + AmmoItem->Range + GetRangeDistTargetSizeMod(GetTarget());
Log.Out(Logs::Detail, Logs::Combat, "Calculated bow range to be %.1f", range);
range *= range;
float dist = DistNoRoot(*other);
float dist = ComparativeDistance(m_Position, other->GetPosition());
if(dist > range) {
Log.Out(Logs::Detail, Logs::Combat, "Ranged attack out of range... client should catch this. (%f > %f).\n", dist, range);
Message_StringID(13,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase.
@ -1219,9 +1219,9 @@ void NPC::RangedAttack(Mob* other)
min_range = static_cast<float>(sa_min_range);
max_range *= max_range;
if(DistNoRoot(*other) > max_range)
if(ComparativeDistance(m_Position, other->GetPosition()) > max_range)
return;
else if(DistNoRoot(*other) < (min_range * min_range))
else if(ComparativeDistance(m_Position, other->GetPosition()) < (min_range * min_range))
return;
if(!other || !IsAttackAllowed(other) ||
@ -1408,7 +1408,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
float range = item->Range + GetRangeDistTargetSizeMod(other);
Log.Out(Logs::Detail, Logs::Combat, "Calculated bow range to be %.1f", range);
range *= range;
float dist = DistNoRoot(*other);
float dist = ComparativeDistance(m_Position, other->GetPosition());
if(dist > range) {
Log.Out(Logs::Detail, Logs::Combat, "Throwing attack out of range... client should catch this. (%f > %f).\n", dist, range);
Message_StringID(13,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase.

View File

@ -3409,7 +3409,7 @@ void Mob::BuffProcess()
{
CastToClient()->SendBuffDurationPacket(buffs[buffs_i]);
// Hack to get UF to play nicer, RoF seems fine without it
if (CastToClient()->GetClientVersion() == EQClientUnderfoot && buffs[buffs_i].numhits > 0)
if (CastToClient()->GetClientVersion() == ClientVersion::Und && buffs[buffs_i].numhits > 0)
CastToClient()->SendBuffNumHitPacket(buffs[buffs_i], buffs_i);
buffs[buffs_i].UpdateClient = false;
}
@ -5646,7 +5646,7 @@ int16 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
return realTotal + realTotal2;
}
void Mob::CheckNumHitsRemaining(uint8 type, int32 buff_slot, uint16 spell_id)
void Mob::CheckNumHitsRemaining(NumHit type, int32 buff_slot, uint16 spell_id)
{
/*
Field 175 = numhits type
@ -5673,7 +5673,7 @@ void Mob::CheckNumHitsRemaining(uint8 type, int32 buff_slot, uint16 spell_id)
if (IsValidSpell(spell_id)) {
for (int d = 0; d < buff_max; d++) {
if (buffs[d].spellid == spell_id && buffs[d].numhits > 0 &&
spells[buffs[d].spellid].numhitstype == type) {
spells[buffs[d].spellid].numhitstype == static_cast<int>(type)) {
if (--buffs[d].numhits == 0) {
CastOnNumHitFade(buffs[d].spellid);
if (!TryFadeEffect(d))
@ -5683,7 +5683,7 @@ void Mob::CheckNumHitsRemaining(uint8 type, int32 buff_slot, uint16 spell_id)
}
}
}
} else if (type == NUMHIT_MatchingSpells) {
} else if (type == NumHit::MatchingSpells) {
if (buff_slot >= 0) {
if (--buffs[buff_slot].numhits == 0) {
CastOnNumHitFade(buffs[buff_slot].spellid);
@ -5712,7 +5712,7 @@ void Mob::CheckNumHitsRemaining(uint8 type, int32 buff_slot, uint16 spell_id)
} else {
for (int d = 0; d < buff_max; d++) {
if (IsValidSpell(buffs[d].spellid) && buffs[d].numhits > 0 &&
spells[buffs[d].spellid].numhitstype == type) {
spells[buffs[d].spellid].numhitstype == static_cast<int>(type)) {
if (--buffs[d].numhits == 0) {
CastOnNumHitFade(buffs[d].spellid);
if (!TryFadeEffect(d))
@ -5976,7 +5976,7 @@ int32 Mob::GetFcDamageAmtIncoming(Mob *caster, uint32 spell_id, bool use_skill,
}
if ((!limit_exists) || (limit_exists && skill_found)){
dmg += temp_dmg;
CheckNumHitsRemaining(NUMHIT_MatchingSpells,i);
CheckNumHitsRemaining(NumHit::MatchingSpells, i);
}
}
@ -5984,7 +5984,7 @@ int32 Mob::GetFcDamageAmtIncoming(Mob *caster, uint32 spell_id, bool use_skill,
int32 focus = caster->CalcFocusEffect(focusFcDamageAmtIncoming, buffs[i].spellid, spell_id);
if(focus){
dmg += focus;
CheckNumHitsRemaining(NUMHIT_MatchingSpells,i);
CheckNumHitsRemaining(NumHit::MatchingSpells, i);
}
}
}
@ -6036,7 +6036,7 @@ int32 Mob::GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spel
value = tmp_focus;
if (tmp_buffslot >= 0)
CheckNumHitsRemaining(NUMHIT_MatchingSpells, tmp_buffslot);
CheckNumHitsRemaining(NumHit::MatchingSpells, tmp_buffslot);
}

View File

@ -256,7 +256,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
bitmask = bitmask << (CastToClient()->GetClass() - 1);
if( itm && itm->GetItem()->Classes != 65535 ) {
if ((itm->GetItem()->Click.Type == ET_EquipClick) && !(itm->GetItem()->Classes & bitmask)) {
if (CastToClient()->GetClientVersion() < EQClientSoF) {
if (CastToClient()->GetClientVersion() < ClientVersion::SoF) {
// They are casting a spell from an item that requires equipping but shouldn't let them equip it
Log.Out(Logs::General, Logs::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) which they shouldn't be able to equip!",
CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
@ -268,14 +268,14 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
return(false);
}
if ((itm->GetItem()->Click.Type == ET_ClickEffect2) && !(itm->GetItem()->Classes & bitmask)) {
if (CastToClient()->GetClientVersion() < EQClientSoF) {
if (CastToClient()->GetClientVersion() < ClientVersion::SoF) {
// They are casting a spell from an item that they don't meet the race/class requirements to cast
Log.Out(Logs::General, Logs::Error, "HACKER: %s (account: %s) attempted to click a race/class restricted effect on item %s (id: %d) which they shouldn't be able to click!",
CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking race/class restricted item with an invalid class");
}
else {
if (CastToClient()->GetClientVersion() >= EQClientRoF)
if (CastToClient()->GetClientVersion() >= ClientVersion::RoF)
{
// Line 181 in eqstr_us.txt was changed in RoF+
Message(15, "Your race, class, or deity cannot use this item.");
@ -289,7 +289,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
}
}
if( itm && (itm->GetItem()->Click.Type == ET_EquipClick) && !(item_slot <= MainAmmo || item_slot == MainPowerSource) ){
if (CastToClient()->GetClientVersion() < EQClientSoF) {
if (CastToClient()->GetClientVersion() < ClientVersion::SoF) {
// They are attempting to cast a must equip clicky without having it equipped
Log.Out(Logs::General, Logs::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) without equiping it!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item without equiping it");
@ -310,7 +310,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();
@ -363,7 +363,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
casting_spell_type = type;
SaveSpellLoc();
Log.Out(Logs::Detail, Logs::Spells, "Casting %d Started at (%.3f,%.3f,%.3f)", spell_id, spell_x, spell_y, spell_z);
Log.Out(Logs::Detail, Logs::Spells, "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
@ -534,8 +534,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;
@ -1269,7 +1269,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot,
}
if(IsClient()) {
CheckNumHitsRemaining(NUMHIT_MatchingSpells);
CheckNumHitsRemaining(NumHit::MatchingSpells);
TrySympatheticProc(target, spell_id);
}
@ -1627,7 +1627,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
{
if(!spell_target)
return false;
ae_center = spell_target;
CastAction = AETarget;
}
@ -1646,7 +1646,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
{
if(!spell_target)
return false;
ae_center = spell_target;
CastAction = AETarget;
}
@ -1919,8 +1919,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;
@ -2003,7 +2003,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
}
if(spell_target != nullptr && spell_target != this) {
//casting a spell on somebody but ourself, make sure they are in range
float dist2 = DistNoRoot(*spell_target);
float dist2 = ComparativeDistance(m_Position, spell_target->GetPosition());
float range2 = range * range;
float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range;
if(dist2 > range2) {
@ -2098,7 +2098,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;
@ -2207,7 +2207,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);
@ -2345,7 +2345,7 @@ bool Mob::ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, uint16 slot) {
range = GetActSpellRange(spell_id, spells[spell_id].range, true);
if(spell_target != nullptr && spell_target != this) {
//casting a spell on somebody but ourself, make sure they are in range
float dist2 = DistNoRoot(*spell_target);
float dist2 = ComparativeDistance(m_Position, spell_target->GetPosition());
float range2 = range * range;
if(dist2 > range2) {
//target is out of range.
@ -3574,7 +3574,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r
if(IsEffectInSpell(buffs[b].spellid, SE_BlockNextSpellFocus)) {
focus = CalcFocusEffect(focusBlockNextSpell, buffs[b].spellid, spell_id);
if(focus) {
CheckNumHitsRemaining(NUMHIT_MatchingSpells,b);
CheckNumHitsRemaining(NumHit::MatchingSpells, b);
Message_StringID(MT_SpellFailure, SPELL_WOULDNT_HOLD);
safe_delete(action_packet);
return false;
@ -3623,7 +3623,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r
}
if(reflect_chance) {
Message_StringID(MT_Spells, SPELL_REFLECT, GetCleanName(), spelltar->GetCleanName());
CheckNumHitsRemaining(NUMHIT_ReflectSpell);
CheckNumHitsRemaining(NumHit::ReflectSpell);
SpellOnTarget(spell_id, this, true, use_resist_adjust, resist_adjust);
safe_delete(action_packet);
return false;
@ -3674,8 +3674,8 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r
}
}
spelltar->CheckNumHitsRemaining(NUMHIT_IncomingSpells);
CheckNumHitsRemaining(NUMHIT_OutgoingSpells);
spelltar->CheckNumHitsRemaining(NumHit::IncomingSpells);
CheckNumHitsRemaining(NumHit::OutgoingSpells);
safe_delete(action_packet);
return false;
@ -3730,13 +3730,13 @@ 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);
CheckNumHitsRemaining(NumHit::OutgoingSpells);
if (spelltar)
spelltar->CheckNumHitsRemaining(NUMHIT_IncomingSpells);
spelltar->CheckNumHitsRemaining(NumHit::IncomingSpells);
}
// send the action packet again now that the spell is successful
@ -3857,9 +3857,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)
Log.Out(Logs::Detail, Logs::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;
Log.Out(Logs::Detail, Logs::Spells, "Discipline %d untrained from slot %d", m_pp.disciplines.values[slot], slot);
Log.Out(Logs::Detail, Logs::Spells, "Discipline %d untrained from slot %d", m_pp.disciplines.values[slot], slot);
m_pp.disciplines.values[slot] = 0;
database.DeleteCharacterDisc(this->CharacterID(), slot);
@ -5250,7 +5250,7 @@ void Client::SendBuffDurationPacket(Buffs_Struct &buff)
void Client::SendBuffNumHitPacket(Buffs_Struct &buff, int slot)
{
// UF+ use this packet
if (GetClientVersion() < EQClientUnderfoot)
if (GetClientVersion() < ClientVersion::Und)
return;
EQApplicationPacket *outapp;
outapp = new EQApplicationPacket(OP_BuffCreate, sizeof(BuffIcon_Struct) + sizeof(BuffIconEntry_Struct));
@ -5461,27 +5461,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;
@ -5489,7 +5489,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) {
@ -5536,7 +5536,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

@ -970,7 +970,7 @@ void TaskManager::TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, i
void TaskManager::SendTaskSelector(Client *c, Mob *mob, int TaskCount, int *TaskList) {
if (c->GetClientVersion() >= EQClientRoF)
if (c->GetClientVersion() >= ClientVersion::RoF)
{
SendTaskSelectorNew(c, mob, TaskCount, TaskList);
return;
@ -2503,7 +2503,7 @@ void TaskManager::SendTaskActivityShort(Client *c, int TaskID, int ActivityID, i
void TaskManager::SendTaskActivityLong(Client *c, int TaskID, int ActivityID, int ClientTaskIndex, bool Optional, bool TaskComplete) {
if (c->GetClientVersion() >= EQClientRoF)
if (c->GetClientVersion() >= ClientVersion::RoF)
{
SendTaskActivityNew(c, TaskID, ActivityID, ClientTaskIndex, Optional, TaskComplete);
return;

View File

@ -2645,7 +2645,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) {
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity);
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity * Price);
if(GetClientVersion() >= EQClientSoD)
if(GetClientVersion() >= ClientVersion::SoD)
{
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); // Think this is the upper 32 bits of a 64 bit price
}
@ -2669,7 +2669,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) {
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity);
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity * Price);
if(Buyer->GetClientVersion() >= EQClientSoD)
if(Buyer->GetClientVersion() >= ClientVersion::SoD)
{
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); // Think this is the upper 32 bits of a 64 bit price
}

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;
}
@ -276,9 +270,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]);
@ -319,7 +311,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; }

Some files were not shown because too many files have changed in this diff Show More