mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 14:41:28 +00:00
commit
79928c190b
@ -1,5 +1,10 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 04/30/2015 ==
|
||||||
|
demonstar55: Implement mob and client melee push
|
||||||
|
You can set Combat:MeleePush to false to turn off or change Combat:MeleePushChance to increase the chance an NPC can be pushed
|
||||||
|
PCs are always pushed, need to do more testing to verify.
|
||||||
|
|
||||||
== 04/22/2015 ==
|
== 04/22/2015 ==
|
||||||
Uleat: Probable fix for 'Debug Assertion Failure' in Client::GarbleMessage() when calling the 'isalpha' macro.
|
Uleat: Probable fix for 'Debug Assertion Failure' in Client::GarbleMessage() when calling the 'isalpha' macro.
|
||||||
ref: https://connect.microsoft.com/VisualStudio/feedback/details/932876/calling-isdigit-with-a-signed-char-1-results-in-a-assert-failure-in-debug-compiles
|
ref: https://connect.microsoft.com/VisualStudio/feedback/details/932876/calling-isdigit-with-a-signed-char-1-results-in-a-assert-failure-in-debug-compiles
|
||||||
|
|||||||
@ -1160,7 +1160,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*000*/ uint32 command;
|
/*000*/ uint32 command;
|
||||||
/*004*/ uint32 unknown;
|
/*004*/ uint32 target;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1318,9 +1318,9 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ uint32 damage;
|
/* 07 */ uint32 damage;
|
||||||
/* 11 */ uint32 unknown11;
|
/* 11 */ float force;
|
||||||
/* 15 */ uint32 sequence; // see above notes in Action_Struct
|
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 19 */ uint32 unknown19;
|
/* 19 */ float meleepush_z;
|
||||||
/* 23 */
|
/* 23 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -658,7 +658,9 @@ namespace RoF
|
|||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force)
|
||||||
|
OUT(meleepush_xy);
|
||||||
|
OUT(meleepush_z)
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -4389,7 +4391,7 @@ namespace RoF
|
|||||||
IN(type);
|
IN(type);
|
||||||
IN(spellid);
|
IN(spellid);
|
||||||
IN(damage);
|
IN(damage);
|
||||||
emu->sequence = eq->sequence;
|
IN(meleepush_xy);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -4717,7 +4719,7 @@ namespace RoF
|
|||||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||||
|
|
||||||
IN(command);
|
IN(command);
|
||||||
emu->unknown = eq->unknown04;
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -729,7 +729,9 @@ namespace RoF2
|
|||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force)
|
||||||
|
OUT(meleepush_xy);
|
||||||
|
OUT(meleepush_z)
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -4538,7 +4540,7 @@ namespace RoF2
|
|||||||
IN(type);
|
IN(type);
|
||||||
IN(spellid);
|
IN(spellid);
|
||||||
IN(damage);
|
IN(damage);
|
||||||
emu->sequence = eq->sequence;
|
IN(meleepush_xy);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -4864,7 +4866,7 @@ namespace RoF2
|
|||||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||||
|
|
||||||
IN(command);
|
IN(command);
|
||||||
emu->unknown = eq->unknown04;
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1293,7 +1293,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*00*/ uint32 command;
|
/*00*/ uint32 command;
|
||||||
/*04*/ uint32 unknown04;
|
/*04*/ uint32 target;
|
||||||
/*08*/ uint32 unknown08;
|
/*08*/ uint32 unknown08;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1484,9 +1484,10 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint32 spellid;
|
/* 05 */ uint32 spellid;
|
||||||
/* 09 */ int32 damage;
|
/* 09 */ int32 damage;
|
||||||
/* 13 */ float unknown11; // cd cc cc 3d
|
/* 13 */ float force; // cd cc cc 3d
|
||||||
/* 17 */ float sequence; // see above notes in Action_Struct
|
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 21 */ uint8 unknown19[9]; // was [9]
|
/* 21 */ float meleepush_z;
|
||||||
|
/* 25 */ uint8 unknown25[5]; // was [9]
|
||||||
/* 30 */
|
/* 30 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1323,7 +1323,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*00*/ uint32 command;
|
/*00*/ uint32 command;
|
||||||
/*04*/ uint32 unknown04;
|
/*04*/ uint32 target;
|
||||||
/*08*/ uint32 unknown08;
|
/*08*/ uint32 unknown08;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1514,9 +1514,10 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint32 spellid;
|
/* 05 */ uint32 spellid;
|
||||||
/* 09 */ int32 damage;
|
/* 09 */ int32 damage;
|
||||||
/* 13 */ float unknown11; // cd cc cc 3d
|
/* 13 */ float force; // cd cc cc 3d
|
||||||
/* 17 */ float sequence; // see above notes in Action_Struct
|
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 21 */ uint8 unknown19[9]; // was [9]
|
/* 21 */ float meleepush_z;
|
||||||
|
/* 25 */ uint8 unknown25[5]; // was [9]
|
||||||
/* 30 */
|
/* 30 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -446,7 +446,9 @@ namespace SoD
|
|||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force)
|
||||||
|
OUT(meleepush_xy);
|
||||||
|
OUT(meleepush_z)
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -3349,7 +3351,7 @@ namespace SoD
|
|||||||
default:
|
default:
|
||||||
emu->command = eq->command;
|
emu->command = eq->command;
|
||||||
}
|
}
|
||||||
OUT(unknown);
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1091,7 +1091,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*000*/ uint32 command;
|
/*000*/ uint32 command;
|
||||||
/*004*/ uint32 unknown;
|
/*004*/ uint32 target;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1272,9 +1272,10 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ int32 damage;
|
/* 07 */ int32 damage;
|
||||||
/* 11 */ float unknown11; // cd cc cc 3d
|
/* 11 */ float force; // cd cc cc 3d
|
||||||
/* 15 */ float sequence; // see above notes in Action_Struct
|
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 19 */ uint8 unknown19[9]; // was [9]
|
/* 19 */ float meleepush_z;
|
||||||
|
/* 23 */ uint8 unknown23[5]; // was [9]
|
||||||
/* 28 */
|
/* 28 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -426,7 +426,9 @@ namespace SoF
|
|||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force)
|
||||||
|
OUT(meleepush_xy);
|
||||||
|
OUT(meleepush_z)
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -2687,7 +2689,7 @@ namespace SoF
|
|||||||
default:
|
default:
|
||||||
emu->command = eq->command;
|
emu->command = eq->command;
|
||||||
}
|
}
|
||||||
OUT(unknown);
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1068,7 +1068,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*000*/ uint32 command;
|
/*000*/ uint32 command;
|
||||||
/*004*/ uint32 unknown;
|
/*004*/ uint32 target;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1249,9 +1249,10 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ int32 damage;
|
/* 07 */ int32 damage;
|
||||||
/* 11 */ float unknown11; // cd cc cc 3d
|
/* 11 */ float force; // cd cc cc 3d
|
||||||
/* 15 */ float sequence; // see above notes in Action_Struct
|
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 19 */ uint8 unknown19[9]; // was [9]
|
/* 19 */ float meleepush_z;
|
||||||
|
/* 23 */ uint8 unknown23[5]; // was [9]
|
||||||
/* 28 */
|
/* 28 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -122,7 +122,7 @@ namespace Titanium
|
|||||||
EAT_ENCODE(OP_GuildMemberLevelUpdate); // added ;
|
EAT_ENCODE(OP_GuildMemberLevelUpdate); // added ;
|
||||||
|
|
||||||
EAT_ENCODE(OP_ZoneServerReady); // added ;
|
EAT_ENCODE(OP_ZoneServerReady); // added ;
|
||||||
|
|
||||||
ENCODE(OP_Action)
|
ENCODE(OP_Action)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_EXACT(Action_Struct);
|
ENCODE_LENGTH_EXACT(Action_Struct);
|
||||||
@ -326,7 +326,7 @@ namespace Titanium
|
|||||||
{
|
{
|
||||||
SETUP_VAR_ENCODE(ExpeditionCompass_Struct);
|
SETUP_VAR_ENCODE(ExpeditionCompass_Struct);
|
||||||
ALLOC_VAR_ENCODE(structs::ExpeditionCompass_Struct, sizeof(structs::ExpeditionInfo_Struct) + sizeof(structs::ExpeditionCompassEntry_Struct) * emu->count);
|
ALLOC_VAR_ENCODE(structs::ExpeditionCompass_Struct, sizeof(structs::ExpeditionInfo_Struct) + sizeof(structs::ExpeditionCompassEntry_Struct) * emu->count);
|
||||||
|
|
||||||
OUT(count);
|
OUT(count);
|
||||||
|
|
||||||
for (uint32 i = 0; i < emu->count; ++i)
|
for (uint32 i = 0; i < emu->count; ++i)
|
||||||
@ -1308,7 +1308,7 @@ namespace Titanium
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||||
|
|
||||||
delete[] __emu_buffer;
|
delete[] __emu_buffer;
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
}
|
}
|
||||||
@ -1351,7 +1351,7 @@ namespace Titanium
|
|||||||
InBuffer += strlen(InBuffer) + 1;
|
InBuffer += strlen(InBuffer) + 1;
|
||||||
|
|
||||||
memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct));
|
memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct));
|
||||||
|
|
||||||
delete[] __emu_buffer;
|
delete[] __emu_buffer;
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
}
|
}
|
||||||
@ -1621,7 +1621,7 @@ namespace Titanium
|
|||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
DECODE(OP_ApplyPoison)
|
DECODE(OP_ApplyPoison)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::ApplyPoison_Struct);
|
DECODE_LENGTH_EXACT(structs::ApplyPoison_Struct);
|
||||||
@ -1942,7 +1942,7 @@ namespace Titanium
|
|||||||
default:
|
default:
|
||||||
emu->command = eq->command;
|
emu->command = eq->command;
|
||||||
}
|
}
|
||||||
OUT(unknown);
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -2151,7 +2151,7 @@ namespace Titanium
|
|||||||
|
|
||||||
return serverSlot; // deprecated
|
return serverSlot; // deprecated
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int16 ServerToTitaniumCorpseSlot(uint32 serverCorpseSlot)
|
static inline int16 ServerToTitaniumCorpseSlot(uint32 serverCorpseSlot)
|
||||||
{
|
{
|
||||||
//int16 TitaniumCorpse;
|
//int16 TitaniumCorpse;
|
||||||
@ -2166,7 +2166,7 @@ namespace Titanium
|
|||||||
|
|
||||||
return titaniumSlot; // deprecated
|
return titaniumSlot; // deprecated
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot)
|
static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot)
|
||||||
{
|
{
|
||||||
//uint32 ServerCorpse;
|
//uint32 ServerCorpse;
|
||||||
|
|||||||
@ -950,7 +950,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*000*/ uint32 command;
|
/*000*/ uint32 command;
|
||||||
/*004*/ uint32 unknown;
|
/*004*/ uint32 target;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1101,9 +1101,9 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ uint32 damage;
|
/* 07 */ uint32 damage;
|
||||||
/* 11 */ uint32 unknown11;
|
/* 11 */ float force;
|
||||||
/* 15 */ uint32 sequence; // see above notes in Action_Struct
|
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 19 */ uint32 unknown19;
|
/* 19 */ float meleepush_z;
|
||||||
/* 23 */
|
/* 23 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -581,7 +581,9 @@ namespace UF
|
|||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force)
|
||||||
|
OUT(meleepush_xy);
|
||||||
|
OUT(meleepush_z)
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -2213,7 +2215,7 @@ namespace UF
|
|||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *emu_ptr = __emu_buffer;
|
unsigned char *emu_ptr = __emu_buffer;
|
||||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||||
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
|
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
|
||||||
@ -3356,7 +3358,7 @@ namespace UF
|
|||||||
IN(type);
|
IN(type);
|
||||||
IN(spellid);
|
IN(spellid);
|
||||||
IN(damage);
|
IN(damage);
|
||||||
emu->sequence = eq->sequence;
|
IN(meleepush_xy);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -3599,7 +3601,7 @@ namespace UF
|
|||||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||||
|
|
||||||
IN(command);
|
IN(command);
|
||||||
IN(unknown);
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -3861,7 +3863,7 @@ namespace UF
|
|||||||
|
|
||||||
UF::structs::ItemSerializationHeaderFinish hdrf;
|
UF::structs::ItemSerializationHeaderFinish hdrf;
|
||||||
hdrf.ornamentIcon = ornaIcon;
|
hdrf.ornamentIcon = ornaIcon;
|
||||||
hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit..
|
hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit..
|
||||||
hdrf.unknown061 = 0; //possibly ornament / special ornament
|
hdrf.unknown061 = 0; //possibly ornament / special ornament
|
||||||
hdrf.isCopied = 0; //Flag for item to be 'Copied'
|
hdrf.isCopied = 0; //Flag for item to be 'Copied'
|
||||||
hdrf.ItemClass = item->ItemClass;
|
hdrf.ItemClass = item->ItemClass;
|
||||||
|
|||||||
@ -1146,7 +1146,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*000*/ uint32 command;
|
/*000*/ uint32 command;
|
||||||
/*004*/ uint32 unknown;
|
/*004*/ uint32 target;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1330,9 +1330,10 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ int32 damage;
|
/* 07 */ int32 damage;
|
||||||
/* 11 */ float unknown11; // cd cc cc 3d
|
/* 11 */ float force; // cd cc cc 3d
|
||||||
/* 15 */ float sequence; // see above notes in Action_Struct
|
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 19 */ uint8 unknown19[9]; // was [9]
|
/* 19 */ float meleepush_z;
|
||||||
|
/* 23 */ uint8 unknown23[5]; // was [9]
|
||||||
/* 28 */
|
/* 28 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -47,6 +47,8 @@
|
|||||||
#define IKSAR 128
|
#define IKSAR 128
|
||||||
#define VAHSHIR 130
|
#define VAHSHIR 130
|
||||||
#define CONTROLLED_BOAT 141
|
#define CONTROLLED_BOAT 141
|
||||||
|
#define MINOR_ILL_OBJ 142
|
||||||
|
#define TREE 143
|
||||||
#define IKSAR_SKELETON 161
|
#define IKSAR_SKELETON 161
|
||||||
#define FROGLOK 330
|
#define FROGLOK 330
|
||||||
#define FROGLOK2 74 // Not sure why /who all reports race as 74 for frogloks
|
#define FROGLOK2 74 // Not sure why /who all reports race as 74 for frogloks
|
||||||
|
|||||||
@ -377,7 +377,7 @@ RULE_REAL ( Combat, HitBonusPerLevel, 1.2) //You gain this % of hit for every le
|
|||||||
RULE_REAL ( Combat, WeaponSkillFalloff, 0.33) //For every weapon skill point that's not maxed you lose this % of hit
|
RULE_REAL ( Combat, WeaponSkillFalloff, 0.33) //For every weapon skill point that's not maxed you lose this % of hit
|
||||||
RULE_REAL ( Combat, ArcheryHitPenalty, 0.25) //Archery has a hit penalty to try to help balance it with the plethora of long term +hit modifiers for it
|
RULE_REAL ( Combat, ArcheryHitPenalty, 0.25) //Archery has a hit penalty to try to help balance it with the plethora of long term +hit modifiers for it
|
||||||
RULE_REAL ( Combat, AgiHitFactor, 0.01)
|
RULE_REAL ( Combat, AgiHitFactor, 0.01)
|
||||||
RULE_REAL ( Combat, MinChancetoHit, 5.0) //Minimum % chance to hit with regular melee/ranged
|
RULE_REAL ( Combat, MinChancetoHit, 5.0) //Minimum % chance to hit with regular melee/ranged
|
||||||
RULE_REAL ( Combat, MaxChancetoHit, 95.0) //Maximum % chance to hit with regular melee/ranged
|
RULE_REAL ( Combat, MaxChancetoHit, 95.0) //Maximum % chance to hit with regular melee/ranged
|
||||||
RULE_INT ( Combat, MinRangedAttackDist, 25) //Minimum Distance to use Ranged Attacks
|
RULE_INT ( Combat, MinRangedAttackDist, 25) //Minimum Distance to use Ranged Attacks
|
||||||
RULE_BOOL ( Combat, ArcheryBonusRequiresStationary, true) //does the 2x archery bonus chance require a stationary npc
|
RULE_BOOL ( Combat, ArcheryBonusRequiresStationary, true) //does the 2x archery bonus chance require a stationary npc
|
||||||
@ -438,6 +438,8 @@ RULE_INT ( Combat, BerserkerFrenzyStart, 35)
|
|||||||
RULE_INT ( Combat, BerserkerFrenzyEnd, 45)
|
RULE_INT ( Combat, BerserkerFrenzyEnd, 45)
|
||||||
RULE_BOOL ( Combat, OneProcPerWeapon, true) //If enabled, One proc per weapon per round
|
RULE_BOOL ( Combat, OneProcPerWeapon, true) //If enabled, One proc per weapon per round
|
||||||
RULE_BOOL ( Combat, ProjectileDmgOnImpact, true) //If enabled, projectiles (ie arrows) will hit on impact, instead of instantly.
|
RULE_BOOL ( Combat, ProjectileDmgOnImpact, true) //If enabled, projectiles (ie arrows) will hit on impact, instead of instantly.
|
||||||
|
RULE_BOOL ( Combat, MeleePush, true) // enable melee push
|
||||||
|
RULE_INT ( Combat, MeleePushChance, 50) // (NPCs) chance the target will be pushed. Made up, 100 actually isn't that bad
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY( NPC )
|
RULE_CATEGORY( NPC )
|
||||||
@ -577,7 +579,7 @@ RULE_INT ( Console, SessionTimeOut, 600000 ) // Amount of time in ms for the con
|
|||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY( QueryServ )
|
RULE_CATEGORY( QueryServ )
|
||||||
RULE_BOOL( QueryServ, PlayerLogChat, false) // Logs Player Chat
|
RULE_BOOL( QueryServ, PlayerLogChat, false) // Logs Player Chat
|
||||||
RULE_BOOL( QueryServ, PlayerLogTrades, false) // Logs Player Trades
|
RULE_BOOL( QueryServ, PlayerLogTrades, false) // Logs Player Trades
|
||||||
RULE_BOOL( QueryServ, PlayerLogHandins, false) // Logs Player Handins
|
RULE_BOOL( QueryServ, PlayerLogHandins, false) // Logs Player Handins
|
||||||
RULE_BOOL( QueryServ, PlayerLogNPCKills, false) // Logs Player NPC Kills
|
RULE_BOOL( QueryServ, PlayerLogNPCKills, false) // Logs Player NPC Kills
|
||||||
@ -590,7 +592,7 @@ RULE_BOOL( QueryServ, PlayerLogZone, false) // Logs Player Zone Events
|
|||||||
RULE_BOOL( QueryServ, PlayerLogDeaths, false) // Logs Player Deaths
|
RULE_BOOL( QueryServ, PlayerLogDeaths, false) // Logs Player Deaths
|
||||||
RULE_BOOL( QueryServ, PlayerLogConnectDisconnect, false) // Logs Player Connect Disconnect State
|
RULE_BOOL( QueryServ, PlayerLogConnectDisconnect, false) // Logs Player Connect Disconnect State
|
||||||
RULE_BOOL( QueryServ, PlayerLogLevels, false) // Logs Player Leveling/Deleveling
|
RULE_BOOL( QueryServ, PlayerLogLevels, false) // Logs Player Leveling/Deleveling
|
||||||
RULE_BOOL( QueryServ, PlayerLogAARate, false) // Logs Player AA Experience Rates
|
RULE_BOOL( QueryServ, PlayerLogAARate, false) // Logs Player AA Experience Rates
|
||||||
RULE_BOOL( QueryServ, PlayerLogQGlobalUpdate, false) // Logs Player QGlobal Updates
|
RULE_BOOL( QueryServ, PlayerLogQGlobalUpdate, false) // Logs Player QGlobal Updates
|
||||||
RULE_BOOL( QueryServ, PlayerLogTaskUpdates, false) // Logs Player Task Updates
|
RULE_BOOL( QueryServ, PlayerLogTaskUpdates, false) // Logs Player Task Updates
|
||||||
RULE_BOOL( QueryServ, PlayerLogKeyringAddition, false) // Log PLayer Keyring additions
|
RULE_BOOL( QueryServ, PlayerLogKeyringAddition, false) // Log PLayer Keyring additions
|
||||||
|
|||||||
@ -55,3 +55,40 @@ bool EQEmu::IsSpecializedSkill(SkillUseTypes skill)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float EQEmu::GetSkillMeleePushForce(SkillUseTypes skill)
|
||||||
|
{
|
||||||
|
// This is the force/magnitude of the push from an attack of this skill type
|
||||||
|
// You can find these numbers in the clients skill struct
|
||||||
|
switch (skill) {
|
||||||
|
case Skill1HBlunt:
|
||||||
|
case Skill1HSlashing:
|
||||||
|
case SkillHandtoHand:
|
||||||
|
case SkillThrowing:
|
||||||
|
return 0.1f;
|
||||||
|
case Skill2HBlunt:
|
||||||
|
case Skill2HSlashing:
|
||||||
|
case SkillEagleStrike:
|
||||||
|
case SkillKick:
|
||||||
|
case SkillTigerClaw:
|
||||||
|
//case Skill2HPiercing:
|
||||||
|
return 0.2f;
|
||||||
|
case SkillArchery:
|
||||||
|
return 0.15f;
|
||||||
|
case SkillBackstab:
|
||||||
|
case SkillBash:
|
||||||
|
return 0.3f;
|
||||||
|
case SkillDragonPunch:
|
||||||
|
case SkillRoundKick:
|
||||||
|
return 0.25f;
|
||||||
|
case SkillFlyingKick:
|
||||||
|
return 0.4f;
|
||||||
|
case Skill1HPiercing:
|
||||||
|
case SkillFrenzy:
|
||||||
|
return 0.05f;
|
||||||
|
case SkillIntimidation:
|
||||||
|
return 2.5f;
|
||||||
|
default:
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -270,6 +270,7 @@ typedef enum {
|
|||||||
namespace EQEmu {
|
namespace EQEmu {
|
||||||
bool IsTradeskill(SkillUseTypes skill);
|
bool IsTradeskill(SkillUseTypes skill);
|
||||||
bool IsSpecializedSkill(SkillUseTypes skill);
|
bool IsSpecializedSkill(SkillUseTypes skill);
|
||||||
|
float GetSkillMeleePushForce(SkillUseTypes skill);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
2
utils/sql/git/optional/2015_4_30_MeleePush.sql
Normal file
2
utils/sql/git/optional/2015_4_30_MeleePush.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Combat:MeleePush', 'true', 'Turns on Melee Push.');
|
||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Combat:MeleePushChance', '50', 'Chance that an NPC can be pushed from melee.');
|
||||||
@ -982,14 +982,24 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if((GetClass() == MONK || GetClass() == BEASTLORD) && GetLevel() >= 30){
|
bool MagicGloves=false;
|
||||||
dmg = GetMonkHandToHandDamage();
|
if (IsClient()) {
|
||||||
if (hate) *hate += dmg;
|
ItemInst *gloves=CastToClient()->GetInv().GetItem(MainHands);
|
||||||
|
if (gloves != nullptr) {
|
||||||
|
MagicGloves = gloves->GetItem()->Magic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((GetClass() == MONK || GetClass() == BEASTLORD)) {
|
||||||
|
if(MagicGloves || GetLevel() >= 30){
|
||||||
|
dmg = GetMonkHandToHandDamage();
|
||||||
|
if (hate) *hate += dmg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(GetOwner() && GetLevel() >= RuleI(Combat, PetAttackMagicLevel)){ //pets wouldn't actually use this but...
|
else if(GetOwner() && GetLevel() >= RuleI(Combat, PetAttackMagicLevel)){ //pets wouldn't actually use this but...
|
||||||
dmg = 1; //it gives us an idea if we can hit
|
dmg = 1; //it gives us an idea if we can hit
|
||||||
}
|
}
|
||||||
else if(GetSpecialAbility(SPECATK_MAGICAL)){
|
else if(MagicGloves || GetSpecialAbility(SPECATK_MAGICAL)){
|
||||||
dmg = 1;
|
dmg = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3700,6 +3710,23 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
|||||||
a->type = SkillDamageTypes[skill_used]; // was 0x1c
|
a->type = SkillDamageTypes[skill_used]; // was 0x1c
|
||||||
a->damage = damage;
|
a->damage = damage;
|
||||||
a->spellid = spell_id;
|
a->spellid = spell_id;
|
||||||
|
a->meleepush_xy = attacker->GetHeading() * 2.0f;
|
||||||
|
if (RuleB(Combat, MeleePush) && damage > 0 && !IsRooted() &&
|
||||||
|
(IsClient() || zone->random.Roll(RuleI(Combat, MeleePushChance)))) {
|
||||||
|
a->force = EQEmu::GetSkillMeleePushForce(skill_used);
|
||||||
|
// update NPC stuff
|
||||||
|
auto new_pos = glm::vec3(m_Position.x + (a->force * std::sin(a->meleepush_xy) + m_Delta.x),
|
||||||
|
m_Position.y + (a->force * std::cos(a->meleepush_xy) + m_Delta.y), m_Position.z);
|
||||||
|
if (zone->zonemap->CheckLoS(glm::vec3(m_Position), new_pos)) { // If we have LoS on the new loc it should be reachable.
|
||||||
|
if (IsNPC()) {
|
||||||
|
// Is this adequate?
|
||||||
|
Teleport(new_pos);
|
||||||
|
SendPosUpdate();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
a->force = 0.0f; // we couldn't move there, so lets not
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Note: if players can become pets, they will not receive damage messages of their own
|
//Note: if players can become pets, they will not receive damage messages of their own
|
||||||
//this was done to simplify the code here (since we can only effectively skip one mob on queue)
|
//this was done to simplify the code here (since we can only effectively skip one mob on queue)
|
||||||
|
|||||||
@ -1051,12 +1051,12 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
if(quest_manager.ProximitySayInUse())
|
if(quest_manager.ProximitySayInUse())
|
||||||
entity_list.ProcessProximitySay(message, this, language);
|
entity_list.ProcessProximitySay(message, this, language);
|
||||||
|
|
||||||
if (GetTarget() != 0 && GetTarget()->IsNPC()) {
|
if (GetTarget() != 0 && GetTarget()->IsNPC() &&
|
||||||
|
!IsInvisible(GetTarget())) {
|
||||||
if(!GetTarget()->CastToNPC()->IsEngaged()) {
|
if(!GetTarget()->CastToNPC()->IsEngaged()) {
|
||||||
CheckLDoNHail(GetTarget());
|
CheckLDoNHail(GetTarget());
|
||||||
CheckEmoteHail(GetTarget(), message);
|
CheckEmoteHail(GetTarget(), message);
|
||||||
|
|
||||||
|
|
||||||
if(DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
|
if(DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
|
||||||
NPC *tar = GetTarget()->CastToNPC();
|
NPC *tar = GetTarget()->CastToNPC();
|
||||||
parse->EventNPC(EVENT_SAY, tar->CastToNPC(), this, message, language);
|
parse->EventNPC(EVENT_SAY, tar->CastToNPC(), this, message, language);
|
||||||
|
|||||||
@ -9752,6 +9752,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
char val1[20] = { 0 };
|
char val1[20] = { 0 };
|
||||||
PetCommand_Struct* pet = (PetCommand_Struct*)app->pBuffer;
|
PetCommand_Struct* pet = (PetCommand_Struct*)app->pBuffer;
|
||||||
Mob* mypet = this->GetPet();
|
Mob* mypet = this->GetPet();
|
||||||
|
Mob *target = entity_list.GetMob(pet->target);
|
||||||
|
|
||||||
if (!mypet || pet->command == PET_LEADER)
|
if (!mypet || pet->command == PET_LEADER)
|
||||||
{
|
{
|
||||||
@ -9799,22 +9800,22 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
switch (PetCommand)
|
switch (PetCommand)
|
||||||
{
|
{
|
||||||
case PET_ATTACK: {
|
case PET_ATTACK: {
|
||||||
if (!GetTarget())
|
if (!target)
|
||||||
break;
|
break;
|
||||||
if (GetTarget()->IsMezzed()) {
|
if (target->IsMezzed()) {
|
||||||
Message_StringID(10, CANNOT_WAKE, mypet->GetCleanName(), GetTarget()->GetCleanName());
|
Message_StringID(10, CANNOT_WAKE, mypet->GetCleanName(), target->GetCleanName());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (mypet->IsFeared())
|
if (mypet->IsFeared())
|
||||||
break; //prevent pet from attacking stuff while feared
|
break; //prevent pet from attacking stuff while feared
|
||||||
|
|
||||||
if (!mypet->IsAttackAllowed(GetTarget())) {
|
if (!mypet->IsAttackAllowed(target)) {
|
||||||
mypet->Say_StringID(NOT_LEGAL_TARGET);
|
mypet->Say_StringID(NOT_LEGAL_TARGET);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
|
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
|
||||||
if (GetTarget() != this && DistanceSquaredNoZ(mypet->GetPosition(), GetTarget()->GetPosition()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
|
if (target != this && DistanceSquaredNoZ(mypet->GetPosition(), target->GetPosition()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
|
||||||
if (mypet->IsHeld()) {
|
if (mypet->IsHeld()) {
|
||||||
if (!mypet->IsFocused()) {
|
if (!mypet->IsFocused()) {
|
||||||
mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
|
mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
|
||||||
@ -9822,12 +9823,12 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
mypet->SetPetOrder(SPO_Follow);
|
mypet->SetPetOrder(SPO_Follow);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mypet->SetTarget(GetTarget());
|
mypet->SetTarget(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zone->AddAggroMob();
|
zone->AddAggroMob();
|
||||||
mypet->AddToHateList(GetTarget(), 1);
|
mypet->AddToHateList(target, 1);
|
||||||
Message_StringID(MT_PetResponse, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName());
|
Message_StringID(MT_PetResponse, PET_ATTACKING, mypet->GetCleanName(), target->GetCleanName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -618,6 +618,7 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
|
|||||||
EQApplicationPacket *app = new EQApplicationPacket;
|
EQApplicationPacket *app = new EQApplicationPacket;
|
||||||
npc->CreateSpawnPacket(app, npc);
|
npc->CreateSpawnPacket(app, npc);
|
||||||
QueueClients(npc, app);
|
QueueClients(npc, app);
|
||||||
|
npc->SendArmorAppearance();
|
||||||
safe_delete(app);
|
safe_delete(app);
|
||||||
} else {
|
} else {
|
||||||
NewSpawn_Struct *ns = new NewSpawn_Struct;
|
NewSpawn_Struct *ns = new NewSpawn_Struct;
|
||||||
@ -726,10 +727,16 @@ void EntityList::CheckSpawnQueue()
|
|||||||
EQApplicationPacket *outapp = 0;
|
EQApplicationPacket *outapp = 0;
|
||||||
|
|
||||||
iterator.Reset();
|
iterator.Reset();
|
||||||
|
NewSpawn_Struct *ns;
|
||||||
|
|
||||||
while(iterator.MoreElements()) {
|
while(iterator.MoreElements()) {
|
||||||
outapp = new EQApplicationPacket;
|
outapp = new EQApplicationPacket;
|
||||||
Mob::CreateSpawnPacket(outapp, iterator.GetData());
|
ns = iterator.GetData();
|
||||||
|
Mob::CreateSpawnPacket(outapp, ns);
|
||||||
QueueClients(0, outapp);
|
QueueClients(0, outapp);
|
||||||
|
auto it = npc_list.find(ns->spawn.spawnId);
|
||||||
|
NPC *pnpc = it->second;
|
||||||
|
pnpc->SendArmorAppearance();
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
iterator.RemoveCurrent();
|
iterator.RemoveCurrent();
|
||||||
}
|
}
|
||||||
@ -1149,19 +1156,39 @@ void EntityList::SendZoneSpawnsBulk(Client *client)
|
|||||||
NewSpawn_Struct ns;
|
NewSpawn_Struct ns;
|
||||||
Mob *spawn;
|
Mob *spawn;
|
||||||
uint32 maxspawns = 100;
|
uint32 maxspawns = 100;
|
||||||
|
EQApplicationPacket *app;
|
||||||
|
|
||||||
if (maxspawns > mob_list.size())
|
if (maxspawns > mob_list.size())
|
||||||
maxspawns = mob_list.size();
|
maxspawns = mob_list.size();
|
||||||
BulkZoneSpawnPacket *bzsp = new BulkZoneSpawnPacket(client, maxspawns);
|
BulkZoneSpawnPacket *bzsp = new BulkZoneSpawnPacket(client, maxspawns);
|
||||||
|
|
||||||
|
int32 race=-1;
|
||||||
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
|
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
|
||||||
spawn = it->second;
|
spawn = it->second;
|
||||||
if (spawn && spawn->InZone()) {
|
if (spawn && spawn->InZone()) {
|
||||||
if (spawn->IsClient() && (spawn->CastToClient()->GMHideMe(client) ||
|
if (spawn->IsClient() && (spawn->CastToClient()->GMHideMe(client) ||
|
||||||
spawn->CastToClient()->IsHoveringForRespawn()))
|
spawn->CastToClient()->IsHoveringForRespawn()))
|
||||||
continue;
|
continue;
|
||||||
memset(&ns, 0, sizeof(NewSpawn_Struct));
|
|
||||||
spawn->FillSpawnStruct(&ns, client);
|
race = spawn->GetRace();
|
||||||
bzsp->AddSpawn(&ns);
|
|
||||||
|
// Illusion races on PCs don't work as a mass spawn
|
||||||
|
// But they will work as an add_spawn AFTER CLIENT_CONNECTED.
|
||||||
|
if (spawn->IsClient() && (race == MINOR_ILL_OBJ || race == TREE)) {
|
||||||
|
app = new EQApplicationPacket;
|
||||||
|
spawn->CreateSpawnPacket(app);
|
||||||
|
client->QueuePacket(app, true, Client::CLIENT_CONNECTED);
|
||||||
|
safe_delete(app);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memset(&ns, 0, sizeof(NewSpawn_Struct));
|
||||||
|
spawn->FillSpawnStruct(&ns, client);
|
||||||
|
bzsp->AddSpawn(&ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Despite being sent in the OP_ZoneSpawns packet, the client
|
||||||
|
// does not display worn armor correctly so display it.
|
||||||
|
spawn->SendArmorAppearance(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
safe_delete(bzsp);
|
safe_delete(bzsp);
|
||||||
|
|||||||
42
zone/mob.cpp
42
zone/mob.cpp
@ -1787,7 +1787,7 @@ bool Mob::IsPlayerRace(uint16 in_race) {
|
|||||||
|
|
||||||
|
|
||||||
uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) {
|
uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) {
|
||||||
if (Mob::IsPlayerRace(in_race) || in_race == 15 || in_race == 50 || in_race == 57 || in_race == 70 || in_race == 98 || in_race == 118) {
|
if (Mob::IsPlayerRace(in_race) || in_race == 15 || in_race == 50 || in_race == 57 || in_race == 70 || in_race == 98 || in_race == 118 || in_race == 23) {
|
||||||
if (in_gender >= 2) {
|
if (in_gender >= 2) {
|
||||||
// Male default for PC Races
|
// Male default for PC Races
|
||||||
return 0;
|
return 0;
|
||||||
@ -2552,7 +2552,35 @@ uint32 NPC::GetEquipment(uint8 material_slot) const
|
|||||||
return equipment[invslot];
|
return equipment[invslot];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::SendWearChange(uint8 material_slot)
|
void Mob::SendArmorAppearance(Client *one_client)
|
||||||
|
{
|
||||||
|
// one_client of 0 means sent to all clients
|
||||||
|
//
|
||||||
|
// Despite the fact that OP_NewSpawn and OP_ZoneSpawns include the
|
||||||
|
// armor being worn and its mats, the client doesn't update the display
|
||||||
|
// on arrival of these packets reliably.
|
||||||
|
//
|
||||||
|
// Send Wear changes if mob is a PC race and item is an armor slot.
|
||||||
|
// The other packets work for primary/secondary.
|
||||||
|
|
||||||
|
if (IsPlayerRace(race))
|
||||||
|
{
|
||||||
|
if (!IsClient())
|
||||||
|
{
|
||||||
|
const Item_Struct *item;
|
||||||
|
for (int i=0; i< 7 ; ++i)
|
||||||
|
{
|
||||||
|
item=database.GetItem(GetEquipment(i));
|
||||||
|
if (item != 0)
|
||||||
|
{
|
||||||
|
SendWearChange(i,one_client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mob::SendWearChange(uint8 material_slot, Client *one_client)
|
||||||
{
|
{
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct));
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct));
|
||||||
WearChange_Struct* wc = (WearChange_Struct*)outapp->pBuffer;
|
WearChange_Struct* wc = (WearChange_Struct*)outapp->pBuffer;
|
||||||
@ -2564,7 +2592,15 @@ void Mob::SendWearChange(uint8 material_slot)
|
|||||||
wc->color.Color = GetEquipmentColor(material_slot);
|
wc->color.Color = GetEquipmentColor(material_slot);
|
||||||
wc->wear_slot_id = material_slot;
|
wc->wear_slot_id = material_slot;
|
||||||
|
|
||||||
entity_list.QueueClients(this, outapp);
|
if (!one_client)
|
||||||
|
{
|
||||||
|
entity_list.QueueClients(this, outapp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
one_client->QueuePacket(outapp, false, Client::CLIENT_CONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -171,7 +171,8 @@ public:
|
|||||||
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5,
|
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5,
|
||||||
Client *specific_target=nullptr);
|
Client *specific_target=nullptr);
|
||||||
void SendTargetable(bool on, Client *specific_target = nullptr);
|
void SendTargetable(bool on, Client *specific_target = nullptr);
|
||||||
virtual void SendWearChange(uint8 material_slot);
|
virtual void SendArmorAppearance(Client *one_client = nullptr);
|
||||||
|
virtual void SendWearChange(uint8 material_slot, Client *one_client = nullptr);
|
||||||
virtual void SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model = 0, uint32 elite_material = 0,
|
virtual void SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model = 0, uint32 elite_material = 0,
|
||||||
uint32 unknown06 = 0, uint32 unknown18 = 0);
|
uint32 unknown06 = 0, uint32 unknown18 = 0);
|
||||||
virtual void SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint);
|
virtual void SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint);
|
||||||
|
|||||||
@ -189,8 +189,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
|
|
||||||
if (!IsPowerDistModSpell(spell_id))
|
if (!IsPowerDistModSpell(spell_id))
|
||||||
SetSpellPowerDistanceMod(0);
|
SetSpellPowerDistanceMod(0);
|
||||||
|
|
||||||
bool SE_SpellTrigger_HasCast = false;
|
bool SE_SpellTrigger_HasCast = false;
|
||||||
|
|
||||||
// iterate through the effects in the spell
|
// iterate through the effects in the spell
|
||||||
for (i = 0; i < EFFECT_COUNT; i++)
|
for (i = 0; i < EFFECT_COUNT; i++)
|
||||||
@ -424,11 +424,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SE_Succor:
|
case SE_Succor:
|
||||||
{
|
{
|
||||||
|
|
||||||
float x, y, z, heading;
|
float x, y, z, heading;
|
||||||
const char *target_zone;
|
const char *target_zone;
|
||||||
|
|
||||||
x = static_cast<float>(spell.base[1]);
|
x = static_cast<float>(spell.base[1]);
|
||||||
y = static_cast<float>(spell.base[0]);
|
y = static_cast<float>(spell.base[0]);
|
||||||
z = static_cast<float>(spell.base[2]);
|
z = static_cast<float>(spell.base[2]);
|
||||||
@ -872,7 +872,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
if(buffs[buffslot].ticsremaining > RuleI(Character, MaxFearDurationForPlayerCharacter))
|
if(buffs[buffslot].ticsremaining > RuleI(Character, MaxFearDurationForPlayerCharacter))
|
||||||
buffs[buffslot].ticsremaining = RuleI(Character, MaxFearDurationForPlayerCharacter);
|
buffs[buffslot].ticsremaining = RuleI(Character, MaxFearDurationForPlayerCharacter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(RuleB(Combat, EnableFearPathing)){
|
if(RuleB(Combat, EnableFearPathing)){
|
||||||
if(IsClient())
|
if(IsClient())
|
||||||
@ -921,7 +921,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
cd->source = action->source;
|
cd->source = action->source;
|
||||||
cd->type = action->type;
|
cd->type = action->type;
|
||||||
cd->spellid = action->spell;
|
cd->spellid = action->spell;
|
||||||
cd->sequence = action->sequence;
|
cd->meleepush_xy = action->sequence;
|
||||||
|
|
||||||
CastToClient()->QueuePacket(action_packet);
|
CastToClient()->QueuePacket(action_packet);
|
||||||
if(caster->IsClient() && caster != this)
|
if(caster->IsClient() && caster != this)
|
||||||
@ -970,7 +970,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
cd->source = action->source;
|
cd->source = action->source;
|
||||||
cd->type = action->type;
|
cd->type = action->type;
|
||||||
cd->spellid = action->spell;
|
cd->spellid = action->spell;
|
||||||
cd->sequence = action->sequence;
|
cd->meleepush_xy = action->sequence;
|
||||||
|
|
||||||
CastToClient()->QueuePacket(action_packet);
|
CastToClient()->QueuePacket(action_packet);
|
||||||
if(caster->IsClient() && caster != this)
|
if(caster->IsClient() && caster != this)
|
||||||
@ -1006,7 +1006,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
cd->source = action->source;
|
cd->source = action->source;
|
||||||
cd->type = action->type;
|
cd->type = action->type;
|
||||||
cd->spellid = action->spell;
|
cd->spellid = action->spell;
|
||||||
cd->sequence = action->sequence;
|
cd->meleepush_xy = action->sequence;
|
||||||
|
|
||||||
CastToClient()->QueuePacket(action_packet);
|
CastToClient()->QueuePacket(action_packet);
|
||||||
if(caster->IsClient() && caster != this)
|
if(caster->IsClient() && caster != this)
|
||||||
@ -1291,7 +1291,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
snprintf(effect_desc, _EDLEN, "Spell Absorb Rune: %+i", effect_value);
|
snprintf(effect_desc, _EDLEN, "Spell Absorb Rune: %+i", effect_value);
|
||||||
#endif
|
#endif
|
||||||
if(effect_value > 0)
|
if(effect_value > 0)
|
||||||
buffs[buffslot].magic_rune = effect_value;
|
buffs[buffslot].magic_rune = effect_value;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1329,12 +1329,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
|
|
||||||
case SE_DistanceRemoval:
|
case SE_DistanceRemoval:
|
||||||
{
|
{
|
||||||
buffs[buffslot].caston_x = int(GetX());
|
buffs[buffslot].caston_x = int(GetX());
|
||||||
buffs[buffslot].caston_y = int(GetY());
|
buffs[buffslot].caston_y = int(GetY());
|
||||||
buffs[buffslot].caston_z = int(GetZ());
|
buffs[buffslot].caston_z = int(GetZ());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SE_Levitate:
|
case SE_Levitate:
|
||||||
{
|
{
|
||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
@ -1349,13 +1349,13 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
case SE_DeathSave: {
|
case SE_DeathSave: {
|
||||||
|
|
||||||
int16 mod = 0;
|
int16 mod = 0;
|
||||||
|
|
||||||
if(caster) {
|
if(caster) {
|
||||||
mod = caster->aabonuses.UnfailingDivinity +
|
mod = caster->aabonuses.UnfailingDivinity +
|
||||||
caster->itembonuses.UnfailingDivinity +
|
caster->itembonuses.UnfailingDivinity +
|
||||||
caster->spellbonuses.UnfailingDivinity;
|
caster->spellbonuses.UnfailingDivinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffs[buffslot].ExtraDIChance = mod;
|
buffs[buffslot].ExtraDIChance = mod;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1440,7 +1440,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
|
|
||||||
for(int x = EmuConstants::MATERIAL_BEGIN; x <= EmuConstants::MATERIAL_TINT_END; x++)
|
for(int x = EmuConstants::MATERIAL_BEGIN; x <= EmuConstants::MATERIAL_TINT_END; x++)
|
||||||
SendWearChange(x);
|
SendWearChange(x);
|
||||||
|
|
||||||
if(caster && (caster->spellbonuses.IllusionPersistence || caster->aabonuses.IllusionPersistence
|
if(caster && (caster->spellbonuses.IllusionPersistence || caster->aabonuses.IllusionPersistence
|
||||||
|| caster->itembonuses.IllusionPersistence))
|
|| caster->itembonuses.IllusionPersistence))
|
||||||
buffs[buffslot].persistant_buff = 1;
|
buffs[buffslot].persistant_buff = 1;
|
||||||
@ -1555,8 +1555,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
{
|
{
|
||||||
uint16 pet_spellid = CastToNPC()->GetPetSpellID();
|
uint16 pet_spellid = CastToNPC()->GetPetSpellID();
|
||||||
uint16 pet_ActSpellCost = caster->GetActSpellCost(pet_spellid, spells[pet_spellid].mana);
|
uint16 pet_ActSpellCost = caster->GetActSpellCost(pet_spellid, spells[pet_spellid].mana);
|
||||||
int16 ImprovedReclaimMod = caster->spellbonuses.ImprovedReclaimEnergy +
|
int16 ImprovedReclaimMod = caster->spellbonuses.ImprovedReclaimEnergy +
|
||||||
caster->itembonuses.ImprovedReclaimEnergy +
|
caster->itembonuses.ImprovedReclaimEnergy +
|
||||||
caster->aabonuses.ImprovedReclaimEnergy;
|
caster->aabonuses.ImprovedReclaimEnergy;
|
||||||
|
|
||||||
if (!ImprovedReclaimMod)
|
if (!ImprovedReclaimMod)
|
||||||
@ -1666,9 +1666,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
// Only allow 2 size changes from Base Size
|
// Only allow 2 size changes from Base Size
|
||||||
float modifyAmount = (static_cast<float>(effect_value) / 100.0f);
|
float modifyAmount = (static_cast<float>(effect_value) / 100.0f);
|
||||||
float maxModAmount = GetBaseSize() * modifyAmount * modifyAmount;
|
float maxModAmount = GetBaseSize() * modifyAmount * modifyAmount;
|
||||||
if ((GetSize() <= GetBaseSize() && GetSize() > maxModAmount) ||
|
if ((GetSize() <= GetBaseSize() && GetSize() > maxModAmount) ||
|
||||||
(GetSize() >= GetBaseSize() && GetSize() < maxModAmount) ||
|
(GetSize() >= GetBaseSize() && GetSize() < maxModAmount) ||
|
||||||
(GetSize() <= GetBaseSize() && maxModAmount > 1.0f) ||
|
(GetSize() <= GetBaseSize() && maxModAmount > 1.0f) ||
|
||||||
(GetSize() >= GetBaseSize() && maxModAmount < 1.0f))
|
(GetSize() >= GetBaseSize() && maxModAmount < 1.0f))
|
||||||
{
|
{
|
||||||
ChangeSize(GetSize() * modifyAmount);
|
ChangeSize(GetSize() * modifyAmount);
|
||||||
@ -1684,7 +1684,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
rooted = true;
|
rooted = true;
|
||||||
|
|
||||||
if (caster){
|
if (caster){
|
||||||
buffs[buffslot].RootBreakChance = caster->aabonuses.RootBreakChance +
|
buffs[buffslot].RootBreakChance = caster->aabonuses.RootBreakChance +
|
||||||
caster->itembonuses.RootBreakChance +
|
caster->itembonuses.RootBreakChance +
|
||||||
caster->spellbonuses.RootBreakChance;
|
caster->spellbonuses.RootBreakChance;
|
||||||
}
|
}
|
||||||
@ -2249,7 +2249,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
float range = 0.0f;
|
float range = 0.0f;
|
||||||
if (spells[spell_id].base2[i])
|
if (spells[spell_id].base2[i])
|
||||||
range = (float)spells[spell_id].base[i];
|
range = (float)spells[spell_id].base[i];
|
||||||
|
|
||||||
entity_list.AETaunt(caster->CastToClient(), range);
|
entity_list.AETaunt(caster->CastToClient(), range);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2540,7 +2540,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
int mana_damage = 0;
|
int mana_damage = 0;
|
||||||
int32 mana_to_use = GetMana() - spell.base[i];
|
int32 mana_to_use = GetMana() - spell.base[i];
|
||||||
if(mana_to_use > -1) {
|
if(mana_to_use > -1) {
|
||||||
SetMana(GetMana() - spell.base[i]);
|
SetMana(GetMana() - spell.base[i]);
|
||||||
TryTriggerOnValueAmount(false, true);
|
TryTriggerOnValueAmount(false, true);
|
||||||
// we take full dmg(-10 to make the damage the right sign)
|
// we take full dmg(-10 to make the damage the right sign)
|
||||||
mana_damage = spell.base[i] / -10 * spell.base2[i];
|
mana_damage = spell.base[i] / -10 * spell.base2[i];
|
||||||
@ -2661,7 +2661,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
{
|
{
|
||||||
if (IsNPC()){
|
if (IsNPC()){
|
||||||
caster->Taunt(this->CastToNPC(), false, static_cast<float>(spell.base[i]));
|
caster->Taunt(this->CastToNPC(), false, static_cast<float>(spell.base[i]));
|
||||||
|
|
||||||
if (spell.base2[i] > 0)
|
if (spell.base2[i] > 0)
|
||||||
CastToNPC()->SetHateAmountOnEnt(caster, (CastToNPC()->GetHateAmount(caster) + spell.base2[i]));
|
CastToNPC()->SetHateAmountOnEnt(caster, (CastToNPC()->GetHateAmount(caster) + spell.base2[i]));
|
||||||
}
|
}
|
||||||
@ -2972,7 +2972,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
case SE_TriggerOnReqTarget:
|
case SE_TriggerOnReqTarget:
|
||||||
case SE_LimitRace:
|
case SE_LimitRace:
|
||||||
case SE_FcLimitUse:
|
case SE_FcLimitUse:
|
||||||
case SE_FcMute:
|
case SE_FcMute:
|
||||||
case SE_LimitUseType:
|
case SE_LimitUseType:
|
||||||
case SE_FcStunTimeMod:
|
case SE_FcStunTimeMod:
|
||||||
case SE_StunBashChance:
|
case SE_StunBashChance:
|
||||||
@ -2981,9 +2981,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
case SE_LimitCastTimeMax:
|
case SE_LimitCastTimeMax:
|
||||||
case SE_TriggerOnReqCaster:
|
case SE_TriggerOnReqCaster:
|
||||||
case SE_FrenziedDevastation:
|
case SE_FrenziedDevastation:
|
||||||
case SE_AStacker:
|
case SE_AStacker:
|
||||||
case SE_BStacker:
|
case SE_BStacker:
|
||||||
case SE_CStacker:
|
case SE_CStacker:
|
||||||
case SE_DStacker:
|
case SE_DStacker:
|
||||||
case SE_DoubleRiposte:
|
case SE_DoubleRiposte:
|
||||||
case SE_Berserk:
|
case SE_Berserk:
|
||||||
@ -3473,7 +3473,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
|
|||||||
effect_value = CalcSpellEffectValue(spell_id, i, caster_level, caster, ticsremaining);
|
effect_value = CalcSpellEffectValue(spell_id, i, caster_level, caster, ticsremaining);
|
||||||
//Handle client cast DOTs here.
|
//Handle client cast DOTs here.
|
||||||
if (caster && effect_value < 0){
|
if (caster && effect_value < 0){
|
||||||
|
|
||||||
if (IsDetrimentalSpell(spell_id)){
|
if (IsDetrimentalSpell(spell_id)){
|
||||||
if (caster->IsClient()){
|
if (caster->IsClient()){
|
||||||
if (!caster->CastToClient()->GetFeigned())
|
if (!caster->CastToClient()->GetFeigned())
|
||||||
@ -3715,7 +3715,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
|
|||||||
{
|
{
|
||||||
if (spellbonuses.DistanceRemoval){
|
if (spellbonuses.DistanceRemoval){
|
||||||
|
|
||||||
int distance = ((int(GetX()) - buffs[slot].caston_x) * (int(GetX()) - buffs[slot].caston_x)) +
|
int distance = ((int(GetX()) - buffs[slot].caston_x) * (int(GetX()) - buffs[slot].caston_x)) +
|
||||||
((int(GetY()) - buffs[slot].caston_y) * (int(GetY()) - buffs[slot].caston_y)) +
|
((int(GetY()) - buffs[slot].caston_y) * (int(GetY()) - buffs[slot].caston_y)) +
|
||||||
((int(GetZ()) - buffs[slot].caston_z) * (int(GetZ()) - buffs[slot].caston_z));
|
((int(GetZ()) - buffs[slot].caston_z) * (int(GetZ()) - buffs[slot].caston_z));
|
||||||
|
|
||||||
@ -3729,12 +3729,12 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SE_AddHateOverTimePct:
|
case SE_AddHateOverTimePct:
|
||||||
{
|
{
|
||||||
if (IsNPC()){
|
if (IsNPC()){
|
||||||
uint32 new_hate = CastToNPC()->GetHateAmount(caster) * (100 + spell.base[i]) / 100;
|
uint32 new_hate = CastToNPC()->GetHateAmount(caster) * (100 + spell.base[i]) / 100;
|
||||||
if (new_hate <= 0)
|
if (new_hate <= 0)
|
||||||
new_hate = 1;
|
new_hate = 1;
|
||||||
|
|
||||||
CastToNPC()->SetHateAmountOnEnt(caster, new_hate);
|
CastToNPC()->SetHateAmountOnEnt(caster, new_hate);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4136,9 +4136,9 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
|||||||
|
|
||||||
uint32 buff_max = GetMaxTotalSlots();
|
uint32 buff_max = GetMaxTotalSlots();
|
||||||
bool found_numhits = false;
|
bool found_numhits = false;
|
||||||
|
|
||||||
for(uint32 d = 0; d < buff_max; d++) {
|
for(uint32 d = 0; d < buff_max; d++) {
|
||||||
|
|
||||||
if(IsValidSpell(buffs[d].spellid) && (buffs[d].numhits > 0)) {
|
if(IsValidSpell(buffs[d].spellid) && (buffs[d].numhits > 0)) {
|
||||||
Numhits(true);
|
Numhits(true);
|
||||||
found_numhits = true;
|
found_numhits = true;
|
||||||
@ -4148,7 +4148,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
|||||||
if (!found_numhits)
|
if (!found_numhits)
|
||||||
Numhits(false);
|
Numhits(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spells[buffs[slot].spellid].NimbusEffect > 0)
|
if (spells[buffs[slot].spellid].NimbusEffect > 0)
|
||||||
RemoveNimbusEffect(spells[buffs[slot].spellid].NimbusEffect);
|
RemoveNimbusEffect(spells[buffs[slot].spellid].NimbusEffect);
|
||||||
|
|
||||||
@ -4204,15 +4204,15 @@ int32 Client::GetAAEffectDataBySlot(uint32 aa_ID, uint32 slot_id, bool GetEffect
|
|||||||
base1 = iter->second.base1;
|
base1 = iter->second.base1;
|
||||||
base2 = iter->second.base2;
|
base2 = iter->second.base2;
|
||||||
slot = iter->second.slot;
|
slot = iter->second.slot;
|
||||||
|
|
||||||
if (slot && slot == slot_id) {
|
if (slot && slot == slot_id) {
|
||||||
|
|
||||||
if (GetEffect)
|
if (GetEffect)
|
||||||
return effect;
|
return effect;
|
||||||
|
|
||||||
if (GetBase1)
|
if (GetBase1)
|
||||||
return base1;
|
return base1;
|
||||||
|
|
||||||
if (GetBase2)
|
if (GetBase2)
|
||||||
return base2;
|
return base2;
|
||||||
}
|
}
|
||||||
@ -4236,7 +4236,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
uint32 slot = 0;
|
uint32 slot = 0;
|
||||||
|
|
||||||
bool LimitFailure = false;
|
bool LimitFailure = false;
|
||||||
bool LimitInclude[MaxLimitInclude] = { false };
|
bool LimitInclude[MaxLimitInclude] = { false };
|
||||||
/* Certain limits require only one of several Include conditions to be true. Ie. Add damage to fire OR ice spells.
|
/* Certain limits require only one of several Include conditions to be true. Ie. Add damage to fire OR ice spells.
|
||||||
0/1 SE_LimitResist
|
0/1 SE_LimitResist
|
||||||
2/3 SE_LimitSpell
|
2/3 SE_LimitSpell
|
||||||
@ -4247,7 +4247,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
12/13 SE_LimitSpellClass:
|
12/13 SE_LimitSpellClass:
|
||||||
14/15 SE_LimitSpellSubClass:
|
14/15 SE_LimitSpellSubClass:
|
||||||
Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes
|
Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes
|
||||||
*/
|
*/
|
||||||
int FocusCount = 0;
|
int FocusCount = 0;
|
||||||
|
|
||||||
std::map<uint32, std::map<uint32, AA_Ability> >::const_iterator find_iter = aa_effects.find(aa_ID);
|
std::map<uint32, std::map<uint32, AA_Ability> >::const_iterator find_iter = aa_effects.find(aa_ID);
|
||||||
@ -4262,7 +4262,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
base1 = iter->second.base1;
|
base1 = iter->second.base1;
|
||||||
base2 = iter->second.base2;
|
base2 = iter->second.base2;
|
||||||
slot = iter->second.slot;
|
slot = iter->second.slot;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AA Foci's can contain multiple focus effects within the same AA.
|
AA Foci's can contain multiple focus effects within the same AA.
|
||||||
To handle this we will not automatically return zero if a limit is found.
|
To handle this we will not automatically return zero if a limit is found.
|
||||||
@ -4283,7 +4283,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if (LimitFailure){
|
if (LimitFailure){
|
||||||
value = 0;
|
value = 0;
|
||||||
LimitFailure = false;
|
LimitFailure = false;
|
||||||
|
|
||||||
for(int e = 0; e < MaxLimitInclude; e++) {
|
for(int e = 0; e < MaxLimitInclude; e++) {
|
||||||
LimitInclude[e] = false; //Reset array
|
LimitInclude[e] = false; //Reset array
|
||||||
}
|
}
|
||||||
@ -4322,7 +4322,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitMaxLevel:
|
case SE_LimitMaxLevel:
|
||||||
spell_level = spell.classes[(GetClass()%16) - 1];
|
spell_level = spell.classes[(GetClass()%16) - 1];
|
||||||
lvldiff = spell_level - base1;
|
lvldiff = spell_level - base1;
|
||||||
@ -4333,7 +4333,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if(lvlModifier < 1)
|
if(lvlModifier < 1)
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4357,7 +4357,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if(base1 < 0) { //Exclude
|
if(base1 < 0) { //Exclude
|
||||||
if (spell_id == -base1)
|
if (spell_id == -base1)
|
||||||
LimitFailure = true;
|
LimitFailure = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LimitInclude[2] = true;
|
LimitInclude[2] = true;
|
||||||
if (spell_id == base1) //Include
|
if (spell_id == base1) //Include
|
||||||
@ -4450,7 +4450,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if(base1 < 0) { //Exclude
|
if(base1 < 0) { //Exclude
|
||||||
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellClass))
|
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellClass))
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LimitInclude[12] = true;
|
LimitInclude[12] = true;
|
||||||
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellClass)) //Include
|
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellClass)) //Include
|
||||||
@ -4462,7 +4462,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if(base1 < 0) { //Exclude
|
if(base1 < 0) { //Exclude
|
||||||
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellSubclass))
|
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellSubclass))
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LimitInclude[14] = true;
|
LimitInclude[14] = true;
|
||||||
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellSubclass)) //Include
|
if (CheckSpellCategory(spell_id, base1, SE_LimitSpellSubclass)) //Include
|
||||||
@ -4599,7 +4599,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
|
|
||||||
//Note if using these as AA, make sure this is first focus used.
|
//Note if using these as AA, make sure this is first focus used.
|
||||||
case SE_SympatheticProc:
|
case SE_SympatheticProc:
|
||||||
if(type == focusSympatheticProc)
|
if(type == focusSympatheticProc)
|
||||||
value = base2;
|
value = base2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4657,12 +4657,12 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
if(type == focusIncreaseNumHits)
|
if(type == focusIncreaseNumHits)
|
||||||
value = base1;
|
value = base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_FcLimitUse:
|
case SE_FcLimitUse:
|
||||||
if(type == focusFcLimitUse)
|
if(type == focusFcLimitUse)
|
||||||
value = base1;
|
value = base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_FcMute:
|
case SE_FcMute:
|
||||||
if(type == focusFcMute)
|
if(type == focusFcMute)
|
||||||
value = base1;
|
value = base1;
|
||||||
@ -4683,7 +4683,7 @@ int16 Client::CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id)
|
|||||||
|
|
||||||
if (LimitFailure)
|
if (LimitFailure)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return(value*lvlModifier/100);
|
return(value*lvlModifier/100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4694,7 +4694,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if(!IsValidSpell(focus_id) || !IsValidSpell(spell_id))
|
if(!IsValidSpell(focus_id) || !IsValidSpell(spell_id))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
const SPDat_Spell_Struct &focus_spell = spells[focus_id];
|
const SPDat_Spell_Struct &focus_spell = spells[focus_id];
|
||||||
const SPDat_Spell_Struct &spell = spells[spell_id];
|
const SPDat_Spell_Struct &spell = spells[spell_id];
|
||||||
|
|
||||||
@ -4704,7 +4704,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
int lvldiff = 0;
|
int lvldiff = 0;
|
||||||
uint32 Caston_spell_id = 0;
|
uint32 Caston_spell_id = 0;
|
||||||
|
|
||||||
bool LimitInclude[MaxLimitInclude] = { false };
|
bool LimitInclude[MaxLimitInclude] = { false };
|
||||||
/* Certain limits require only one of several Include conditions to be true. Ie. Add damage to fire OR ice spells.
|
/* Certain limits require only one of several Include conditions to be true. Ie. Add damage to fire OR ice spells.
|
||||||
0/1 SE_LimitResist
|
0/1 SE_LimitResist
|
||||||
2/3 SE_LimitSpell
|
2/3 SE_LimitSpell
|
||||||
@ -4715,15 +4715,15 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
12/13 SE_LimitSpellClass:
|
12/13 SE_LimitSpellClass:
|
||||||
14/15 SE_LimitSpellSubClass:
|
14/15 SE_LimitSpellSubClass:
|
||||||
Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes
|
Remember: Update MaxLimitInclude in spdat.h if adding new limits that require Includes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||||
|
|
||||||
switch (focus_spell.effectid[i]) {
|
switch (focus_spell.effectid[i]) {
|
||||||
|
|
||||||
case SE_Blank:
|
case SE_Blank:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitResist:
|
case SE_LimitResist:
|
||||||
if(focus_spell.base[i] < 0){
|
if(focus_spell.base[i] < 0){
|
||||||
if (spell.resisttype == -focus_spell.base[i]) //Exclude
|
if (spell.resisttype == -focus_spell.base[i]) //Exclude
|
||||||
@ -4735,7 +4735,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
LimitInclude[1] = true;
|
LimitInclude[1] = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitInstant:
|
case SE_LimitInstant:
|
||||||
if(focus_spell.base[i] == 1 && spell.buffduration) //Fail if not instant
|
if(focus_spell.base[i] == 1 && spell.buffduration) //Fail if not instant
|
||||||
return 0;
|
return 0;
|
||||||
@ -4760,7 +4760,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitMinLevel:
|
case SE_LimitMinLevel:
|
||||||
if (IsNPC())
|
if (IsNPC())
|
||||||
break;
|
break;
|
||||||
@ -4777,12 +4777,12 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (spells[spell_id].cast_time > (uint16)focus_spell.base[i])
|
if (spells[spell_id].cast_time > (uint16)focus_spell.base[i])
|
||||||
return(0);
|
return(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitSpell:
|
case SE_LimitSpell:
|
||||||
if(focus_spell.base[i] < 0) { //Exclude
|
if(focus_spell.base[i] < 0) { //Exclude
|
||||||
if (spell_id == -focus_spell.base[i])
|
if (spell_id == -focus_spell.base[i])
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LimitInclude[2] = true;
|
LimitInclude[2] = true;
|
||||||
if (spell_id == focus_spell.base[i]) //Include
|
if (spell_id == focus_spell.base[i]) //Include
|
||||||
@ -4871,7 +4871,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
LimitInclude[11] = true;
|
LimitInclude[11] = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_LimitClass:
|
case SE_LimitClass:
|
||||||
//Do not use this limit more then once per spell. If multiple class, treat value like items would.
|
//Do not use this limit more then once per spell. If multiple class, treat value like items would.
|
||||||
if (!PassLimitClass(focus_spell.base[i], GetClass()))
|
if (!PassLimitClass(focus_spell.base[i], GetClass()))
|
||||||
@ -4989,7 +4989,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
if (type == focusSpellHaste && focus_spell.base[i] > value)
|
if (type == focusSpellHaste && focus_spell.base[i] > value)
|
||||||
value = focus_spell.base[i];
|
value = focus_spell.base[i];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_IncreaseSpellDuration:
|
case SE_IncreaseSpellDuration:
|
||||||
if (type == focusSpellDuration && focus_spell.base[i] > value)
|
if (type == focusSpellDuration && focus_spell.base[i] > value)
|
||||||
value = focus_spell.base[i];
|
value = focus_spell.base[i];
|
||||||
@ -5161,14 +5161,14 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
Log.Out(Logs::General, Logs::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
|
Log.Out(Logs::General, Logs::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int e = 0; e < MaxLimitInclude; e+=2) {
|
for(int e = 0; e < MaxLimitInclude; e+=2) {
|
||||||
if (LimitInclude[e] && !LimitInclude[e+1])
|
if (LimitInclude[e] && !LimitInclude[e+1])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Caston_spell_id){
|
if (Caston_spell_id){
|
||||||
if(IsValidSpell(Caston_spell_id) && (Caston_spell_id != spell_id))
|
if(IsValidSpell(Caston_spell_id) && (Caston_spell_id != spell_id))
|
||||||
SpellFinished(Caston_spell_id, this, 10, 0, -1, spells[Caston_spell_id].ResistDiff);
|
SpellFinished(Caston_spell_id, this, 10, 0, -1, spells[Caston_spell_id].ResistDiff);
|
||||||
@ -5260,7 +5260,7 @@ uint16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Note: At present, ff designing custom AA to have a sympathetic proc effect, only use one focus
|
/*Note: At present, ff designing custom AA to have a sympathetic proc effect, only use one focus
|
||||||
effect within the aa_effects data for each AA*[No live AA's use this effect to my knowledge]*/
|
effect within the aa_effects data for each AA*[No live AA's use this effect to my knowledge]*/
|
||||||
if (aabonuses.FocusEffects[type]){
|
if (aabonuses.FocusEffects[type]){
|
||||||
|
|
||||||
@ -5557,10 +5557,10 @@ int16 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
|
|||||||
//item focus
|
//item focus
|
||||||
for(int i = 0; i < EmuConstants::EQUIPMENT_SIZE; i++){
|
for(int i = 0; i < EmuConstants::EQUIPMENT_SIZE; i++){
|
||||||
const Item_Struct *cur = database.GetItem(equipment[i]);
|
const Item_Struct *cur = database.GetItem(equipment[i]);
|
||||||
|
|
||||||
if(!cur)
|
if(!cur)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
TempItem = cur;
|
TempItem = cur;
|
||||||
|
|
||||||
if (TempItem && TempItem->Focus.Effect > 0 && TempItem->Focus.Effect != SPELL_UNKNOWN) {
|
if (TempItem && TempItem->Focus.Effect > 0 && TempItem->Focus.Effect != SPELL_UNKNOWN) {
|
||||||
@ -5590,7 +5590,7 @@ int16 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UsedItem && rand_effectiveness && focus_max_real != 0)
|
if(UsedItem && rand_effectiveness && focus_max_real != 0)
|
||||||
realTotal = CalcFocusEffect(type, UsedFocusID, spell_id);
|
realTotal = CalcFocusEffect(type, UsedFocusID, spell_id);
|
||||||
}
|
}
|
||||||
@ -5909,21 +5909,21 @@ float Mob::GetSympatheticProcChances(uint16 spell_id, int16 ProcRateMod, int32 I
|
|||||||
int32 total_cast_time = 0;
|
int32 total_cast_time = 0;
|
||||||
float cast_time_mod = 0.0f;
|
float cast_time_mod = 0.0f;
|
||||||
ProcRateMod -= 100;
|
ProcRateMod -= 100;
|
||||||
|
|
||||||
|
|
||||||
if (spells[spell_id].recast_time >= spells[spell_id].recovery_time)
|
if (spells[spell_id].recast_time >= spells[spell_id].recovery_time)
|
||||||
total_cast_time = spells[spell_id].recast_time + spells[spell_id].cast_time;
|
total_cast_time = spells[spell_id].recast_time + spells[spell_id].cast_time;
|
||||||
else
|
else
|
||||||
total_cast_time = spells[spell_id].recovery_time + spells[spell_id].cast_time;
|
total_cast_time = spells[spell_id].recovery_time + spells[spell_id].cast_time;
|
||||||
|
|
||||||
if (total_cast_time > 0 && total_cast_time <= 2500)
|
|
||||||
cast_time_mod = 0.25f;
|
|
||||||
else if (total_cast_time > 2500 && total_cast_time < 7000)
|
|
||||||
cast_time_mod = 0.167f*((static_cast<float>(total_cast_time) - 1000.0f)/1000.0f);
|
|
||||||
else
|
|
||||||
cast_time_mod = static_cast<float>(total_cast_time) / 7000.0f;
|
|
||||||
|
|
||||||
ProcChance = (RuleR(Casting, AvgSpellProcsPerMinute)/100.0f) * (static_cast<float>(100.0f + ProcRateMod) / 10.0f)
|
if (total_cast_time > 0 && total_cast_time <= 2500)
|
||||||
|
cast_time_mod = 0.25f;
|
||||||
|
else if (total_cast_time > 2500 && total_cast_time < 7000)
|
||||||
|
cast_time_mod = 0.167f*((static_cast<float>(total_cast_time) - 1000.0f)/1000.0f);
|
||||||
|
else
|
||||||
|
cast_time_mod = static_cast<float>(total_cast_time) / 7000.0f;
|
||||||
|
|
||||||
|
ProcChance = (RuleR(Casting, AvgSpellProcsPerMinute)/100.0f) * (static_cast<float>(100.0f + ProcRateMod) / 10.0f)
|
||||||
* cast_time_mod * (static_cast<float>(100.0f + ItemProcRate)/100.0f);
|
* cast_time_mod * (static_cast<float>(100.0f + ItemProcRate)/100.0f);
|
||||||
|
|
||||||
return ProcChance;
|
return ProcChance;
|
||||||
@ -6063,7 +6063,7 @@ int32 Mob::GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spel
|
|||||||
CheckNumHitsRemaining(NumHit::MatchingSpells, tmp_buffslot);
|
CheckNumHitsRemaining(NumHit::MatchingSpells, tmp_buffslot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6147,8 +6147,8 @@ uint16 Mob::GetSpellEffectResistChance(uint16 spell_id)
|
|||||||
|
|
||||||
bool Mob::TryDispel(uint8 caster_level, uint8 buff_level, int level_modifier){
|
bool Mob::TryDispel(uint8 caster_level, uint8 buff_level, int level_modifier){
|
||||||
|
|
||||||
/*Live 5-20-14 Patch Note: Updated all spells which use Remove Detrimental and
|
/*Live 5-20-14 Patch Note: Updated all spells which use Remove Detrimental and
|
||||||
Cancel Beneficial spell effects to use a new method. The chances for those spells to
|
Cancel Beneficial spell effects to use a new method. The chances for those spells to
|
||||||
affect their targets have not changed unless otherwise noted.*/
|
affect their targets have not changed unless otherwise noted.*/
|
||||||
|
|
||||||
/*This should provide a somewhat accurate conversion between pre 5/14 base values and post.
|
/*This should provide a somewhat accurate conversion between pre 5/14 base values and post.
|
||||||
@ -6160,7 +6160,7 @@ bool Mob::TryDispel(uint8 caster_level, uint8 buff_level, int level_modifier){
|
|||||||
//Effect value of dispels are treated as a level modifier.
|
//Effect value of dispels are treated as a level modifier.
|
||||||
//Values for scaling were obtain from live parses, best estimates.
|
//Values for scaling were obtain from live parses, best estimates.
|
||||||
|
|
||||||
caster_level += level_modifier - 1;
|
caster_level += level_modifier - 1;
|
||||||
int dispel_chance = 32; //Baseline chance if no level difference and no modifier
|
int dispel_chance = 32; //Baseline chance if no level difference and no modifier
|
||||||
int level_diff = caster_level - buff_level;
|
int level_diff = caster_level - buff_level;
|
||||||
|
|
||||||
@ -6201,7 +6201,7 @@ bool Mob::ImprovedTaunt(){
|
|||||||
else {
|
else {
|
||||||
if(!TryFadeEffect(spellbonuses.ImprovedTaunt[2]))
|
if(!TryFadeEffect(spellbonuses.ImprovedTaunt[2]))
|
||||||
BuffFadeBySlot(spellbonuses.ImprovedTaunt[2], true); //If caster killed removed effect.
|
BuffFadeBySlot(spellbonuses.ImprovedTaunt[2], true); //If caster killed removed effect.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6267,7 +6267,7 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
|||||||
Range 845 - 847 : UNKNOWN
|
Range 845 - 847 : UNKNOWN
|
||||||
Range 10000 - 11000 : Limit to Race [base2 - 10000 = Race] (*Not on live: Too useful a function to not implement)
|
Range 10000 - 11000 : Limit to Race [base2 - 10000 = Race] (*Not on live: Too useful a function to not implement)
|
||||||
THIS IS A WORK IN PROGRESS
|
THIS IS A WORK IN PROGRESS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (value <= 0)
|
if (value <= 0)
|
||||||
return true;
|
return true;
|
||||||
@ -6276,174 +6276,174 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
|||||||
|
|
||||||
switch(value)
|
switch(value)
|
||||||
{
|
{
|
||||||
case 100:
|
case 100:
|
||||||
if ((GetBodyType() == BT_Animal) || (GetBodyType() == BT_Humanoid))
|
if ((GetBodyType() == BT_Animal) || (GetBodyType() == BT_Humanoid))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 101:
|
case 101:
|
||||||
if (GetBodyType() == BT_Dragon || GetBodyType() == BT_VeliousDragon || GetBodyType() == BT_Dragon3)
|
if (GetBodyType() == BT_Dragon || GetBodyType() == BT_VeliousDragon || GetBodyType() == BT_Dragon3)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 102:
|
case 102:
|
||||||
if ((GetBodyType() == BT_Animal) || (GetBodyType() == BT_Insect))
|
if ((GetBodyType() == BT_Animal) || (GetBodyType() == BT_Insect))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 104:
|
case 104:
|
||||||
if (GetBodyType() == BT_Animal)
|
if (GetBodyType() == BT_Animal)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 105:
|
case 105:
|
||||||
if (GetBodyType() == BT_Plant)
|
if (GetBodyType() == BT_Plant)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 106:
|
case 106:
|
||||||
if (GetBodyType() == BT_Giant)
|
if (GetBodyType() == BT_Giant)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 108:
|
case 108:
|
||||||
if ((GetBodyType() != BT_Animal) || (GetBodyType() != BT_Humanoid))
|
if ((GetBodyType() != BT_Animal) || (GetBodyType() != BT_Humanoid))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 109:
|
case 109:
|
||||||
if ((GetRace() == 520) ||(GetRace() == 79))
|
if ((GetRace() == 520) ||(GetRace() == 79))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 111:
|
case 111:
|
||||||
if ((GetRace() == 527) ||(GetRace() == 11))
|
if ((GetRace() == 527) ||(GetRace() == 11))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 112:
|
case 112:
|
||||||
if ((GetRace() == 456) ||(GetRace() == 28))
|
if ((GetRace() == 456) ||(GetRace() == 28))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 113:
|
case 113:
|
||||||
if ((GetRace() == 456) ||(GetRace() == 48))
|
if ((GetRace() == 456) ||(GetRace() == 48))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 114:
|
case 114:
|
||||||
if (GetRace() == 526)
|
if (GetRace() == 526)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 115:
|
case 115:
|
||||||
if (GetRace() == 522)
|
if (GetRace() == 522)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 117:
|
case 117:
|
||||||
if ((GetBodyType() == BT_Animal) || (GetBodyType() == BT_Plant))
|
if ((GetBodyType() == BT_Animal) || (GetBodyType() == BT_Plant))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 118:
|
case 118:
|
||||||
if (GetBodyType() == BT_Summoned)
|
if (GetBodyType() == BT_Summoned)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 119:
|
case 119:
|
||||||
if (IsPet() && ((GetRace() == 212) || ((GetRace() == 75) && GetTexture() == 1)))
|
if (IsPet() && ((GetRace() == 212) || ((GetRace() == 75) && GetTexture() == 1)))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 120:
|
case 120:
|
||||||
if (GetBodyType() == BT_Undead)
|
if (GetBodyType() == BT_Undead)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 121:
|
case 121:
|
||||||
if (GetBodyType() != BT_Undead)
|
if (GetBodyType() != BT_Undead)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 122:
|
case 122:
|
||||||
if ((GetRace() == 473) || (GetRace() == 425))
|
if ((GetRace() == 473) || (GetRace() == 425))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 123:
|
case 123:
|
||||||
if (GetBodyType() == BT_Humanoid)
|
if (GetBodyType() == BT_Humanoid)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 124:
|
case 124:
|
||||||
if ((GetBodyType() == BT_Undead) && (GetHPRatio() < 10))
|
if ((GetBodyType() == BT_Undead) && (GetHPRatio() < 10))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 125:
|
case 125:
|
||||||
if ((GetRace() == 457 || GetRace() == 88) && (GetHPRatio() < 10))
|
if ((GetRace() == 457 || GetRace() == 88) && (GetHPRatio() < 10))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 126:
|
case 126:
|
||||||
if ((GetRace() == 581 || GetRace() == 69) && (GetHPRatio() < 10))
|
if ((GetRace() == 581 || GetRace() == 69) && (GetHPRatio() < 10))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 201:
|
case 201:
|
||||||
if (GetHPRatio() > 75)
|
if (GetHPRatio() > 75)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 204:
|
case 204:
|
||||||
if (GetHPRatio() < 20)
|
if (GetHPRatio() < 20)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 216:
|
case 216:
|
||||||
if (!IsEngaged())
|
if (!IsEngaged())
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 250:
|
case 250:
|
||||||
if (GetHPRatio() < 35)
|
if (GetHPRatio() < 35)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 304:
|
case 304:
|
||||||
if (IsClient() &&
|
if (IsClient() &&
|
||||||
((GetClass() == WARRIOR) || (GetClass() == BARD) || (GetClass() == SHADOWKNIGHT) || (GetClass() == PALADIN) || (GetClass() == CLERIC)
|
((GetClass() == WARRIOR) || (GetClass() == BARD) || (GetClass() == SHADOWKNIGHT) || (GetClass() == PALADIN) || (GetClass() == CLERIC)
|
||||||
|| (GetClass() == RANGER) || (GetClass() == SHAMAN) || (GetClass() == ROGUE) || (GetClass() == BERSERKER)))
|
|| (GetClass() == RANGER) || (GetClass() == SHAMAN) || (GetClass() == ROGUE) || (GetClass() == BERSERKER)))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 701:
|
case 701:
|
||||||
if (!IsPet())
|
if (!IsPet())
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 818:
|
case 818:
|
||||||
if (GetBodyType() == BT_Undead)
|
if (GetBodyType() == BT_Undead)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 819:
|
case 819:
|
||||||
if (GetBodyType() != BT_Undead)
|
if (GetBodyType() != BT_Undead)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 842:
|
case 842:
|
||||||
if (GetBodyType() == BT_Humanoid && GetLevel() <= 84)
|
if (GetBodyType() == BT_Humanoid && GetLevel() <= 84)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 843:
|
case 843:
|
||||||
if (GetBodyType() == BT_Humanoid && GetLevel() <= 86)
|
if (GetBodyType() == BT_Humanoid && GetLevel() <= 86)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 844:
|
case 844:
|
||||||
if (GetBodyType() == BT_Humanoid && GetLevel() <= 88)
|
if (GetBodyType() == BT_Humanoid && GetLevel() <= 88)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
@ -6452,7 +6452,7 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
|||||||
//Limit to amount of pets
|
//Limit to amount of pets
|
||||||
if (value >= 221 && value <= 249){
|
if (value >= 221 && value <= 249){
|
||||||
int count = hate_list.GetSummonedPetCountOnHateList(this);
|
int count = hate_list.GetSummonedPetCountOnHateList(this);
|
||||||
|
|
||||||
for (int base2_value = 221; base2_value <= 249; ++base2_value){
|
for (int base2_value = 221; base2_value <= 249; ++base2_value){
|
||||||
if (value == base2_value){
|
if (value == base2_value){
|
||||||
if (count >= (base2_value - 220)){
|
if (count >= (base2_value - 220)){
|
||||||
@ -6476,12 +6476,12 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
|||||||
} //End Damage
|
} //End Damage
|
||||||
|
|
||||||
if (!IsDamage || UseCastRestriction) {
|
if (!IsDamage || UseCastRestriction) {
|
||||||
|
|
||||||
//Heal only if HP within specified range. [Doesn't follow a set forumla for all values...]
|
//Heal only if HP within specified range. [Doesn't follow a set forumla for all values...]
|
||||||
if (value >= 400 && value <= 408){
|
if (value >= 400 && value <= 408){
|
||||||
for (int base2_value = 400; base2_value <= 408; ++base2_value){
|
for (int base2_value = 400; base2_value <= 408; ++base2_value){
|
||||||
if (value == base2_value){
|
if (value == base2_value){
|
||||||
|
|
||||||
if (value == 400 && GetHPRatio() <= 25)
|
if (value == 400 && GetHPRatio() <= 25)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -6492,11 +6492,11 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (value >= 500 && value <= 549){
|
else if (value >= 500 && value <= 549){
|
||||||
for (int base2_value = 500; base2_value <= 520; ++base2_value){
|
for (int base2_value = 500; base2_value <= 520; ++base2_value){
|
||||||
if (value == base2_value){
|
if (value == base2_value){
|
||||||
if (GetHPRatio() < (base2_value - 500)*5)
|
if (GetHPRatio() < (base2_value - 500)*5)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6507,8 +6507,8 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // End Heal
|
} // End Heal
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6521,18 +6521,18 @@ bool Mob::TrySpellProjectile(Mob* spell_target, uint16 spell_id, float speed){
|
|||||||
and you lose your mana. If there is LOS the bolt will lock onto your target and the damage is applied when it hits the target.
|
and you lose your mana. If there is LOS the bolt will lock onto your target and the damage is applied when it hits the target.
|
||||||
-If your target moves the bolt moves with it in any direction or angle (consistent with other projectiles).
|
-If your target moves the bolt moves with it in any direction or angle (consistent with other projectiles).
|
||||||
-The way this is written once a bolt is cast a the distance from the initial cast to the target repeatedly
|
-The way this is written once a bolt is cast a the distance from the initial cast to the target repeatedly
|
||||||
check and if target is moving recalculates at what predicted time the bolt should hit that target in client_process
|
check and if target is moving recalculates at what predicted time the bolt should hit that target in client_process
|
||||||
When bolt hits its predicted point the damage is then done to target.
|
When bolt hits its predicted point the damage is then done to target.
|
||||||
Note: Projectile speed of 1 takes 3 seconds to go 100 distance units. Calculations are based on this constant.
|
Note: Projectile speed of 1 takes 3 seconds to go 100 distance units. Calculations are based on this constant.
|
||||||
Live Bolt speed: Projectile speed of X takes 5 seconds to go 300 distance units.
|
Live Bolt speed: Projectile speed of X takes 5 seconds to go 300 distance units.
|
||||||
Pending Implementation: What this code can not do is prevent damage if the bolt hits a barrier after passing the initial LOS check
|
Pending Implementation: What this code can not do is prevent damage if the bolt hits a barrier after passing the initial LOS check
|
||||||
because the target has moved while the bolt is in motion. (it is rare to actual get this to occur on live in normal game play)
|
because the target has moved while the bolt is in motion. (it is rare to actual get this to occur on live in normal game play)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!spell_target)
|
if (!spell_target)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint8 anim = spells[spell_id].CastingAnim;
|
uint8 anim = spells[spell_id].CastingAnim;
|
||||||
int slot = -1;
|
int slot = -1;
|
||||||
|
|
||||||
//Make sure there is an avialable bolt to be cast.
|
//Make sure there is an avialable bolt to be cast.
|
||||||
@ -6545,9 +6545,9 @@ bool Mob::TrySpellProjectile(Mob* spell_target, uint16 spell_id, float speed){
|
|||||||
|
|
||||||
if (slot < 0)
|
if (slot < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (CheckLosFN(spell_target)) {
|
if (CheckLosFN(spell_target)) {
|
||||||
|
|
||||||
float speed_mod = speed * 0.45f; //Constant for adjusting speeds to match calculated impact time.
|
float speed_mod = speed * 0.45f; //Constant for adjusting speeds to match calculated impact time.
|
||||||
float distance = spell_target->CalculateDistance(GetX(), GetY(), GetZ());
|
float distance = spell_target->CalculateDistance(GetX(), GetY(), GetZ());
|
||||||
float hit = 60.0f + (distance / speed_mod);
|
float hit = 60.0f + (distance / speed_mod);
|
||||||
@ -6570,18 +6570,18 @@ bool Mob::TrySpellProjectile(Mob* spell_target, uint16 spell_id, float speed){
|
|||||||
ProjectileAnimation(spell_target,0, false, speed,0,0,0, spells[spell_id].player_1);
|
ProjectileAnimation(spell_target,0, false, speed,0,0,0, spells[spell_id].player_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//This allows limited support for server using older spell files that do not contain data for bolt graphics.
|
//This allows limited support for server using older spell files that do not contain data for bolt graphics.
|
||||||
else {
|
else {
|
||||||
//Only use fire graphic for fire spells.
|
//Only use fire graphic for fire spells.
|
||||||
if (spells[spell_id].resisttype == RESIST_FIRE) {
|
if (spells[spell_id].resisttype == RESIST_FIRE) {
|
||||||
|
|
||||||
if (IsClient()){
|
if (IsClient()){
|
||||||
if (CastToClient()->GetClientVersionBit() <= 4) //Titanium needs alternate graphic.
|
if (CastToClient()->GetClientVersionBit() <= 4) //Titanium needs alternate graphic.
|
||||||
ProjectileAnimation(spell_target,(RuleI(Spells, FRProjectileItem_Titanium)), false, speed);
|
ProjectileAnimation(spell_target,(RuleI(Spells, FRProjectileItem_Titanium)), false, speed);
|
||||||
else
|
else
|
||||||
ProjectileAnimation(spell_target,(RuleI(Spells, FRProjectileItem_SOF)), false, speed);
|
ProjectileAnimation(spell_target,(RuleI(Spells, FRProjectileItem_SOF)), false, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
ProjectileAnimation(spell_target,(RuleI(Spells, FRProjectileItem_NPC)), false, speed);
|
ProjectileAnimation(spell_target,(RuleI(Spells, FRProjectileItem_NPC)), false, speed);
|
||||||
}
|
}
|
||||||
@ -6627,7 +6627,7 @@ void Mob::ResourceTap(int32 damage, uint16 spellid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mob::TryTriggerThreshHold(int32 damage, int effect_id, Mob* attacker){
|
void Mob::TryTriggerThreshHold(int32 damage, int effect_id, Mob* attacker){
|
||||||
|
|
||||||
if (damage <= 0)
|
if (damage <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -6649,15 +6649,15 @@ void Mob::TryTriggerThreshHold(int32 damage, int effect_id, Mob* attacker){
|
|||||||
uint16 spell_id = spells[buffs[slot].spellid].base[i];
|
uint16 spell_id = spells[buffs[slot].spellid].base[i];
|
||||||
|
|
||||||
if (damage > spells[buffs[slot].spellid].base2[i]){
|
if (damage > spells[buffs[slot].spellid].base2[i]){
|
||||||
|
|
||||||
BuffFadeBySlot(slot);
|
BuffFadeBySlot(slot);
|
||||||
|
|
||||||
if (IsValidSpell(spell_id)) {
|
if (IsValidSpell(spell_id)) {
|
||||||
|
|
||||||
if (IsBeneficialSpell(spell_id))
|
if (IsBeneficialSpell(spell_id))
|
||||||
SpellFinished(spell_id, this, 10, 0, -1, spells[spell_id].ResistDiff);
|
SpellFinished(spell_id, this, 10, 0, -1, spells[spell_id].ResistDiff);
|
||||||
|
|
||||||
else if(attacker)
|
else if(attacker)
|
||||||
SpellFinished(spell_id, attacker, 10, 0, -1, spells[spell_id].ResistDiff);
|
SpellFinished(spell_id, attacker, 10, 0, -1, spells[spell_id].ResistDiff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6734,7 +6734,7 @@ void Mob::CalcSpellPowerDistanceMod(uint16 spell_id, float range, Mob* caster)
|
|||||||
float dist_from_min = distance - spells[spell_id].min_dist;
|
float dist_from_min = distance - spells[spell_id].min_dist;
|
||||||
float mod = spells[spell_id].min_dist_mod + (dist_from_min * (dm_mod_interval/dm_range));
|
float mod = spells[spell_id].min_dist_mod + (dist_from_min * (dm_mod_interval/dm_range));
|
||||||
mod *= 100.0f;
|
mod *= 100.0f;
|
||||||
|
|
||||||
SetSpellPowerDistanceMod(static_cast<int>(mod));
|
SetSpellPowerDistanceMod(static_cast<int>(mod));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1165,12 +1165,14 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot,
|
|||||||
}
|
}
|
||||||
else if (!bard_song_mode)
|
else if (!bard_song_mode)
|
||||||
{
|
{
|
||||||
|
int noexpend;
|
||||||
for(int t_count = 0; t_count < 4; t_count++) {
|
for(int t_count = 0; t_count < 4; t_count++) {
|
||||||
component = spells[spell_id].components[t_count];
|
component = spells[spell_id].components[t_count];
|
||||||
if (component == -1)
|
noexpend = spells[spell_id].NoexpendReagent[t_count];
|
||||||
|
if (component == -1 || noexpend == component)
|
||||||
continue;
|
continue;
|
||||||
component_count = spells[spell_id].component_counts[t_count];
|
component_count = spells[spell_id].component_counts[t_count];
|
||||||
Log.Out(Logs::Detail, Logs::Spells, "Spell %d: Consuming %d of spell component item id %d", spell_id, component, component_count);
|
Log.Out(Logs::Detail, Logs::Spells, "Spell %d: Consuming %d of spell component item id %d", spell_id, component_count, component);
|
||||||
// Components found, Deleting
|
// Components found, Deleting
|
||||||
// now we go looking for and deleting the items one by one
|
// now we go looking for and deleting the items one by one
|
||||||
for(int s = 0; s < component_count; s++)
|
for(int s = 0; s < component_count; s++)
|
||||||
@ -1478,7 +1480,10 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
|
|||||||
{
|
{
|
||||||
//invalid target
|
//invalid target
|
||||||
Log.Out(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target of body type %d (undead)", spell_id, mob_body);
|
Log.Out(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target of body type %d (undead)", spell_id, mob_body);
|
||||||
Message_StringID(13,SPELL_NEED_TAR);
|
if(!spell_target)
|
||||||
|
Message_StringID(13,SPELL_NEED_TAR);
|
||||||
|
else
|
||||||
|
Message_StringID(13,CANNOT_AFFECT_NPC);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CastAction = SingleTarget;
|
CastAction = SingleTarget;
|
||||||
@ -2561,7 +2566,7 @@ void Mob::BardPulse(uint16 spell_id, Mob *caster) {
|
|||||||
cd->source = action->source;
|
cd->source = action->source;
|
||||||
cd->type = DamageTypeSpell;
|
cd->type = DamageTypeSpell;
|
||||||
cd->spellid = action->spell;
|
cd->spellid = action->spell;
|
||||||
cd->sequence = action->sequence;
|
cd->meleepush_xy = action->sequence;
|
||||||
cd->damage = 0;
|
cd->damage = 0;
|
||||||
if(!IsEffectInSpell(spell_id, SE_BindAffinity))
|
if(!IsEffectInSpell(spell_id, SE_BindAffinity))
|
||||||
{
|
{
|
||||||
@ -3825,7 +3830,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r
|
|||||||
cd->source = action->source;
|
cd->source = action->source;
|
||||||
cd->type = action->type;
|
cd->type = action->type;
|
||||||
cd->spellid = action->spell;
|
cd->spellid = action->spell;
|
||||||
cd->sequence = action->sequence;
|
cd->meleepush_xy = action->sequence;
|
||||||
cd->damage = 0;
|
cd->damage = 0;
|
||||||
if(!IsEffectInSpell(spell_id, SE_BindAffinity))
|
if(!IsEffectInSpell(spell_id, SE_BindAffinity))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -192,7 +192,7 @@ void Trap::Trigger(Mob* trigger)
|
|||||||
int dmg = zone->random.Int(effectvalue, effectvalue2);
|
int dmg = zone->random.Int(effectvalue, effectvalue2);
|
||||||
trigger->SetHP(trigger->GetHP() - dmg);
|
trigger->SetHP(trigger->GetHP() - dmg);
|
||||||
a->damage = dmg;
|
a->damage = dmg;
|
||||||
a->sequence = zone->random.Int(0, 1234567);
|
a->meleepush_xy = zone->random.Int(0, 1234567);
|
||||||
a->source = GetHiddenTrigger()!=nullptr ? GetHiddenTrigger()->GetID() : trigger->GetID();
|
a->source = GetHiddenTrigger()!=nullptr ? GetHiddenTrigger()->GetID() : trigger->GetID();
|
||||||
a->spellid = 0;
|
a->spellid = 0;
|
||||||
a->target = trigger->GetID();
|
a->target = trigger->GetID();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user