mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-13 00:42:26 +00:00
Merge from master
This commit is contained in:
commit
5cbd741358
@ -1,5 +1,22 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 12/20/2014 ==
|
||||||
|
Akkadius: Updated #cvs to display RoF2 Client Stream count
|
||||||
|
|
||||||
|
== 12/19/2014 ==
|
||||||
|
Trevius: (RoF2) Fixed Leadership AA Purchasing and Recipe Search by correcting opcodes.
|
||||||
|
Trevius: Fixed Armor Tinting (players and NPCs) that was broken during a previous update.
|
||||||
|
Trevius: (RoF2) Fixed Rest Timer, Show Helm Option, Auto-Consent Options, and identified Krono in the PP.
|
||||||
|
Trevius: Fixed Selling for Alternate Currency Merchants for RoF and RoF2.
|
||||||
|
|
||||||
|
== 12/18/2014 ==
|
||||||
|
Trevius: Finished lining up the RoF2 Player Profile Struct. Zone times are now normal, and everything from the PP is accurate in game now.
|
||||||
|
Trevius: Fixed zoning after death for RoF2.
|
||||||
|
|
||||||
|
== 12/17/2014 ==
|
||||||
|
demonstar55: Use vectors for route stuff, should be more CPU cache friendly so faster
|
||||||
|
Secrets: EQStream changes as recommended by a community member in private.
|
||||||
|
|
||||||
== 12/15/2014 ==
|
== 12/15/2014 ==
|
||||||
Trevius: (RoF+) Implemented the 6th Augment Slot for Items.
|
Trevius: (RoF+) Implemented the 6th Augment Slot for Items.
|
||||||
Trevius: Player Corpses now saved attuned settings for Items.
|
Trevius: Player Corpses now saved attuned settings for Items.
|
||||||
|
|||||||
@ -548,6 +548,7 @@ uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) {
|
|||||||
},
|
},
|
||||||
{ // local[MapBank]
|
{ // local[MapBank]
|
||||||
/*Unknown*/ NOT_USED,
|
/*Unknown*/ NOT_USED,
|
||||||
|
/*62*/ NOT_USED,
|
||||||
/*Titanium*/ Titanium::consts::MAP_BANK_SIZE,
|
/*Titanium*/ Titanium::consts::MAP_BANK_SIZE,
|
||||||
/*SoF*/ EmuConstants::MAP_BANK_SIZE,
|
/*SoF*/ EmuConstants::MAP_BANK_SIZE,
|
||||||
/*SoD*/ EmuConstants::MAP_BANK_SIZE,
|
/*SoD*/ EmuConstants::MAP_BANK_SIZE,
|
||||||
@ -697,6 +698,7 @@ uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) {
|
|||||||
},
|
},
|
||||||
{ // local[MapCorpse]
|
{ // local[MapCorpse]
|
||||||
/*Unknown*/ NOT_USED,
|
/*Unknown*/ NOT_USED,
|
||||||
|
/*62*/ NOT_USED,
|
||||||
/*Titanium*/ Titanium::consts::MAP_CORPSE_SIZE,
|
/*Titanium*/ Titanium::consts::MAP_CORPSE_SIZE,
|
||||||
/*SoF*/ SoF::consts::MAP_CORPSE_SIZE,
|
/*SoF*/ SoF::consts::MAP_CORPSE_SIZE,
|
||||||
/*SoD*/ SoD::consts::MAP_CORPSE_SIZE,
|
/*SoD*/ SoD::consts::MAP_CORPSE_SIZE,
|
||||||
@ -726,6 +728,7 @@ uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) {
|
|||||||
},
|
},
|
||||||
{ // local[MapInspect]
|
{ // local[MapInspect]
|
||||||
/*Unknown*/ NOT_USED,
|
/*Unknown*/ NOT_USED,
|
||||||
|
/*62*/ NOT_USED,
|
||||||
/*Titanium*/ Titanium::consts::MAP_INSPECT_SIZE,
|
/*Titanium*/ Titanium::consts::MAP_INSPECT_SIZE,
|
||||||
/*SoF*/ SoF::consts::MAP_INSPECT_SIZE,
|
/*SoF*/ SoF::consts::MAP_INSPECT_SIZE,
|
||||||
/*SoD*/ SoD::consts::MAP_INSPECT_SIZE,
|
/*SoD*/ SoD::consts::MAP_INSPECT_SIZE,
|
||||||
@ -1003,6 +1006,7 @@ uint64 EQLimits::CursorBitmask(uint32 version) {
|
|||||||
bool EQLimits::AllowsEmptyBagInBag(uint32 version) {
|
bool EQLimits::AllowsEmptyBagInBag(uint32 version) {
|
||||||
static const bool local[_EmuClientCount] = {
|
static const bool local[_EmuClientCount] = {
|
||||||
/*Unknown*/ false,
|
/*Unknown*/ false,
|
||||||
|
/*62*/ false,
|
||||||
/*Titanium*/ Titanium::limits::ALLOWS_EMPTY_BAG_IN_BAG,
|
/*Titanium*/ Titanium::limits::ALLOWS_EMPTY_BAG_IN_BAG,
|
||||||
/*SoF*/ SoF::limits::ALLOWS_EMPTY_BAG_IN_BAG,
|
/*SoF*/ SoF::limits::ALLOWS_EMPTY_BAG_IN_BAG,
|
||||||
/*SoD*/ SoD::limits::ALLOWS_EMPTY_BAG_IN_BAG,
|
/*SoD*/ SoD::limits::ALLOWS_EMPTY_BAG_IN_BAG,
|
||||||
@ -1023,6 +1027,8 @@ bool EQLimits::AllowsEmptyBagInBag(uint32 version) {
|
|||||||
bool EQLimits::AllowsClickCastFromBag(uint32 version) {
|
bool EQLimits::AllowsClickCastFromBag(uint32 version) {
|
||||||
static const bool local[_EmuClientCount] = {
|
static const bool local[_EmuClientCount] = {
|
||||||
/*Unknown*/ false,
|
/*Unknown*/ false,
|
||||||
|
/*62*/ false,
|
||||||
|
/*Titanium*/ Titanium::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||||
/*SoF*/ SoF::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
/*SoF*/ SoF::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||||
/*SoD*/ SoD::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
/*SoD*/ SoD::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||||
/*Underfoot*/ Underfoot::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
/*Underfoot*/ Underfoot::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||||
@ -1082,6 +1088,7 @@ uint16 EQLimits::ItemContainerSize(uint32 version) {
|
|||||||
bool EQLimits::CoinHasWeight(uint32 version) {
|
bool EQLimits::CoinHasWeight(uint32 version) {
|
||||||
static const bool local[_EmuClientCount] = {
|
static const bool local[_EmuClientCount] = {
|
||||||
/*Unknown*/ true,
|
/*Unknown*/ true,
|
||||||
|
/*62*/ true,
|
||||||
/*Titanium*/ Titanium::limits::COIN_HAS_WEIGHT,
|
/*Titanium*/ Titanium::limits::COIN_HAS_WEIGHT,
|
||||||
/*SoF*/ SoF::limits::COIN_HAS_WEIGHT,
|
/*SoF*/ SoF::limits::COIN_HAS_WEIGHT,
|
||||||
/*SoD*/ SoD::limits::COIN_HAS_WEIGHT,
|
/*SoD*/ SoD::limits::COIN_HAS_WEIGHT,
|
||||||
|
|||||||
@ -1380,19 +1380,19 @@ struct PlayerPositionUpdateServer_Struct
|
|||||||
struct PlayerPositionUpdateClient_Struct
|
struct PlayerPositionUpdateClient_Struct
|
||||||
{
|
{
|
||||||
/*0000*/ uint16 spawn_id;
|
/*0000*/ uint16 spawn_id;
|
||||||
/*0022*/ uint16 sequence; //increments one each packet
|
/*0002*/ uint16 sequence; //increments one each packet
|
||||||
/*0004*/ float y_pos; // y coord
|
/*0004*/ float y_pos; // y coord
|
||||||
/*0008*/ float delta_z; // Change in z
|
/*0008*/ float delta_z; // Change in z
|
||||||
/*0016*/ float delta_x; // Change in x
|
/*0012*/ float delta_x; // Change in x
|
||||||
/*0012*/ float delta_y; // Change in y
|
/*0016*/ float delta_y; // Change in y
|
||||||
/*0020*/ int32 animation:10, // animation
|
/*0020*/ int32 animation:10, // animation
|
||||||
delta_heading:10, // change in heading
|
delta_heading:10, // change in heading
|
||||||
padding0020:12; // ***Placeholder (mostly 1)
|
padding0020:12; // ***Placeholder (mostly 1)
|
||||||
/*0024*/ float x_pos; // x coord
|
/*0024*/ float x_pos; // x coord
|
||||||
/*0028*/ float z_pos; // z coord
|
/*0028*/ float z_pos; // z coord
|
||||||
/*0034*/ uint16 heading:12, // Directional heading
|
/*0032*/ uint16 heading:12, // Directional heading
|
||||||
padding0004:4; // ***Placeholder
|
padding0004:4; // ***Placeholder
|
||||||
/*0032*/ uint8 unknown0006[2]; // ***Placeholder
|
/*0034*/ uint8 unknown0006[2]; // ***Placeholder
|
||||||
/*0036*/
|
/*0036*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,13 @@
|
|||||||
|
|
||||||
uint16 EQStream::MaxWindowSize=2048;
|
uint16 EQStream::MaxWindowSize=2048;
|
||||||
|
|
||||||
void EQStream::init() {
|
void EQStream::init(bool resetSession) {
|
||||||
|
// we only reset these statistics if it is a 'new' connection
|
||||||
|
if ( resetSession )
|
||||||
|
{
|
||||||
|
streamactive = false;
|
||||||
|
sessionAttempts = 0;
|
||||||
|
}
|
||||||
active_users = 0;
|
active_users = 0;
|
||||||
Session=0;
|
Session=0;
|
||||||
Key=0;
|
Key=0;
|
||||||
@ -313,18 +319,22 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
}
|
}
|
||||||
#ifndef COLLECTOR
|
#ifndef COLLECTOR
|
||||||
if (GetState()==ESTABLISHED) {
|
if (GetState()==ESTABLISHED) {
|
||||||
_log(NET__ERROR, _L "Received OP_SessionRequest in ESTABLISHED state (%d)" __L, GetState());
|
_log(NET__ERROR, _L "Received OP_SessionRequest in ESTABLISHED state (%d) streamactive (%i) attempt (%i)" __L, GetState(),streamactive,sessionAttempts);
|
||||||
|
|
||||||
/*RemoveData();
|
// client seems to try a max of 30 times (initial+3 retries) then gives up, giving it a few more attempts just in case
|
||||||
init();
|
// streamactive means we identified the opcode for the stream, we cannot re-establish this connection
|
||||||
State=UNESTABLISHED;*/
|
if ( streamactive || ( sessionAttempts > MAX_SESSION_RETRIES ) )
|
||||||
_SendDisconnect();
|
{
|
||||||
SetState(CLOSED);
|
_SendDisconnect();
|
||||||
break;
|
SetState(CLOSED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//std::cout << "Got OP_SessionRequest" << std::endl;
|
//std::cout << "Got OP_SessionRequest" << std::endl;
|
||||||
init();
|
sessionAttempts++;
|
||||||
|
// we set established below, so statistics will not be reset for session attempts/stream active.
|
||||||
|
init(GetState()!=ESTABLISHED);
|
||||||
OutboundQueueClear();
|
OutboundQueueClear();
|
||||||
SessionRequest *Request=(SessionRequest *)p->pBuffer;
|
SessionRequest *Request=(SessionRequest *)p->pBuffer;
|
||||||
Session=ntohl(Request->Session);
|
Session=ntohl(Request->Session);
|
||||||
|
|||||||
@ -49,6 +49,10 @@ class EQProtocolPacket;
|
|||||||
#define RETRANSMIT_ACKED_PACKETS true
|
#define RETRANSMIT_ACKED_PACKETS true
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_SESSION_RETRIES
|
||||||
|
#define MAX_SESSION_RETRIES 30
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
struct SessionRequest {
|
struct SessionRequest {
|
||||||
uint32 UnknownA;
|
uint32 UnknownA;
|
||||||
@ -104,6 +108,9 @@ class EQStream : public EQStreamInterface {
|
|||||||
uint32 retransmittimer;
|
uint32 retransmittimer;
|
||||||
uint32 retransmittimeout;
|
uint32 retransmittimeout;
|
||||||
|
|
||||||
|
uint16 sessionAttempts;
|
||||||
|
bool streamactive;
|
||||||
|
|
||||||
//uint32 buffer_len;
|
//uint32 buffer_len;
|
||||||
|
|
||||||
uint32 Session, Key;
|
uint32 Session, Key;
|
||||||
@ -197,9 +204,9 @@ class EQStream : public EQStreamInterface {
|
|||||||
|
|
||||||
void _SendDisconnect();
|
void _SendDisconnect();
|
||||||
|
|
||||||
void init();
|
void init(bool resetSession=true);
|
||||||
public:
|
public:
|
||||||
EQStream() { init(); remote_ip = 0; remote_port = 0; State=UNESTABLISHED; StreamType=UnknownStream; compressed=true; encoded=false; app_opcode_size=2; bytes_sent=0; bytes_recv=0; create_time=Timer::GetTimeSeconds(); }
|
EQStream() { init(); remote_ip = 0; remote_port = 0; State=UNESTABLISHED; StreamType=UnknownStream; compressed=true; encoded=false; app_opcode_size=2; bytes_sent=0; bytes_recv=0; create_time=Timer::GetTimeSeconds(); sessionAttempts = 0; streamactive=false; }
|
||||||
EQStream(sockaddr_in addr) { init(); remote_ip=addr.sin_addr.s_addr; remote_port=addr.sin_port; State=UNESTABLISHED; StreamType=UnknownStream; compressed=true; encoded=false; app_opcode_size=2; bytes_sent=0; bytes_recv=0; create_time=Timer::GetTimeSeconds(); }
|
EQStream(sockaddr_in addr) { init(); remote_ip=addr.sin_addr.s_addr; remote_port=addr.sin_port; State=UNESTABLISHED; StreamType=UnknownStream; compressed=true; encoded=false; app_opcode_size=2; bytes_sent=0; bytes_recv=0; create_time=Timer::GetTimeSeconds(); }
|
||||||
virtual ~EQStream() { RemoveData(); SetState(CLOSED); }
|
virtual ~EQStream() { RemoveData(); SetState(CLOSED); }
|
||||||
void SetMaxLen(uint32 length) { MaxLen=length; }
|
void SetMaxLen(uint32 length) { MaxLen=length; }
|
||||||
@ -224,6 +231,9 @@ class EQStream : public EQStreamInterface {
|
|||||||
void SetLastPacketTime(uint32 t) {LastPacket=t;}
|
void SetLastPacketTime(uint32 t) {LastPacket=t;}
|
||||||
void Write(int eq_fd);
|
void Write(int eq_fd);
|
||||||
|
|
||||||
|
// whether or not the stream has been assigned (we passed our stream match)
|
||||||
|
void SetActive(bool val) { streamactive = val; }
|
||||||
|
|
||||||
//
|
//
|
||||||
inline bool IsInUse() { bool flag; MInUse.lock(); flag=(active_users>0); MInUse.unlock(); return flag; }
|
inline bool IsInUse() { bool flag; MInUse.lock(); flag=(active_users>0); MInUse.unlock(); return flag; }
|
||||||
inline void PutInUse() { MInUse.lock(); active_users++; MInUse.unlock(); }
|
inline void PutInUse() { MInUse.lock(); active_users++; MInUse.unlock(); }
|
||||||
|
|||||||
@ -110,6 +110,9 @@ void EQStreamIdentifier::Process() {
|
|||||||
|
|
||||||
_log(NET__IDENTIFY, "Identified stream %s:%d with signature %s", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort()), p->name.c_str());
|
_log(NET__IDENTIFY, "Identified stream %s:%d with signature %s", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort()), p->name.c_str());
|
||||||
|
|
||||||
|
// before we assign the eqstream to an interface, let the stream recognize it is in use and the session should not be reset any further
|
||||||
|
r->stream->SetActive(true);
|
||||||
|
|
||||||
//might want to do something less-specific here... some day..
|
//might want to do something less-specific here... some day..
|
||||||
EQStreamInterface *s = new EQStreamProxy(r->stream, p->structs, p->opcodes);
|
EQStreamInterface *s = new EQStreamProxy(r->stream, p->structs, p->opcodes);
|
||||||
m_identified.push(s);
|
m_identified.push(s);
|
||||||
|
|||||||
@ -205,7 +205,7 @@ namespace RoF
|
|||||||
SETUP_DIRECT_ENCODE(AltCurrencySellItem_Struct, structs::AltCurrencySellItem_Struct);
|
SETUP_DIRECT_ENCODE(AltCurrencySellItem_Struct, structs::AltCurrencySellItem_Struct);
|
||||||
|
|
||||||
OUT(merchant_entity_id);
|
OUT(merchant_entity_id);
|
||||||
eq->slot_id = ServerToRoFSlot(emu->slot_id);
|
eq->slot_id = ServerToRoFMainInvSlot(emu->slot_id);
|
||||||
OUT(charges);
|
OUT(charges);
|
||||||
OUT(cost);
|
OUT(cost);
|
||||||
|
|
||||||
@ -2045,15 +2045,6 @@ namespace RoF
|
|||||||
outapp->WriteUInt32(emu->skills[r]);
|
outapp->WriteUInt32(emu->skills[r]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// deprecated
|
|
||||||
// Write zeroes for the rest of the skills
|
|
||||||
/*
|
|
||||||
for(uint32 r = 0; r < structs::MAX_PP_SKILL - MAX_PP_SKILL; r++)
|
|
||||||
{
|
|
||||||
outapp->WriteUInt32(emu->skills[r]);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
outapp->WriteUInt32(25); // Unknown count
|
outapp->WriteUInt32(25); // Unknown count
|
||||||
|
|
||||||
for (uint32 r = 0; r < 25; r++)
|
for (uint32 r = 0; r < 25; r++)
|
||||||
@ -2130,18 +2121,6 @@ namespace RoF
|
|||||||
|
|
||||||
outapp->WriteUInt32(structs::BUFF_COUNT);
|
outapp->WriteUInt32(structs::BUFF_COUNT);
|
||||||
|
|
||||||
//*000*/ uint8 slotid; // badly named... seems to be 2 for a real buff, 0 otherwise
|
|
||||||
//*001*/ float unknown004; // Seen 1 for no buff
|
|
||||||
//*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
|
||||||
//*009*/ uint32 unknown016;
|
|
||||||
//*013*/ uint8 bard_modifier;
|
|
||||||
//*014*/ uint32 duration;
|
|
||||||
//*018*/ uint8 level;
|
|
||||||
//*019*/ uint32 spellid;
|
|
||||||
//*023*/ uint32 counters;
|
|
||||||
//*027*/ uint8 unknown0028[53];
|
|
||||||
//*080*/
|
|
||||||
|
|
||||||
for (uint32 r = 0; r < BUFF_COUNT; r++)
|
for (uint32 r = 0; r < BUFF_COUNT; r++)
|
||||||
{
|
{
|
||||||
float instrument_mod = 0.0f;
|
float instrument_mod = 0.0f;
|
||||||
@ -3902,7 +3881,7 @@ namespace RoF
|
|||||||
SETUP_DIRECT_DECODE(AltCurrencySellItem_Struct, structs::AltCurrencySellItem_Struct);
|
SETUP_DIRECT_DECODE(AltCurrencySellItem_Struct, structs::AltCurrencySellItem_Struct);
|
||||||
|
|
||||||
IN(merchant_entity_id);
|
IN(merchant_entity_id);
|
||||||
emu->slot_id = RoFToServerSlot(eq->slot_id);
|
emu->slot_id = RoFToServerMainInvSlot(eq->slot_id);
|
||||||
IN(charges);
|
IN(charges);
|
||||||
IN(cost);
|
IN(cost);
|
||||||
|
|
||||||
@ -3915,7 +3894,7 @@ namespace RoF
|
|||||||
SETUP_DIRECT_DECODE(AltCurrencySelectItem_Struct, structs::AltCurrencySelectItem_Struct);
|
SETUP_DIRECT_DECODE(AltCurrencySelectItem_Struct, structs::AltCurrencySelectItem_Struct);
|
||||||
|
|
||||||
IN(merchant_entity_id);
|
IN(merchant_entity_id);
|
||||||
emu->slot_id = RoFToServerSlot(eq->slot_id);
|
emu->slot_id = RoFToServerMainInvSlot(eq->slot_id);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -4878,7 +4857,8 @@ namespace RoF
|
|||||||
uint16 ornaIcon = 0;
|
uint16 ornaIcon = 0;
|
||||||
int32 heroModel = 0;
|
int32 heroModel = 0;
|
||||||
/*
|
/*
|
||||||
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
|
if (inst->GetOrnamentationAug(ornamentationAugtype))
|
||||||
|
{
|
||||||
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||||
//Mainhand
|
//Mainhand
|
||||||
ss.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
|
ss.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
|
||||||
@ -5081,11 +5061,6 @@ namespace RoF
|
|||||||
isbs.augslots[x].unknown = item->AugSlotUnk2[x];
|
isbs.augslots[x].unknown = item->AugSlotUnk2[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increased to 6 max aug slots
|
|
||||||
//isbs.augslots[5].type = 0;
|
|
||||||
//isbs.augslots[5].visible = 1;
|
|
||||||
//isbs.augslots[5].unknown = 0;
|
|
||||||
|
|
||||||
isbs.ldonpoint_type = item->PointType;
|
isbs.ldonpoint_type = item->PointType;
|
||||||
isbs.ldontheme = item->LDoNTheme;
|
isbs.ldontheme = item->LDoNTheme;
|
||||||
isbs.ldonprice = item->LDoNPrice;
|
isbs.ldonprice = item->LDoNPrice;
|
||||||
|
|||||||
@ -205,7 +205,7 @@ namespace RoF2
|
|||||||
SETUP_DIRECT_ENCODE(AltCurrencySellItem_Struct, structs::AltCurrencySellItem_Struct);
|
SETUP_DIRECT_ENCODE(AltCurrencySellItem_Struct, structs::AltCurrencySellItem_Struct);
|
||||||
|
|
||||||
OUT(merchant_entity_id);
|
OUT(merchant_entity_id);
|
||||||
eq->slot_id = ServerToRoF2Slot(emu->slot_id);
|
eq->slot_id = ServerToRoF2MainInvSlot(emu->slot_id);
|
||||||
OUT(charges);
|
OUT(charges);
|
||||||
OUT(cost);
|
OUT(cost);
|
||||||
|
|
||||||
@ -1696,6 +1696,8 @@ namespace RoF2
|
|||||||
eq->unknown932 = -1; // Set from PoK Example
|
eq->unknown932 = -1; // Set from PoK Example
|
||||||
eq->unknown936 = -1; // Set from PoK Example
|
eq->unknown936 = -1; // Set from PoK Example
|
||||||
eq->unknown944 = 1.0; // Set from PoK Example
|
eq->unknown944 = 1.0; // Set from PoK Example
|
||||||
|
eq->unknown948 = 0; // New on Live as of Dec 15 2014
|
||||||
|
eq->unknown952 = 100; // New on Live as of Dec 15 2014
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -2121,18 +2123,6 @@ namespace RoF2
|
|||||||
|
|
||||||
outapp->WriteUInt32(structs::BUFF_COUNT);
|
outapp->WriteUInt32(structs::BUFF_COUNT);
|
||||||
|
|
||||||
//*000*/ uint8 slotid; // badly named... seems to be 2 for a real buff, 0 otherwise
|
|
||||||
//*001*/ float unknown004; // Seen 1 for no buff
|
|
||||||
//*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
|
||||||
//*009*/ uint32 unknown016;
|
|
||||||
//*013*/ uint8 bard_modifier;
|
|
||||||
//*014*/ uint32 duration;
|
|
||||||
//*018*/ uint8 level;
|
|
||||||
//*019*/ uint32 spellid;
|
|
||||||
//*023*/ uint32 counters;
|
|
||||||
//*027*/ uint8 unknown0028[53];
|
|
||||||
//*080*/
|
|
||||||
|
|
||||||
for (uint32 r = 0; r < BUFF_COUNT; r++)
|
for (uint32 r = 0; r < BUFF_COUNT; r++)
|
||||||
{
|
{
|
||||||
float instrument_mod = 0.0f;
|
float instrument_mod = 0.0f;
|
||||||
@ -2172,7 +2162,6 @@ namespace RoF2
|
|||||||
// 80 bytes of zeroes
|
// 80 bytes of zeroes
|
||||||
for (uint32 j = 0; j < 20; ++j)
|
for (uint32 j = 0; j < 20; ++j)
|
||||||
outapp->WriteUInt32(0);
|
outapp->WriteUInt32(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
outapp->WriteUInt32(emu->platinum);
|
outapp->WriteUInt32(emu->platinum);
|
||||||
@ -2197,8 +2186,8 @@ namespace RoF2
|
|||||||
|
|
||||||
outapp->WriteUInt32(emu->aapoints_spent);
|
outapp->WriteUInt32(emu->aapoints_spent);
|
||||||
|
|
||||||
outapp->WriteUInt32(5); // AA Points count ??
|
outapp->WriteUInt32(5); // AA Window Tab Count
|
||||||
outapp->WriteUInt32(1234); // AA Points assigned
|
outapp->WriteUInt32(0); // AA Points assigned ?
|
||||||
outapp->WriteUInt32(0); // AA Points in General ?
|
outapp->WriteUInt32(0); // AA Points in General ?
|
||||||
outapp->WriteUInt32(0); // AA Points in Class ?
|
outapp->WriteUInt32(0); // AA Points in Class ?
|
||||||
outapp->WriteUInt32(0); // AA Points in Archetype ?
|
outapp->WriteUInt32(0); // AA Points in Archetype ?
|
||||||
@ -2326,36 +2315,31 @@ namespace RoF2
|
|||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
outapp->WriteUInt8(emu->gm);
|
outapp->WriteUInt8(emu->gm);
|
||||||
outapp->WriteUInt32(emu->guild_id);
|
outapp->WriteUInt32(emu->guild_id);
|
||||||
outapp->WriteUInt8(0); // Unknown - observed 1 in a live packet.
|
|
||||||
outapp->WriteUInt32(0); // Unknown - observed 1 in a live packet.
|
outapp->WriteUInt8(0); // Unknown
|
||||||
outapp->WriteUInt8(0); // Unknown - observed 1 in a live packet.
|
outapp->WriteUInt32(0); // Unknown
|
||||||
|
outapp->WriteUInt8(0); // Unknown
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
|
|
||||||
outapp->WriteUInt64(emu->exp);
|
outapp->WriteUInt64(emu->exp); // int32 in client
|
||||||
outapp->WriteUInt8(0); // Unknown
|
|
||||||
|
outapp->WriteUInt8(0); // Unknown - Seen 5 on Live
|
||||||
|
|
||||||
outapp->WriteUInt32(emu->platinum_bank);
|
outapp->WriteUInt32(emu->platinum_bank);
|
||||||
outapp->WriteUInt32(emu->gold_bank);
|
outapp->WriteUInt32(emu->gold_bank);
|
||||||
outapp->WriteUInt32(emu->silver_bank);
|
outapp->WriteUInt32(emu->silver_bank);
|
||||||
outapp->WriteUInt32(emu->copper_bank);
|
outapp->WriteUInt32(emu->copper_bank);
|
||||||
|
|
||||||
// Commenting out for RoF Test
|
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
|
|
||||||
outapp->WriteUInt32(42); // The meaning of life ?
|
|
||||||
|
|
||||||
for (uint32 r = 0; r < 42; r++)
|
|
||||||
{
|
|
||||||
outapp->WriteUInt32(0); // Unknown
|
|
||||||
outapp->WriteUInt32(0); // Unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
outapp->WriteUInt32(0); // Unknown
|
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
|
|
||||||
|
outapp->WriteSInt32(-1); // Unknown
|
||||||
|
outapp->WriteSInt32(-1); // Unknown
|
||||||
|
|
||||||
outapp->WriteUInt32(emu->career_tribute_points);
|
outapp->WriteUInt32(emu->career_tribute_points);
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
outapp->WriteUInt32(emu->tribute_points);
|
outapp->WriteUInt32(emu->tribute_points);
|
||||||
@ -2386,18 +2370,12 @@ namespace RoF2
|
|||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
|
|
||||||
/*
|
for (uint32 r = 0; r < 125; r++)
|
||||||
|
{
|
||||||
// Begin RoF2 Test
|
|
||||||
for (uint32 r = 0; r < 1000; r++)
|
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
// End RoF2 Test
|
}
|
||||||
|
|
||||||
// Block of 121 unknown bytes
|
|
||||||
for (uint32 r = 0; r < 121; r++)
|
|
||||||
outapp->WriteUInt8(0); // Unknown
|
|
||||||
|
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
outapp->WriteUInt32(emu->currentRadCrystals);
|
outapp->WriteUInt32(emu->currentRadCrystals);
|
||||||
@ -2411,7 +2389,9 @@ namespace RoF2
|
|||||||
// Unknown String ?
|
// Unknown String ?
|
||||||
outapp->WriteUInt32(64); // Unknown
|
outapp->WriteUInt32(64); // Unknown
|
||||||
for (uint32 r = 0; r < 64; r++)
|
for (uint32 r = 0; r < 64; r++)
|
||||||
|
{
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
|
}
|
||||||
|
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
@ -2439,22 +2419,30 @@ namespace RoF2
|
|||||||
// Unknown String ?
|
// Unknown String ?
|
||||||
outapp->WriteUInt32(64); // Unknown
|
outapp->WriteUInt32(64); // Unknown
|
||||||
for (uint32 r = 0; r < 64; r++)
|
for (uint32 r = 0; r < 64; r++)
|
||||||
|
{
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
|
}
|
||||||
|
|
||||||
// Unknown String ?
|
// Unknown String ?
|
||||||
outapp->WriteUInt32(64); // Unknown
|
outapp->WriteUInt32(64); // Unknown
|
||||||
for (uint32 r = 0; r < 64; r++)
|
for (uint32 r = 0; r < 64; r++)
|
||||||
|
{
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
|
}
|
||||||
|
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
|
|
||||||
// Block of 320 unknown bytes
|
// Block of 320 unknown bytes
|
||||||
for (uint32 r = 0; r < 320; r++)
|
for (uint32 r = 0; r < 320; r++)
|
||||||
|
{
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
|
}
|
||||||
|
|
||||||
// Block of 343 unknown bytes
|
// Block of 343 unknown bytes
|
||||||
for (uint32 r = 0; r < 343; r++)
|
for (uint32 r = 0; r < 343; r++)
|
||||||
|
{
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
|
}
|
||||||
|
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
|
|
||||||
@ -2479,10 +2467,14 @@ namespace RoF2
|
|||||||
outapp->WriteUInt32(64); // Group of 64 int32s follow Group/Raid Leadership abilities ?
|
outapp->WriteUInt32(64); // Group of 64 int32s follow Group/Raid Leadership abilities ?
|
||||||
|
|
||||||
for (uint32 r = 0; r < MAX_LEADERSHIP_AA_ARRAY; r++)
|
for (uint32 r = 0; r < MAX_LEADERSHIP_AA_ARRAY; r++)
|
||||||
|
{
|
||||||
outapp->WriteUInt32(emu->leader_abilities.ranks[r]);
|
outapp->WriteUInt32(emu->leader_abilities.ranks[r]);
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32 r = 0; r < 64 - MAX_LEADERSHIP_AA_ARRAY; r++)
|
for (uint32 r = 0; r < 64 - MAX_LEADERSHIP_AA_ARRAY; r++)
|
||||||
|
{
|
||||||
outapp->WriteUInt32(0); // Unused/unsupported Leadership abilities
|
outapp->WriteUInt32(0); // Unused/unsupported Leadership abilities
|
||||||
|
}
|
||||||
|
|
||||||
outapp->WriteUInt32(emu->air_remaining); // ?
|
outapp->WriteUInt32(emu->air_remaining); // ?
|
||||||
|
|
||||||
@ -2535,33 +2527,31 @@ namespace RoF2
|
|||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
|
|
||||||
*/
|
outapp->WriteUInt32(0); // Unknown
|
||||||
|
outapp->WriteUInt32(0); // Krono - itemid 88888 Hard coded in client?
|
||||||
|
|
||||||
outapp->WriteUInt8(emu->groupAutoconsent);
|
outapp->WriteUInt8(emu->groupAutoconsent);
|
||||||
outapp->WriteUInt8(emu->raidAutoconsent);
|
outapp->WriteUInt8(emu->raidAutoconsent);
|
||||||
outapp->WriteUInt8(emu->guildAutoconsent);
|
outapp->WriteUInt8(emu->guildAutoconsent);
|
||||||
|
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
|
|
||||||
outapp->WriteUInt32(emu->level); // Level3 ?
|
outapp->WriteUInt32(emu->level); // Level3 ?
|
||||||
|
|
||||||
outapp->WriteUInt8(emu->showhelm);
|
outapp->WriteUInt8(emu->showhelm);
|
||||||
|
|
||||||
outapp->WriteUInt32(emu->RestTimer);
|
outapp->WriteUInt32(emu->RestTimer);
|
||||||
|
|
||||||
outapp->WriteUInt32(1024); // Unknown Count
|
outapp->WriteUInt32(1024); // Unknown Count
|
||||||
|
|
||||||
// Block of 1024 unknown bytes
|
// Block of 1024 unknown bytes
|
||||||
outapp->WriteUInt8(31); // Unknown
|
for (uint32 r = 0; r < 1024; r++)
|
||||||
|
{
|
||||||
for (uint32 r = 0; r < 1023; r++)
|
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
|
}
|
||||||
|
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
|
|
||||||
// Think we need 1 byte of padding at the end
|
// Think we need 1 byte of padding at the end
|
||||||
|
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
|
|
||||||
_log(NET__STRUCTS, "Player Profile Packet is %i bytes", outapp->GetWritePosition());
|
_log(NET__STRUCTS, "Player Profile Packet is %i bytes", outapp->GetWritePosition());
|
||||||
@ -3887,6 +3877,7 @@ namespace RoF2
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DECODE methods
|
// DECODE methods
|
||||||
|
|
||||||
DECODE(OP_AdventureMerchantSell)
|
DECODE(OP_AdventureMerchantSell)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::Adventure_Sell_Struct);
|
DECODE_LENGTH_EXACT(structs::Adventure_Sell_Struct);
|
||||||
@ -3906,7 +3897,7 @@ namespace RoF2
|
|||||||
SETUP_DIRECT_DECODE(AltCurrencySellItem_Struct, structs::AltCurrencySellItem_Struct);
|
SETUP_DIRECT_DECODE(AltCurrencySellItem_Struct, structs::AltCurrencySellItem_Struct);
|
||||||
|
|
||||||
IN(merchant_entity_id);
|
IN(merchant_entity_id);
|
||||||
emu->slot_id = RoF2ToServerSlot(eq->slot_id);
|
emu->slot_id = RoF2ToServerMainInvSlot(eq->slot_id);
|
||||||
IN(charges);
|
IN(charges);
|
||||||
IN(cost);
|
IN(cost);
|
||||||
|
|
||||||
@ -3919,7 +3910,7 @@ namespace RoF2
|
|||||||
SETUP_DIRECT_DECODE(AltCurrencySelectItem_Struct, structs::AltCurrencySelectItem_Struct);
|
SETUP_DIRECT_DECODE(AltCurrencySelectItem_Struct, structs::AltCurrencySelectItem_Struct);
|
||||||
|
|
||||||
IN(merchant_entity_id);
|
IN(merchant_entity_id);
|
||||||
emu->slot_id = RoF2ToServerSlot(eq->slot_id);
|
emu->slot_id = RoF2ToServerMainInvSlot(eq->slot_id);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -4860,8 +4851,8 @@ namespace RoF2
|
|||||||
hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||||
hdr.unknown044 = 0;
|
hdr.unknown044 = 0;
|
||||||
hdr.unknown048 = 7300 + Inventory::CalcMaterialFromSlot(slot_id_in); //0;
|
hdr.unknown048 = 0;
|
||||||
hdr.unknown052 = 7300 + Inventory::CalcMaterialFromSlot(slot_id_in); //0;
|
hdr.unknown052 = 0;
|
||||||
hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0;
|
hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0;
|
||||||
ss.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader));
|
ss.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader));
|
||||||
|
|
||||||
@ -5085,11 +5076,6 @@ namespace RoF2
|
|||||||
isbs.augslots[x].unknown = item->AugSlotUnk2[x];
|
isbs.augslots[x].unknown = item->AugSlotUnk2[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increased to 6 max aug slots
|
|
||||||
//isbs.augslots[5].type = 0;
|
|
||||||
//isbs.augslots[5].visible = 1;
|
|
||||||
//isbs.augslots[5].unknown = 0;
|
|
||||||
|
|
||||||
isbs.ldonpoint_type = item->PointType;
|
isbs.ldonpoint_type = item->PointType;
|
||||||
isbs.ldontheme = item->LDoNTheme;
|
isbs.ldontheme = item->LDoNTheme;
|
||||||
isbs.ldonprice = item->LDoNPrice;
|
isbs.ldonprice = item->LDoNPrice;
|
||||||
@ -5325,13 +5311,8 @@ namespace RoF2
|
|||||||
iqbs.SpellDmg = item->SpellDmg;
|
iqbs.SpellDmg = item->SpellDmg;
|
||||||
iqbs.clairvoyance = item->Clairvoyance;
|
iqbs.clairvoyance = item->Clairvoyance;
|
||||||
iqbs.unknown28 = 0;
|
iqbs.unknown28 = 0;
|
||||||
|
|
||||||
|
|
||||||
// Begin RoF2 Test
|
|
||||||
iqbs.unknown_TEST1 = 0;
|
|
||||||
// End RoF2 Test
|
|
||||||
|
|
||||||
iqbs.unknown30 = 0;
|
iqbs.unknown30 = 0;
|
||||||
|
iqbs.unknown37a = 0;
|
||||||
iqbs.unknown39 = 1;
|
iqbs.unknown39 = 1;
|
||||||
|
|
||||||
iqbs.subitem_count = 0;
|
iqbs.subitem_count = 0;
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
// incoming packets that require a DECODE translation:
|
// incoming packets that require a DECODE translation:
|
||||||
// Begin RoF2 Decodes
|
// Begin RoF2 Decodes
|
||||||
|
|
||||||
|
|
||||||
// End RoF2 Encodes/Decodes
|
// End RoF2 Encodes/Decodes
|
||||||
|
|
||||||
// These require Encodes/Decodes for RoF, so they do for RoF2 as well
|
// These require Encodes/Decodes for RoF, so they do for RoF2 as well
|
||||||
|
|||||||
@ -520,72 +520,73 @@ struct ServerZoneEntry_Struct //Adjusted from SEQ Everquest.h Struct
|
|||||||
|
|
||||||
//New Zone Struct - Size: 948
|
//New Zone Struct - Size: 948
|
||||||
struct NewZone_Struct {
|
struct NewZone_Struct {
|
||||||
/*0000*/ char char_name[64]; // Character Name
|
/*0000*/ char char_name[64]; // Character Name
|
||||||
/*0064*/ char zone_short_name[32]; // Zone Short Name
|
/*0064*/ char zone_short_name[32]; // Zone Short Name
|
||||||
/*0096*/ char unknown0096[96];
|
/*0096*/ char unknown0096[96];
|
||||||
/*0192*/ char zone_long_name[278]; // Zone Long Name
|
/*0192*/ char zone_long_name[278]; // Zone Long Name
|
||||||
/*0470*/ uint8 ztype; // Zone type (usually FF)
|
/*0470*/ uint8 ztype; // Zone type (usually FF)
|
||||||
/*0471*/ uint8 fog_red[4]; // Zone fog (red)
|
/*0471*/ uint8 fog_red[4]; // Zone fog (red)
|
||||||
/*0475*/ uint8 fog_green[4]; // Zone fog (green)
|
/*0475*/ uint8 fog_green[4]; // Zone fog (green)
|
||||||
/*0479*/ uint8 fog_blue[4]; // Zone fog (blue)
|
/*0479*/ uint8 fog_blue[4]; // Zone fog (blue)
|
||||||
/*0483*/ uint8 unknown323;
|
/*0483*/ uint8 unknown323;
|
||||||
/*0484*/ float fog_minclip[4];
|
/*0484*/ float fog_minclip[4];
|
||||||
/*0500*/ float fog_maxclip[4];
|
/*0500*/ float fog_maxclip[4];
|
||||||
/*0516*/ float gravity;
|
/*0516*/ float gravity;
|
||||||
/*0520*/ uint8 time_type;
|
/*0520*/ uint8 time_type;
|
||||||
/*0521*/ uint8 rain_chance[4];
|
/*0521*/ uint8 rain_chance[4];
|
||||||
/*0525*/ uint8 rain_duration[4];
|
/*0525*/ uint8 rain_duration[4];
|
||||||
/*0529*/ uint8 snow_chance[4];
|
/*0529*/ uint8 snow_chance[4];
|
||||||
/*0533*/ uint8 snow_duration[4];
|
/*0533*/ uint8 snow_duration[4];
|
||||||
/*0537*/ uint8 unknown537[33];
|
/*0537*/ uint8 unknown537[33];
|
||||||
/*0570*/ uint8 sky; // Sky Type
|
/*0570*/ uint8 sky; // Sky Type
|
||||||
/*0571*/ uint8 unknown571[13]; // ***Placeholder
|
/*0571*/ uint8 unknown571[13]; // ***Placeholder
|
||||||
/*0584*/ float zone_exp_multiplier; // Experience Multiplier
|
/*0584*/ float zone_exp_multiplier; // Experience Multiplier
|
||||||
/*0588*/ float safe_y; // Zone Safe Y
|
/*0588*/ float safe_y; // Zone Safe Y
|
||||||
/*0592*/ float safe_x; // Zone Safe X
|
/*0592*/ float safe_x; // Zone Safe X
|
||||||
/*0596*/ float safe_z; // Zone Safe Z
|
/*0596*/ float safe_z; // Zone Safe Z
|
||||||
/*0600*/ float min_z; // Guessed - NEW - Seen 0
|
/*0600*/ float min_z; // Guessed - NEW - Seen 0
|
||||||
/*0604*/ float max_z; // Guessed
|
/*0604*/ float max_z; // Guessed
|
||||||
/*0608*/ float underworld; // Underworld, min z (Not Sure?)
|
/*0608*/ float underworld; // Underworld, min z (Not Sure?)
|
||||||
/*0612*/ float minclip; // Minimum View Distance
|
/*0612*/ float minclip; // Minimum View Distance
|
||||||
/*0616*/ float maxclip; // Maximum View DIstance
|
/*0616*/ float maxclip; // Maximum View DIstance
|
||||||
/*0620*/ uint8 unknown620[84]; // ***Placeholder
|
/*0620*/ uint8 unknown620[84]; // ***Placeholder
|
||||||
/*0704*/ char zone_short_name2[96]; //zone file name? excludes instance number which can be in previous version.
|
/*0704*/ char zone_short_name2[96]; //zone file name? excludes instance number which can be in previous version.
|
||||||
/*0800*/ int32 unknown800; //seen -1
|
/*0800*/ int32 unknown800; //seen -1
|
||||||
/*0804*/ char unknown804[40]; //
|
/*0804*/ char unknown804[40]; //
|
||||||
/*0844*/ int32 unknown844; //seen 600
|
/*0844*/ int32 unknown844; //seen 600
|
||||||
/*0848*/ int32 unknown848;
|
/*0848*/ int32 unknown848;
|
||||||
/*0852*/ uint16 zone_id;
|
/*0852*/ uint16 zone_id;
|
||||||
/*0854*/ uint16 zone_instance;
|
/*0854*/ uint16 zone_instance;
|
||||||
/*0856*/ char unknown856[20];
|
/*0856*/ char unknown856[20];
|
||||||
/*0876*/ uint32 SuspendBuffs;
|
/*0876*/ uint32 SuspendBuffs;
|
||||||
/*0880*/ uint32 unknown880; // Seen 50
|
/*0880*/ uint32 unknown880; // Seen 50
|
||||||
/*0884*/ uint32 unknown884; // Seen 10
|
/*0884*/ uint32 unknown884; // Seen 10
|
||||||
/*0888*/ uint8 unknown888; // Seen 1
|
/*0888*/ uint8 unknown888; // Seen 1
|
||||||
/*0889*/ uint8 unknown889; // Seen 0 (POK) or 1 (rujj)
|
/*0889*/ uint8 unknown889; // Seen 0 (POK) or 1 (rujj)
|
||||||
/*0890*/ uint8 unknown890; // Seen 1
|
/*0890*/ uint8 unknown890; // Seen 1
|
||||||
/*0891*/ uint8 unknown891; // Seen 0
|
/*0891*/ uint8 unknown891; // Seen 0
|
||||||
/*0892*/ uint8 unknown892; // Seen 0
|
/*0892*/ uint8 unknown892; // Seen 0
|
||||||
/*0893*/ uint8 unknown893; // Seen 0 - 00
|
/*0893*/ uint8 unknown893; // Seen 0 - 00
|
||||||
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off
|
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off
|
||||||
/*0895*/ uint8 unknown895; // Seen 0 - 00
|
/*0895*/ uint8 unknown895; // Seen 0 - 00
|
||||||
/*0896*/ uint32 unknown896; // Seen 180
|
/*0896*/ uint32 unknown896; // Seen 180
|
||||||
/*0900*/ uint32 unknown900; // Seen 180
|
/*0900*/ uint32 unknown900; // Seen 180
|
||||||
/*0904*/ uint32 unknown904; // Seen 180
|
/*0904*/ uint32 unknown904; // Seen 180
|
||||||
/*0908*/ uint32 unknown908; // Seen 2
|
/*0908*/ uint32 unknown908; // Seen 2
|
||||||
/*0912*/ uint32 unknown912; // Seen 2
|
/*0912*/ uint32 unknown912; // Seen 2
|
||||||
/*0916*/ float FogDensity; // Most zones have this set to 0.33 Blightfire had 0.16
|
/*0916*/ float FogDensity; // Most zones have this set to 0.33 Blightfire had 0.16
|
||||||
/*0920*/ uint32 unknown920; // Seen 0
|
/*0920*/ uint32 unknown920; // Seen 0
|
||||||
/*0924*/ uint32 unknown924; // Seen 0
|
/*0924*/ uint32 unknown924; // Seen 0
|
||||||
/*0928*/ uint32 unknown928; // Seen 0
|
/*0928*/ uint32 unknown928; // Seen 0
|
||||||
/*0932*/ int32 unknown932; // Seen -1
|
/*0932*/ int32 unknown932; // Seen -1
|
||||||
/*0936*/ int32 unknown936; // Seen -1
|
/*0936*/ int32 unknown936; // Seen -1
|
||||||
/*0940*/ uint32 unknown940; // Seen 0
|
/*0940*/ uint32 unknown940; // Seen 0
|
||||||
/*0944*/ float unknown944; // Seen 1.0
|
/*0944*/ float unknown944; // Seen 1.0
|
||||||
/*0948*/
|
/*0948*/ uint32 unknown948; // Seen 0 - New on Live as of Dec 15 2014
|
||||||
|
/*0952*/ uint32 unknown952; // Seen 100 - New on Live as of Dec 15 2014
|
||||||
|
/*0956*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Memorize Spell Struct
|
** Memorize Spell Struct
|
||||||
** Length: 16 Bytes
|
** Length: 16 Bytes
|
||||||
@ -1598,23 +1599,24 @@ struct RespawnWindow_Struct {
|
|||||||
*/
|
*/
|
||||||
struct PlayerPositionUpdateServer_Struct
|
struct PlayerPositionUpdateServer_Struct
|
||||||
{
|
{
|
||||||
uint16 spawn_id;
|
/*0000*/ uint16 spawn_id;
|
||||||
uint16 spawnId2;
|
/*0002*/ uint16 spawnId2;
|
||||||
signed padding0004:12;
|
/*0004*/ signed padding0004 : 12;
|
||||||
signed y_pos:19; // y coord
|
signed y_pos : 19; // y coord
|
||||||
unsigned padding:1;
|
unsigned padding : 1;
|
||||||
signed delta_z:13; // change in z
|
/*0008*/ signed delta_z : 13; // change in z
|
||||||
signed delta_x:13; // change in x
|
signed delta_x : 13; // change in x
|
||||||
signed padding0008:6;
|
signed padding0008 : 6;
|
||||||
signed x_pos:19; // x coord
|
/*0012*/ signed x_pos : 19; // x coord
|
||||||
unsigned heading:12; // heading
|
unsigned heading : 12; // heading
|
||||||
signed padding0016:1;
|
signed padding0016 : 1;
|
||||||
signed delta_heading:10; // change in heading
|
/*0016*/ signed delta_heading : 10; // change in heading
|
||||||
signed z_pos:19; // z coord
|
signed z_pos : 19; // z coord
|
||||||
signed padding0020:3;
|
signed padding0020 : 3;
|
||||||
signed animation:10; // animation
|
/*0020*/ signed animation : 10; // animation
|
||||||
signed delta_y:13; // change in y
|
signed delta_y : 13; // change in y
|
||||||
signed padding0024:9;
|
signed padding0024 : 9;
|
||||||
|
/*0024*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1625,21 +1627,22 @@ struct PlayerPositionUpdateServer_Struct
|
|||||||
*/
|
*/
|
||||||
struct PlayerPositionUpdateClient_Struct
|
struct PlayerPositionUpdateClient_Struct
|
||||||
{
|
{
|
||||||
uint16 sequence; // increments one each packet - Verified
|
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
||||||
uint16 spawn_id; // Player's spawn id
|
/*0002*/ uint16 spawn_id; // Player's spawn id
|
||||||
uint8 unknown0004[6]; // ***Placeholder
|
/*0004*/ uint8 unknown0004[6]; // ***Placeholder
|
||||||
float delta_x; // Change in x
|
/*0010*/ float delta_x; // Change in x
|
||||||
unsigned heading:12; // Directional heading
|
/*0014*/ unsigned heading : 12; // Directional heading
|
||||||
unsigned padding0040:20; // ***Placeholder
|
unsigned padding0040 : 20; // ***Placeholder
|
||||||
float x_pos; // x coord (2nd loc value)
|
/*0018*/ float x_pos; // x coord (2nd loc value)
|
||||||
float delta_z; // Change in z
|
/*0022*/ float delta_z; // Change in z
|
||||||
float z_pos; // z coord (3rd loc value)
|
/*0026*/ float z_pos; // z coord (3rd loc value)
|
||||||
float y_pos; // y coord (1st loc value)
|
/*0030*/ float y_pos; // y coord (1st loc value)
|
||||||
unsigned animation:10; // ***Placeholder
|
/*0034*/ unsigned animation : 10; // ***Placeholder
|
||||||
unsigned padding0024:22; // animation
|
unsigned padding0024 : 22; // animation
|
||||||
float delta_y; // Change in y
|
/*0038*/ float delta_y; // Change in y
|
||||||
signed delta_heading:10; // change in heading
|
/*0042*/ signed delta_heading : 10; // change in heading
|
||||||
unsigned padding0041:22; // ***Placeholder
|
unsigned padding0041 : 22; // ***Placeholder
|
||||||
|
/*0046*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2177,8 +2180,8 @@ struct AltCurrencyUpdate_Struct {
|
|||||||
//When an item is selected while the alt currency merchant window is open
|
//When an item is selected while the alt currency merchant window is open
|
||||||
struct AltCurrencySelectItem_Struct {
|
struct AltCurrencySelectItem_Struct {
|
||||||
/*000*/ uint32 merchant_entity_id;
|
/*000*/ uint32 merchant_entity_id;
|
||||||
|
/*004*/ MainInvItemSlotStruct slot_id;
|
||||||
/*004*/ //uint32 slot_id;
|
/*004*/ //uint32 slot_id;
|
||||||
ItemSlotStruct slot_id;
|
|
||||||
/*008*/ uint32 unknown008;
|
/*008*/ uint32 unknown008;
|
||||||
/*012*/ uint32 unknown012;
|
/*012*/ uint32 unknown012;
|
||||||
/*016*/ uint32 unknown016;
|
/*016*/ uint32 unknown016;
|
||||||
@ -2235,10 +2238,10 @@ struct AltCurrencyReclaim_Struct {
|
|||||||
|
|
||||||
struct AltCurrencySellItem_Struct {
|
struct AltCurrencySellItem_Struct {
|
||||||
/*000*/ uint32 merchant_entity_id;
|
/*000*/ uint32 merchant_entity_id;
|
||||||
|
/*004*/ MainInvItemSlotStruct slot_id;
|
||||||
/*004*/ //uint32 slot_id;
|
/*004*/ //uint32 slot_id;
|
||||||
ItemSlotStruct slot_id;
|
/*016*/ uint32 charges;
|
||||||
/*008*/ uint32 charges;
|
/*020*/ uint32 cost;
|
||||||
/*012*/ uint32 cost;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Adventure_Purchase_Struct {
|
struct Adventure_Purchase_Struct {
|
||||||
@ -2258,14 +2261,14 @@ struct Adventure_Sell_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AdventurePoints_Update_Struct {
|
struct AdventurePoints_Update_Struct {
|
||||||
/*000*/ uint32 ldon_available_points; // Total available points
|
/*000*/ uint32 ldon_available_points; // Total available points
|
||||||
/*004*/ uint8 unkown_apu004[20];
|
/*004*/ uint8 unkown_apu004[20];
|
||||||
/*024*/ uint32 ldon_guk_points; // Earned Deepest Guk points
|
/*024*/ uint32 ldon_guk_points; // Earned Deepest Guk points
|
||||||
/*028*/ uint32 ldon_mirugal_points; // Earned Mirugal' Mebagerie points
|
/*028*/ uint32 ldon_mirugal_points; // Earned Mirugal' Mebagerie points
|
||||||
/*032*/ uint32 ldon_mistmoore_points; // Earned Mismoore Catacombs Points
|
/*032*/ uint32 ldon_mistmoore_points; // Earned Mismoore Catacombs Points
|
||||||
/*036*/ uint32 ldon_rujarkian_points; // Earned Rujarkian Hills points
|
/*036*/ uint32 ldon_rujarkian_points; // Earned Rujarkian Hills points
|
||||||
/*040*/ uint32 ldon_takish_points; // Earned Takish points
|
/*040*/ uint32 ldon_takish_points; // Earned Takish points
|
||||||
/*044*/ uint8 unknown_apu042[216];
|
/*044*/ uint8 unknown_apu042[216];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -4687,11 +4690,7 @@ struct ItemQuaternaryBodyStruct
|
|||||||
uint32 unknown37;
|
uint32 unknown37;
|
||||||
uint32 unknown_RoF27;
|
uint32 unknown_RoF27;
|
||||||
uint32 unknown_RoF28;
|
uint32 unknown_RoF28;
|
||||||
|
uint8 unknown37a; // (guessed position) New to RoF2
|
||||||
// Begin RoF2 Test
|
|
||||||
uint8 unknown_TEST1;
|
|
||||||
// End RoF2 Test
|
|
||||||
|
|
||||||
uint8 unknown38; // 0
|
uint8 unknown38; // 0
|
||||||
uint8 unknown39; // 1
|
uint8 unknown39; // 1
|
||||||
uint32 subitem_count;
|
uint32 subitem_count;
|
||||||
|
|||||||
@ -2174,8 +2174,7 @@ struct AltCurrencyUpdate_Struct {
|
|||||||
//When an item is selected while the alt currency merchant window is open
|
//When an item is selected while the alt currency merchant window is open
|
||||||
struct AltCurrencySelectItem_Struct {
|
struct AltCurrencySelectItem_Struct {
|
||||||
/*000*/ uint32 merchant_entity_id;
|
/*000*/ uint32 merchant_entity_id;
|
||||||
/*004*/ //uint32 slot_id;
|
/*004*/ MainInvItemSlotStruct slot_id;
|
||||||
ItemSlotStruct slot_id;
|
|
||||||
/*008*/ uint32 unknown008;
|
/*008*/ uint32 unknown008;
|
||||||
/*012*/ uint32 unknown012;
|
/*012*/ uint32 unknown012;
|
||||||
/*016*/ uint32 unknown016;
|
/*016*/ uint32 unknown016;
|
||||||
@ -2232,8 +2231,7 @@ struct AltCurrencyReclaim_Struct {
|
|||||||
|
|
||||||
struct AltCurrencySellItem_Struct {
|
struct AltCurrencySellItem_Struct {
|
||||||
/*000*/ uint32 merchant_entity_id;
|
/*000*/ uint32 merchant_entity_id;
|
||||||
/*004*/ //uint32 slot_id;
|
/*004*/ MainInvItemSlotStruct slot_id;
|
||||||
ItemSlotStruct slot_id;
|
|
||||||
/*008*/ uint32 charges;
|
/*008*/ uint32 charges;
|
||||||
/*012*/ uint32 cost;
|
/*012*/ uint32 cost;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4365,8 +4365,8 @@ struct AltCurrencySelectItem_Struct {
|
|||||||
struct AltCurrencySellItem_Struct {
|
struct AltCurrencySellItem_Struct {
|
||||||
/*000*/ uint32 merchant_entity_id;
|
/*000*/ uint32 merchant_entity_id;
|
||||||
/*004*/ uint32 slot_id;
|
/*004*/ uint32 slot_id;
|
||||||
/*006*/ uint32 charges;
|
/*008*/ uint32 charges;
|
||||||
/*010*/ uint32 cost;
|
/*012*/ uint32 cost;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AltCurrencyPopulateEntry_Struct
|
struct AltCurrencyPopulateEntry_Struct
|
||||||
|
|||||||
@ -1234,6 +1234,9 @@ ItemInst* SharedDatabase::CreateBaseItem(const Item_Struct* item, int16 charges)
|
|||||||
// set it to 1 charge so that it is usable on creation
|
// set it to 1 charge so that it is usable on creation
|
||||||
if (charges == 0 && item->MaxCharges == -1)
|
if (charges == 0 && item->MaxCharges == -1)
|
||||||
charges = 1;
|
charges = 1;
|
||||||
|
// Stackable items need a minimum charge of 1 to remain moveable.
|
||||||
|
if(charges <= 0 && item->Stackable)
|
||||||
|
charges = 1;
|
||||||
|
|
||||||
inst = new ItemInst(item, charges);
|
inst = new ItemInst(item, charges);
|
||||||
|
|
||||||
|
|||||||
@ -113,7 +113,7 @@ OP_ClientUpdate=0x7dfc
|
|||||||
OP_ClientReady=0x345d
|
OP_ClientReady=0x345d
|
||||||
OP_SetServerFilter=0x444d
|
OP_SetServerFilter=0x444d
|
||||||
|
|
||||||
# Guild Opcodes - Disabled until crashes are resolved in RoF
|
# Guild Opcodes
|
||||||
OP_GetGuildMOTD=0x36e0
|
OP_GetGuildMOTD=0x36e0
|
||||||
OP_GetGuildMOTDReply=0x4f1f
|
OP_GetGuildMOTDReply=0x4f1f
|
||||||
OP_GuildMemberUpdate=0x69b9
|
OP_GuildMemberUpdate=0x69b9
|
||||||
@ -121,7 +121,6 @@ OP_GuildInvite=0x7099
|
|||||||
OP_GuildRemove=0x1444
|
OP_GuildRemove=0x1444
|
||||||
OP_GuildPeace=0x67e3
|
OP_GuildPeace=0x67e3
|
||||||
OP_SetGuildMOTD=0x0b0b
|
OP_SetGuildMOTD=0x0b0b
|
||||||
OP_GuildList=0x6279
|
|
||||||
OP_GuildWar=0x1ffb
|
OP_GuildWar=0x1ffb
|
||||||
OP_GuildLeader=0x7e09
|
OP_GuildLeader=0x7e09
|
||||||
OP_GuildDelete=0x3708
|
OP_GuildDelete=0x3708
|
||||||
@ -212,7 +211,7 @@ OP_ChannelMessage=0x2b2d
|
|||||||
OP_Assist=0x4478
|
OP_Assist=0x4478
|
||||||
OP_AssistGroup=0x27f8
|
OP_AssistGroup=0x27f8
|
||||||
OP_MoveCoin=0x0bcf
|
OP_MoveCoin=0x0bcf
|
||||||
OP_ZonePlayerToBind=0x0ecb
|
OP_ZonePlayerToBind=0x08d8
|
||||||
OP_KeyRing=0x6857
|
OP_KeyRing=0x6857
|
||||||
OP_WhoAllRequest=0x674b
|
OP_WhoAllRequest=0x674b
|
||||||
OP_WhoAllResponse=0x578c
|
OP_WhoAllResponse=0x578c
|
||||||
@ -257,9 +256,9 @@ OP_MoveDoor=0x08e8
|
|||||||
OP_RemoveAllDoors=0x700c
|
OP_RemoveAllDoors=0x700c
|
||||||
OP_EnvDamage=0x51fd
|
OP_EnvDamage=0x51fd
|
||||||
OP_BoardBoat=0x4211
|
OP_BoardBoat=0x4211
|
||||||
OP_Forage=0x5306
|
|
||||||
OP_LeaveBoat=0x7617
|
OP_LeaveBoat=0x7617
|
||||||
OP_ControlBoat=0x0ae7
|
OP_ControlBoat=0x0ae7
|
||||||
|
OP_Forage=0x5306
|
||||||
OP_SafeFallSuccess=0x2219
|
OP_SafeFallSuccess=0x2219
|
||||||
OP_RezzComplete=0x760d
|
OP_RezzComplete=0x760d
|
||||||
OP_RezzRequest=0x3c21
|
OP_RezzRequest=0x3c21
|
||||||
@ -287,16 +286,16 @@ OP_ReadBook=0x72df
|
|||||||
OP_Dye=0x23b9
|
OP_Dye=0x23b9
|
||||||
OP_InterruptCast=0x048c
|
OP_InterruptCast=0x048c
|
||||||
OP_AAAction=0x424e
|
OP_AAAction=0x424e
|
||||||
OP_LeadershipExpToggle=0x6c55
|
OP_LeadershipExpToggle=0x74bd
|
||||||
OP_LeadershipExpUpdate=0x2797
|
OP_LeadershipExpUpdate=0x2797
|
||||||
OP_PurchaseLeadershipAA=0x0026
|
OP_PurchaseLeadershipAA=0x6c55
|
||||||
OP_UpdateLeadershipAA=0x026
|
OP_UpdateLeadershipAA=0x0026
|
||||||
OP_MarkNPC=0x5a58
|
OP_MarkNPC=0x1fb5
|
||||||
OP_MarkRaidNPC=0x74bd #unimplemented
|
OP_MarkRaidNPC=0x5a58 #unimplemented
|
||||||
OP_ClearNPCMarks=0x2003
|
OP_ClearNPCMarks=0x2003
|
||||||
OP_ClearRaidNPCMarks=0x20d3 #unimplemented
|
OP_ClearRaidNPCMarks=0x20d3 #unimplemented
|
||||||
OP_DelegateAbility=0x76b8
|
OP_DelegateAbility=0x4c9d
|
||||||
OP_SetGroupTarget=0x2814
|
OP_SetGroupTarget=0x026
|
||||||
OP_Charm=0x5d92
|
OP_Charm=0x5d92
|
||||||
OP_Stun=0x36a4
|
OP_Stun=0x36a4
|
||||||
OP_SendFindableNPCs=0x4613
|
OP_SendFindableNPCs=0x4613
|
||||||
@ -318,7 +317,7 @@ OP_PVPLeaderBoardReply=0x071f
|
|||||||
OP_PVPLeaderBoardDetailsRequest=0x3707
|
OP_PVPLeaderBoardDetailsRequest=0x3707
|
||||||
OP_PVPLeaderBoardDetailsReply=0x25b7
|
OP_PVPLeaderBoardDetailsReply=0x25b7
|
||||||
OP_RestState=0x000f
|
OP_RestState=0x000f
|
||||||
OP_RespawnWindow=0x28bc
|
OP_RespawnWindow=0x0ecb
|
||||||
OP_LDoNButton=0x5327
|
OP_LDoNButton=0x5327
|
||||||
OP_SetStartCity=0x6326
|
OP_SetStartCity=0x6326
|
||||||
OP_VoiceMacroIn=0x17fd
|
OP_VoiceMacroIn=0x17fd
|
||||||
@ -367,7 +366,7 @@ OP_DzExpeditionInfo=0x4f7e
|
|||||||
OP_DzExpeditionList=0x9119
|
OP_DzExpeditionList=0x9119
|
||||||
OP_DzMemberStatus=0xb2e3
|
OP_DzMemberStatus=0xb2e3
|
||||||
OP_DzLeaderStatus=0x32f0
|
OP_DzLeaderStatus=0x32f0
|
||||||
OP_DzExpeditionEndsWarning=0x7e94
|
OP_DzExpeditionEndsWarning=0x383c
|
||||||
OP_DzMemberList=0x3de9
|
OP_DzMemberList=0x3de9
|
||||||
OP_DzCompass=0x3e0e
|
OP_DzCompass=0x3e0e
|
||||||
OP_DzChooseZone=0x0b7d
|
OP_DzChooseZone=0x0b7d
|
||||||
@ -445,11 +444,11 @@ OP_ShopDelItem=0x724f
|
|||||||
OP_ClickObject=0x4aa1
|
OP_ClickObject=0x4aa1
|
||||||
OP_ClickObjectAction=0x0c1e
|
OP_ClickObjectAction=0x0c1e
|
||||||
OP_ClearObject=0x7a11
|
OP_ClearObject=0x7a11
|
||||||
OP_RecipeDetails=0x40d7
|
OP_RecipeDetails=0x6e02
|
||||||
OP_RecipesFavorite=0x71b1
|
OP_RecipesFavorite=0x71b1
|
||||||
OP_RecipesSearch=0x1db6
|
OP_RecipesSearch=0x6290
|
||||||
OP_RecipeReply=0x6e02
|
OP_RecipeReply=0x1db6
|
||||||
OP_RecipeAutoCombine=0x6261
|
OP_RecipeAutoCombine=0x40d7
|
||||||
OP_TradeSkillCombine=0x579a
|
OP_TradeSkillCombine=0x579a
|
||||||
|
|
||||||
# Tribute Packets:
|
# Tribute Packets:
|
||||||
@ -501,7 +500,7 @@ OP_GroupDisbandOther=0x74da
|
|||||||
OP_GroupLeaderChange=0x21b4
|
OP_GroupLeaderChange=0x21b4
|
||||||
OP_GroupRoles=0x70e2
|
OP_GroupRoles=0x70e2
|
||||||
OP_GroupMakeLeader=0x4229
|
OP_GroupMakeLeader=0x4229
|
||||||
OP_DoGroupLeadershipAbility=0x1fb5
|
OP_DoGroupLeadershipAbility=0x6eae
|
||||||
OP_GroupLeadershipAAUpdate=0x02cf
|
OP_GroupLeadershipAAUpdate=0x02cf
|
||||||
OP_GroupMentor=0x3342
|
OP_GroupMentor=0x3342
|
||||||
OP_InspectBuffs=0x486c
|
OP_InspectBuffs=0x486c
|
||||||
|
|||||||
@ -1301,6 +1301,8 @@ void ClientList::SendClientVersionSummary(const char *Name)
|
|||||||
uint32 ClientSoDCount = 0;
|
uint32 ClientSoDCount = 0;
|
||||||
uint32 ClientUnderfootCount = 0;
|
uint32 ClientUnderfootCount = 0;
|
||||||
uint32 ClientRoFCount = 0;
|
uint32 ClientRoFCount = 0;
|
||||||
|
uint32 ClientRoF2Count = 0;
|
||||||
|
|
||||||
|
|
||||||
LinkedListIterator<ClientListEntry*> Iterator(clientlist);
|
LinkedListIterator<ClientListEntry*> Iterator(clientlist);
|
||||||
|
|
||||||
@ -1343,6 +1345,11 @@ void ClientList::SendClientVersionSummary(const char *Name)
|
|||||||
++ClientRoFCount;
|
++ClientRoFCount;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 7:
|
||||||
|
{
|
||||||
|
++ClientRoF2Count;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1352,7 +1359,7 @@ void ClientList::SendClientVersionSummary(const char *Name)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zoneserver_list.SendEmoteMessage(Name, 0, 0, 13, "There are %i Titanium, %i SoF, %i SoD, %i UF, %i RoF clients currently connected.",
|
zoneserver_list.SendEmoteMessage(Name, 0, 0, 13, "There are %i Titanium, %i SoF, %i SoD, %i UF, %i RoF, %i RoF2 clients currently connected.",
|
||||||
ClientTitaniumCount, ClientSoFCount, ClientSoDCount, ClientUnderfootCount, ClientRoFCount);
|
ClientTitaniumCount, ClientSoFCount, ClientSoDCount, ClientUnderfootCount, ClientRoFCount, ClientRoF2Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -213,11 +213,21 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
uint32 color = 0;
|
||||||
|
if (pp.item_tint[matslot].rgb.use_tint)
|
||||||
|
{
|
||||||
|
color = pp.item_tint[matslot].color;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color = inst->GetColor();
|
||||||
|
}
|
||||||
|
|
||||||
// Armor Materials/Models
|
// Armor Materials/Models
|
||||||
cs->equip[char_num][matslot].material = item->Material;
|
cs->equip[char_num][matslot].material = item->Material;
|
||||||
cs->equip[char_num][matslot].elitematerial = item->EliteMaterial;
|
cs->equip[char_num][matslot].elitematerial = item->EliteMaterial;
|
||||||
cs->equip[char_num][matslot].heroforgemodel = inst->GetOrnamentHeroModel(matslot);
|
cs->equip[char_num][matslot].heroforgemodel = inst->GetOrnamentHeroModel(matslot);
|
||||||
cs->equip[char_num][matslot].color.color = inst->GetColor();
|
cs->equip[char_num][matslot].color.color = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2107,6 +2107,18 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
#endif //BOTS
|
#endif //BOTS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(give_exp && give_exp->IsTempPet() && give_exp->IsPetOwnerClient()) {
|
||||||
|
|
||||||
|
if (give_exp->IsNPC() && give_exp->CastToNPC()->GetSwarmOwner()){
|
||||||
|
Mob* temp_owner = nullptr;
|
||||||
|
temp_owner = entity_list.GetMobID(give_exp->CastToNPC()->GetSwarmOwner());
|
||||||
|
|
||||||
|
if (temp_owner)
|
||||||
|
give_exp = temp_owner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int PlayerCount = 0; // QueryServ Player Counting
|
int PlayerCount = 0; // QueryServ Player Counting
|
||||||
|
|
||||||
Client *give_exp_client = nullptr;
|
Client *give_exp_client = nullptr;
|
||||||
@ -3937,6 +3949,11 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DivineAura()) {
|
||||||
|
mlog(COMBAT__PROCS, "Procs canceled, Divine Aura is in effect.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(!weapon_g) {
|
if(!weapon_g) {
|
||||||
TrySpellProc(nullptr, (const Item_Struct*)nullptr, on);
|
TrySpellProc(nullptr, (const Item_Struct*)nullptr, on);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -538,9 +538,9 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAu
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Client::CalcEdibleBonuses(StatBonuses* newbon) {
|
void Client::CalcEdibleBonuses(StatBonuses* newbon) {
|
||||||
#if EQDEBUG >= 11
|
//#if EQDEBUG >= 11
|
||||||
std::cout<<"Client::CalcEdibleBonuses(StatBonuses* newbon)"<<std::endl;
|
// std::cout<<"Client::CalcEdibleBonuses(StatBonuses* newbon)"<<std::endl;
|
||||||
#endif
|
//#endif
|
||||||
// Search player slots for skill=14(food) and skill=15(drink)
|
// Search player slots for skill=14(food) and skill=15(drink)
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
|
||||||
|
|||||||
@ -11276,7 +11276,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
|||||||
if(!results.Success())
|
if(!results.Success())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int slotmaterial = Inventory::CalcMaterialFromSlot(setslot);
|
uint8 slotmaterial = Inventory::CalcMaterialFromSlot(setslot);
|
||||||
c->GetTarget()->CastToBot()->SendWearChange(slotmaterial);
|
c->GetTarget()->CastToBot()->SendWearChange(slotmaterial);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@ -2685,8 +2685,11 @@ void Client::SetMaterial(int16 in_slot, uint32 item_id) {
|
|||||||
const Item_Struct* item = database.GetItem(item_id);
|
const Item_Struct* item = database.GetItem(item_id);
|
||||||
if (item && (item->ItemClass==ItemClassCommon))
|
if (item && (item->ItemClass==ItemClassCommon))
|
||||||
{
|
{
|
||||||
uint32 matslot = Inventory::CalcMaterialFromSlot(in_slot);
|
uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot);
|
||||||
m_pp.item_material[matslot] = GetEquipmentMaterial(matslot);
|
if (matslot != _MaterialInvalid)
|
||||||
|
{
|
||||||
|
m_pp.item_material[matslot] = GetEquipmentMaterial(matslot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3016,31 +3019,14 @@ void Client::SetTint(int16 in_slot, uint32 color) {
|
|||||||
|
|
||||||
// Still need to reconcile bracer01 versus bracer02
|
// Still need to reconcile bracer01 versus bracer02
|
||||||
void Client::SetTint(int16 in_slot, Color_Struct& color) {
|
void Client::SetTint(int16 in_slot, Color_Struct& color) {
|
||||||
if (in_slot==MainHead)
|
|
||||||
m_pp.item_tint[MaterialHead].color=color.color;
|
|
||||||
else if (in_slot==MainArms)
|
|
||||||
m_pp.item_tint[MaterialArms].color=color.color;
|
|
||||||
else if (in_slot==MainWrist1)
|
|
||||||
m_pp.item_tint[MaterialWrist].color=color.color;
|
|
||||||
/*
|
|
||||||
// non-live behavior
|
|
||||||
else if (in_slot==SLOT_BRACER02)
|
|
||||||
m_pp.item_tint[MaterialWrist].color=color.color;
|
|
||||||
*/
|
|
||||||
else if (in_slot==MainHands)
|
|
||||||
m_pp.item_tint[MaterialHands].color=color.color;
|
|
||||||
else if (in_slot==MainPrimary)
|
|
||||||
m_pp.item_tint[MaterialPrimary].color=color.color;
|
|
||||||
else if (in_slot==MainSecondary)
|
|
||||||
m_pp.item_tint[MaterialSecondary].color=color.color;
|
|
||||||
else if (in_slot==MainChest)
|
|
||||||
m_pp.item_tint[MaterialChest].color=color.color;
|
|
||||||
else if (in_slot==MainLegs)
|
|
||||||
m_pp.item_tint[MaterialLegs].color=color.color;
|
|
||||||
else if (in_slot==MainFeet)
|
|
||||||
m_pp.item_tint[MaterialFeet].color=color.color;
|
|
||||||
|
|
||||||
database.SaveCharacterMaterialColor(this->CharacterID(), in_slot, color.color);
|
uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot);
|
||||||
|
if (matslot != _MaterialInvalid)
|
||||||
|
{
|
||||||
|
m_pp.item_tint[matslot].color = color.color;
|
||||||
|
database.SaveCharacterMaterialColor(this->CharacterID(), in_slot, color.color);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SetHideMe(bool flag)
|
void Client::SetHideMe(bool flag)
|
||||||
|
|||||||
@ -1428,8 +1428,12 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
/* Set item material tint */
|
/* Set item material tint */
|
||||||
for (int i = EmuConstants::MATERIAL_BEGIN; i <= EmuConstants::MATERIAL_END; i++)
|
for (int i = EmuConstants::MATERIAL_BEGIN; i <= EmuConstants::MATERIAL_END; i++)
|
||||||
if (m_pp.item_tint[i].rgb.use_tint == 1 || m_pp.item_tint[i].rgb.use_tint == 255)
|
{
|
||||||
m_pp.item_tint[i].rgb.use_tint = 0xFF;
|
if (m_pp.item_tint[i].rgb.use_tint == 1 || m_pp.item_tint[i].rgb.use_tint == 255)
|
||||||
|
{
|
||||||
|
m_pp.item_tint[i].rgb.use_tint = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (level){ level = m_pp.level; }
|
if (level){ level = m_pp.level; }
|
||||||
|
|
||||||
@ -5745,7 +5749,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::list<int> pathlist = zone->pathing->FindRoute(Start, End);
|
std::deque<int> pathlist = zone->pathing->FindRoute(Start, End);
|
||||||
|
|
||||||
if (pathlist.size() == 0)
|
if (pathlist.size() == 0)
|
||||||
{
|
{
|
||||||
@ -5784,7 +5788,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
|
|||||||
p.z = GetZ();
|
p.z = GetZ();
|
||||||
points.push_back(p);
|
points.push_back(p);
|
||||||
|
|
||||||
for (std::list<int>::iterator Iterator = pathlist.begin(); Iterator != pathlist.end(); ++Iterator)
|
for (auto Iterator = pathlist.begin(); Iterator != pathlist.end(); ++Iterator)
|
||||||
{
|
{
|
||||||
if ((*Iterator) == -1) // Teleporter
|
if ((*Iterator) == -1) // Teleporter
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2664,7 +2664,7 @@ void EntityList::FindPathsToAllNPCs()
|
|||||||
while (it != npc_list.end()) {
|
while (it != npc_list.end()) {
|
||||||
Map::Vertex Node0 = zone->pathing->GetPathNodeCoordinates(0, false);
|
Map::Vertex Node0 = zone->pathing->GetPathNodeCoordinates(0, false);
|
||||||
Map::Vertex Dest(it->second->GetX(), it->second->GetY(), it->second->GetZ());
|
Map::Vertex Dest(it->second->GetX(), it->second->GetY(), it->second->GetZ());
|
||||||
std::list<int> Route = zone->pathing->FindRoute(Node0, Dest);
|
std::deque<int> Route = zone->pathing->FindRoute(Node0, Dest);
|
||||||
if (Route.size() == 0)
|
if (Route.size() == 0)
|
||||||
printf("Unable to find a route to %s\n", it->second->GetName());
|
printf("Unable to find a route to %s\n", it->second->GetName());
|
||||||
else
|
else
|
||||||
|
|||||||
@ -158,7 +158,7 @@ void Mob::CalculateNewFearpoint()
|
|||||||
|
|
||||||
Map::Vertex CurrentPosition(GetX(), GetY(), GetZ());
|
Map::Vertex CurrentPosition(GetX(), GetY(), GetZ());
|
||||||
|
|
||||||
std::list<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc);
|
std::deque<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc);
|
||||||
|
|
||||||
if(Route.size() > 0)
|
if(Route.size() > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
179
zone/mob.cpp
179
zone/mob.cpp
@ -542,6 +542,8 @@ float Mob::_GetMovementSpeed(int mod) const
|
|||||||
// http://everquest.allakhazam.com/db/item.html?item=1721;page=1;howmany=50#m10822246245352
|
// http://everquest.allakhazam.com/db/item.html?item=1721;page=1;howmany=50#m10822246245352
|
||||||
if (IsRooted())
|
if (IsRooted())
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
else if (IsPseudoRooted())
|
||||||
|
return 0.00001f;
|
||||||
|
|
||||||
float speed_mod = runspeed;
|
float speed_mod = runspeed;
|
||||||
|
|
||||||
@ -2795,10 +2797,17 @@ uint32 Mob::GetEquipmentColor(uint8 material_slot) const
|
|||||||
{
|
{
|
||||||
const Item_Struct *item;
|
const Item_Struct *item;
|
||||||
|
|
||||||
item = database.GetItem(GetEquipment(material_slot));
|
if (armor_tint[material_slot])
|
||||||
if(item != 0)
|
|
||||||
{
|
{
|
||||||
return item->Color;
|
return armor_tint[material_slot];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item = database.GetItem(GetEquipment(material_slot));
|
||||||
|
if (item != 0)
|
||||||
|
{
|
||||||
|
return item->Color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -5323,98 +5332,98 @@ int32 Mob::GetSpellStat(uint32 spell_id, const char *identifier, uint8 slot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (slot < 16){
|
if (slot < 16){
|
||||||
if (id == "classes") {stat = spells[spell_id].classes[slot]; }
|
if (id == "classes") {return spells[spell_id].classes[slot]; }
|
||||||
else if (id == "dieties") {stat = spells[spell_id].deities[slot];}
|
else if (id == "dieties") {return spells[spell_id].deities[slot];}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slot < 12){
|
if (slot < 12){
|
||||||
if (id == "base") {stat = spells[spell_id].base[slot];}
|
if (id == "base") {return spells[spell_id].base[slot];}
|
||||||
else if (id == "base2") {stat = spells[spell_id].base2[slot];}
|
else if (id == "base2") {return spells[spell_id].base2[slot];}
|
||||||
else if (id == "max") {stat = spells[spell_id].max[slot];}
|
else if (id == "max") {return spells[spell_id].max[slot];}
|
||||||
else if (id == "formula") {spells[spell_id].formula[slot];}
|
else if (id == "formula") {return spells[spell_id].formula[slot];}
|
||||||
else if (id == "effectid") {spells[spell_id].effectid[slot];}
|
else if (id == "effectid") {return spells[spell_id].effectid[slot];}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slot < 4){
|
if (slot < 4){
|
||||||
if (id == "components") { spells[spell_id].components[slot];}
|
if (id == "components") { return spells[spell_id].components[slot];}
|
||||||
else if (id == "component_counts") {spells[spell_id].component_counts[slot];}
|
else if (id == "component_counts") { return spells[spell_id].component_counts[slot];}
|
||||||
else if (id == "NoexpendReagent") {spells[spell_id].NoexpendReagent[slot];}
|
else if (id == "NoexpendReagent") {return spells[spell_id].NoexpendReagent[slot];}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == "range") {stat = static_cast<int32>(spells[spell_id].range); }
|
if (id == "range") {return static_cast<int32>(spells[spell_id].range); }
|
||||||
else if (id == "aoerange") {stat = static_cast<int32>(spells[spell_id].aoerange);}
|
else if (id == "aoerange") {return static_cast<int32>(spells[spell_id].aoerange);}
|
||||||
else if (id == "pushback") {stat = static_cast<int32>(spells[spell_id].pushback);}
|
else if (id == "pushback") {return static_cast<int32>(spells[spell_id].pushback);}
|
||||||
else if (id == "pushup") {stat = static_cast<int32>(spells[spell_id].pushup);}
|
else if (id == "pushup") {return static_cast<int32>(spells[spell_id].pushup);}
|
||||||
else if (id == "cast_time") {stat = spells[spell_id].cast_time;}
|
else if (id == "cast_time") {return spells[spell_id].cast_time;}
|
||||||
else if (id == "recovery_time") {stat = spells[spell_id].recovery_time;}
|
else if (id == "recovery_time") {return spells[spell_id].recovery_time;}
|
||||||
else if (id == "recast_time") {stat = spells[spell_id].recast_time;}
|
else if (id == "recast_time") {return spells[spell_id].recast_time;}
|
||||||
else if (id == "buffdurationformula") {stat = spells[spell_id].buffdurationformula;}
|
else if (id == "buffdurationformula") {return spells[spell_id].buffdurationformula;}
|
||||||
else if (id == "buffduration") {stat = spells[spell_id].buffduration;}
|
else if (id == "buffduration") {return spells[spell_id].buffduration;}
|
||||||
else if (id == "AEDuration") {stat = spells[spell_id].AEDuration;}
|
else if (id == "AEDuration") {return spells[spell_id].AEDuration;}
|
||||||
else if (id == "mana") {stat = spells[spell_id].mana;}
|
else if (id == "mana") {return spells[spell_id].mana;}
|
||||||
//else if (id == "LightType") {stat = spells[spell_id].LightType;} - Not implemented
|
//else if (id == "LightType") {stat = spells[spell_id].LightType;} - Not implemented
|
||||||
else if (id == "goodEffect") {stat = spells[spell_id].goodEffect;}
|
else if (id == "goodEffect") {return spells[spell_id].goodEffect;}
|
||||||
else if (id == "Activated") {stat = spells[spell_id].Activated;}
|
else if (id == "Activated") {return spells[spell_id].Activated;}
|
||||||
else if (id == "resisttype") {stat = spells[spell_id].resisttype;}
|
else if (id == "resisttype") {return spells[spell_id].resisttype;}
|
||||||
else if (id == "targettype") {stat = spells[spell_id].targettype;}
|
else if (id == "targettype") {return spells[spell_id].targettype;}
|
||||||
else if (id == "basedeiff") {stat = spells[spell_id].basediff;}
|
else if (id == "basedeiff") {return spells[spell_id].basediff;}
|
||||||
else if (id == "skill") {stat = spells[spell_id].skill;}
|
else if (id == "skill") {return spells[spell_id].skill;}
|
||||||
else if (id == "zonetype") {stat = spells[spell_id].zonetype;}
|
else if (id == "zonetype") {return spells[spell_id].zonetype;}
|
||||||
else if (id == "EnvironmentType") {stat = spells[spell_id].EnvironmentType;}
|
else if (id == "EnvironmentType") {return spells[spell_id].EnvironmentType;}
|
||||||
else if (id == "TimeOfDay") {stat = spells[spell_id].TimeOfDay;}
|
else if (id == "TimeOfDay") {return spells[spell_id].TimeOfDay;}
|
||||||
else if (id == "CastingAnim") {stat = spells[spell_id].CastingAnim;}
|
else if (id == "CastingAnim") {return spells[spell_id].CastingAnim;}
|
||||||
else if (id == "SpellAffectIndex") {stat = spells[spell_id].SpellAffectIndex; }
|
else if (id == "SpellAffectIndex") {return spells[spell_id].SpellAffectIndex; }
|
||||||
else if (id == "disallow_sit") {stat = spells[spell_id].disallow_sit; }
|
else if (id == "disallow_sit") {return spells[spell_id].disallow_sit; }
|
||||||
//else if (id == "spellanim") {stat = spells[spell_id].spellanim; } - Not implemented
|
//else if (id == "spellanim") {stat = spells[spell_id].spellanim; } - Not implemented
|
||||||
else if (id == "uninterruptable") {stat = spells[spell_id].uninterruptable; }
|
else if (id == "uninterruptable") {return spells[spell_id].uninterruptable; }
|
||||||
else if (id == "ResistDiff") {stat = spells[spell_id].ResistDiff; }
|
else if (id == "ResistDiff") {return spells[spell_id].ResistDiff; }
|
||||||
else if (id == "dot_stacking_exemp") {stat = spells[spell_id].dot_stacking_exempt; }
|
else if (id == "dot_stacking_exemp") {return spells[spell_id].dot_stacking_exempt; }
|
||||||
else if (id == "RecourseLink") {stat = spells[spell_id].RecourseLink; }
|
else if (id == "RecourseLink") {return spells[spell_id].RecourseLink; }
|
||||||
else if (id == "no_partial_resist") {stat = spells[spell_id].no_partial_resist; }
|
else if (id == "no_partial_resist") {return spells[spell_id].no_partial_resist; }
|
||||||
else if (id == "short_buff_box") {stat = spells[spell_id].short_buff_box; }
|
else if (id == "short_buff_box") {return spells[spell_id].short_buff_box; }
|
||||||
else if (id == "descnum") {stat = spells[spell_id].descnum; }
|
else if (id == "descnum") {return spells[spell_id].descnum; }
|
||||||
else if (id == "effectdescnum") {stat = spells[spell_id].effectdescnum; }
|
else if (id == "effectdescnum") {return spells[spell_id].effectdescnum; }
|
||||||
else if (id == "npc_no_los") {stat = spells[spell_id].npc_no_los; }
|
else if (id == "npc_no_los") {return spells[spell_id].npc_no_los; }
|
||||||
else if (id == "reflectable") {stat = spells[spell_id].reflectable; }
|
else if (id == "reflectable") {return spells[spell_id].reflectable; }
|
||||||
else if (id == "bonushate") {stat = spells[spell_id].bonushate; }
|
else if (id == "bonushate") {return spells[spell_id].bonushate; }
|
||||||
else if (id == "EndurCost") {stat = spells[spell_id].EndurCost; }
|
else if (id == "EndurCost") {return spells[spell_id].EndurCost; }
|
||||||
else if (id == "EndurTimerIndex") {stat = spells[spell_id].EndurTimerIndex; }
|
else if (id == "EndurTimerIndex") {return spells[spell_id].EndurTimerIndex; }
|
||||||
else if (id == "IsDisciplineBuf") {stat = spells[spell_id].IsDisciplineBuff; }
|
else if (id == "IsDisciplineBuf") {return spells[spell_id].IsDisciplineBuff; }
|
||||||
else if (id == "HateAdded") {stat = spells[spell_id].HateAdded; }
|
else if (id == "HateAdded") {return spells[spell_id].HateAdded; }
|
||||||
else if (id == "EndurUpkeep") {stat = spells[spell_id].EndurUpkeep; }
|
else if (id == "EndurUpkeep") {return spells[spell_id].EndurUpkeep; }
|
||||||
else if (id == "numhitstype") {stat = spells[spell_id].numhitstype; }
|
else if (id == "numhitstype") {return spells[spell_id].numhitstype; }
|
||||||
else if (id == "numhits") {stat = spells[spell_id].numhits; }
|
else if (id == "numhits") {return spells[spell_id].numhits; }
|
||||||
else if (id == "pvpresistbase") {stat = spells[spell_id].pvpresistbase; }
|
else if (id == "pvpresistbase") {return spells[spell_id].pvpresistbase; }
|
||||||
else if (id == "pvpresistcalc") {stat = spells[spell_id].pvpresistcalc; }
|
else if (id == "pvpresistcalc") {return spells[spell_id].pvpresistcalc; }
|
||||||
else if (id == "pvpresistcap") {stat = spells[spell_id].pvpresistcap; }
|
else if (id == "pvpresistcap") {return spells[spell_id].pvpresistcap; }
|
||||||
else if (id == "spell_category") {stat = spells[spell_id].spell_category; }
|
else if (id == "spell_category") {return spells[spell_id].spell_category; }
|
||||||
else if (id == "can_mgb") {stat = spells[spell_id].can_mgb; }
|
else if (id == "can_mgb") {return spells[spell_id].can_mgb; }
|
||||||
else if (id == "dispel_flag") {stat = spells[spell_id].dispel_flag; }
|
else if (id == "dispel_flag") {return spells[spell_id].dispel_flag; }
|
||||||
else if (id == "MinResist") {stat = spells[spell_id].MinResist; }
|
else if (id == "MinResist") {return spells[spell_id].MinResist; }
|
||||||
else if (id == "MaxResist") {stat = spells[spell_id].MaxResist; }
|
else if (id == "MaxResist") {return spells[spell_id].MaxResist; }
|
||||||
else if (id == "viral_targets") {stat = spells[spell_id].viral_targets; }
|
else if (id == "viral_targets") {return spells[spell_id].viral_targets; }
|
||||||
else if (id == "viral_timer") {stat = spells[spell_id].viral_timer; }
|
else if (id == "viral_timer") {return spells[spell_id].viral_timer; }
|
||||||
else if (id == "NimbusEffect") {stat = spells[spell_id].NimbusEffect; }
|
else if (id == "NimbusEffect") {return spells[spell_id].NimbusEffect; }
|
||||||
else if (id == "directional_start") {stat = static_cast<int32>(spells[spell_id].directional_start); }
|
else if (id == "directional_start") {return static_cast<int32>(spells[spell_id].directional_start); }
|
||||||
else if (id == "directional_end") {stat = static_cast<int32>(spells[spell_id].directional_end); }
|
else if (id == "directional_end") {return static_cast<int32>(spells[spell_id].directional_end); }
|
||||||
else if (id == "not_extendable") {stat = spells[spell_id].not_extendable; }
|
else if (id == "not_extendable") {return spells[spell_id].not_extendable; }
|
||||||
else if (id == "suspendable") {stat = spells[spell_id].suspendable; }
|
else if (id == "suspendable") {return spells[spell_id].suspendable; }
|
||||||
else if (id == "viral_range") {stat = spells[spell_id].viral_range; }
|
else if (id == "viral_range") {return spells[spell_id].viral_range; }
|
||||||
else if (id == "spellgroup") {stat = spells[spell_id].spellgroup; }
|
else if (id == "spellgroup") {return spells[spell_id].spellgroup; }
|
||||||
else if (id == "rank") {stat = spells[spell_id].rank; }
|
else if (id == "rank") {return spells[spell_id].rank; }
|
||||||
else if (id == "powerful_flag") {stat = spells[spell_id].powerful_flag; }
|
else if (id == "powerful_flag") {return spells[spell_id].powerful_flag; }
|
||||||
else if (id == "CastRestriction") {stat = spells[spell_id].CastRestriction; }
|
else if (id == "CastRestriction") {return spells[spell_id].CastRestriction; }
|
||||||
else if (id == "AllowRest") {stat = spells[spell_id].AllowRest; }
|
else if (id == "AllowRest") {return spells[spell_id].AllowRest; }
|
||||||
else if (id == "InCombat") {stat = spells[spell_id].InCombat; }
|
else if (id == "InCombat") {return spells[spell_id].InCombat; }
|
||||||
else if (id == "OutofCombat") {stat = spells[spell_id].OutofCombat; }
|
else if (id == "OutofCombat") {return spells[spell_id].OutofCombat; }
|
||||||
else if (id == "aemaxtargets") {stat = spells[spell_id].aemaxtargets; }
|
else if (id == "aemaxtargets") {return spells[spell_id].aemaxtargets; }
|
||||||
else if (id == "maxtargets") {stat = spells[spell_id].maxtargets; }
|
else if (id == "maxtargets") {return spells[spell_id].maxtargets; }
|
||||||
else if (id == "persistdeath") {stat = spells[spell_id].persistdeath; }
|
else if (id == "persistdeath") {return spells[spell_id].persistdeath; }
|
||||||
else if (id == "min_dist") {stat = static_cast<int32>(spells[spell_id].min_dist); }
|
else if (id == "min_dist") {return static_cast<int32>(spells[spell_id].min_dist); }
|
||||||
else if (id == "min_dist_mod") {stat = static_cast<int32>(spells[spell_id].min_dist_mod); }
|
else if (id == "min_dist_mod") {return static_cast<int32>(spells[spell_id].min_dist_mod); }
|
||||||
else if (id == "max_dist") {stat = static_cast<int32>(spells[spell_id].max_dist); }
|
else if (id == "max_dist") {return static_cast<int32>(spells[spell_id].max_dist); }
|
||||||
else if (id == "min_range") {stat = static_cast<int32>(spells[spell_id].min_range); }
|
else if (id == "min_range") {return static_cast<int32>(spells[spell_id].min_range); }
|
||||||
else if (id == "DamageShieldType") {stat = spells[spell_id].DamageShieldType; }
|
else if (id == "DamageShieldType") {return spells[spell_id].DamageShieldType; }
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1225,7 +1225,7 @@ protected:
|
|||||||
Map::Vertex PathingLastPosition;
|
Map::Vertex PathingLastPosition;
|
||||||
int PathingLoopCount;
|
int PathingLoopCount;
|
||||||
int PathingLastNodeVisited;
|
int PathingLastNodeVisited;
|
||||||
std::list<int> Route;
|
std::deque<int> Route;
|
||||||
LOSType PathingLOSState;
|
LOSType PathingLOSState;
|
||||||
Timer *PathingLOSCheckTimer;
|
Timer *PathingLOSCheckTimer;
|
||||||
Timer *PathingRouteUpdateTimerShort;
|
Timer *PathingRouteUpdateTimerShort;
|
||||||
|
|||||||
@ -2751,7 +2751,7 @@ DBnpcspells_Struct* ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID) {
|
|||||||
npc_spells_cache[iDBSpellsID]->attack_proc = tmpattack_proc;
|
npc_spells_cache[iDBSpellsID]->attack_proc = tmpattack_proc;
|
||||||
npc_spells_cache[iDBSpellsID]->proc_chance = tmpproc_chance;
|
npc_spells_cache[iDBSpellsID]->proc_chance = tmpproc_chance;
|
||||||
npc_spells_cache[iDBSpellsID]->range_proc = tmprange_proc;
|
npc_spells_cache[iDBSpellsID]->range_proc = tmprange_proc;
|
||||||
npc_spells_cache[iDBSpellsID]->rproc_chance = tmpdproc_chance;
|
npc_spells_cache[iDBSpellsID]->rproc_chance = tmprproc_chance;
|
||||||
npc_spells_cache[iDBSpellsID]->defensive_proc = tmpdefensive_proc;
|
npc_spells_cache[iDBSpellsID]->defensive_proc = tmpdefensive_proc;
|
||||||
npc_spells_cache[iDBSpellsID]->dproc_chance = tmpdproc_chance;
|
npc_spells_cache[iDBSpellsID]->dproc_chance = tmpdproc_chance;
|
||||||
npc_spells_cache[iDBSpellsID]->fail_recast = tmppfail_recast;
|
npc_spells_cache[iDBSpellsID]->fail_recast = tmppfail_recast;
|
||||||
|
|||||||
@ -476,7 +476,7 @@ void NPC::CheckMinMaxLevel(Mob *them)
|
|||||||
if(themlevel < (*cur)->min_level || themlevel > (*cur)->max_level)
|
if(themlevel < (*cur)->min_level || themlevel > (*cur)->max_level)
|
||||||
{
|
{
|
||||||
material = Inventory::CalcMaterialFromSlot((*cur)->equip_slot);
|
material = Inventory::CalcMaterialFromSlot((*cur)->equip_slot);
|
||||||
if(material != 0xFF)
|
if (material != _MaterialInvalid)
|
||||||
SendWearChange(material);
|
SendWearChange(material);
|
||||||
|
|
||||||
cur = itemlist.erase(cur);
|
cur = itemlist.erase(cur);
|
||||||
@ -1942,6 +1942,7 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue)
|
|||||||
else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; }
|
else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; }
|
||||||
else if(id == "special_abilities") { ProcessSpecialAbilities(val.c_str()); return; }
|
else if(id == "special_abilities") { ProcessSpecialAbilities(val.c_str()); return; }
|
||||||
else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; }
|
else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; }
|
||||||
|
else if(id == "attack_delay") { attack_delay = atoi(val.c_str()); CalcBonuses(); return; }
|
||||||
else if(id == "atk") { ATK = atoi(val.c_str()); return; }
|
else if(id == "atk") { ATK = atoi(val.c_str()); return; }
|
||||||
else if(id == "accuracy") { accuracy_rating = atoi(val.c_str()); return; }
|
else if(id == "accuracy") { accuracy_rating = atoi(val.c_str()); return; }
|
||||||
else if(id == "avoidance") { avoidance_rating = atoi(val.c_str()); return; }
|
else if(id == "avoidance") { avoidance_rating = atoi(val.c_str()); return; }
|
||||||
|
|||||||
@ -155,6 +155,7 @@ public:
|
|||||||
virtual void RangedAttack(Mob* other);
|
virtual void RangedAttack(Mob* other);
|
||||||
virtual void ThrowingAttack(Mob* other) { }
|
virtual void ThrowingAttack(Mob* other) { }
|
||||||
int32 GetNumberOfAttacks() const { return attack_count; }
|
int32 GetNumberOfAttacks() const { return attack_count; }
|
||||||
|
void DoRangedAttackDmg(Mob* other, bool Launch=true, int16 damage_mod=0, int16 chance_mod=0, SkillUseTypes skill=SkillArchery, float speed=4.0f, const char *IDFile = nullptr);
|
||||||
|
|
||||||
bool DatabaseCastAccepted(int spell_id);
|
bool DatabaseCastAccepted(int spell_id);
|
||||||
bool IsFactionListAlly(uint32 other_faction);
|
bool IsFactionListAlly(uint32 other_faction);
|
||||||
@ -259,6 +260,7 @@ public:
|
|||||||
uint32 GetMinDMG() const {return min_dmg;}
|
uint32 GetMinDMG() const {return min_dmg;}
|
||||||
int16 GetSlowMitigation() const {return slow_mitigation;}
|
int16 GetSlowMitigation() const {return slow_mitigation;}
|
||||||
float GetAttackSpeed() const {return attack_speed;}
|
float GetAttackSpeed() const {return attack_speed;}
|
||||||
|
uint8 GetAttackDelay() const {return attack_delay;}
|
||||||
bool IsAnimal() const { return(bodytype == BT_Animal); }
|
bool IsAnimal() const { return(bodytype == BT_Animal); }
|
||||||
uint16 GetPetSpellID() const {return pet_spell_id;}
|
uint16 GetPetSpellID() const {return pet_spell_id;}
|
||||||
void SetPetSpellID(uint16 amt) {pet_spell_id = amt;}
|
void SetPetSpellID(uint16 amt) {pet_spell_id = amt;}
|
||||||
|
|||||||
@ -205,15 +205,15 @@ Map::Vertex PathManager::GetPathNodeCoordinates(int NodeNumber, bool BestZ)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<int> PathManager::FindRoute(int startID, int endID)
|
std::deque<int> PathManager::FindRoute(int startID, int endID)
|
||||||
{
|
{
|
||||||
_log(PATHING__DEBUG, "FindRoute from node %i to %i", startID, endID);
|
_log(PATHING__DEBUG, "FindRoute from node %i to %i", startID, endID);
|
||||||
|
|
||||||
memset(ClosedListFlag, 0, sizeof(int) * Head.PathNodeCount);
|
memset(ClosedListFlag, 0, sizeof(int) * Head.PathNodeCount);
|
||||||
|
|
||||||
std::list<AStarNode> OpenList, ClosedList;
|
std::deque<AStarNode> OpenList, ClosedList;
|
||||||
|
|
||||||
std::list<int>Route;
|
std::deque<int>Route;
|
||||||
|
|
||||||
AStarNode AStarEntry, CurrentNode;
|
AStarNode AStarEntry, CurrentNode;
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ std::list<int> PathManager::FindRoute(int startID, int endID)
|
|||||||
|
|
||||||
Route.push_back(endID);
|
Route.push_back(endID);
|
||||||
|
|
||||||
std::list<AStarNode>::iterator RouteIterator;
|
std::deque<AStarNode>::iterator RouteIterator;
|
||||||
|
|
||||||
while(CurrentNode.PathNodeID != startID)
|
while(CurrentNode.PathNodeID != startID)
|
||||||
{
|
{
|
||||||
@ -300,7 +300,7 @@ std::list<int> PathManager::FindRoute(int startID, int endID)
|
|||||||
|
|
||||||
bool AlreadyInOpenList = false;
|
bool AlreadyInOpenList = false;
|
||||||
|
|
||||||
std::list<AStarNode>::iterator OpenListIterator, InsertionPoint = OpenList.end();
|
std::deque<AStarNode>::iterator OpenListIterator, InsertionPoint = OpenList.end();
|
||||||
|
|
||||||
for(OpenListIterator = OpenList.begin(); OpenListIterator != OpenList.end(); ++OpenListIterator)
|
for(OpenListIterator = OpenList.begin(); OpenListIterator != OpenList.end(); ++OpenListIterator)
|
||||||
{
|
{
|
||||||
@ -350,11 +350,11 @@ bool SortPathNodesByDistance(PathNodeSortStruct n1, PathNodeSortStruct n2)
|
|||||||
return n1.Distance < n2.Distance;
|
return n1.Distance < n2.Distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
||||||
{
|
{
|
||||||
_log(PATHING__DEBUG, "FindRoute(%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f)", Start.x, Start.y, Start.z, End.x, End.y, End.z);
|
_log(PATHING__DEBUG, "FindRoute(%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f)", Start.x, Start.y, Start.z, End.x, End.y, End.z);
|
||||||
|
|
||||||
std::list<int> noderoute;
|
std::deque<int> noderoute;
|
||||||
|
|
||||||
float CandidateNodeRangeXY = RuleR(Pathing, CandidateNodeRangeXY);
|
float CandidateNodeRangeXY = RuleR(Pathing, CandidateNodeRangeXY);
|
||||||
|
|
||||||
@ -365,7 +365,7 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
|||||||
//
|
//
|
||||||
int ClosestPathNodeToStart = -1;
|
int ClosestPathNodeToStart = -1;
|
||||||
|
|
||||||
std::list<PathNodeSortStruct> SortedByDistance;
|
std::deque<PathNodeSortStruct> SortedByDistance;
|
||||||
|
|
||||||
PathNodeSortStruct TempNode;
|
PathNodeSortStruct TempNode;
|
||||||
|
|
||||||
@ -382,9 +382,9 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SortedByDistance.sort(SortPathNodesByDistance);
|
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
|
||||||
|
|
||||||
for(std::list<PathNodeSortStruct>::iterator Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
|
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
|
||||||
{
|
{
|
||||||
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
|
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
|
||||||
|
|
||||||
@ -420,9 +420,9 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SortedByDistance.sort(SortPathNodesByDistance);
|
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
|
||||||
|
|
||||||
for(std::list<PathNodeSortStruct>::iterator Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
|
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
|
||||||
{
|
{
|
||||||
_log(PATHING__DEBUG, "Checking Reachability of Node %i from End Position.", PathNodes[(*Iterator).id].id);
|
_log(PATHING__DEBUG, "Checking Reachability of Node %i from End Position.", PathNodes[(*Iterator).id].id);
|
||||||
_log(PATHING__DEBUG, " (%8.3f, %8.3f, %8.3f) to (%8.3f, %8.3f, %8.3f)",
|
_log(PATHING__DEBUG, " (%8.3f, %8.3f, %8.3f) to (%8.3f, %8.3f, %8.3f)",
|
||||||
@ -456,7 +456,7 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
|||||||
{
|
{
|
||||||
int CulledNodes = 0;
|
int CulledNodes = 0;
|
||||||
|
|
||||||
std::list<int>::iterator First, Second;
|
std::deque<int>::iterator First, Second;
|
||||||
|
|
||||||
while((noderoute.size() >= 2) && (CulledNodes < NodesToAttemptToCull))
|
while((noderoute.size() >= 2) && (CulledNodes < NodesToAttemptToCull))
|
||||||
{
|
{
|
||||||
@ -487,7 +487,7 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
|
|||||||
{
|
{
|
||||||
int CulledNodes = 0;
|
int CulledNodes = 0;
|
||||||
|
|
||||||
std::list<int>::iterator First, Second;
|
std::deque<int>::iterator First, Second;
|
||||||
|
|
||||||
while((noderoute.size() >= 2) && (CulledNodes < NodesToAttemptToCull))
|
while((noderoute.size() >= 2) && (CulledNodes < NodesToAttemptToCull))
|
||||||
{
|
{
|
||||||
@ -611,7 +611,7 @@ void PathManager::MeshTest()
|
|||||||
if(j == i)
|
if(j == i)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::list<int> Route = FindRoute(PathNodes[i].id, PathNodes[j].id);
|
std::deque<int> Route = FindRoute(PathNodes[i].id, PathNodes[j].id);
|
||||||
|
|
||||||
if(Route.size() == 0)
|
if(Route.size() == 0)
|
||||||
{
|
{
|
||||||
@ -638,7 +638,7 @@ void PathManager::SimpleMeshTest()
|
|||||||
|
|
||||||
for(uint32 j = 1; j < Head.PathNodeCount; ++j)
|
for(uint32 j = 1; j < Head.PathNodeCount; ++j)
|
||||||
{
|
{
|
||||||
std::list<int> Route = FindRoute(PathNodes[0].id, PathNodes[j].id);
|
std::deque<int> Route = FindRoute(PathNodes[0].id, PathNodes[j].id);
|
||||||
|
|
||||||
if(Route.size() == 0)
|
if(Route.size() == 0)
|
||||||
{
|
{
|
||||||
@ -1103,7 +1103,7 @@ int PathManager::FindNearestPathNode(Map::Vertex Position)
|
|||||||
|
|
||||||
int ClosestPathNodeToStart = -1;
|
int ClosestPathNodeToStart = -1;
|
||||||
|
|
||||||
std::list<PathNodeSortStruct> SortedByDistance;
|
std::deque<PathNodeSortStruct> SortedByDistance;
|
||||||
|
|
||||||
PathNodeSortStruct TempNode;
|
PathNodeSortStruct TempNode;
|
||||||
|
|
||||||
@ -1120,9 +1120,9 @@ int PathManager::FindNearestPathNode(Map::Vertex Position)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SortedByDistance.sort(SortPathNodesByDistance);
|
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
|
||||||
|
|
||||||
for(std::list<PathNodeSortStruct>::iterator Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
|
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
|
||||||
{
|
{
|
||||||
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
|
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
|
||||||
|
|
||||||
@ -1262,9 +1262,7 @@ void Mob::PrintRoute()
|
|||||||
|
|
||||||
printf("Route is : ");
|
printf("Route is : ");
|
||||||
|
|
||||||
std::list<int>::iterator Iterator;
|
for(auto Iterator = Route.begin(); Iterator !=Route.end(); ++Iterator)
|
||||||
|
|
||||||
for(Iterator = Route.begin(); Iterator !=Route.end(); ++Iterator)
|
|
||||||
{
|
{
|
||||||
printf("%i, ", (*Iterator));
|
printf("%i, ", (*Iterator));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
#include <list>
|
#include <deque>
|
||||||
|
|
||||||
class Client;
|
class Client;
|
||||||
class Mob;
|
class Mob;
|
||||||
@ -60,8 +60,8 @@ public:
|
|||||||
static PathManager *LoadPathFile(const char *ZoneName);
|
static PathManager *LoadPathFile(const char *ZoneName);
|
||||||
bool loadPaths(FILE *fp);
|
bool loadPaths(FILE *fp);
|
||||||
void PrintPathing();
|
void PrintPathing();
|
||||||
std::list<int> FindRoute(Map::Vertex Start, Map::Vertex End);
|
std::deque<int> FindRoute(Map::Vertex Start, Map::Vertex End);
|
||||||
std::list<int> FindRoute(int startID, int endID);
|
std::deque<int> FindRoute(int startID, int endID);
|
||||||
|
|
||||||
Map::Vertex GetPathNodeCoordinates(int NodeNumber, bool BestZ = true);
|
Map::Vertex GetPathNodeCoordinates(int NodeNumber, bool BestZ = true);
|
||||||
bool CheckLosFN(Map::Vertex a, Map::Vertex b);
|
bool CheckLosFN(Map::Vertex a, Map::Vertex b);
|
||||||
|
|||||||
@ -2119,6 +2119,32 @@ XS(XS_NPC_GetAttackSpeed)
|
|||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_NPC_GetAttackDelay); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_NPC_GetAttackDelay)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: NPC::GetAttackDelay(THIS)");
|
||||||
|
{
|
||||||
|
NPC * THIS;
|
||||||
|
float RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "NPC")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(NPC *,tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type NPC");
|
||||||
|
if(THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->GetAttackDelay();
|
||||||
|
XSprePUSH; PUSHn((double)RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS_NPC_GetAccuracyRating); /* prototype to pass -Wmissing-prototypes */
|
XS(XS_NPC_GetAccuracyRating); /* prototype to pass -Wmissing-prototypes */
|
||||||
XS(XS_NPC_GetAccuracyRating)
|
XS(XS_NPC_GetAccuracyRating)
|
||||||
{
|
{
|
||||||
@ -2145,6 +2171,32 @@ XS(XS_NPC_GetAccuracyRating)
|
|||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_NPC_GetAvoidanceRating); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_NPC_GetAvoidanceRating)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: NPC::GetAvoidanceyRating(THIS)");
|
||||||
|
{
|
||||||
|
NPC * THIS;
|
||||||
|
int32 RETVAL;
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "NPC")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(NPC *,tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type NPC");
|
||||||
|
if(THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->GetAvoidanceRating();
|
||||||
|
XSprePUSH; PUSHu((UV)RETVAL);
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS_NPC_GetSpawnKillCount); /* prototype to pass -Wmissing-prototypes */
|
XS(XS_NPC_GetSpawnKillCount); /* prototype to pass -Wmissing-prototypes */
|
||||||
XS(XS_NPC_GetSpawnKillCount)
|
XS(XS_NPC_GetSpawnKillCount)
|
||||||
{
|
{
|
||||||
@ -2245,6 +2297,81 @@ XS(XS_NPC_GetMerchantProbability) {
|
|||||||
XSRETURN(1);
|
XSRETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_NPC_AddMeleeProc);
|
||||||
|
XS(XS_NPC_AddMeleeProc) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 3)
|
||||||
|
Perl_croak(aTHX_ "Usage: NPC::AddMeleeProc(THIS,spellid,chance)");
|
||||||
|
{
|
||||||
|
NPC * THIS;
|
||||||
|
int spell_id = (int)SvIV(ST(1));
|
||||||
|
int chance = (int)SvIV(ST(2));
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "NPC")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(NPC *,tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type NPC");
|
||||||
|
if(THIS == NULL)
|
||||||
|
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||||
|
|
||||||
|
THIS->AddProcToWeapon(spell_id, true, chance);
|
||||||
|
}
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_NPC_AddRangedProc);
|
||||||
|
XS(XS_NPC_AddRangedProc) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 3)
|
||||||
|
Perl_croak(aTHX_ "Usage: NPC::AddRangedProc(THIS,spellid,chance)");
|
||||||
|
{
|
||||||
|
NPC * THIS;
|
||||||
|
int spell_id = (int)SvIV(ST(1));
|
||||||
|
int chance = (int)SvIV(ST(2));
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "NPC")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(NPC *,tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type NPC");
|
||||||
|
if(THIS == NULL)
|
||||||
|
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||||
|
|
||||||
|
THIS->AddDefensiveProc(spell_id,chance);
|
||||||
|
}
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS_NPC_AddDefensiveProc);
|
||||||
|
XS(XS_NPC_AddDefensiveProc) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 3)
|
||||||
|
Perl_croak(aTHX_ "Usage: NPC::AddDefensiveProc(THIS,spellid,chance)");
|
||||||
|
{
|
||||||
|
NPC * THIS;
|
||||||
|
int spell_id = (int)SvIV(ST(1));
|
||||||
|
int chance = (int)SvIV(ST(2));
|
||||||
|
dXSTARG;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "NPC")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(NPC *,tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type NPC");
|
||||||
|
if(THIS == NULL)
|
||||||
|
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||||
|
|
||||||
|
THIS->AddProcToWeapon(spell_id, true, chance);
|
||||||
|
}
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
#endif
|
#endif
|
||||||
@ -2342,11 +2469,16 @@ XS(boot_NPC)
|
|||||||
newXSproto(strcpy(buf, "GetSpellFocusHeal"), XS_NPC_GetSpellFocusHeal, file, "$");
|
newXSproto(strcpy(buf, "GetSpellFocusHeal"), XS_NPC_GetSpellFocusHeal, file, "$");
|
||||||
newXSproto(strcpy(buf, "GetSlowMitigation"), XS_NPC_GetSlowMitigation, file, "$");
|
newXSproto(strcpy(buf, "GetSlowMitigation"), XS_NPC_GetSlowMitigation, file, "$");
|
||||||
newXSproto(strcpy(buf, "GetAttackSpeed"), XS_NPC_GetAttackSpeed, file, "$");
|
newXSproto(strcpy(buf, "GetAttackSpeed"), XS_NPC_GetAttackSpeed, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "GetAttackDelay"), XS_NPC_GetAttackDelay, file, "$");
|
||||||
newXSproto(strcpy(buf, "GetAccuracyRating"), XS_NPC_GetAccuracyRating, file, "$");
|
newXSproto(strcpy(buf, "GetAccuracyRating"), XS_NPC_GetAccuracyRating, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "GetAvoidanceRating"), XS_NPC_GetAvoidanceRating, file, "$");
|
||||||
newXSproto(strcpy(buf, "GetSpawnKillCount"), XS_NPC_GetSpawnKillCount, file, "$");
|
newXSproto(strcpy(buf, "GetSpawnKillCount"), XS_NPC_GetSpawnKillCount, file, "$");
|
||||||
newXSproto(strcpy(buf, "GetScore"), XS_NPC_GetScore, file, "$");
|
newXSproto(strcpy(buf, "GetScore"), XS_NPC_GetScore, file, "$");
|
||||||
newXSproto(strcpy(buf, "SetMerchantProbability"), XS_NPC_SetMerchantProbability, file, "$$");
|
newXSproto(strcpy(buf, "SetMerchantProbability"), XS_NPC_SetMerchantProbability, file, "$$");
|
||||||
newXSproto(strcpy(buf, "GetMerchantProbability"), XS_NPC_GetMerchantProbability, file, "$");
|
newXSproto(strcpy(buf, "GetMerchantProbability"), XS_NPC_GetMerchantProbability, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "AddMeleeProc"), XS_NPC_AddMeleeProc, file, "$$$");
|
||||||
|
newXSproto(strcpy(buf, "AddRangedProc"), XS_NPC_AddRangedProc, file, "$$$");
|
||||||
|
newXSproto(strcpy(buf, "AddDefensiveProc"), XS_NPC_AddDefensiveProc, file, "$$$");
|
||||||
XSRETURN_YES;
|
XSRETURN_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -103,6 +103,9 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
|
|||||||
if (!who)
|
if (!who)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(who->GetInvul() || who->GetSpecialAbility(IMMUNE_MELEE) || who->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE))
|
||||||
|
return; //-5?
|
||||||
|
|
||||||
int32 hate = max_damage;
|
int32 hate = max_damage;
|
||||||
if(hate_override > -1)
|
if(hate_override > -1)
|
||||||
hate = hate_override;
|
hate = hate_override;
|
||||||
@ -1059,8 +1062,8 @@ bool Mob::TryProjectileAttack(Mob* other, const Item_Struct *item, SkillUseTypes
|
|||||||
|
|
||||||
if(item)
|
if(item)
|
||||||
SendItemAnimation(other, item, skillInUse, speed);
|
SendItemAnimation(other, item, skillInUse, speed);
|
||||||
else if (IsNPC())
|
//else if (IsNPC())
|
||||||
ProjectileAnimation(other, 0,false,speed,0,0,0,CastToNPC()->GetAmmoIDfile(),skillInUse);
|
//ProjectileAnimation(other, 0,false,speed,0,0,0,CastToNPC()->GetAmmoIDfile(),skillInUse);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1097,12 +1100,19 @@ void Mob::ProjectileAttack()
|
|||||||
if (ProjectileAtk[i].hit_increment <= ProjectileAtk[i].increment){
|
if (ProjectileAtk[i].hit_increment <= ProjectileAtk[i].increment){
|
||||||
|
|
||||||
if (target){
|
if (target){
|
||||||
if (ProjectileAtk[i].skill == SkillArchery)
|
|
||||||
DoArcheryAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0,ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_id, nullptr, ProjectileAtk[i].ammo_slot);
|
if (IsNPC())
|
||||||
else if (ProjectileAtk[i].skill == SkillThrowing)
|
CastToNPC()->DoRangedAttackDmg(target, false, ProjectileAtk[i].wpn_dmg,0, static_cast<SkillUseTypes>(ProjectileAtk[i].skill));
|
||||||
DoThrowingAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0, ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_slot);
|
|
||||||
else if (ProjectileAtk[i].skill == SkillConjuration && IsValidSpell(ProjectileAtk[i].wpn_dmg))
|
else
|
||||||
SpellOnTarget(ProjectileAtk[i].wpn_dmg, target, false, true, spells[ProjectileAtk[i].wpn_dmg].ResistDiff, true);
|
{
|
||||||
|
if (ProjectileAtk[i].skill == SkillArchery)
|
||||||
|
DoArcheryAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0,ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_id, nullptr, ProjectileAtk[i].ammo_slot);
|
||||||
|
else if (ProjectileAtk[i].skill == SkillThrowing)
|
||||||
|
DoThrowingAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0, ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_slot);
|
||||||
|
else if (ProjectileAtk[i].skill == SkillConjuration && IsValidSpell(ProjectileAtk[i].wpn_dmg))
|
||||||
|
SpellOnTarget(ProjectileAtk[i].wpn_dmg, target, false, true, spells[ProjectileAtk[i].wpn_dmg].ResistDiff, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectileAtk[i].increment = 0;
|
ProjectileAtk[i].increment = 0;
|
||||||
@ -1187,14 +1197,8 @@ void NPC::RangedAttack(Mob* other)
|
|||||||
attacks = attacks > 0 ? attacks : 1;
|
attacks = attacks > 0 ? attacks : 1;
|
||||||
for(int i = 0; i < attacks; ++i) {
|
for(int i = 0; i < attacks; ++i) {
|
||||||
|
|
||||||
//if we have SPECATK_RANGED_ATK set then we range attack without weapon or ammo
|
|
||||||
const Item_Struct* weapon = nullptr;
|
|
||||||
const Item_Struct* ammo = nullptr;
|
|
||||||
if(!GetSpecialAbility(SPECATK_RANGED_ATK))
|
if(!GetSpecialAbility(SPECATK_RANGED_ATK))
|
||||||
{
|
|
||||||
//find our bow and ammo return if we can't find them...
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
int sa_min_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 4); //Min Range of NPC attack
|
int sa_min_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 4); //Min Range of NPC attack
|
||||||
int sa_max_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 1); //Max Range of NPC attack
|
int sa_max_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 1); //Max Range of NPC attack
|
||||||
@ -1208,16 +1212,11 @@ void NPC::RangedAttack(Mob* other)
|
|||||||
if (sa_min_range)
|
if (sa_min_range)
|
||||||
min_range = static_cast<float>(sa_min_range);
|
min_range = static_cast<float>(sa_min_range);
|
||||||
|
|
||||||
mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", max_range);
|
|
||||||
max_range *= max_range;
|
max_range *= max_range;
|
||||||
if(DistNoRootNoZ(*other) > max_range) {
|
if(DistNoRoot(*other) > max_range)
|
||||||
mlog(COMBAT__RANGED, "Ranged attack out of range...%.2f vs %.2f", DistNoRootNoZ(*other), max_range);
|
|
||||||
//target is out of range, client does a message
|
|
||||||
return;
|
return;
|
||||||
}
|
else if(DistNoRoot(*other) < (min_range * min_range))
|
||||||
else if(DistNoRootNoZ(*other) < (min_range * min_range))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
if(!other || !IsAttackAllowed(other) ||
|
if(!other || !IsAttackAllowed(other) ||
|
||||||
IsCasting() ||
|
IsCasting() ||
|
||||||
@ -1229,74 +1228,100 @@ void NPC::RangedAttack(Mob* other)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkillUseTypes skillinuse = SkillArchery;
|
|
||||||
skillinuse = static_cast<SkillUseTypes>(GetRangedSkill());
|
|
||||||
|
|
||||||
if(!ammo && !GetAmmoIDfile())
|
|
||||||
ammo = database.GetItem(8005);
|
|
||||||
|
|
||||||
if(ammo)
|
|
||||||
SendItemAnimation(other, ammo, SkillArchery);
|
|
||||||
else
|
|
||||||
ProjectileAnimation(other, 0,false,0,0,0,0,GetAmmoIDfile(),skillinuse);
|
|
||||||
|
|
||||||
FaceTarget(other);
|
FaceTarget(other);
|
||||||
|
|
||||||
if (!other->CheckHitChance(this, skillinuse, MainRange, GetSpecialAbilityParam(SPECATK_RANGED_ATK, 2)))
|
DoRangedAttackDmg(other);
|
||||||
{
|
|
||||||
mlog(COMBAT__RANGED, "Ranged attack missed %s.", other->GetName());
|
|
||||||
other->Damage(this, 0, SPELL_UNKNOWN, skillinuse);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int16 WDmg = GetWeaponDamage(other, weapon);
|
|
||||||
int16 ADmg = GetWeaponDamage(other, ammo);
|
|
||||||
int32 TotalDmg = 0;
|
|
||||||
if(WDmg > 0 || ADmg > 0)
|
|
||||||
{
|
|
||||||
mlog(COMBAT__RANGED, "Ranged attack hit %s.", other->GetName());
|
|
||||||
|
|
||||||
int32 MaxDmg = max_dmg * RuleR(Combat, ArcheryNPCMultiplier); // should add a field to npc_types
|
|
||||||
int32 MinDmg = min_dmg * RuleR(Combat, ArcheryNPCMultiplier);
|
|
||||||
|
|
||||||
if(RuleB(Combat, UseIntervalAC))
|
|
||||||
TotalDmg = MaxDmg;
|
|
||||||
else
|
|
||||||
TotalDmg = zone->random.Int(MinDmg, MaxDmg);
|
|
||||||
|
|
||||||
TotalDmg += TotalDmg * GetSpecialAbilityParam(SPECATK_RANGED_ATK, 3) / 100; //Damage modifier
|
|
||||||
|
|
||||||
other->AvoidDamage(this, TotalDmg, false);
|
|
||||||
other->MeleeMitigation(this, TotalDmg, MinDmg);
|
|
||||||
if (TotalDmg > 0)
|
|
||||||
CommonOutgoingHitSuccess(other, TotalDmg, skillinuse);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
TotalDmg = -5;
|
|
||||||
|
|
||||||
if (TotalDmg > 0)
|
|
||||||
other->AddToHateList(this, TotalDmg, 0, false);
|
|
||||||
else
|
|
||||||
other->AddToHateList(this, 0, 0, false);
|
|
||||||
|
|
||||||
other->Damage(this, TotalDmg, SPELL_UNKNOWN, skillinuse);
|
|
||||||
|
|
||||||
if (TotalDmg > 0 && HasSkillProcSuccess() && GetTarget() && !other->HasDied())
|
|
||||||
TrySkillProc(other, skillinuse, 0, true, MainRange);
|
|
||||||
}
|
|
||||||
|
|
||||||
//try proc on hits and misses
|
|
||||||
if(other && !other->HasDied())
|
|
||||||
TrySpellProc(nullptr, (const Item_Struct*)nullptr, other, MainRange);
|
|
||||||
|
|
||||||
if (HasSkillProcs() && other && !other->HasDied())
|
|
||||||
TrySkillProc(other, skillinuse, 0, false, MainRange);
|
|
||||||
|
|
||||||
CommonBreakInvisible();
|
CommonBreakInvisible();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 chance_mod, SkillUseTypes skill, float speed, const char *IDFile) {
|
||||||
|
|
||||||
|
if ((other == nullptr ||
|
||||||
|
(other->HasDied())) ||
|
||||||
|
HasDied() ||
|
||||||
|
(!IsAttackAllowed(other)) ||
|
||||||
|
(other->GetInvul() ||
|
||||||
|
other->GetSpecialAbility(IMMUNE_MELEE)))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkillUseTypes skillInUse = static_cast<SkillUseTypes>(GetRangedSkill());
|
||||||
|
|
||||||
|
if (skill != skillInUse)
|
||||||
|
skillInUse = skill;
|
||||||
|
|
||||||
|
if (Launch)
|
||||||
|
{
|
||||||
|
const char *ammo = "IT10";
|
||||||
|
|
||||||
|
if (IDFile != nullptr)
|
||||||
|
ammo = IDFile;
|
||||||
|
else if (GetAmmoIDfile())
|
||||||
|
ammo = GetAmmoIDfile();
|
||||||
|
|
||||||
|
ProjectileAnimation(other, 0,false,speed,0,0,0,ammo,skillInUse);
|
||||||
|
|
||||||
|
if (RuleB(Combat, ProjectileDmgOnImpact))
|
||||||
|
{
|
||||||
|
TryProjectileAttack(other, nullptr, skillInUse, damage_mod, nullptr, nullptr, 0, speed);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chance_mod)
|
||||||
|
chance_mod = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 2);
|
||||||
|
|
||||||
|
if (!other->CheckHitChance(this, skillInUse, MainRange, chance_mod))
|
||||||
|
{
|
||||||
|
other->Damage(this, 0, SPELL_UNKNOWN, skillInUse);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32 TotalDmg = 0;
|
||||||
|
int32 MaxDmg = max_dmg * RuleR(Combat, ArcheryNPCMultiplier); // should add a field to npc_types
|
||||||
|
int32 MinDmg = min_dmg * RuleR(Combat, ArcheryNPCMultiplier);
|
||||||
|
|
||||||
|
if(RuleB(Combat, UseIntervalAC))
|
||||||
|
TotalDmg = MaxDmg;
|
||||||
|
else
|
||||||
|
TotalDmg = zone->random.Int(MinDmg, MaxDmg);
|
||||||
|
|
||||||
|
|
||||||
|
if (!damage_mod)
|
||||||
|
damage_mod = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 3);//Damage modifier
|
||||||
|
|
||||||
|
TotalDmg += TotalDmg * damage_mod / 100;
|
||||||
|
|
||||||
|
other->AvoidDamage(this, TotalDmg, false);
|
||||||
|
other->MeleeMitigation(this, TotalDmg, MinDmg);
|
||||||
|
|
||||||
|
if (TotalDmg > 0)
|
||||||
|
CommonOutgoingHitSuccess(other, TotalDmg, skillInUse);
|
||||||
|
else
|
||||||
|
TotalDmg = -5;
|
||||||
|
|
||||||
|
if (TotalDmg > 0)
|
||||||
|
other->AddToHateList(this, TotalDmg, 0, false);
|
||||||
|
else
|
||||||
|
other->AddToHateList(this, 0, 0, false);
|
||||||
|
|
||||||
|
other->Damage(this, TotalDmg, SPELL_UNKNOWN, skillInUse);
|
||||||
|
|
||||||
|
if (TotalDmg > 0 && HasSkillProcSuccess() && !other->HasDied())
|
||||||
|
TrySkillProc(other, skillInUse, 0, true, MainRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
//try proc on hits and misses
|
||||||
|
if(other && !other->HasDied())
|
||||||
|
TrySpellProc(nullptr, (const Item_Struct*)nullptr, other, MainRange);
|
||||||
|
|
||||||
|
if (HasSkillProcs() && other && !other->HasDied())
|
||||||
|
TrySkillProc(other, skillInUse, 0, false, MainRange);
|
||||||
|
}
|
||||||
|
|
||||||
uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg) {
|
uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg) {
|
||||||
uint16 MaxDmg = (((2 * wDmg) * GetDamageTable(SkillThrowing)) / 100);
|
uint16 MaxDmg = (((2 * wDmg) * GetDamageTable(SkillThrowing)) / 100);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user