mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 07:21:48 +00:00
Merge
This commit is contained in:
commit
ffbee0ad1a
@ -408,6 +408,7 @@ N(OP_ReloadUI),
|
|||||||
N(OP_RemoveAllDoors),
|
N(OP_RemoveAllDoors),
|
||||||
N(OP_RemoveBlockedBuffs),
|
N(OP_RemoveBlockedBuffs),
|
||||||
N(OP_RemoveNimbusEffect),
|
N(OP_RemoveNimbusEffect),
|
||||||
|
N(OP_RemoveTrap),
|
||||||
N(OP_Report),
|
N(OP_Report),
|
||||||
N(OP_ReqClientSpawn),
|
N(OP_ReqClientSpawn),
|
||||||
N(OP_ReqNewZone),
|
N(OP_ReqNewZone),
|
||||||
@ -523,6 +524,7 @@ N(OP_TributeToggle),
|
|||||||
N(OP_TributeUpdate),
|
N(OP_TributeUpdate),
|
||||||
N(OP_Untargetable),
|
N(OP_Untargetable),
|
||||||
N(OP_UpdateAA),
|
N(OP_UpdateAA),
|
||||||
|
N(OP_UpdateAura),
|
||||||
N(OP_UpdateLeadershipAA),
|
N(OP_UpdateLeadershipAA),
|
||||||
N(OP_VetClaimReply),
|
N(OP_VetClaimReply),
|
||||||
N(OP_VetClaimRequest),
|
N(OP_VetClaimRequest),
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
//SpawnAppearance types: (compared two clients for server-originating types: SoF & RoF2)
|
//SpawnAppearance types: (compared two clients for server-originating types: SoF & RoF2)
|
||||||
#define AT_Die 0 // this causes the client to keel over and zone to bind point (default action)
|
#define AT_Die 0 // this causes the client to keel over and zone to bind point (default action)
|
||||||
#define AT_WhoLevel 1 // the level that shows up on /who
|
#define AT_WhoLevel 1 // the level that shows up on /who
|
||||||
//#define AT_2 2 // unknown
|
#define AT_HPMax 2 // idk
|
||||||
#define AT_Invis 3 // 0 = visible, 1 = invisible
|
#define AT_Invis 3 // 0 = visible, 1 = invisible
|
||||||
#define AT_PVP 4 // 0 = blue, 1 = pvp (red)
|
#define AT_PVP 4 // 0 = blue, 1 = pvp (red)
|
||||||
#define AT_Light 5 // light type emitted by player (lightstone, shiny shield)
|
#define AT_Light 5 // light type emitted by player (lightstone, shiny shield)
|
||||||
@ -36,33 +36,37 @@
|
|||||||
#define AT_SpawnID 16 // server to client, sets player spawn id
|
#define AT_SpawnID 16 // server to client, sets player spawn id
|
||||||
#define AT_HP 17 // Client->Server, my HP has changed (like regen tic)
|
#define AT_HP 17 // Client->Server, my HP has changed (like regen tic)
|
||||||
#define AT_Linkdead 18 // 0 = normal, 1 = linkdead
|
#define AT_Linkdead 18 // 0 = normal, 1 = linkdead
|
||||||
#define AT_Levitate 19 // 0=off, 1=flymode, 2=levitate
|
#define AT_Levitate 19 // 0=off, 1=flymode, 2=levitate max 5, see GravityBehavior enum
|
||||||
#define AT_GM 20 // 0 = normal, 1 = GM - all odd numbers seem to make it GM
|
#define AT_GM 20 // 0 = normal, 1 = GM - all odd numbers seem to make it GM
|
||||||
#define AT_Anon 21 // 0 = normal, 1 = anon, 2 = roleplay
|
#define AT_Anon 21 // 0 = normal, 1 = anon, 2 = roleplay
|
||||||
#define AT_GuildID 22
|
#define AT_GuildID 22
|
||||||
#define AT_GuildRank 23 // 0=member, 1=officer, 2=leader
|
#define AT_GuildRank 23 // 0=member, 1=officer, 2=leader
|
||||||
#define AT_AFK 24 // 0 = normal, 1 = afk
|
#define AT_AFK 24 // 0 = normal, 1 = afk
|
||||||
#define AT_Pet 25 // Param is EntityID of owner, or 0 for when charm breaks
|
#define AT_Pet 25 // Param is EntityID of owner, or 0 for when charm breaks
|
||||||
//#define AT_27 27 // unknown
|
#define AT_Summoned 27 // Unsure
|
||||||
#define AT_Split 28 // 0 = normal, 1 = autosplit on (not showing in SoF+) (client-to-server only)
|
#define AT_Split 28 // 0 = normal, 1 = autosplit on (not showing in SoF+) (client-to-server only)
|
||||||
#define AT_Size 29 // spawn's size (present: SoF, absent: RoF2)
|
#define AT_Size 29 // spawn's size (present: SoF, absent: RoF2)
|
||||||
//#define AT_30 30 // unknown
|
#define AT_SetType 30 // 0 = PC, 1 = NPC, 2 <= = corpse
|
||||||
#define AT_NPCName 31 // change PC's name's color to NPC color 0 = normal, 1 = npc name
|
#define AT_NPCName 31 // change PC's name's color to NPC color 0 = normal, 1 = npc name, Trader on RoF2?
|
||||||
//#define AT_32 32 // unknown
|
#define AT_AARank 32 // AA Rank Title ID thingy, does is this the title in /who?
|
||||||
//#define AT_33 33 // unknown
|
#define AT_CancelSneakHide 33 // Turns off Hide and Sneak
|
||||||
//#define AT_34 34 // unknown (present: SoF, absent: RoF2)
|
//#define AT_34 34 // unknown (present: SoF, absent: RoF2)
|
||||||
//#define AT_35 35 // unknown
|
#define AT_AreaHPRegen 35 // guild hall regen pool sets to value * 0.001
|
||||||
//#define AT_36 36 // unknown
|
#define AT_AreaManaRegen 36 // guild hall regen pool sets to value * 0.001
|
||||||
//#define AT_37 37 // unknown
|
#define AT_AreaEndRegen 37 // guild hall regen pool sets to value * 0.001
|
||||||
//#define AT_38 38 // unknown
|
#define AT_FreezeBuffs 38 // Freezes beneficial buff timers
|
||||||
//#define AT_39 39 // unknown
|
#define AT_NpcTintIndex 39 // not 100% sure
|
||||||
|
#define AT_GroupConsent 40 // auto consent group
|
||||||
|
#define AT_RaidConsent 41 // auto consent raid
|
||||||
|
#define AT_GuildConsent 42 // auto consent guild
|
||||||
#define AT_ShowHelm 43 // 0 = hide graphic, 1 = show graphic
|
#define AT_ShowHelm 43 // 0 = hide graphic, 1 = show graphic
|
||||||
#define AT_DamageState 44 // The damage state of a destructible object (0 through 4)
|
#define AT_DamageState 44 // The damage state of a destructible object (0 through 10) plays soundids most only have 2 or 4 states though
|
||||||
//#define AT_46 46 // unknown
|
#define AT_EQPlayers 45 // /eqplayersupdate
|
||||||
//#define AT_48 48 // unknown
|
#define AT_FindBits 46 // set FindBits, whatever those are!
|
||||||
//#define AT_49 49 // unknown
|
#define AT_TextureType 48 // TextureType
|
||||||
//#define AT_52 52 // (absent: SoF, present: RoF2) (not a replacement for RoF absent 29 or 34)
|
#define AT_FacePick 49 // Turns off face pick window? maybe ...
|
||||||
//#define AT_53 53 // (absent: SoF, present: RoF2) (not a replacement for RoF absent 29 or 34)
|
#define AT_GuildShow 52 // this is what MQ2 call sit, not sure
|
||||||
|
#define AT_Offline 53 // Offline mode
|
||||||
|
|
||||||
//#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2)
|
//#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2)
|
||||||
|
|
||||||
|
|||||||
@ -5333,6 +5333,24 @@ struct fling_struct {
|
|||||||
/* 28 */
|
/* 28 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// used when action == 0
|
||||||
|
struct AuraCreate_Struct {
|
||||||
|
/* 00 */ uint32 action; // 0 = add, 1 = delete, 2 = reset
|
||||||
|
/* 04 */ uint32 type; // unsure -- normal auras show 1 clicky (ex. Circle of Power) show 0
|
||||||
|
/* 08 */ char aura_name[64];
|
||||||
|
/* 72 */ uint32 entity_id;
|
||||||
|
/* 76 */ uint32 icon;
|
||||||
|
/* 80 */
|
||||||
|
};
|
||||||
|
|
||||||
|
// used when action == 1
|
||||||
|
struct AuraDestory_Struct {
|
||||||
|
/* 00 */ uint32 action; // 0 = add, 1 = delete, 2 = reset
|
||||||
|
/* 04 */ uint32 entity_id;
|
||||||
|
/* 08 */
|
||||||
|
};
|
||||||
|
// I think we can assume it's just action for 2, client doesn't seem to do anything with the rest of the data in that case
|
||||||
|
|
||||||
// Restore structure packing to default
|
// Restore structure packing to default
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
|||||||
@ -1883,35 +1883,34 @@ namespace RoF2
|
|||||||
eq->FogDensity = emu->fog_density;
|
eq->FogDensity = emu->fog_density;
|
||||||
|
|
||||||
/*fill in some unknowns with observed values, hopefully it will help */
|
/*fill in some unknowns with observed values, hopefully it will help */
|
||||||
eq->unknown569 = 0;
|
eq->ZoneTimeZone = 0;
|
||||||
eq->unknown571 = 0;
|
eq->unknown571 = 0;
|
||||||
eq->unknown572 = 4;
|
eq->WaterMidi = 4;
|
||||||
eq->unknown576 = 2;
|
eq->DayMidi = 2;
|
||||||
eq->unknown580 = 0;
|
eq->NightMidi = 0;
|
||||||
|
|
||||||
eq->unknown800 = -1;
|
eq->SkyRelated2 = -1;
|
||||||
eq->unknown844 = 600;
|
eq->NPCAggroMaxDist = 600;
|
||||||
eq->unknown848 = 2008; // Guild Lobby observed value
|
eq->FilterID = 2008; // Guild Lobby observed value
|
||||||
eq->unknown880 = 50;
|
eq->LavaDamage = 50;
|
||||||
eq->unknown884 = 10;
|
eq->MinLavaDamage = 10;
|
||||||
eq->unknown888 = 1;
|
eq->bDisallowManaStone = 1;
|
||||||
eq->unknown889 = 0;
|
eq->bNoBind = 0;
|
||||||
eq->unknown890 = 1;
|
eq->bNoAttack = 0;
|
||||||
eq->unknown891 = 0;
|
eq->bNoCallOfHero = 0;
|
||||||
eq->unknown892 = 0;
|
eq->bNoFlux = 0;
|
||||||
eq->unknown893 = 0;
|
eq->bNoFear = 0;
|
||||||
eq->fall_damage = 0; // 0 = Fall Damage on, 1 = Fall Damage off
|
eq->fall_damage = 0; // 0 = Fall Damage on, 1 = Fall Damage off
|
||||||
eq->unknown895 = 0;
|
eq->unknown895 = 0;
|
||||||
eq->unknown896 = 180;
|
eq->FastRegenHP = 180;
|
||||||
eq->unknown900 = 180;
|
eq->FastRegenMana = 180;
|
||||||
eq->unknown904 = 180;
|
eq->FastRegenEndurance = 180;
|
||||||
eq->unknown908 = 2;
|
eq->CanPlaceCampsite = 2;
|
||||||
eq->unknown912 = 2;
|
eq->CanPlaceGuildBanner = 2;
|
||||||
eq->unknown932 = -1; // Set from PoK Example
|
eq->FishingRelated = -1; // Set from PoK Example
|
||||||
eq->unknown936 = -1; // Set from PoK Example
|
eq->ForageRelated = -1; // Set from PoK Example
|
||||||
eq->unknown944 = 1.0; // Set from PoK Example
|
eq->bNoLevitate = 0;
|
||||||
eq->unknown948 = 0; // New on Live as of Dec 15 2014
|
eq->Blooming = 1.0; // Set from PoK Example
|
||||||
eq->unknown952 = 100; // New on Live as of Dec 15 2014
|
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -4120,6 +4119,7 @@ namespace RoF2
|
|||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->name);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->name);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->spawnId);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->spawnId);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->level);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->level);
|
||||||
|
// actually melee range variable, this probably screws the shit out of melee ranges :D
|
||||||
if (emu->DestructibleObject)
|
if (emu->DestructibleObject)
|
||||||
{
|
{
|
||||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, 10); // was int and 0x41200000
|
VARSTRUCT_ENCODE_TYPE(float, Buffer, 10); // was int and 0x41200000
|
||||||
@ -4128,7 +4128,7 @@ namespace RoF2
|
|||||||
{
|
{
|
||||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, SpawnSize - 0.7); // Eye Height?
|
VARSTRUCT_ENCODE_TYPE(float, Buffer, SpawnSize - 0.7); // Eye Height?
|
||||||
}
|
}
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->NPC);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->NPC); // 0 PC, 1 NPC etc
|
||||||
|
|
||||||
structs::Spawn_Struct_Bitfields *Bitfields = (structs::Spawn_Struct_Bitfields*)Buffer;
|
structs::Spawn_Struct_Bitfields *Bitfields = (structs::Spawn_Struct_Bitfields*)Buffer;
|
||||||
|
|
||||||
@ -4159,6 +4159,7 @@ namespace RoF2
|
|||||||
|
|
||||||
Buffer += sizeof(structs::Spawn_Struct_Bitfields);
|
Buffer += sizeof(structs::Spawn_Struct_Bitfields);
|
||||||
|
|
||||||
|
// actually part of bitfields
|
||||||
uint8 OtherData = 0;
|
uint8 OtherData = 0;
|
||||||
|
|
||||||
if (emu->class_ == 62) //LDoN Chest
|
if (emu->class_ == 62) //LDoN Chest
|
||||||
@ -4174,6 +4175,7 @@ namespace RoF2
|
|||||||
OtherData = OtherData | 0xe1; // Live has 0xe1 for OtherData
|
OtherData = OtherData | 0xe1; // Live has 0xe1 for OtherData
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, OtherData);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, OtherData);
|
||||||
|
// float EmitterScalingRadius
|
||||||
|
|
||||||
if (emu->DestructibleObject)
|
if (emu->DestructibleObject)
|
||||||
{
|
{
|
||||||
@ -4183,6 +4185,7 @@ namespace RoF2
|
|||||||
{
|
{
|
||||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, -1); // unknown3
|
VARSTRUCT_ENCODE_TYPE(float, Buffer, -1); // unknown3
|
||||||
}
|
}
|
||||||
|
// int DefaultEmitterID
|
||||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4
|
VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4
|
||||||
|
|
||||||
if (emu->DestructibleObject || emu->class_ == 62)
|
if (emu->DestructibleObject || emu->class_ == 62)
|
||||||
@ -4192,8 +4195,9 @@ namespace RoF2
|
|||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleString);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleString);
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleAppearance);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleAppearance);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk1);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk1); // ObjectAnimationID
|
||||||
|
|
||||||
|
// these 10 are SoundIDs
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleID1);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleID1);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleID2);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleID2);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleID3);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleID3);
|
||||||
@ -4205,8 +4209,8 @@ namespace RoF2
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk5);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk5);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk6);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk6);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk7);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk7);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->DestructibleUnk8);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->DestructibleUnk8); // bInteractiveObjectCollidable
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk9);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->DestructibleUnk9); // IteractiveObjectType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4214,6 +4218,7 @@ namespace RoF2
|
|||||||
{
|
{
|
||||||
// Setting this next field to zero will cause a crash. Looking at ShowEQ, if it is zero, the bodytype field is not
|
// Setting this next field to zero will cause a crash. Looking at ShowEQ, if it is zero, the bodytype field is not
|
||||||
// present. Will sort that out later.
|
// present. Will sort that out later.
|
||||||
|
// This is the CharacterPropertyHash, it can have multiple fields
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 1); // This is a properties count field
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 1); // This is a properties count field
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->bodytype);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->bodytype);
|
||||||
}
|
}
|
||||||
@ -4233,10 +4238,10 @@ namespace RoF2
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->drakkin_tattoo);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->drakkin_tattoo);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->drakkin_details);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->drakkin_details);
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->equip_chest2);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->equip_chest2); // InNonPCRaceIllusion
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown9
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // material
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown10
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // variation
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->helm); // unknown11
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->helm); // headtype
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, emu->size);
|
VARSTRUCT_ENCODE_TYPE(float, Buffer, emu->size);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->face);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->face);
|
||||||
@ -4244,6 +4249,7 @@ namespace RoF2
|
|||||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, emu->runspeed);
|
VARSTRUCT_ENCODE_TYPE(float, Buffer, emu->runspeed);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->race);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->race);
|
||||||
|
|
||||||
|
// From MQ2: todo: create enum for this byte. Holding: Nothing=0 A RightHand Weapon=1 A Shield=2 Dual Wielding Two Weapons=3 A Spear=4 A LeftHand Weapon=5 A Two Handed Weapon=6 A bow=7
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // ShowEQ calls this 'Holding'
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // ShowEQ calls this 'Holding'
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->deity);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->deity);
|
||||||
if (emu->NPC)
|
if (emu->NPC)
|
||||||
@ -4276,19 +4282,19 @@ namespace RoF2
|
|||||||
|
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->lastName);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->lastName);
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // aatitle ??
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // aatitle
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->NPC ? 0 : 1); // unknown - Must be 1 for guild name to be shown abover players head.
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->NPC ? 0 : 1); // unknown - Must be 1 for guild name to be shown abover players head.
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // TempPet
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // FindBits MQ2 name
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // NpcTintIndex
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // PrimaryTintIndex
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // SecondaryTintIndex
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown18
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // These do something with OP_WeaponEquip1
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown19
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // ^
|
||||||
|
|
||||||
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
|
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
|
||||||
{
|
{
|
||||||
@ -4356,12 +4362,16 @@ namespace RoF2
|
|||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->suffix);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skipping two ints
|
||||||
|
// unknown, maybe some sort of spawn ID
|
||||||
|
// SplineID -- no idea
|
||||||
Buffer += 8;
|
Buffer += 8;
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->IsMercenary);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->IsMercenary);
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, "0000000000000000");
|
VARSTRUCT_ENCODE_STRING(Buffer, "0000000000000000"); // RealEstateItemGuid
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // RealEstateID
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // RealEstateItemID
|
||||||
// 29 zero bytes follow
|
// 29 zero bytes follow
|
||||||
|
// PhysicsEffects follow here ... unsure what they are but it's a count followed by a struct like {spellid, casterid, effectid, baseeffect}
|
||||||
Buffer += 29;
|
Buffer += 29;
|
||||||
if (Buffer != (BufferStart + PacketSize))
|
if (Buffer != (BufferStart + PacketSize))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -328,38 +328,43 @@ showeq -> eqemu
|
|||||||
sed -e 's/_t//g' -e 's/seto_0xFF/set_to_0xFF/g'
|
sed -e 's/_t//g' -e 's/seto_0xFF/set_to_0xFF/g'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// I think this is actually 5 bytes
|
||||||
|
// IDA's pseudocode reads this as 5 bytes pulled into 2 DWORDs
|
||||||
struct Spawn_Struct_Bitfields
|
struct Spawn_Struct_Bitfields
|
||||||
{
|
{
|
||||||
|
// byte 1
|
||||||
/*00*/ unsigned gender:2; // Gender (0=male, 1=female, 2=monster)
|
/*00*/ unsigned gender:2; // Gender (0=male, 1=female, 2=monster)
|
||||||
/*02*/ unsigned ispet:1; // Guessed based on observing live spawns
|
/*02*/ unsigned ispet:1; // Guessed based on observing live spawns
|
||||||
/*03*/ unsigned afk:1; // 0=no, 1=afk
|
/*03*/ unsigned afk:1; // 0=no, 1=afk
|
||||||
/*04*/ unsigned anon:2; // 0=normal, 1=anon, 2=roleplay
|
/*04*/ unsigned anon:2; // 0=normal, 1=anon, 2=roleplay
|
||||||
/*06*/ unsigned gm:1;
|
/*06*/ unsigned gm:1;
|
||||||
/*06*/ unsigned sneak:1;
|
/*07*/ unsigned sneak:1;
|
||||||
|
// byte 2
|
||||||
/*08*/ unsigned lfg:1;
|
/*08*/ unsigned lfg:1;
|
||||||
/*09*/ unsigned unknown09:1;
|
/*09*/ unsigned betabuffed:1;
|
||||||
/*10*/ unsigned invis:1; // May have invis & sneak the wrong way around ... not sure how to tell which is which
|
/*10*/ unsigned invis:12; // there are 3000 different (non-GM) invis levels
|
||||||
/*11*/ unsigned invis1:1; // GM Invis? Can only be seen with #gm on - same for the below
|
|
||||||
/*12*/ unsigned invis2:1; // This one also make the NPC/PC invis
|
|
||||||
/*13*/ unsigned invis3:1; // This one also make the NPC/PC invis
|
|
||||||
/*14*/ unsigned invis4:1; // This one also make the NPC/PC invis
|
|
||||||
/*15*/ unsigned invis6:1; // This one also make the NPC/PC invis
|
|
||||||
/*16*/ unsigned invis7:1; // This one also make the NPC/PC invis
|
|
||||||
/*17*/ unsigned invis8:1; // This one also make the NPC/PC invis
|
|
||||||
/*18*/ unsigned invis9:1; // This one also make the NPC/PC invis
|
|
||||||
/*19*/ unsigned invis10:1; // This one also make the NPC/PC invis
|
|
||||||
/*20*/ unsigned invis11:1; // This one also make the NPC/PC invis
|
|
||||||
/*21*/ unsigned invis12:1; // This one also make the NPC/PC invis
|
|
||||||
/*22*/ unsigned linkdead:1; // 1 Toggles LD on or off after name. Correct for RoF2
|
/*22*/ unsigned linkdead:1; // 1 Toggles LD on or off after name. Correct for RoF2
|
||||||
/*23*/ unsigned showhelm:1;
|
/*23*/ unsigned showhelm:1;
|
||||||
|
// byte 4
|
||||||
/*24*/ unsigned unknown24:1; // Prefixes name with !
|
/*24*/ unsigned unknown24:1; // Prefixes name with !
|
||||||
/*25*/ unsigned trader:1;
|
/*25*/ unsigned trader:1;
|
||||||
/*26*/ unsigned unknown26:1;
|
/*26*/ unsigned animationonpop:1;
|
||||||
/*27*/ unsigned targetable:1;
|
/*27*/ unsigned targetable:1;
|
||||||
/*28*/ unsigned targetable_with_hotkey:1;
|
/*28*/ unsigned targetable_with_hotkey:1;
|
||||||
/*29*/ unsigned showname:1;
|
/*29*/ unsigned showname:1;
|
||||||
/*30*/ unsigned unknown30:1;
|
/*30*/ unsigned idleanimationsoff:1; // what we called statue?
|
||||||
/*30*/ unsigned untargetable:1; // Untargetable with mouse
|
/*31*/ unsigned untargetable:1; // bClickThrough
|
||||||
|
/* do these later
|
||||||
|
32 unsigned buyer:1;
|
||||||
|
33 unsigned offline:1;
|
||||||
|
34 unsigned interactiveobject:1;
|
||||||
|
35 unsigned flung:1; // hmm this vfunc appears to do stuff with leve and flung variables
|
||||||
|
36 unsigned title:1;
|
||||||
|
37 unsigned suffix:1;
|
||||||
|
38 unsigned padding1:1;
|
||||||
|
39 unsigned padding2:1;
|
||||||
|
40 unsinged padding3:1;
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
// Unknown in RoF2
|
// Unknown in RoF2
|
||||||
unsigned betabuffed:1;
|
unsigned betabuffed:1;
|
||||||
@ -498,7 +503,7 @@ struct Spawn_Struct
|
|||||||
|
|
||||||
/*0000*/ //char title[0]; // only read if(hasTitleOrSuffix & 4)
|
/*0000*/ //char title[0]; // only read if(hasTitleOrSuffix & 4)
|
||||||
/*0000*/ //char suffix[0]; // only read if(hasTitleOrSuffix & 8)
|
/*0000*/ //char suffix[0]; // only read if(hasTitleOrSuffix & 8)
|
||||||
char unknown20[8];
|
char unknown20[8]; // 2 ints, first unknown, 2nd SplineID
|
||||||
uint8 IsMercenary; // If NPC == 1 and this == 1, then the NPC name is Orange.
|
uint8 IsMercenary; // If NPC == 1 and this == 1, then the NPC name is Orange.
|
||||||
/*0000*/ char unknown21[55];
|
/*0000*/ char unknown21[55];
|
||||||
};
|
};
|
||||||
@ -556,74 +561,100 @@ struct ServerZoneEntry_Struct //Adjusted from SEQ Everquest.h Struct
|
|||||||
//New Zone Struct - Size: 948
|
//New Zone Struct - Size: 948
|
||||||
struct NewZone_Struct {
|
struct NewZone_Struct {
|
||||||
/*0000*/ char char_name[64]; // Character Name
|
/*0000*/ char char_name[64]; // Character Name
|
||||||
/*0064*/ char zone_short_name[32]; // Zone Short Name
|
/*0064*/ char zone_short_name[128]; // Zone Short Name
|
||||||
/*0096*/ char unknown0096[96];
|
/*0192*/ char zone_long_name[128]; // Zone Long Name
|
||||||
/*0192*/ char zone_long_name[278]; // Zone Long Name
|
/*0320*/ char zone_desc[5][30]; // mostly just empty strings
|
||||||
/*0470*/ uint8 ztype; // Zone type (usually FF)
|
/*0470*/ uint8 ztype; // Zone type (usually FF) FogOnOff
|
||||||
/*0471*/ uint8 fog_red[4]; // Zone fog (red)
|
/*0471*/ uint8 fog_red[4]; // Zone fog (red) ARGBCOLOR
|
||||||
/*0475*/ uint8 fog_green[4]; // Zone fog (green)
|
/*0475*/ uint8 fog_green[4]; // Zone fog (green) ARGBCOLOR
|
||||||
/*0479*/ uint8 fog_blue[4]; // Zone fog (blue)
|
/*0479*/ uint8 fog_blue[4]; // Zone fog (blue) ARGBCOLO
|
||||||
/*0483*/ uint8 unknown323;
|
/*0483*/ uint8 unknown323; // padding?
|
||||||
/*0484*/ float fog_minclip[4];
|
/*0484*/ float fog_minclip[4]; // MQ2 has this starting at this offset, must be padding above
|
||||||
/*0500*/ float fog_maxclip[4];
|
/*0500*/ float fog_maxclip[4];
|
||||||
/*0516*/ float gravity;
|
/*0516*/ float gravity;
|
||||||
/*0520*/ uint8 time_type;
|
/*0520*/ uint8 time_type; // OutDoor flag 0 = IndoorDungeon, 1 = OUtdoor, 2 = OutdoorCity, 3 = DungeonCity, 4 = IndoorCity, 5 = OutdoorDungeon
|
||||||
/*0521*/ uint8 rain_chance[4];
|
/*0521*/ uint8 rain_chance[4];
|
||||||
/*0525*/ uint8 rain_duration[4];
|
/*0525*/ uint8 rain_duration[4];
|
||||||
/*0529*/ uint8 snow_chance[4];
|
/*0529*/ uint8 snow_chance[4];
|
||||||
/*0533*/ uint8 snow_duration[4];
|
/*0533*/ uint8 snow_duration[4];
|
||||||
/*0537*/ uint8 unknown537[32]; // Seen all 0xff
|
/*0537*/ uint8 unknown537[32]; // this is removed on live, specialdates and specialcodes probably macro'd out
|
||||||
/*0569*/ uint8 unknown569; // Unknown - Seen 0
|
/*0569*/ uint8 ZoneTimeZone; // MQ2 "in hours from worldserver, can be negative"
|
||||||
/*0570*/ uint8 sky; // Sky Type
|
/*0570*/ uint8 sky; // Sky Type
|
||||||
/*0571*/ uint8 unknown571; // Unknown - Seen 0
|
/*0571*/ uint8 unknown571; // Padding I think
|
||||||
/*0572*/ uint32 unknown572; // Unknown - Seen 4 in Guild Lobby
|
/*0572*/ uint32 WaterMidi; // Unknown - Seen 4 in Guild Lobby
|
||||||
/*0576*/ uint32 unknown576; // Unknown - Seen 2 in Guild Lobby
|
/*0576*/ uint32 DayMidi; // Unknown - Seen 2 in Guild Lobby
|
||||||
/*0580*/ uint32 unknown580; // Unknown - Seen 0 in Guild Lobby
|
/*0580*/ uint32 NightMidi; // Unknown - Seen 0 in Guild Lobby
|
||||||
/*0584*/ float zone_exp_multiplier; // Experience Multiplier
|
/*0584*/ float zone_exp_multiplier; // Experience Multiplier
|
||||||
/*0588*/ float safe_y; // Zone Safe Y
|
/*0588*/ float safe_y; // Zone Safe Y
|
||||||
/*0592*/ float safe_x; // Zone Safe X
|
/*0592*/ float safe_x; // Zone Safe X
|
||||||
/*0596*/ float safe_z; // Zone Safe Z
|
/*0596*/ float safe_z; // Zone Safe Z
|
||||||
/*0600*/ float min_z; // Guessed - NEW - Seen 0
|
/*0600*/ float min_z; // This isn't safe heading like live -- could be default heading rather than succor heading
|
||||||
/*0604*/ float max_z; // Guessed
|
/*0604*/ float max_z; // Ceiling
|
||||||
/*0608*/ float underworld; // Underworld, min z (Not Sure?)
|
/*0608*/ float underworld; // Underworld, min z (Not Sure?) Floor
|
||||||
/*0612*/ float minclip; // Minimum View Distance
|
/*0612*/ float minclip; // Minimum View Distance
|
||||||
/*0616*/ float maxclip; // Maximum View DIstance
|
/*0616*/ float maxclip; // Maximum View DIstance
|
||||||
/*0620*/ uint8 unknown620[84]; // ***Placeholder
|
/*0620*/ uint32 ForageLow; // Forage loot table ID?
|
||||||
/*0704*/ char zone_short_name2[96]; //zone file name? excludes instance number which can be in previous version.
|
/*0624*/ uint32 ForageMedium; // Forage loot table ID?
|
||||||
/*0800*/ int32 unknown800; //seen -1
|
/*0628*/ uint32 ForageHigh; // Forage loot table ID?
|
||||||
/*0804*/ char unknown804[40]; //
|
/*0632*/ uint32 FishingLow; // Fishing loot table ID?
|
||||||
/*0844*/ int32 unknown844; //seen 600
|
/*0636*/ uint32 FishingMedium; // Fishing loot table ID?
|
||||||
/*0848*/ int32 unknown848; //seen 2008
|
/*0640*/ uint32 FishingHigh; // Fishing loot table ID?
|
||||||
/*0852*/ uint16 zone_id;
|
/*0644*/ uint32 sky_lock; // MQ2 skyrelated
|
||||||
|
/*0648*/ uint32 graveyard_timer; // minutes until corpse pop to graveyard
|
||||||
|
/*0652*/ uint32 scriptIDHour; // These are IDs of scripts
|
||||||
|
/*0656*/ uint32 scriptIDMinute; // These are IDs of scripts
|
||||||
|
/*0660*/ uint32 scriptIDTick; // These are IDs of scripts
|
||||||
|
/*0664*/ uint32 scriptIDOnPlayerDeath; // These are IDs of scripts
|
||||||
|
/*0668*/ uint32 scriptIDOnNPCDeath; // These are IDs of scripts
|
||||||
|
/*0672*/ uint32 scriptIDPlayerEnteringZone; // These are IDs of scripts
|
||||||
|
/*0676*/ uint32 scriptIDOnZonePop; // These are IDs of scripts
|
||||||
|
/*0680*/ uint32 scriptIDNPCLoot; // These are IDs of scripts
|
||||||
|
/*0684*/ uint32 scriptIDAdventureFailed; // These are IDs of scripts
|
||||||
|
/*0688*/ uint32 CanExploreTasks;
|
||||||
|
/*0692*/ uint32 UnknownFlag; // not sure, neither is MQ2!
|
||||||
|
/*0696*/ uint32 scriptIDOnFishing; // THese are IDs of scripts
|
||||||
|
/*0700*/ uint32 scriptIDOnForage; // THese are IDs of scripts
|
||||||
|
/*0704*/ char zone_short_name2[32]; //zone file name? excludes instance number which can be in previous version.
|
||||||
|
/*0736*/ char WeatherString[32];
|
||||||
|
/*0768*/ char SkyString2[32];
|
||||||
|
/*0800*/ int32 SkyRelated2; //seen -1
|
||||||
|
/*0804*/ char WeatherString2[32]; //
|
||||||
|
/*0836*/ float WeatherChangeTime; // not sure :P
|
||||||
|
/*0840*/ uint32 Climate;
|
||||||
|
/*0844*/ int32 NPCAggroMaxDist; //seen 600
|
||||||
|
/*0848*/ int32 FilterID; //seen 2008 -- maybe zone guide related?
|
||||||
|
/*0852*/ uint16 zone_id; // this might just be instance ID got 1736 for time
|
||||||
/*0854*/ uint16 zone_instance;
|
/*0854*/ uint16 zone_instance;
|
||||||
/*0856*/ char unknown856[20];
|
/*0856*/ uint32 scriptNPCReceivedanItem;
|
||||||
/*0876*/ uint32 SuspendBuffs;
|
/*0860*/ uint32 bCheck; // padded bool
|
||||||
/*0880*/ uint32 unknown880; // Seen 50
|
/*0864*/ uint32 scriptIDSomething;
|
||||||
/*0884*/ uint32 unknown884; // Seen 10
|
/*0868*/ uint32 scriptIDSomething2;
|
||||||
/*0888*/ uint8 unknown888; // Seen 1
|
/*0872*/ uint32 scriptIDSomething3;
|
||||||
/*0889*/ uint8 unknown889; // Seen 0 (POK) or 1 (rujj)
|
/*0876*/ uint32 SuspendBuffs; // padded bool
|
||||||
/*0890*/ uint8 unknown890; // Seen 1
|
/*0880*/ uint32 LavaDamage; // LavaDamage value
|
||||||
/*0891*/ uint8 unknown891; // Seen 0
|
/*0884*/ uint32 MinLavaDamage; // min cap after resist calcs
|
||||||
/*0892*/ uint8 unknown892; // Seen 0
|
/*0888*/ uint8 bDisallowManaStone; // can't use manastone in this zone
|
||||||
/*0893*/ uint8 unknown893; // Seen 0 - 00
|
/*0889*/ uint8 bNoBind; // can't bind even if outdoor says we can!
|
||||||
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off
|
/*0890*/ uint8 bNoAttack; // non-attack zone
|
||||||
/*0895*/ uint8 unknown895; // Seen 0 - 00
|
/*0891*/ uint8 bNoCallOfHero; // coth line disabled
|
||||||
/*0896*/ uint32 unknown896; // Seen 180
|
/*0892*/ uint8 bNoFlux; // gflux no worky
|
||||||
/*0900*/ uint32 unknown900; // Seen 180
|
/*0893*/ uint8 bNoFear; // fear spells no worky
|
||||||
/*0904*/ uint32 unknown904; // Seen 180
|
/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off MQ2 calls bNoEncumber
|
||||||
/*0908*/ uint32 unknown908; // Seen 2
|
/*0895*/ uint8 unknown895; // padding
|
||||||
/*0912*/ uint32 unknown912; // Seen 2
|
/*0896*/ uint32 FastRegenHP; // percentage I think?
|
||||||
|
/*0900*/ uint32 FastRegenMana; // percentage I think?
|
||||||
|
/*0904*/ uint32 FastRegenEndurance; // percentage I think?
|
||||||
|
/*0908*/ uint32 CanPlaceCampsite; // 0 = no, 1 = can place, 2 = place and goto
|
||||||
|
/*0912*/ uint32 CanPlaceGuildBanner; // ^
|
||||||
/*0916*/ float FogDensity; // Most zones have this set to 0.33 Blightfire had 0.16
|
/*0916*/ float FogDensity; // Most zones have this set to 0.33 Blightfire had 0.16
|
||||||
/*0920*/ uint32 unknown920; // Seen 0
|
/*0920*/ uint32 bAdjustGamma; // padded bool
|
||||||
/*0924*/ uint32 unknown924; // Seen 0
|
/*0924*/ uint32 TimeStringID; // Seen 0
|
||||||
/*0928*/ uint32 unknown928; // Seen 0
|
/*0928*/ uint32 bNoMercenaries; // padded bool
|
||||||
/*0932*/ int32 unknown932; // Seen -1
|
/*0932*/ int32 FishingRelated; // Seen -1 idk
|
||||||
/*0936*/ int32 unknown936; // Seen -1
|
/*0936*/ int32 ForageRelated; // Seen -1 idk
|
||||||
/*0940*/ uint32 unknown940; // Seen 0
|
/*0940*/ uint32 bNoLevitate; // padded bool
|
||||||
/*0944*/ float unknown944; // Seen 1.0 in PoK, and 0.25 in Guild Lobby
|
/*0944*/ float Blooming; // Seen 1.0 in PoK, and 0.25 in Guild Lobby
|
||||||
/*0948*/ uint32 unknown948; // Seen 0 - New on Live as of Dec 15 2014
|
/*0948*/
|
||||||
/*0952*/ uint32 unknown952; // Seen 100 - New on Live as of Dec 15 2014
|
|
||||||
/*0956*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -339,18 +339,7 @@ struct Spawn_Struct_Bitfields
|
|||||||
/*06*/ unsigned sneak:1;
|
/*06*/ unsigned sneak:1;
|
||||||
/*08*/ unsigned lfg:1;
|
/*08*/ unsigned lfg:1;
|
||||||
/*09*/ unsigned unknown09:1;
|
/*09*/ unsigned unknown09:1;
|
||||||
/*10*/ unsigned invis:1; // May have invis & sneak the wrong way around ... not sure how to tell which is which
|
/*10*/ unsigned invis:12; // there are 3000 different (non-GM) invis levels
|
||||||
/*11*/ unsigned invis1:1; // GM Invis? Can only be seen with #gm on - same for the below
|
|
||||||
/*12*/ unsigned invis2:1; // This one also make the NPC/PC invis
|
|
||||||
/*13*/ unsigned invis3:1; // This one also make the NPC/PC invis
|
|
||||||
/*14*/ unsigned invis4:1; // This one also make the NPC/PC invis
|
|
||||||
/*15*/ unsigned invis6:1; // This one also make the NPC/PC invis
|
|
||||||
/*16*/ unsigned invis7:1; // This one also make the NPC/PC invis
|
|
||||||
/*17*/ unsigned invis8:1; // This one also make the NPC/PC invis
|
|
||||||
/*18*/ unsigned invis9:1; // This one also make the NPC/PC invis
|
|
||||||
/*19*/ unsigned invis10:1; // This one also make the NPC/PC invis
|
|
||||||
/*20*/ unsigned invis11:1; // This one also make the NPC/PC invis
|
|
||||||
/*21*/ unsigned invis12:1; // This one also make the NPC/PC invis
|
|
||||||
/*22*/ unsigned linkdead:1; // 1 Toggles LD on or off after name. Correct for RoF
|
/*22*/ unsigned linkdead:1; // 1 Toggles LD on or off after name. Correct for RoF
|
||||||
/*23*/ unsigned showhelm:1;
|
/*23*/ unsigned showhelm:1;
|
||||||
/*24*/ unsigned unknown24:1; // Prefixes name with !
|
/*24*/ unsigned unknown24:1; // Prefixes name with !
|
||||||
|
|||||||
@ -250,8 +250,7 @@ struct Spawn_Struct_Bitfields
|
|||||||
unsigned sneak:1;
|
unsigned sneak:1;
|
||||||
unsigned lfg:1;
|
unsigned lfg:1;
|
||||||
unsigned padding5:1;
|
unsigned padding5:1;
|
||||||
unsigned invis:1; // 0 = visible, 1 = invis/sneaking
|
unsigned invis:12; // there are 3000 different (non-GM) invis levels
|
||||||
unsigned padding7:11;
|
|
||||||
unsigned gm:1;
|
unsigned gm:1;
|
||||||
unsigned anon:2; // 0=normal, 1=anon, 2=roleplay
|
unsigned anon:2; // 0=normal, 1=anon, 2=roleplay
|
||||||
unsigned gender:2; // Gender (0=male, 1=female, 2=monster)
|
unsigned gender:2; // Gender (0=male, 1=female, 2=monster)
|
||||||
|
|||||||
@ -250,8 +250,7 @@ struct Spawn_Struct_Bitfields
|
|||||||
unsigned sneak:1;
|
unsigned sneak:1;
|
||||||
unsigned lfg:1;
|
unsigned lfg:1;
|
||||||
unsigned padding5:1;
|
unsigned padding5:1;
|
||||||
unsigned invis:1; // 0 = visible, 1 = invis/sneaking
|
unsigned invis:12; // there are 3000 different (non-GM) invis levels
|
||||||
unsigned padding7:11;
|
|
||||||
unsigned gm:1;
|
unsigned gm:1;
|
||||||
unsigned anon:2; // 0=normal, 1=anon, 2=roleplay
|
unsigned anon:2; // 0=normal, 1=anon, 2=roleplay
|
||||||
unsigned gender:2; // Gender (0=male, 1=female, 2=monster)
|
unsigned gender:2; // Gender (0=male, 1=female, 2=monster)
|
||||||
|
|||||||
@ -1674,6 +1674,7 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
|
|||||||
for (y = 0; y < 16; y++)
|
for (y = 0; y < 16; y++)
|
||||||
sp[tempid].deities[y]=atoi(row[126+y]);
|
sp[tempid].deities[y]=atoi(row[126+y]);
|
||||||
|
|
||||||
|
sp[tempid].new_icon=atoi(row[144]);
|
||||||
sp[tempid].uninterruptable=atoi(row[146]) != 0;
|
sp[tempid].uninterruptable=atoi(row[146]) != 0;
|
||||||
sp[tempid].ResistDiff=atoi(row[147]);
|
sp[tempid].ResistDiff=atoi(row[147]);
|
||||||
sp[tempid].dot_stacking_exempt = atoi(row[148]) != 0;
|
sp[tempid].dot_stacking_exempt = atoi(row[148]) != 0;
|
||||||
|
|||||||
@ -562,9 +562,9 @@ typedef enum {
|
|||||||
#define SE_LimitManaMin 348 // implemented
|
#define SE_LimitManaMin 348 // implemented
|
||||||
#define SE_ShieldEquipDmgMod 349 // implemented[AA] Increase melee base damage (indirectly increasing hate) when wearing a shield.
|
#define SE_ShieldEquipDmgMod 349 // implemented[AA] Increase melee base damage (indirectly increasing hate) when wearing a shield.
|
||||||
#define SE_ManaBurn 350 // implemented - Drains mana for damage/heal at a defined ratio up to a defined maximum amount of mana.
|
#define SE_ManaBurn 350 // implemented - Drains mana for damage/heal at a defined ratio up to a defined maximum amount of mana.
|
||||||
//#define SE_PersistentEffect 351 // *not implemented. creates a trap/totem that casts a spell (spell id + base1?) when anything comes near it. can probably make a beacon for this
|
#define SE_PersistentEffect 351 // *not implemented. creates a trap/totem that casts a spell (spell id + base1?) when anything comes near it. can probably make a beacon for this
|
||||||
//#define SE_IncreaseTrapCount 352 // *not implemented - looks to be some type of invulnerability? Test ITC (8755)
|
#define SE_IncreaseTrapCount 352 // *not implemented - looks to be some type of invulnerability? Test ITC (8755)
|
||||||
//#define SE_AdditionalAura 353 // *not implemented - allows use of more than 1 aura, aa effect
|
#define SE_AdditionalAura 353 // *not implemented - allows use of more than 1 aura, aa effect
|
||||||
//#define SE_DeactivateAllTraps 354 // *not implemented - looks to be some type of invulnerability? Test DAT (8757)
|
//#define SE_DeactivateAllTraps 354 // *not implemented - looks to be some type of invulnerability? Test DAT (8757)
|
||||||
//#define SE_LearnTrap 355 // *not implemented - looks to be some type of invulnerability? Test LT (8758)
|
//#define SE_LearnTrap 355 // *not implemented - looks to be some type of invulnerability? Test LT (8758)
|
||||||
//#define SE_ChangeTriggerType 356 // not used
|
//#define SE_ChangeTriggerType 356 // not used
|
||||||
@ -757,7 +757,7 @@ struct SPDat_Spell_Struct
|
|||||||
// -- DIETY_BERTOXXULOUS ... DIETY_VEESHAN
|
// -- DIETY_BERTOXXULOUS ... DIETY_VEESHAN
|
||||||
/* 142 */ //int8 npc_no_cast; // 142: between 0 & 100 -- NPC_NO_CAST
|
/* 142 */ //int8 npc_no_cast; // 142: between 0 & 100 -- NPC_NO_CAST
|
||||||
/* 143 */ //int ai_pt_bonus; // 143: always set to 0, client doesn't save this -- AI_PT_BONUS
|
/* 143 */ //int ai_pt_bonus; // 143: always set to 0, client doesn't save this -- AI_PT_BONUS
|
||||||
/* 144 */ //int16 new_icon // Spell icon used by the client in uifiles/default/spells??.tga, both for spell gems & buff window. Looks to depreciate icon & memicon -- NEW_ICON
|
/* 144 */ int16 new_icon; // Spell icon used by the client in uifiles/default/spells??.tga, both for spell gems & buff window. Looks to depreciate icon & memicon -- NEW_ICON
|
||||||
/* 145 */ //int16 spellanim; // Doesn't look like it's the same as #doanim, so not sure what this is, particles I think -- SPELL_EFFECT_INDEX
|
/* 145 */ //int16 spellanim; // Doesn't look like it's the same as #doanim, so not sure what this is, particles I think -- SPELL_EFFECT_INDEX
|
||||||
/* 146 */ bool uninterruptable; // Looks like anything != 0 is uninterruptable. Values are mostly -1, 0, & 1 (Fetid Breath = 90?) -- NO_INTERRUPT
|
/* 146 */ bool uninterruptable; // Looks like anything != 0 is uninterruptable. Values are mostly -1, 0, & 1 (Fetid Breath = 90?) -- NO_INTERRUPT
|
||||||
/* 147 */ int16 ResistDiff; // -- RESIST_MOD
|
/* 147 */ int16 ResistDiff; // -- RESIST_MOD
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9113
|
#define CURRENT_BINARY_DATABASE_VERSION 9114
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9017
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9017
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -672,3 +672,7 @@ OP_Some3ByteHPUpdate=0x0000 # initial HP update for mobs
|
|||||||
OP_InitialHPUpdate=0x0000
|
OP_InitialHPUpdate=0x0000
|
||||||
|
|
||||||
OP_ItemRecastDelay=0x57ed
|
OP_ItemRecastDelay=0x57ed
|
||||||
|
|
||||||
|
#aura related
|
||||||
|
OP_UpdateAura=0x1fa9
|
||||||
|
OP_RemoveTrap=0x6a4d
|
||||||
|
|||||||
@ -675,3 +675,7 @@ OP_RAWOutOfSession=0x0000
|
|||||||
# we need to document the differences between these packets to make identifying them easier
|
# we need to document the differences between these packets to make identifying them easier
|
||||||
OP_Some3ByteHPUpdate=0x0000 # initial HP update for mobs
|
OP_Some3ByteHPUpdate=0x0000 # initial HP update for mobs
|
||||||
OP_InitialHPUpdate=0x0000
|
OP_InitialHPUpdate=0x0000
|
||||||
|
|
||||||
|
#aura related
|
||||||
|
OP_UpdateAura=0x1456
|
||||||
|
OP_RemoveTrap=0x71da
|
||||||
|
|||||||
@ -669,3 +669,7 @@ OP_Some3ByteHPUpdate=0x0000 # initial HP update for mobs
|
|||||||
OP_InitialHPUpdate=0x0000 #
|
OP_InitialHPUpdate=0x0000 #
|
||||||
|
|
||||||
OP_ItemRecastDelay=0x15c4
|
OP_ItemRecastDelay=0x15c4
|
||||||
|
|
||||||
|
#aura related
|
||||||
|
OP_UpdateAura=0x169a
|
||||||
|
OP_RemoveTrap=0x4bb6
|
||||||
|
|||||||
@ -658,3 +658,7 @@ OP_ItemRecastDelay=0x0ada
|
|||||||
#OP_NpcMoveUpdate=0x0d11 #SEQ 10/07/08 --NEW FROM SEQ
|
#OP_NpcMoveUpdate=0x0d11 #SEQ 10/07/08 --NEW FROM SEQ
|
||||||
#OP_Zone_MissingName01=0x0000 #
|
#OP_Zone_MissingName01=0x0000 #
|
||||||
#new titles avaliable: #
|
#new titles avaliable: #
|
||||||
|
|
||||||
|
#aura related
|
||||||
|
OP_UpdateAura=0x62a9
|
||||||
|
OP_RemoveTrap=0x7bd9
|
||||||
|
|||||||
@ -685,3 +685,7 @@ OP_ItemRecastDelay=0x82d7
|
|||||||
|
|
||||||
# unhandled
|
# unhandled
|
||||||
OP_ShieldGroup=0x23a1
|
OP_ShieldGroup=0x23a1
|
||||||
|
|
||||||
|
#aura related
|
||||||
|
OP_UpdateAura=0x2480
|
||||||
|
OP_RemoveTrap=0x0115
|
||||||
|
|||||||
@ -367,6 +367,7 @@
|
|||||||
9111|2017_06_24_saylink_index.sql|SHOW INDEX FROM `saylink` WHERE `key_name` = 'phrase_index'|empty|
|
9111|2017_06_24_saylink_index.sql|SHOW INDEX FROM `saylink` WHERE `key_name` = 'phrase_index'|empty|
|
||||||
9112|2017_06_24_rule_values_expand.sql|SHOW COLUMNS FROM rule_values WHERE Field = 'rule_value' and Type = 'varchar(30)'|empty|
|
9112|2017_06_24_rule_values_expand.sql|SHOW COLUMNS FROM rule_values WHERE Field = 'rule_value' and Type = 'varchar(30)'|empty|
|
||||||
9113|2017_07_19_show_name.sql|SHOW COLUMNS FROM `npc_types` LIKE 'show_name'|empty|
|
9113|2017_07_19_show_name.sql|SHOW COLUMNS FROM `npc_types` LIKE 'show_name'|empty|
|
||||||
|
9114|2017_07_22_aura.sql|SHOW TABLES LIKE 'auras'|empty|
|
||||||
|
|
||||||
# Upgrade conditions:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
127
utils/sql/git/required/2017_07_22_aura.sql
Normal file
127
utils/sql/git/required/2017_07_22_aura.sql
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
CREATE TABLE `auras` (
|
||||||
|
`type` INT(10) NOT NULL,
|
||||||
|
`npc_type` INT(10) NOT NULL,
|
||||||
|
`name` VARCHAR(64) NOT NULL,
|
||||||
|
`spell_id` INT(10) NOT NULL,
|
||||||
|
`distance` INT(10) NOT NULL DEFAULT 60,
|
||||||
|
`aura_type` INT(10) NOT NULL DEFAULT 1,
|
||||||
|
`spawn_type` INT(10) NOT NULL DEFAULT 0,
|
||||||
|
`movement` INT(10) NOT NULL DEFAULT 0,
|
||||||
|
`duration` INT(10) NOT NULL DEFAULT 5400,
|
||||||
|
`icon` INT(10) NOT NULL DEFAULT -1,
|
||||||
|
`cast_time` INT(10) NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY(`type`)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE `character_auras` (
|
||||||
|
`id` INT(10) NOT NULL,
|
||||||
|
`slot` TINYINT(10) NOT NULL,
|
||||||
|
`spell_id` INT(10) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`, `slot`)
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOAuraOfTheMuse55", lastname="", level="55", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8926, npc_type=@suggestedid, name="Aura_of_Insight", spell_id=8939, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=99, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOAuraOfTheMuse", lastname="", level="70", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8488, npc_type=@suggestedid, name="Aura_of_the_Muse", spell_id=8489, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOChampionsAura55", lastname="", level="55", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8921, npc_type=@suggestedid, name="Myrmidon's_Aura", spell_id=8935, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOChampionsAura", lastname="", level="70", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8468, npc_type=@suggestedid, name="Champion's_Aura", spell_id=8469, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOBlessedAura55", lastname="", level="55", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8925, npc_type=@suggestedid, name="Holy_Aura", spell_id=8938, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOBlessedAura", lastname="", level="70", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8481, npc_type=@suggestedid, name="Blessed_Aura", spell_id=8482, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOMastersAura55", lastname="", level="55", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8923, npc_type=@suggestedid, name="Disciples_Aura", spell_id=8937, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOMastersAura", lastname="", level="70", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8474, npc_type=@suggestedid, name="Master's_Aura", spell_id=8475, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOQuicksandTrap55", lastname="", level="55", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8933, npc_type=@suggestedid, name="Earthen_Strength", spell_id=8948, distance=60, aura_type=2, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOQuicksandTrap", lastname="", level="70", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8518, npc_type=@suggestedid, name="Rathe's_Strength", spell_id=8519, distance=60, aura_type=2, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOIllusionistsAura55", lastname="", level="55", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8931, npc_type=@suggestedid, name="Beguiler's_Aura", spell_id=8946, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOIllusionistsAura", lastname="", level="70", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8509, npc_type=@suggestedid, name="Illusionist's_Aura", spell_id=8510, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOLivingVineTrap55", lastname="", level="55", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8929, npc_type=@suggestedid, name="Aura_of_the_Grove", spell_id=8943, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=1, cast_time=12;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOLivingVineTrap", lastname="", level="70", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8499, npc_type=@suggestedid, name="Aura_of_Life", spell_id=8500, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=1, cast_time=12;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOAuraOfThePious55", lastname="", level="55", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8928, npc_type=@suggestedid, name="Aura_of_the_Zealot", spell_id=8940, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOAuraOfThePious", lastname="", level="70", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8495, npc_type=@suggestedid, name="Aura_of_the_Pious", spell_id=8496, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOBloodlustAura55", lastname="", level="55", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8924, npc_type=@suggestedid, name="Aura_of_Rage", spell_id=8959, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOBloodlustAura", lastname="", level="70", race="127", class="62", bodytype="11", hp="4027.6216", mana="0.0000", gender="0", texture="0", helmtexture="0", herosforgemodel="0", size="2", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8477, npc_type=@suggestedid, name="Bloodlust_Aura", spell_id=8478, distance=60, aura_type=1, spawn_type=0, movement=0, duration=5400, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOIdolOfMalaTrap55", lastname="", level="55", race="514", class="62", bodytype="5", hp="4027.6216", mana="0.0000", gender="2", texture="0", helmtexture="0", herosforgemodel="0", size="2.5", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8930, npc_type=@suggestedid, name="Soul_Idol", spell_id=8945, distance=60, aura_type=3, spawn_type=1, movement=1, duration=120, icon=-1, cast_time=12;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOIdolOfMalaTrap", lastname="", level="70", race="514", class="62", bodytype="5", hp="4027.6216", mana="0.0000", gender="2", texture="0", helmtexture="0", herosforgemodel="0", size="2.5", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8504, npc_type=@suggestedid, name="Spirit_Idol", spell_id=8505, distance=60, aura_type=3, spawn_type=1, movement=1, duration=120, icon=-1, cast_time=12;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IODeathRuneTrap55", lastname="", level="55", race="510", class="62", bodytype="5", hp="4027.6216", mana="0.0000", gender="2", texture="0", helmtexture="0", herosforgemodel="0", size="3", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8934, npc_type=@suggestedid, name="a_dark_rune", spell_id=8949, distance=25, aura_type=4, spawn_type=1, movement=1, duration=120, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IODeathRuneTrap", lastname="", level="70", race="510", class="62", bodytype="5", hp="4027.6216", mana="0.0000", gender="2", texture="0", helmtexture="0", herosforgemodel="0", size="3", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8523, npc_type=@suggestedid, name="a_death_rune", spell_id=8524, distance=25, aura_type=4, spawn_type=1, movement=1, duration=120, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOFireRuneTrap55", lastname="", level="55", race="510", class="62", bodytype="5", hp="4027.6216", mana="0.0000", gender="2", texture="0", helmtexture="0", herosforgemodel="0", size="3", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8932, npc_type=@suggestedid, name="a_fiery_rune", spell_id=8947, distance=25, aura_type=4, spawn_type=1, movement=1, duration=120, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOFireRuneTrap", lastname="", level="70", race="510", class="62", bodytype="5", hp="4027.6216", mana="0.0000", gender="2", texture="0", helmtexture="0", herosforgemodel="0", size="3", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8513, npc_type=@suggestedid, name="a_fire_rune", spell_id=8514, distance=25, aura_type=4, spawn_type=1, movement=1, duration=120, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOPoisonSpikesTrap55", lastname="", level="55", race="513", class="62", bodytype="5", hp="4027.6216", mana="0.0000", gender="2", texture="0", helmtexture="0", herosforgemodel="0", size="3", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8922, npc_type=@suggestedid, name="poison_spurs", spell_id=8936, distance=25, aura_type=4, spawn_type=1, movement=1, duration=120, icon=-1, cast_time=-1;
|
||||||
|
|
||||||
|
SELECT IFNULL((MAX(id) + 1), 2000000) INTO @suggestedid FROM npc_types where id LIKE '2000___';
|
||||||
|
INSERT INTO npc_types SET id=@suggestedid, name="IOPoisonSpikesTrap", lastname="", level="70", race="513", class="62", bodytype="5", hp="4027.6216", mana="0.0000", gender="2", texture="0", helmtexture="0", herosforgemodel="0", size="3", hp_regen_rate="0", mana_regen_rate="0", loottable_id="0", npc_spells_id="0", mindmg="52.7514", maxdmg="166.8270", attack_count="-1", special_abilities="12,1^13,1^14,1^15,1^16,1^17,1^18,1^19,1^20,1^21,1^22,1^23,1^24,1^25,1^28,1^31,1^35,1^", aggroradius="70", assistradius="0", face="0", luclin_hairstyle="0", luclin_haircolor="0", luclin_eyecolor="0", luclin_eyecolor2="0", luclin_beardcolor="0", luclin_beard="0", drakkin_heritage="0", drakkin_tattoo="0", drakkin_details="0", armortint_red="0", armortint_green="0", armortint_blue="0", d_melee_texture1="0", d_melee_texture2="0", prim_melee_type="28", sec_melee_type="28", runspeed="1.25", MR="21.1027", CR="21.1027", DR="21.1027", FR="21.1027", PR="21.1027", Corrup="21.1027", PhR="48.3333", see_invis="0", see_invis_undead="0", qglobal="0", AC="257.3784", npc_aggro="0", spawn_limit="0", attack_delay="29.4486", findable="0", STR="205.0000", STA="205.0000", DEX="205.0000", AGI="205.0000", _INT="205.0000", WIS="205.0000", CHA="205.0000", see_hide="0", see_improved_hide="0", trackable="0", ATK="0", Accuracy="0", Avoidance="0", slow_mitigation="0", version="0", maxlevel="0", scalerate="100", private_corpse="0", unique_spawn_by_name="0", underwater="0", emoteid="0", spellscale="100", healscale="100", no_target_hotkey="0", raid_target="0", light="0", ignore_despawn="0", show_name="0";
|
||||||
|
INSERT INTO auras SET type=8471, npc_type=@suggestedid, name="Poison Spikes", spell_id=8472, distance=25, aura_type=4, spawn_type=1, movement=1, duration=120, icon=-1, cast_time=-1;
|
||||||
|
UPDATE npc_types SET special_abilities = TRIM(TRAILING '^' FROM special_abilities);
|
||||||
|
|
||||||
@ -5,6 +5,7 @@ SET(zone_sources
|
|||||||
aa_ability.cpp
|
aa_ability.cpp
|
||||||
aggro.cpp
|
aggro.cpp
|
||||||
aggromanager.cpp
|
aggromanager.cpp
|
||||||
|
aura.cpp
|
||||||
attack.cpp
|
attack.cpp
|
||||||
beacon.cpp
|
beacon.cpp
|
||||||
bonuses.cpp
|
bonuses.cpp
|
||||||
@ -140,6 +141,7 @@ SET(zone_headers
|
|||||||
aa.h
|
aa.h
|
||||||
aa_ability.h
|
aa_ability.h
|
||||||
aggromanager.h
|
aggromanager.h
|
||||||
|
aura.h
|
||||||
basic_functions.h
|
basic_functions.h
|
||||||
beacon.h
|
beacon.h
|
||||||
bot.h
|
bot.h
|
||||||
|
|||||||
936
zone/aura.cpp
Normal file
936
zone/aura.cpp
Normal file
@ -0,0 +1,936 @@
|
|||||||
|
#include "../common/string_util.h"
|
||||||
|
|
||||||
|
#include "aura.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "string_ids.h"
|
||||||
|
#include "raids.h"
|
||||||
|
|
||||||
|
Aura::Aura(NPCType *type_data, Mob *owner, AuraRecord &record)
|
||||||
|
: NPC(type_data, 0, owner->GetPosition(), FlyMode3), spell_id(record.spell_id), distance(record.distance),
|
||||||
|
remove_timer(record.duration), movement_timer(100), process_timer(100), aura_id(-1)
|
||||||
|
{
|
||||||
|
GiveNPCTypeData(type_data); // we will delete this later on
|
||||||
|
m_owner = owner->GetID();
|
||||||
|
|
||||||
|
if (record.cast_time) {
|
||||||
|
cast_timer.SetTimer(record.cast_time);
|
||||||
|
cast_timer.Disable(); // we don't want to be enabled yet
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.aura_type < static_cast<int>(AuraType::Max))
|
||||||
|
type = static_cast<AuraType>(record.aura_type);
|
||||||
|
else
|
||||||
|
type = AuraType::OnAllGroupMembers;
|
||||||
|
|
||||||
|
if (record.spawn_type < static_cast<int>(AuraSpawns::Max))
|
||||||
|
spawn_type = static_cast<AuraSpawns>(record.spawn_type);
|
||||||
|
else
|
||||||
|
spawn_type = AuraSpawns::GroupMembers;
|
||||||
|
|
||||||
|
if (record.movement < static_cast<int>(AuraMovement::Max))
|
||||||
|
movement_type = static_cast<AuraMovement>(record.movement);
|
||||||
|
else
|
||||||
|
movement_type = AuraMovement::Follow;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case AuraType::OnAllFriendlies:
|
||||||
|
process_func = &Aura::ProcessOnAllFriendlies;
|
||||||
|
break;
|
||||||
|
case AuraType::OnAllGroupMembers:
|
||||||
|
process_func = &Aura::ProcessOnAllGroupMembers;
|
||||||
|
break;
|
||||||
|
case AuraType::OnGroupMembersPets:
|
||||||
|
process_func = &Aura::ProcessOnGroupMembersPets;
|
||||||
|
break;
|
||||||
|
case AuraType::Totem:
|
||||||
|
process_func = &Aura::ProcessTotem;
|
||||||
|
break;
|
||||||
|
case AuraType::EnterTrap:
|
||||||
|
process_func = &Aura::ProcessEnterTrap;
|
||||||
|
break;
|
||||||
|
case AuraType::ExitTrap:
|
||||||
|
process_func = &Aura::ProcessExitTrap;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
process_func = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mob *Aura::GetOwner()
|
||||||
|
{
|
||||||
|
return entity_list.GetMob(m_owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// not 100% sure how this one should work and PVP affects ...
|
||||||
|
void Aura::ProcessOnAllFriendlies(Mob *owner)
|
||||||
|
{
|
||||||
|
auto &mob_list = entity_list.GetMobList(); // read only reference so we can do it all inline
|
||||||
|
std::set<int> delayed_remove;
|
||||||
|
bool is_buff = IsBuffSpell(spell_id); // non-buff spells don't cast on enter
|
||||||
|
|
||||||
|
for (auto &e : mob_list) {
|
||||||
|
auto mob = e.second;
|
||||||
|
if (mob->IsClient() || mob->IsPetOwnerClient() || mob->IsMerc()) {
|
||||||
|
auto it = casted_on.find(mob->GetID());
|
||||||
|
|
||||||
|
if (it != casted_on.end()) { // we are already on the list, let's check for removal
|
||||||
|
if (DistanceSquared(GetPosition(), mob->GetPosition()) > distance)
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
} else { // not on list, lets check if we're in range
|
||||||
|
if (DistanceSquared(GetPosition(), mob->GetPosition()) <= distance) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &e : delayed_remove) {
|
||||||
|
auto mob = entity_list.GetMob(e);
|
||||||
|
if (mob != nullptr && is_buff) // some auras cast instant spells so no need to remove
|
||||||
|
mob->BuffFadeBySpellIDAndCaster(spell_id, GetID());
|
||||||
|
casted_on.erase(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// so if we have a cast timer and our set isn't empty and timer is disabled we need to enable it
|
||||||
|
if (cast_timer.GetDuration() > 0 && !cast_timer.Enabled() && !casted_on.empty())
|
||||||
|
cast_timer.Start();
|
||||||
|
|
||||||
|
if (!cast_timer.Enabled() || !cast_timer.Check())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto &e : casted_on) {
|
||||||
|
auto mob = entity_list.GetMob(e);
|
||||||
|
if (mob != nullptr)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aura::ProcessOnAllGroupMembers(Mob *owner)
|
||||||
|
{
|
||||||
|
auto &mob_list = entity_list.GetMobList(); // read only reference so we can do it all inline
|
||||||
|
std::set<int> delayed_remove;
|
||||||
|
bool is_buff = IsBuffSpell(spell_id); // non-buff spells don't cast on enter
|
||||||
|
|
||||||
|
if (owner->IsRaidGrouped() && owner->IsClient()) { // currently raids are just client, but safety check
|
||||||
|
auto raid = owner->GetRaid();
|
||||||
|
if (raid == nullptr) { // well shit
|
||||||
|
owner->RemoveAura(GetID(), false, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto group_id = raid->GetGroup(owner->CastToClient());
|
||||||
|
|
||||||
|
// some lambdas so the for loop is less horrible ...
|
||||||
|
auto verify_raid_client = [&raid, &group_id, this](Client *c) {
|
||||||
|
auto idx = raid->GetPlayerIndex(c);
|
||||||
|
if (c->GetID() == m_owner) {
|
||||||
|
return DistanceSquared(GetPosition(), c->GetPosition()) <= distance;
|
||||||
|
} else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || raid->members[idx].GroupNumber == 0xFFFFFFFF) {
|
||||||
|
return false;
|
||||||
|
} else if (DistanceSquared(GetPosition(), c->GetPosition()) > distance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto verify_raid_client_pet = [&raid, &group_id, this](Mob *m) {
|
||||||
|
auto idx = raid->GetPlayerIndex(m->GetOwner()->CastToClient());
|
||||||
|
if (m->GetOwner()->GetID() == m_owner) {
|
||||||
|
return DistanceSquared(GetPosition(), m->GetPosition()) <= distance;
|
||||||
|
} else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || raid->members[idx].GroupNumber == 0xFFFFFFFF) {
|
||||||
|
return false;
|
||||||
|
} else if (DistanceSquared(GetPosition(), m->GetPosition()) > distance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto verify_raid_client_swarm = [&raid, &group_id, this](NPC *n) {
|
||||||
|
auto owner = entity_list.GetMob(n->GetSwarmOwner());
|
||||||
|
if (owner == nullptr)
|
||||||
|
return false;
|
||||||
|
auto idx = raid->GetPlayerIndex(owner->CastToClient());
|
||||||
|
if (owner->GetID() == m_owner) {
|
||||||
|
return DistanceSquared(GetPosition(), n->GetPosition()) <= distance;
|
||||||
|
} else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || raid->members[idx].GroupNumber == 0xFFFFFFFF) {
|
||||||
|
return false;
|
||||||
|
} else if (DistanceSquared(GetPosition(), n->GetPosition()) > distance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &e : mob_list) {
|
||||||
|
auto mob = e.second;
|
||||||
|
// step 1: check if we're already managing this NPC's buff
|
||||||
|
auto it = casted_on.find(mob->GetID());
|
||||||
|
if (it != casted_on.end()) {
|
||||||
|
// verify still good!
|
||||||
|
if (mob->IsClient()) {
|
||||||
|
if (!verify_raid_client(mob->CastToClient()))
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
} else if (mob->IsPet() && mob->IsPetOwnerClient() && mob->GetOwner()) {
|
||||||
|
if (!verify_raid_client_pet(mob))
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
} else if (mob->IsNPC() && mob->IsPetOwnerClient()) {
|
||||||
|
auto npc = mob->CastToNPC();
|
||||||
|
if (!verify_raid_client_swarm(npc))
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
}
|
||||||
|
} else { // we're not on it!
|
||||||
|
if (mob->IsClient() && verify_raid_client(mob->CastToClient())) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
} else if (mob->IsPet() && mob->IsPetOwnerClient() && mob->GetOwner() && verify_raid_client_pet(mob)) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
} else if (mob->IsNPC() && mob->IsPetOwnerClient()) {
|
||||||
|
auto npc = mob->CastToNPC();
|
||||||
|
if (verify_raid_client_swarm(npc)) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (owner->IsGrouped()) {
|
||||||
|
auto group = owner->GetGroup();
|
||||||
|
if (group == nullptr) { // uh oh
|
||||||
|
owner->RemoveAura(GetID(), false, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lambdas to make for loop less ugly
|
||||||
|
auto verify_group_pet = [&group, this](Mob *m) {
|
||||||
|
auto owner = m->GetOwner();
|
||||||
|
if (owner != nullptr && group->IsGroupMember(owner) && DistanceSquared(GetPosition(), m->GetPosition()) <= distance)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto verify_group_swarm = [&group, this](NPC *n) {
|
||||||
|
auto owner = entity_list.GetMob(n->GetSwarmOwner());
|
||||||
|
if (owner != nullptr && group->IsGroupMember(owner) && DistanceSquared(GetPosition(), n->GetPosition()) <= distance)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &e : mob_list) {
|
||||||
|
auto mob = e.second;
|
||||||
|
auto it = casted_on.find(mob->GetID());
|
||||||
|
|
||||||
|
if (it != casted_on.end()) { // make sure we're still valid
|
||||||
|
if (mob->IsPet()) {
|
||||||
|
if (!verify_group_pet(mob))
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
} else if (mob->IsNPC() && mob->CastToNPC()->GetSwarmInfo()) {
|
||||||
|
if (!verify_group_swarm(mob->CastToNPC()))
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
} else if (!group->IsGroupMember(mob) || DistanceSquared(GetPosition(), mob->GetPosition()) > distance) {
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
}
|
||||||
|
} else { // not on, check if we should be!
|
||||||
|
if (mob->IsPet() && verify_group_pet(mob)) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
} else if (mob->IsNPC() && mob->CastToNPC()->GetSwarmInfo() && verify_group_swarm(mob->CastToNPC())) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
} else if (group->IsGroupMember(mob) && DistanceSquared(GetPosition(), mob->GetPosition()) <= distance) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto verify_solo = [&owner, this](Mob *m) {
|
||||||
|
if (m->IsPet() && m->GetOwnerID() == owner->GetID())
|
||||||
|
return true;
|
||||||
|
else if (m->IsNPC() && m->CastToNPC()->GetSwarmOwner() == owner->GetID())
|
||||||
|
return true;
|
||||||
|
else if (m->GetID() == owner->GetID())
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
for (auto &e : mob_list) {
|
||||||
|
auto mob = e.second;
|
||||||
|
auto it = casted_on.find(mob->GetID());
|
||||||
|
bool good = verify_solo(mob);
|
||||||
|
|
||||||
|
if (it != casted_on.end()) { // make sure still valid
|
||||||
|
if (!good || DistanceSquared(GetPosition(), mob->GetPosition()) > distance) {
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
}
|
||||||
|
} else if (good && DistanceSquared(GetPosition(), mob->GetPosition()) <= distance) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &e : delayed_remove) {
|
||||||
|
auto mob = entity_list.GetMob(e);
|
||||||
|
if (mob != nullptr && is_buff) // some auras cast instant spells so no need to remove
|
||||||
|
mob->BuffFadeBySpellIDAndCaster(spell_id, GetID());
|
||||||
|
casted_on.erase(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// so if we have a cast timer and our set isn't empty and timer is disabled we need to enable it
|
||||||
|
if (cast_timer.GetDuration() > 0 && !cast_timer.Enabled() && !casted_on.empty())
|
||||||
|
cast_timer.Start();
|
||||||
|
|
||||||
|
if (!cast_timer.Enabled() || !cast_timer.Check())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// some auras have to recast (DRU for example, non-buff too)
|
||||||
|
for (auto &e : casted_on) {
|
||||||
|
auto mob = entity_list.GetMob(e);
|
||||||
|
if (mob != nullptr)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aura::ProcessOnGroupMembersPets(Mob *owner)
|
||||||
|
{
|
||||||
|
auto &mob_list = entity_list.GetMobList(); // read only reference so we can do it all inline
|
||||||
|
std::set<int> delayed_remove;
|
||||||
|
bool is_buff = IsBuffSpell(spell_id); // non-buff spells don't cast on enter
|
||||||
|
// This type can either live on the pet (level 55/70 MAG aura) or on the pet owner (level 85 MAG aura)
|
||||||
|
auto group_member = owner->GetOwnerOrSelf();
|
||||||
|
|
||||||
|
if (group_member->IsRaidGrouped() && group_member->IsClient()) { // currently raids are just client, but safety check
|
||||||
|
auto raid = group_member->GetRaid();
|
||||||
|
if (raid == nullptr) { // well shit
|
||||||
|
owner->RemoveAura(GetID(), false, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto group_id = raid->GetGroup(group_member->CastToClient());
|
||||||
|
|
||||||
|
// some lambdas so the for loop is less horrible ...
|
||||||
|
auto verify_raid_client_pet = [&raid, &group_id, &group_member, this](Mob *m) {
|
||||||
|
auto idx = raid->GetPlayerIndex(m->GetOwner()->CastToClient());
|
||||||
|
if (m->GetOwner()->GetID() == group_member->GetID()) {
|
||||||
|
return DistanceSquared(GetPosition(), m->GetPosition()) <= distance;
|
||||||
|
} else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || raid->members[idx].GroupNumber == 0xFFFFFFFF) {
|
||||||
|
return false;
|
||||||
|
} else if (DistanceSquared(GetPosition(), m->GetPosition()) > distance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto verify_raid_client_swarm = [&raid, &group_id, &group_member, this](NPC *n) {
|
||||||
|
auto owner = entity_list.GetMob(n->GetSwarmOwner());
|
||||||
|
if (owner == nullptr)
|
||||||
|
return false;
|
||||||
|
auto idx = raid->GetPlayerIndex(owner->CastToClient());
|
||||||
|
if (owner->GetID() == group_member->GetID()) {
|
||||||
|
return DistanceSquared(GetPosition(), n->GetPosition()) <= distance;
|
||||||
|
} else if (idx == 0xFFFFFFFF || raid->members[idx].GroupNumber != group_id || raid->members[idx].GroupNumber == 0xFFFFFFFF) {
|
||||||
|
return false;
|
||||||
|
} else if (DistanceSquared(GetPosition(), n->GetPosition()) > distance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &e : mob_list) {
|
||||||
|
auto mob = e.second;
|
||||||
|
// step 1: check if we're already managing this NPC's buff
|
||||||
|
auto it = casted_on.find(mob->GetID());
|
||||||
|
if (it != casted_on.end()) {
|
||||||
|
// verify still good!
|
||||||
|
if (mob->IsPet() && mob->IsPetOwnerClient() && mob->GetOwner()) {
|
||||||
|
if (!verify_raid_client_pet(mob))
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
} else if (mob->IsNPC() && mob->IsPetOwnerClient()) {
|
||||||
|
auto npc = mob->CastToNPC();
|
||||||
|
if (!verify_raid_client_swarm(npc))
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
}
|
||||||
|
} else { // we're not on it!
|
||||||
|
if (mob->IsClient()) {
|
||||||
|
continue; // never hit client
|
||||||
|
} else if (mob->IsPet() && mob->IsPetOwnerClient() && mob->GetOwner() && verify_raid_client_pet(mob)) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
} else if (mob->IsNPC() && mob->IsPetOwnerClient()) {
|
||||||
|
auto npc = mob->CastToNPC();
|
||||||
|
if (verify_raid_client_swarm(npc)) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (group_member->IsGrouped()) {
|
||||||
|
auto group = group_member->GetGroup();
|
||||||
|
if (group == nullptr) { // uh oh
|
||||||
|
owner->RemoveAura(GetID(), false, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lambdas to make for loop less ugly
|
||||||
|
auto verify_group_pet = [&group, this](Mob *m) {
|
||||||
|
auto owner = m->GetOwner();
|
||||||
|
if (owner != nullptr && group->IsGroupMember(owner) && DistanceSquared(GetPosition(), m->GetPosition()) <= distance)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto verify_group_swarm = [&group, this](NPC *n) {
|
||||||
|
auto owner = entity_list.GetMob(n->GetSwarmOwner());
|
||||||
|
if (owner != nullptr && group->IsGroupMember(owner) && DistanceSquared(GetPosition(), n->GetPosition()) <= distance)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &e : mob_list) {
|
||||||
|
auto mob = e.second;
|
||||||
|
auto it = casted_on.find(mob->GetID());
|
||||||
|
|
||||||
|
if (it != casted_on.end()) { // make sure we're still valid
|
||||||
|
if (mob->IsPet()) {
|
||||||
|
if (!verify_group_pet(mob))
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
} else if (mob->IsNPC() && mob->CastToNPC()->GetSwarmInfo()) {
|
||||||
|
if (!verify_group_swarm(mob->CastToNPC()))
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
}
|
||||||
|
} else { // not on, check if we should be!
|
||||||
|
if (mob->IsClient()) {
|
||||||
|
continue;
|
||||||
|
} else if (mob->IsPet() && verify_group_pet(mob)) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
} else if (mob->IsNPC() && mob->CastToNPC()->GetSwarmInfo() && verify_group_swarm(mob->CastToNPC())) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto verify_solo = [&group_member, this](Mob *m) {
|
||||||
|
if (m->IsPet() && m->GetOwnerID() == group_member->GetID())
|
||||||
|
return true;
|
||||||
|
else if (m->IsNPC() && m->CastToNPC()->GetSwarmOwner() == group_member->GetID())
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
for (auto &e : mob_list) {
|
||||||
|
auto mob = e.second;
|
||||||
|
auto it = casted_on.find(mob->GetID());
|
||||||
|
bool good = verify_solo(mob);
|
||||||
|
|
||||||
|
if (it != casted_on.end()) { // make sure still valid
|
||||||
|
if (!good || DistanceSquared(GetPosition(), mob->GetPosition()) > distance) {
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
}
|
||||||
|
} else if (good && DistanceSquared(GetPosition(), mob->GetPosition()) <= distance) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
if (is_buff)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &e : delayed_remove) {
|
||||||
|
auto mob = entity_list.GetMob(e);
|
||||||
|
if (mob != nullptr && is_buff) // some auras cast instant spells so no need to remove
|
||||||
|
mob->BuffFadeBySpellIDAndCaster(spell_id, GetID());
|
||||||
|
casted_on.erase(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// so if we have a cast timer and our set isn't empty and timer is disabled we need to enable it
|
||||||
|
if (cast_timer.GetDuration() > 0 && !cast_timer.Enabled() && !casted_on.empty())
|
||||||
|
cast_timer.Start();
|
||||||
|
|
||||||
|
if (!cast_timer.Enabled() || !cast_timer.Check())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// some auras have to recast (DRU for example, non-buff too)
|
||||||
|
for (auto &e : casted_on) {
|
||||||
|
auto mob = entity_list.GetMob(e);
|
||||||
|
if (mob != nullptr)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aura::ProcessTotem(Mob *owner)
|
||||||
|
{
|
||||||
|
auto &mob_list = entity_list.GetMobList(); // read only reference so we can do it all inline
|
||||||
|
std::set<int> delayed_remove;
|
||||||
|
bool is_buff = IsBuffSpell(spell_id); // non-buff spells don't cast on enter
|
||||||
|
|
||||||
|
for (auto &e : mob_list) {
|
||||||
|
auto mob = e.second;
|
||||||
|
if (mob == this)
|
||||||
|
continue;
|
||||||
|
if (mob == owner)
|
||||||
|
continue;
|
||||||
|
if (owner->IsAttackAllowed(mob)) { // might need more checks ...
|
||||||
|
bool in_range = DistanceSquared(GetPosition(), mob->GetPosition()) <= distance;
|
||||||
|
auto it = casted_on.find(mob->GetID());
|
||||||
|
if (it != casted_on.end()) {
|
||||||
|
if (!in_range)
|
||||||
|
delayed_remove.insert(mob->GetID());
|
||||||
|
} else if (in_range) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &e : delayed_remove) {
|
||||||
|
auto mob = entity_list.GetMob(e);
|
||||||
|
if (mob != nullptr && is_buff) // some auras cast instant spells so no need to remove
|
||||||
|
mob->BuffFadeBySpellIDAndCaster(spell_id, GetID());
|
||||||
|
casted_on.erase(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// so if we have a cast timer and our set isn't empty and timer is disabled we need to enable it
|
||||||
|
if (cast_timer.GetDuration() > 0 && !cast_timer.Enabled() && !casted_on.empty())
|
||||||
|
cast_timer.Start();
|
||||||
|
|
||||||
|
if (!cast_timer.Enabled() || !cast_timer.Check())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto &e : casted_on) {
|
||||||
|
auto mob = entity_list.GetMob(e);
|
||||||
|
if (mob != nullptr)
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aura::ProcessEnterTrap(Mob *owner)
|
||||||
|
{
|
||||||
|
auto &mob_list = entity_list.GetMobList(); // read only reference so we can do it all inline
|
||||||
|
|
||||||
|
for (auto &e : mob_list) {
|
||||||
|
auto mob = e.second;
|
||||||
|
if (mob == this)
|
||||||
|
continue;
|
||||||
|
// might need more checks ...
|
||||||
|
if (owner->IsAttackAllowed(mob) && DistanceSquared(GetPosition(), mob->GetPosition()) <= distance) {
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
owner->RemoveAura(GetID(), false); // if we're a buff (ex. NEC) we don't want to strip :P
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aura::ProcessExitTrap(Mob *owner)
|
||||||
|
{
|
||||||
|
auto &mob_list = entity_list.GetMobList(); // read only reference so we can do it all inline
|
||||||
|
|
||||||
|
for (auto &e : mob_list) {
|
||||||
|
auto mob = e.second;
|
||||||
|
if (mob == this)
|
||||||
|
continue;
|
||||||
|
// might need more checks ...
|
||||||
|
if (owner->IsAttackAllowed(mob)) {
|
||||||
|
bool in_range = DistanceSquared(GetPosition(), mob->GetPosition()) <= distance;
|
||||||
|
auto it = casted_on.find(mob->GetID());
|
||||||
|
if (it != casted_on.end()) {
|
||||||
|
if (!in_range) {
|
||||||
|
SpellFinished(spell_id, mob);
|
||||||
|
owner->RemoveAura(GetID(), false); // if we're a buff we don't want to strip :P
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (in_range) {
|
||||||
|
casted_on.insert(mob->GetID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is less than ideal, but other solutions are a bit all over the place
|
||||||
|
// and hard to reason about
|
||||||
|
void Aura::ProcessSpawns()
|
||||||
|
{
|
||||||
|
const auto &clients = entity_list.GetClientList();
|
||||||
|
for (auto &e : clients) {
|
||||||
|
auto c = e.second;
|
||||||
|
bool spawned = spawned_for.find(c->GetID()) != spawned_for.end();
|
||||||
|
if (ShouldISpawnFor(c)) {
|
||||||
|
if (!spawned) {
|
||||||
|
EQApplicationPacket app;
|
||||||
|
CreateSpawnPacket(&app, this);
|
||||||
|
c->QueuePacket(&app);
|
||||||
|
SendArmorAppearance(c);
|
||||||
|
spawned_for.insert(c->GetID());
|
||||||
|
}
|
||||||
|
} else if (spawned) {
|
||||||
|
EQApplicationPacket app;
|
||||||
|
CreateDespawnPacket(&app, false);
|
||||||
|
c->QueuePacket(&app);
|
||||||
|
spawned_for.erase(c->GetID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Aura::Process()
|
||||||
|
{
|
||||||
|
// Aura::Depop clears buffs
|
||||||
|
if (p_depop)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto owner = entity_list.GetMob(m_owner);
|
||||||
|
if (owner == nullptr) {
|
||||||
|
Depop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove_timer.Check()) {
|
||||||
|
owner->RemoveAura(GetID(), false, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (movement_type == AuraMovement::Follow && GetPosition() != owner->GetPosition() && movement_timer.Check()) {
|
||||||
|
m_Position = owner->GetPosition();
|
||||||
|
auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||||
|
auto spu = (PlayerPositionUpdateServer_Struct*)app->pBuffer;
|
||||||
|
MakeSpawnUpdate(spu);
|
||||||
|
auto it = spawned_for.begin();
|
||||||
|
while (it != spawned_for.end()) {
|
||||||
|
auto client = entity_list.GetClientByID(*it);
|
||||||
|
if (client) {
|
||||||
|
client->QueuePacket(app);
|
||||||
|
++it;
|
||||||
|
} else {
|
||||||
|
it = spawned_for.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: waypoints?
|
||||||
|
|
||||||
|
if (!process_timer.Check())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (spawn_type != AuraSpawns::Noone)
|
||||||
|
ProcessSpawns(); // bit of a hack
|
||||||
|
|
||||||
|
if (process_func)
|
||||||
|
process_func(*this, owner);
|
||||||
|
|
||||||
|
// TODO: quest calls
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Aura::ShouldISpawnFor(Client *c)
|
||||||
|
{
|
||||||
|
if (spawn_type == AuraSpawns::Noone)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (spawn_type == AuraSpawns::Everyone)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// hey, it's our owner!
|
||||||
|
if (c->GetID() == m_owner)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// so this one is a bit trickier
|
||||||
|
auto owner = GetOwner();
|
||||||
|
if (owner == nullptr)
|
||||||
|
return false; // hmm
|
||||||
|
|
||||||
|
owner = owner->GetOwnerOrSelf(); // pet auras we need the pet's owner
|
||||||
|
if (owner == nullptr) // shouldn't really be needed
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// gotta check again for pet aura case -.-
|
||||||
|
if (owner == c)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (owner->IsRaidGrouped() && owner->IsClient()) {
|
||||||
|
auto raid = owner->GetRaid();
|
||||||
|
if (raid == nullptr)
|
||||||
|
return false; // hmm
|
||||||
|
auto group_id = raid->GetGroup(owner->CastToClient());
|
||||||
|
if (group_id == 0xFFFFFFFF) // owner handled above, and they're in a raid and groupless
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto idx = raid->GetPlayerIndex(c);
|
||||||
|
if (idx == 0xFFFFFFFF) // they're not in our raid!
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (raid->members[idx].GroupNumber != group_id) // in our raid, but not our group
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true; // we got here so we know that 1 they're in our raid and 2 they're in our group!
|
||||||
|
} else if (owner->IsGrouped()) {
|
||||||
|
auto group = owner->GetGroup();
|
||||||
|
if (group == nullptr)
|
||||||
|
return false; // hmm
|
||||||
|
|
||||||
|
// easy, in our group
|
||||||
|
return group->IsGroupMember(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// our owner is not raided or grouped, and they're handled above so we don't spawn!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aura::Depop(bool skip_strip)
|
||||||
|
{
|
||||||
|
// NEC trap casts a dot, so we need some way to not strip :P
|
||||||
|
if (!skip_strip && IsBuffSpell(spell_id)) {
|
||||||
|
for (auto &e : casted_on) {
|
||||||
|
auto mob = entity_list.GetMob(e);
|
||||||
|
if (mob != nullptr)
|
||||||
|
mob->BuffFadeBySpellIDAndCaster(spell_id, GetID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
casted_on.clear();
|
||||||
|
p_depop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This creates an aura from a casted spell
|
||||||
|
void Mob::MakeAura(uint16 spell_id)
|
||||||
|
{
|
||||||
|
// TODO: verify room in AuraMgr
|
||||||
|
if (!IsValidSpell(spell_id))
|
||||||
|
return;
|
||||||
|
|
||||||
|
AuraRecord record;
|
||||||
|
if (!database.GetAuraEntry(spell_id, record)) {
|
||||||
|
Message(13, "Unable to find data for aura %s", spells[spell_id].name);
|
||||||
|
Log(Logs::General, Logs::Error, "Unable to find data for aura %d, check auras table.", spell_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsValidSpell(record.spell_id)) {
|
||||||
|
Message(13, "Casted spell (%d) is not valid for aura %s", record.spell_id, spells[spell_id].name);
|
||||||
|
Log(Logs::General, Logs::Error, "Casted spell (%d) is not valid for aura %d, check auras table.",
|
||||||
|
record.spell_id, spell_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.aura_type > static_cast<int>(AuraType::Max)) {
|
||||||
|
return; // TODO: log
|
||||||
|
}
|
||||||
|
|
||||||
|
bool trap = false;
|
||||||
|
|
||||||
|
switch (static_cast<AuraType>(record.aura_type)) {
|
||||||
|
case AuraType::ExitTrap:
|
||||||
|
case AuraType::EnterTrap:
|
||||||
|
case AuraType::Totem:
|
||||||
|
trap = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
trap = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CanSpawnAura(trap))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto base = database.LoadNPCTypesData(record.npc_type);
|
||||||
|
if (base == nullptr) {
|
||||||
|
Message(13, "Unable to load NPC data for aura %s", spells[spell_id].teleport_zone);
|
||||||
|
Log(Logs::General, Logs::Error,
|
||||||
|
"Unable to load NPC data for aura %s (NPC ID %d), check auras and npc_types tables.",
|
||||||
|
spells[spell_id].teleport_zone, record.npc_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto npc_type = new NPCType;
|
||||||
|
memcpy(npc_type, base, sizeof(NPCType));
|
||||||
|
|
||||||
|
strn0cpy(npc_type->name, record.name, 64);
|
||||||
|
|
||||||
|
auto npc = new Aura(npc_type, this, record);
|
||||||
|
npc->SetAuraID(spell_id);
|
||||||
|
entity_list.AddNPC(npc, false);
|
||||||
|
|
||||||
|
if (trap)
|
||||||
|
AddTrap(npc, record);
|
||||||
|
else
|
||||||
|
AddAura(npc, record);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneDatabase::GetAuraEntry(uint16 spell_id, AuraRecord &record)
|
||||||
|
{
|
||||||
|
auto query = StringFormat("SELECT npc_type, name, spell_id, distance, aura_type, spawn_type, movement, "
|
||||||
|
"duration, icon, cast_time FROM auras WHERE type='%d'",
|
||||||
|
spell_id);
|
||||||
|
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (results.RowCount() != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
record.npc_type = atoi(row[0]);
|
||||||
|
strn0cpy(record.name, row[1], 64);
|
||||||
|
record.spell_id = atoi(row[2]);
|
||||||
|
record.distance = atoi(row[3]);
|
||||||
|
record.distance *= record.distance; // so we can avoid sqrt
|
||||||
|
record.aura_type = atoi(row[4]);
|
||||||
|
record.spawn_type = atoi(row[5]);
|
||||||
|
record.movement = atoi(row[6]);
|
||||||
|
record.duration = atoi(row[7]) * 1000; // DB is in seconds
|
||||||
|
record.icon = atoi(row[8]);
|
||||||
|
record.cast_time = atoi(row[9]) * 1000; // DB is in seconds
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mob::AddAura(Aura *aura, AuraRecord &record)
|
||||||
|
{
|
||||||
|
// this is called only when it's safe
|
||||||
|
assert(aura != nullptr);
|
||||||
|
strn0cpy(aura_mgr.auras[aura_mgr.count].name, aura->GetCleanName(), 64);
|
||||||
|
aura_mgr.auras[aura_mgr.count].spawn_id = aura->GetID();
|
||||||
|
aura_mgr.auras[aura_mgr.count].aura = aura;
|
||||||
|
if (record.icon == -1)
|
||||||
|
aura_mgr.auras[aura_mgr.count].icon = spells[record.spell_id].new_icon;
|
||||||
|
else
|
||||||
|
aura_mgr.auras[aura_mgr.count].icon = record.icon;
|
||||||
|
if (IsClient()) {
|
||||||
|
auto outapp = new EQApplicationPacket(OP_UpdateAura, sizeof(AuraCreate_Struct));
|
||||||
|
auto aura_create = (AuraCreate_Struct *)outapp->pBuffer;
|
||||||
|
aura_create->action = 0;
|
||||||
|
aura_create->type = 1; // this can be 0 sometimes too
|
||||||
|
strn0cpy(aura_create->aura_name, aura_mgr.auras[aura_mgr.count].name, 64);
|
||||||
|
aura_create->entity_id = aura_mgr.auras[aura_mgr.count].spawn_id;
|
||||||
|
aura_create->icon = aura_mgr.auras[aura_mgr.count].icon;
|
||||||
|
CastToClient()->FastQueuePacket(&outapp);
|
||||||
|
}
|
||||||
|
// we can increment this now
|
||||||
|
aura_mgr.count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mob::AddTrap(Aura *aura, AuraRecord &record)
|
||||||
|
{
|
||||||
|
// this is called only when it's safe
|
||||||
|
assert(aura != nullptr);
|
||||||
|
strn0cpy(trap_mgr.auras[trap_mgr.count].name, aura->GetCleanName(), 64);
|
||||||
|
trap_mgr.auras[trap_mgr.count].spawn_id = aura->GetID();
|
||||||
|
trap_mgr.auras[trap_mgr.count].aura = aura;
|
||||||
|
if (record.icon == -1)
|
||||||
|
trap_mgr.auras[trap_mgr.count].icon = spells[record.spell_id].new_icon;
|
||||||
|
else
|
||||||
|
trap_mgr.auras[trap_mgr.count].icon = record.icon;
|
||||||
|
// doesn't send to client
|
||||||
|
trap_mgr.count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mob::CanSpawnAura(bool trap)
|
||||||
|
{
|
||||||
|
if (trap && !HasFreeTrapSlots()) {
|
||||||
|
Message_StringID(MT_SpellFailure, NO_MORE_TRAPS);
|
||||||
|
return false;
|
||||||
|
} else if (!trap && !HasFreeAuraSlots()) {
|
||||||
|
Message_StringID(MT_SpellFailure, NO_MORE_AURAS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mob::RemoveAllAuras()
|
||||||
|
{
|
||||||
|
if (IsClient()) {
|
||||||
|
database.SaveAuras(CastToClient());
|
||||||
|
EQApplicationPacket outapp(OP_UpdateAura, 4);
|
||||||
|
outapp.WriteUInt32(2);
|
||||||
|
CastToClient()->QueuePacket(&outapp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is sent on camp/zone, so it just despawns?
|
||||||
|
if (aura_mgr.count) {
|
||||||
|
for (auto &e : aura_mgr.auras) {
|
||||||
|
if (e.aura)
|
||||||
|
e.aura->Depop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aura_mgr.count = 0;
|
||||||
|
|
||||||
|
if (trap_mgr.count) {
|
||||||
|
for (auto &e : trap_mgr.auras) {
|
||||||
|
if (e.aura)
|
||||||
|
e.aura->Depop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trap_mgr.count = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mob::RemoveAura(int spawn_id, bool skip_strip, bool expired)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < aura_mgr.count; ++i) {
|
||||||
|
auto &aura = aura_mgr.auras[i];
|
||||||
|
if (aura.spawn_id == spawn_id) {
|
||||||
|
if (aura.aura)
|
||||||
|
aura.aura->Depop(skip_strip);
|
||||||
|
if (expired && IsClient()) {
|
||||||
|
CastToClient()->SendColoredText(
|
||||||
|
CC_Yellow, StringFormat("%s has expired.", aura.name)); // TODO: verify color
|
||||||
|
// need to update client UI too
|
||||||
|
auto app = new EQApplicationPacket(OP_UpdateAura, sizeof(AuraDestory_Struct));
|
||||||
|
auto ads = (AuraDestory_Struct *)app->pBuffer;
|
||||||
|
ads->action = 1; // delete
|
||||||
|
ads->entity_id = spawn_id;
|
||||||
|
CastToClient()->QueuePacket(app);
|
||||||
|
safe_delete(app);
|
||||||
|
}
|
||||||
|
while (aura_mgr.count - 1 > i) {
|
||||||
|
i++;
|
||||||
|
aura.spawn_id = aura_mgr.auras[i].spawn_id;
|
||||||
|
aura.icon = aura_mgr.auras[i].icon;
|
||||||
|
aura.aura = aura_mgr.auras[i].aura;
|
||||||
|
aura_mgr.auras[i].aura = nullptr;
|
||||||
|
strn0cpy(aura.name, aura_mgr.auras[i].name, 64);
|
||||||
|
}
|
||||||
|
aura_mgr.count--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < trap_mgr.count; ++i) {
|
||||||
|
auto &aura = trap_mgr.auras[i];
|
||||||
|
if (aura.spawn_id == spawn_id) {
|
||||||
|
if (aura.aura)
|
||||||
|
aura.aura->Depop(skip_strip);
|
||||||
|
if (expired && IsClient())
|
||||||
|
CastToClient()->SendColoredText(
|
||||||
|
CC_Yellow, StringFormat("%s has expired.", aura.name)); // TODO: verify color
|
||||||
|
while (trap_mgr.count - 1 > i) {
|
||||||
|
i++;
|
||||||
|
aura.spawn_id = trap_mgr.auras[i].spawn_id;
|
||||||
|
aura.icon = trap_mgr.auras[i].icon;
|
||||||
|
aura.aura = trap_mgr.auras[i].aura;
|
||||||
|
trap_mgr.auras[i].aura = nullptr;
|
||||||
|
strn0cpy(aura.name, trap_mgr.auras[i].name, 64);
|
||||||
|
}
|
||||||
|
trap_mgr.count--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
91
zone/aura.h
Normal file
91
zone/aura.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#ifndef AURA_H
|
||||||
|
#define AURA_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "mob.h"
|
||||||
|
#include "npc.h"
|
||||||
|
#include "../common/types.h"
|
||||||
|
#include "../common/timer.h"
|
||||||
|
|
||||||
|
class Group;
|
||||||
|
class Raid;
|
||||||
|
class Mob;
|
||||||
|
struct NPCType;
|
||||||
|
|
||||||
|
enum class AuraType {
|
||||||
|
OnAllFriendlies, // AE PC/Pet basically (ex. Circle of Power)
|
||||||
|
OnAllGroupMembers, // Normal buffing aura (ex. Champion's Aura)
|
||||||
|
OnGroupMembersPets, // Hits just pets (ex. Rathe's Strength)
|
||||||
|
Totem, // Starts pulsing on a timer when an enemy enters (ex. Idol of Malos)
|
||||||
|
EnterTrap, // Casts once when an enemy enters (ex. Fire Rune)
|
||||||
|
ExitTrap, // Casts when they start to flee (ex. Poison Spikes Trap)
|
||||||
|
FullyScripted, // We just call script function not a predefined
|
||||||
|
Max
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AuraSpawns {
|
||||||
|
GroupMembers, // most auras use this
|
||||||
|
Everyone, // this is like traps and clickies who cast on everyone
|
||||||
|
Noone, // custom!
|
||||||
|
Max
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AuraMovement {
|
||||||
|
Follow, // follows caster
|
||||||
|
Stationary,
|
||||||
|
Pathing, // some sorted pathing TODO: implement
|
||||||
|
Max
|
||||||
|
};
|
||||||
|
|
||||||
|
class Aura : public NPC
|
||||||
|
{
|
||||||
|
// NOTE: We may have to override more virtual functions if they're causing issues
|
||||||
|
public:
|
||||||
|
Aura(NPCType *type_data, Mob *owner, AuraRecord &record);
|
||||||
|
~Aura() { };
|
||||||
|
|
||||||
|
bool IsAura() const { return true; }
|
||||||
|
bool Process();
|
||||||
|
void Depop(bool skip_strip = false);
|
||||||
|
Mob *GetOwner();
|
||||||
|
|
||||||
|
void ProcessOnAllFriendlies(Mob *owner);
|
||||||
|
void ProcessOnAllGroupMembers(Mob *owner);
|
||||||
|
void ProcessOnGroupMembersPets(Mob *owner);
|
||||||
|
void ProcessTotem(Mob *owner);
|
||||||
|
void ProcessEnterTrap(Mob *owner);
|
||||||
|
void ProcessExitTrap(Mob *owner);
|
||||||
|
void ProcessSpawns();
|
||||||
|
|
||||||
|
// we only save auras that follow you, and player casted
|
||||||
|
inline bool AuraZones() { return movement_type == AuraMovement::Follow && aura_id > -1; }
|
||||||
|
inline int GetSpellID() { return spell_id; }
|
||||||
|
inline int GetAuraID() { return aura_id; }
|
||||||
|
inline void SetAuraID(int in) { aura_id = in; }
|
||||||
|
|
||||||
|
bool ShouldISpawnFor(Client *c);
|
||||||
|
// so when we join a group, we need to spawn not already spawned auras
|
||||||
|
// This is only possible when spawn type is GroupMembers
|
||||||
|
inline bool JoinGroupSpawnCheck() { return spawn_type == AuraSpawns::GroupMembers; }
|
||||||
|
private:
|
||||||
|
int m_owner;
|
||||||
|
int aura_id; // spell ID of the aura spell -1 if aura isn't from a casted spell
|
||||||
|
int spell_id; // spell we cast
|
||||||
|
int distance; // distance we remove
|
||||||
|
Timer remove_timer; // when we depop
|
||||||
|
Timer process_timer; // rate limit process calls
|
||||||
|
Timer cast_timer; // some auras pulse
|
||||||
|
Timer movement_timer; // rate limit movement updates
|
||||||
|
AuraType type;
|
||||||
|
AuraSpawns spawn_type;
|
||||||
|
AuraMovement movement_type;
|
||||||
|
|
||||||
|
std::function<void(Aura &, Mob *)> process_func;
|
||||||
|
std::set<int> casted_on; // we keep track of the other entities we've casted on
|
||||||
|
std::set<int> spawned_for;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* !AURA_H */
|
||||||
|
|
||||||
@ -1460,6 +1460,14 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
newbon->FeignedMinionChance = base1;
|
newbon->FeignedMinionChance = base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_AdditionalAura:
|
||||||
|
newbon->aura_slots += base1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SE_IncreaseTrapCount:
|
||||||
|
newbon->trap_slots += base1;
|
||||||
|
break;
|
||||||
|
|
||||||
// to do
|
// to do
|
||||||
case SE_PetDiscipline:
|
case SE_PetDiscipline:
|
||||||
break;
|
break;
|
||||||
@ -3202,6 +3210,16 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
new_bonus->FeignedCastOnChance = effect_value;
|
new_bonus->FeignedCastOnChance = effect_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_AdditionalAura:
|
||||||
|
if (new_bonus->aura_slots < effect_value)
|
||||||
|
new_bonus->aura_slots = effect_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SE_IncreaseTrapCount:
|
||||||
|
if (new_bonus->trap_slots < effect_value)
|
||||||
|
new_bonus->trap_slots = effect_value;
|
||||||
|
break;
|
||||||
|
|
||||||
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
|
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
|
||||||
if (IsAISpellEffect) {
|
if (IsAISpellEffect) {
|
||||||
|
|
||||||
|
|||||||
@ -2929,6 +2929,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
|||||||
ns->spawn.light = m_Light.Type[EQEmu::lightsource::LightActive];
|
ns->spawn.light = m_Light.Type[EQEmu::lightsource::LightActive];
|
||||||
ns->spawn.helm = helmtexture; //(GetShowHelm() ? helmtexture : 0); //0xFF;
|
ns->spawn.helm = helmtexture; //(GetShowHelm() ? helmtexture : 0); //0xFF;
|
||||||
ns->spawn.equip_chest2 = texture; //0xFF;
|
ns->spawn.equip_chest2 = texture; //0xFF;
|
||||||
|
ns->spawn.show_name = true;
|
||||||
const EQEmu::ItemData* item = nullptr;
|
const EQEmu::ItemData* item = nullptr;
|
||||||
const EQEmu::ItemInstance* inst = nullptr;
|
const EQEmu::ItemInstance* inst = nullptr;
|
||||||
uint32 spawnedbotid = 0;
|
uint32 spawnedbotid = 0;
|
||||||
|
|||||||
@ -299,6 +299,7 @@ public:
|
|||||||
const char* GetBuyerWelcomeMessage() { return BuyerWelcomeMessage.c_str(); }
|
const char* GetBuyerWelcomeMessage() { return BuyerWelcomeMessage.c_str(); }
|
||||||
|
|
||||||
void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||||
|
bool ShouldISpawnFor(Client *c) { return !GMHideMe(c) && !IsHoveringForRespawn(); }
|
||||||
virtual bool Process();
|
virtual bool Process();
|
||||||
void ProcessPackets();
|
void ProcessPackets();
|
||||||
void LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const EQEmu::ItemData* item, bool buying);
|
void LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const EQEmu::ItemData* item, bool buying);
|
||||||
|
|||||||
@ -323,6 +323,7 @@ void MapOpcodes()
|
|||||||
ConnectedOpcodes[OP_RecipesSearch] = &Client::Handle_OP_RecipesSearch;
|
ConnectedOpcodes[OP_RecipesSearch] = &Client::Handle_OP_RecipesSearch;
|
||||||
ConnectedOpcodes[OP_ReloadUI] = &Client::Handle_OP_ReloadUI;
|
ConnectedOpcodes[OP_ReloadUI] = &Client::Handle_OP_ReloadUI;
|
||||||
ConnectedOpcodes[OP_RemoveBlockedBuffs] = &Client::Handle_OP_RemoveBlockedBuffs;
|
ConnectedOpcodes[OP_RemoveBlockedBuffs] = &Client::Handle_OP_RemoveBlockedBuffs;
|
||||||
|
ConnectedOpcodes[OP_RemoveTrap] = &Client::Handle_OP_RemoveTrap;
|
||||||
ConnectedOpcodes[OP_Report] = &Client::Handle_OP_Report;
|
ConnectedOpcodes[OP_Report] = &Client::Handle_OP_Report;
|
||||||
ConnectedOpcodes[OP_RequestDuel] = &Client::Handle_OP_RequestDuel;
|
ConnectedOpcodes[OP_RequestDuel] = &Client::Handle_OP_RequestDuel;
|
||||||
ConnectedOpcodes[OP_RequestTitles] = &Client::Handle_OP_RequestTitles;
|
ConnectedOpcodes[OP_RequestTitles] = &Client::Handle_OP_RequestTitles;
|
||||||
@ -383,6 +384,7 @@ void MapOpcodes()
|
|||||||
ConnectedOpcodes[OP_TributeUpdate] = &Client::Handle_OP_TributeUpdate;
|
ConnectedOpcodes[OP_TributeUpdate] = &Client::Handle_OP_TributeUpdate;
|
||||||
ConnectedOpcodes[OP_VetClaimRequest] = &Client::Handle_OP_VetClaimRequest;
|
ConnectedOpcodes[OP_VetClaimRequest] = &Client::Handle_OP_VetClaimRequest;
|
||||||
ConnectedOpcodes[OP_VoiceMacroIn] = &Client::Handle_OP_VoiceMacroIn;
|
ConnectedOpcodes[OP_VoiceMacroIn] = &Client::Handle_OP_VoiceMacroIn;
|
||||||
|
ConnectedOpcodes[OP_UpdateAura] = &Client::Handle_OP_UpdateAura;;
|
||||||
ConnectedOpcodes[OP_WearChange] = &Client::Handle_OP_WearChange;
|
ConnectedOpcodes[OP_WearChange] = &Client::Handle_OP_WearChange;
|
||||||
ConnectedOpcodes[OP_WhoAllRequest] = &Client::Handle_OP_WhoAllRequest;
|
ConnectedOpcodes[OP_WhoAllRequest] = &Client::Handle_OP_WhoAllRequest;
|
||||||
ConnectedOpcodes[OP_WorldUnknown001] = &Client::Handle_OP_Ignore;
|
ConnectedOpcodes[OP_WorldUnknown001] = &Client::Handle_OP_Ignore;
|
||||||
@ -882,6 +884,8 @@ void Client::CompleteConnect()
|
|||||||
SetPetCommandState(PET_BUTTON_SPELLHOLD, 0);
|
SetPetCommandState(PET_BUTTON_SPELLHOLD, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
database.LoadAuras(this); // this ends up spawning them so probably safer to load this later (here)
|
||||||
|
|
||||||
entity_list.RefreshClientXTargets(this);
|
entity_list.RefreshClientXTargets(this);
|
||||||
|
|
||||||
worldserver.RequestTellQueue(GetName());
|
worldserver.RequestTellQueue(GetName());
|
||||||
@ -11776,6 +11780,28 @@ void Client::Handle_OP_RemoveBlockedBuffs(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::Handle_OP_RemoveTrap(const EQApplicationPacket *app)
|
||||||
|
{
|
||||||
|
if (app->size != 4) {// just an int
|
||||||
|
Log(Logs::General, Logs::None, "Size mismatch in OP_RemoveTrap expected 4 got %i", app->size);
|
||||||
|
DumpPacket(app);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto id = app->ReadUInt32(0);
|
||||||
|
bool good = false;
|
||||||
|
for (int i = 0; i < trap_mgr.count; ++i) {
|
||||||
|
if (trap_mgr.auras[i].spawn_id == id) {
|
||||||
|
good = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (good)
|
||||||
|
RemoveAura(id);
|
||||||
|
else
|
||||||
|
Message_StringID(MT_SpellFailure, NOT_YOUR_TRAP); // pretty sure this was red
|
||||||
|
}
|
||||||
|
|
||||||
void Client::Handle_OP_Report(const EQApplicationPacket *app)
|
void Client::Handle_OP_Report(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
if (!CanUseReport)
|
if (!CanUseReport)
|
||||||
@ -14294,6 +14320,24 @@ void Client::Handle_OP_VoiceMacroIn(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::Handle_OP_UpdateAura(const EQApplicationPacket *app)
|
||||||
|
{
|
||||||
|
if (app->size != sizeof(AuraDestory_Struct)) {
|
||||||
|
Log(Logs::General, Logs::None, "Size mismatch in OP_UpdateAura expected %i got %i",
|
||||||
|
sizeof(AuraDestory_Struct), app->size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// client only sends this for removing
|
||||||
|
auto aura = (AuraDestory_Struct *)app->pBuffer;
|
||||||
|
if (aura->action != 1)
|
||||||
|
return; // could log I guess, but should only ever get this action
|
||||||
|
|
||||||
|
RemoveAura(aura->entity_id);
|
||||||
|
QueuePacket(app); // if we don't resend this, the client gets confused
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void Client::Handle_OP_WearChange(const EQApplicationPacket *app)
|
void Client::Handle_OP_WearChange(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
if (app->size != sizeof(WearChange_Struct)) {
|
if (app->size != sizeof(WearChange_Struct)) {
|
||||||
|
|||||||
@ -236,6 +236,7 @@
|
|||||||
void Handle_OP_RecipesSearch(const EQApplicationPacket *app);
|
void Handle_OP_RecipesSearch(const EQApplicationPacket *app);
|
||||||
void Handle_OP_ReloadUI(const EQApplicationPacket *app);
|
void Handle_OP_ReloadUI(const EQApplicationPacket *app);
|
||||||
void Handle_OP_RemoveBlockedBuffs(const EQApplicationPacket *app);
|
void Handle_OP_RemoveBlockedBuffs(const EQApplicationPacket *app);
|
||||||
|
void Handle_OP_RemoveTrap(const EQApplicationPacket *app);
|
||||||
void Handle_OP_Report(const EQApplicationPacket *app);
|
void Handle_OP_Report(const EQApplicationPacket *app);
|
||||||
void Handle_OP_RequestDuel(const EQApplicationPacket *app);
|
void Handle_OP_RequestDuel(const EQApplicationPacket *app);
|
||||||
void Handle_OP_RequestTitles(const EQApplicationPacket *app);
|
void Handle_OP_RequestTitles(const EQApplicationPacket *app);
|
||||||
@ -288,6 +289,7 @@
|
|||||||
void Handle_OP_TributeNPC(const EQApplicationPacket *app);
|
void Handle_OP_TributeNPC(const EQApplicationPacket *app);
|
||||||
void Handle_OP_TributeToggle(const EQApplicationPacket *app);
|
void Handle_OP_TributeToggle(const EQApplicationPacket *app);
|
||||||
void Handle_OP_TributeUpdate(const EQApplicationPacket *app);
|
void Handle_OP_TributeUpdate(const EQApplicationPacket *app);
|
||||||
|
void Handle_OP_UpdateAura(const EQApplicationPacket *app);
|
||||||
void Handle_OP_VetClaimRequest(const EQApplicationPacket *app);
|
void Handle_OP_VetClaimRequest(const EQApplicationPacket *app);
|
||||||
void Handle_OP_VoiceMacroIn(const EQApplicationPacket *app);
|
void Handle_OP_VoiceMacroIn(const EQApplicationPacket *app);
|
||||||
void Handle_OP_WearChange(const EQApplicationPacket *app);
|
void Handle_OP_WearChange(const EQApplicationPacket *app);
|
||||||
|
|||||||
@ -722,6 +722,8 @@ void Client::OnDisconnect(bool hard_disconnect) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RemoveAllAuras();
|
||||||
|
|
||||||
Mob *Other = trade->With();
|
Mob *Other = trade->With();
|
||||||
if(Other)
|
if(Other)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -105,6 +105,8 @@
|
|||||||
#define PET_BUTTON_FOCUS 8
|
#define PET_BUTTON_FOCUS 8
|
||||||
#define PET_BUTTON_SPELLHOLD 9
|
#define PET_BUTTON_SPELLHOLD 9
|
||||||
|
|
||||||
|
#define AURA_HARDCAP 2
|
||||||
|
|
||||||
typedef enum { //focus types
|
typedef enum { //focus types
|
||||||
focusSpellHaste = 1,
|
focusSpellHaste = 1,
|
||||||
focusSpellDuration,
|
focusSpellDuration,
|
||||||
@ -205,6 +207,16 @@ typedef enum { //fear states
|
|||||||
|
|
||||||
enum { FlyMode0 = 0, FlyMode1 = 1, Flymode2 = 2, FlyMode3 = 3 };
|
enum { FlyMode0 = 0, FlyMode1 = 1, Flymode2 = 2, FlyMode3 = 3 };
|
||||||
|
|
||||||
|
// This is actually FlyMode, from MQ2
|
||||||
|
enum GravityBehavior {
|
||||||
|
Ground,
|
||||||
|
Flying,
|
||||||
|
Levitating,
|
||||||
|
Water,
|
||||||
|
Floating, // boat
|
||||||
|
LevitateWhileRunning
|
||||||
|
};
|
||||||
|
|
||||||
struct TradeEntity;
|
struct TradeEntity;
|
||||||
class Trade;
|
class Trade;
|
||||||
enum TradeState {
|
enum TradeState {
|
||||||
@ -536,6 +548,8 @@ struct StatBonuses {
|
|||||||
int16 FeignedCastOnChance; // Percent Value
|
int16 FeignedCastOnChance; // Percent Value
|
||||||
bool PetCommands[PET_MAXCOMMANDS]; // SPA 267
|
bool PetCommands[PET_MAXCOMMANDS]; // SPA 267
|
||||||
int FeignedMinionChance; // SPA 281 base1 = chance, just like normal FD
|
int FeignedMinionChance; // SPA 281 base1 = chance, just like normal FD
|
||||||
|
int aura_slots;
|
||||||
|
int trap_slots;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@ -1246,13 +1246,10 @@ void EntityList::SendZoneSpawns(Client *client)
|
|||||||
auto it = mob_list.begin();
|
auto it = mob_list.begin();
|
||||||
while (it != mob_list.end()) {
|
while (it != mob_list.end()) {
|
||||||
Mob *ent = it->second;
|
Mob *ent = it->second;
|
||||||
if (!(ent->InZone()) || (ent->IsClient())) {
|
if (!ent->InZone() || !ent->ShouldISpawnFor(client)) {
|
||||||
if (ent->CastToClient()->GMHideMe(client) ||
|
|
||||||
ent->CastToClient()->IsHoveringForRespawn()) {
|
|
||||||
++it;
|
++it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
app = new EQApplicationPacket;
|
app = new EQApplicationPacket;
|
||||||
it->second->CastToMob()->CreateSpawnPacket(app); // TODO: Use zonespawns opcode instead
|
it->second->CastToMob()->CreateSpawnPacket(app); // TODO: Use zonespawns opcode instead
|
||||||
@ -1279,8 +1276,7 @@ void EntityList::SendZoneSpawnsBulk(Client *client)
|
|||||||
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->GetID() > 0 && spawn->Spawned()) {
|
if (spawn && spawn->GetID() > 0 && spawn->Spawned()) {
|
||||||
if (spawn->IsClient() && (spawn->CastToClient()->GMHideMe(client) ||
|
if (!spawn->ShouldISpawnFor(client))
|
||||||
spawn->CastToClient()->IsHoveringForRespawn()))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
@ -2659,7 +2655,7 @@ void EntityList::SendPositionUpdates(Client *client, uint32 cLastUpdate, float u
|
|||||||
mob && !mob->IsCorpse()
|
mob && !mob->IsCorpse()
|
||||||
&& (it->second != client)
|
&& (it->second != client)
|
||||||
&& (mob->IsClient() || iSendEvenIfNotChanged || (mob->LastChange() >= cLastUpdate))
|
&& (mob->IsClient() || iSendEvenIfNotChanged || (mob->LastChange() >= cLastUpdate))
|
||||||
&& (!it->second->IsClient() || !it->second->CastToClient()->GMHideMe(client))
|
&& (it->second->ShouldISpawnFor(client))
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
update_range == 0
|
update_range == 0
|
||||||
|
|||||||
@ -80,6 +80,7 @@ public:
|
|||||||
virtual bool IsBeacon() const { return false; }
|
virtual bool IsBeacon() const { return false; }
|
||||||
virtual bool IsEncounter() const { return false; }
|
virtual bool IsEncounter() const { return false; }
|
||||||
virtual bool IsBot() const { return false; }
|
virtual bool IsBot() const { return false; }
|
||||||
|
virtual bool IsAura() const { return false; }
|
||||||
|
|
||||||
virtual bool Process() { return false; }
|
virtual bool Process() { return false; }
|
||||||
virtual bool Save() { return true; }
|
virtual bool Save() { return true; }
|
||||||
|
|||||||
@ -142,7 +142,8 @@ void Mob::CalculateNewFearpoint()
|
|||||||
|
|
||||||
int loop = 0;
|
int loop = 0;
|
||||||
float ranx, rany, ranz;
|
float ranx, rany, ranz;
|
||||||
currently_fleeing = false;
|
|
||||||
|
currently_fleeing = true;
|
||||||
while (loop < 100) //Max 100 tries
|
while (loop < 100) //Max 100 tries
|
||||||
{
|
{
|
||||||
int ran = 250 - (loop*2);
|
int ran = 250 - (loop*2);
|
||||||
@ -155,7 +156,6 @@ void Mob::CalculateNewFearpoint()
|
|||||||
float fdist = ranz - GetZ();
|
float fdist = ranz - GetZ();
|
||||||
if (fdist >= -12 && fdist <= 12 && CheckCoordLosNoZLeaps(GetX(),GetY(),GetZ(),ranx,rany,ranz))
|
if (fdist >= -12 && fdist <= 12 && CheckCoordLosNoZLeaps(GetX(),GetY(),GetZ(),ranx,rany,ranz))
|
||||||
{
|
{
|
||||||
currently_fleeing = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1211,6 +1211,7 @@ void Merc::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
|||||||
ns->spawn.flymode = 0;
|
ns->spawn.flymode = 0;
|
||||||
ns->spawn.NPC = 1; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
ns->spawn.NPC = 1; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||||
ns->spawn.IsMercenary = 1;
|
ns->spawn.IsMercenary = 1;
|
||||||
|
ns->spawn.show_name = true;
|
||||||
|
|
||||||
UpdateActiveLight();
|
UpdateActiveLight();
|
||||||
ns->spawn.light = m_Light.Type[EQEmu::lightsource::LightActive];
|
ns->spawn.light = m_Light.Type[EQEmu::lightsource::LightActive];
|
||||||
|
|||||||
40
zone/mob.h
40
zone/mob.h
@ -45,6 +45,8 @@ class EQApplicationPacket;
|
|||||||
class Group;
|
class Group;
|
||||||
class NPC;
|
class NPC;
|
||||||
class Raid;
|
class Raid;
|
||||||
|
class Aura;
|
||||||
|
struct AuraRecord;
|
||||||
struct NewSpawn_Struct;
|
struct NewSpawn_Struct;
|
||||||
struct PlayerPositionUpdateServer_Struct;
|
struct PlayerPositionUpdateServer_Struct;
|
||||||
|
|
||||||
@ -85,6 +87,23 @@ public:
|
|||||||
int params[MAX_SPECIAL_ATTACK_PARAMS];
|
int params[MAX_SPECIAL_ATTACK_PARAMS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AuraInfo {
|
||||||
|
char name[64];
|
||||||
|
int spawn_id;
|
||||||
|
int icon;
|
||||||
|
Aura *aura;
|
||||||
|
AuraInfo() : spawn_id(0), icon(0), aura(nullptr)
|
||||||
|
{
|
||||||
|
memset(name, 0, 64);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AuraMgr {
|
||||||
|
int count; // active auras
|
||||||
|
AuraInfo auras[AURA_HARDCAP];
|
||||||
|
AuraMgr() : count(0) { }
|
||||||
|
};
|
||||||
|
|
||||||
Mob(const char* in_name,
|
Mob(const char* in_name,
|
||||||
const char* in_lastname,
|
const char* in_lastname,
|
||||||
int32 in_cur_hp,
|
int32 in_cur_hp,
|
||||||
@ -308,6 +327,7 @@ public:
|
|||||||
void BuffProcess();
|
void BuffProcess();
|
||||||
virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr);
|
virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr);
|
||||||
void BuffFadeBySpellID(uint16 spell_id);
|
void BuffFadeBySpellID(uint16 spell_id);
|
||||||
|
void BuffFadeBySpellIDAndCaster(uint16 spell_id, uint16 caster_id);
|
||||||
void BuffFadeByEffect(int effectid, int skipslot = -1);
|
void BuffFadeByEffect(int effectid, int skipslot = -1);
|
||||||
void BuffFadeAll();
|
void BuffFadeAll();
|
||||||
void BuffFadeNonPersistDeath();
|
void BuffFadeNonPersistDeath();
|
||||||
@ -315,6 +335,7 @@ public:
|
|||||||
void BuffFadeBySlot(int slot, bool iRecalcBonuses = true);
|
void BuffFadeBySlot(int slot, bool iRecalcBonuses = true);
|
||||||
void BuffFadeDetrimentalByCaster(Mob *caster);
|
void BuffFadeDetrimentalByCaster(Mob *caster);
|
||||||
void BuffFadeBySitModifier();
|
void BuffFadeBySitModifier();
|
||||||
|
bool IsAffectedByBuff(uint16 spell_id);
|
||||||
void BuffModifyDurationBySpellID(uint16 spell_id, int32 newDuration);
|
void BuffModifyDurationBySpellID(uint16 spell_id, int32 newDuration);
|
||||||
int AddBuff(Mob *caster, const uint16 spell_id, int duration = 0, int32 level_override = -1);
|
int AddBuff(Mob *caster, const uint16 spell_id, int duration = 0, int32 level_override = -1);
|
||||||
int CanBuffStack(uint16 spellid, uint8 caster_level, bool iFailIfOverwrite = false);
|
int CanBuffStack(uint16 spellid, uint8 caster_level, bool iFailIfOverwrite = false);
|
||||||
@ -528,6 +549,7 @@ public:
|
|||||||
void SendPosition();
|
void SendPosition();
|
||||||
void SetSpawned() { spawned = true; };
|
void SetSpawned() { spawned = true; };
|
||||||
bool Spawned() { return spawned; };
|
bool Spawned() { return spawned; };
|
||||||
|
virtual bool ShouldISpawnFor(Client *c) { return true; }
|
||||||
void SetFlyMode(uint8 flymode);
|
void SetFlyMode(uint8 flymode);
|
||||||
inline void Teleport(glm::vec3 NewPosition) { m_Position.x = NewPosition.x; m_Position.y = NewPosition.y;
|
inline void Teleport(glm::vec3 NewPosition) { m_Position.x = NewPosition.x; m_Position.y = NewPosition.y;
|
||||||
m_Position.z = NewPosition.z; };
|
m_Position.z = NewPosition.z; };
|
||||||
@ -604,6 +626,19 @@ public:
|
|||||||
bool PlotPositionAroundTarget(Mob* target, float &x_dest, float &y_dest, float &z_dest,
|
bool PlotPositionAroundTarget(Mob* target, float &x_dest, float &y_dest, float &z_dest,
|
||||||
bool lookForAftArc = true);
|
bool lookForAftArc = true);
|
||||||
|
|
||||||
|
// aura functions
|
||||||
|
void MakeAura(uint16 spell_id);
|
||||||
|
inline int GetAuraSlots() { return 1 + aabonuses.aura_slots + itembonuses.aura_slots + spellbonuses.aura_slots; }
|
||||||
|
inline int GetTrapSlots() { return 1 + aabonuses.trap_slots + itembonuses.trap_slots + spellbonuses.trap_slots; }
|
||||||
|
inline bool HasFreeAuraSlots() { return aura_mgr.count < GetAuraSlots(); }
|
||||||
|
inline bool HasFreeTrapSlots() { return trap_mgr.count < GetTrapSlots(); }
|
||||||
|
void AddAura(Aura *aura, AuraRecord &record);
|
||||||
|
void AddTrap(Aura *aura, AuraRecord &record);
|
||||||
|
bool CanSpawnAura(bool trap);
|
||||||
|
void RemoveAura(int spawn_id, bool skip_strip = false, bool expired = false);
|
||||||
|
void RemoveAllAuras();
|
||||||
|
inline AuraMgr &GetAuraMgr() { return aura_mgr; } // mainly used for zone db loading/saving
|
||||||
|
|
||||||
//Procs
|
//Procs
|
||||||
void TriggerDefensiveProcs(Mob *on, uint16 hand = EQEmu::inventory::slotPrimary, bool FromSkillProc = false, int damage = 0);
|
void TriggerDefensiveProcs(Mob *on, uint16 hand = EQEmu::inventory::slotPrimary, bool FromSkillProc = false, int damage = 0);
|
||||||
bool AddRangedProc(uint16 spell_id, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN);
|
bool AddRangedProc(uint16 spell_id, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN);
|
||||||
@ -1090,7 +1125,7 @@ protected:
|
|||||||
int _GetWalkSpeed() const;
|
int _GetWalkSpeed() const;
|
||||||
int _GetRunSpeed() const;
|
int _GetRunSpeed() const;
|
||||||
int _GetFearSpeed() const;
|
int _GetFearSpeed() const;
|
||||||
virtual bool MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, bool checkZ);
|
virtual bool MakeNewPositionAndSendUpdate(float x, float y, float z, int speed);
|
||||||
|
|
||||||
virtual bool AI_EngagedCastCheck() { return(false); }
|
virtual bool AI_EngagedCastCheck() { return(false); }
|
||||||
virtual bool AI_PursueCastCheck() { return(false); }
|
virtual bool AI_PursueCastCheck() { return(false); }
|
||||||
@ -1455,6 +1490,9 @@ protected:
|
|||||||
|
|
||||||
bool IsHorse;
|
bool IsHorse;
|
||||||
|
|
||||||
|
AuraMgr aura_mgr;
|
||||||
|
AuraMgr trap_mgr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _StopSong(); //this is not what you think it is
|
void _StopSong(); //this is not what you think it is
|
||||||
Mob* target;
|
Mob* target;
|
||||||
|
|||||||
@ -1532,7 +1532,11 @@ void NPC::AI_DoMovement() {
|
|||||||
|
|
||||||
Log(Logs::Detail, Logs::AI, "Roam Box: d=%.3f (%.3f->%.3f,%.3f->%.3f): Go To (%.3f,%.3f)",
|
Log(Logs::Detail, Logs::AI, "Roam Box: d=%.3f (%.3f->%.3f,%.3f->%.3f): Go To (%.3f,%.3f)",
|
||||||
roambox_distance, roambox_min_x, roambox_max_x, roambox_min_y, roambox_max_y, roambox_movingto_x, roambox_movingto_y);
|
roambox_distance, roambox_min_x, roambox_max_x, roambox_min_y, roambox_max_y, roambox_movingto_x, roambox_movingto_y);
|
||||||
if (!CalculateNewPosition(roambox_movingto_x, roambox_movingto_y, GetZ(), walksp, true))
|
|
||||||
|
float new_z = this->FindGroundZ(m_Position.x, m_Position.y, 5);
|
||||||
|
new_z += (this->GetSize() / 1.55);
|
||||||
|
|
||||||
|
if (!CalculateNewPosition2(roambox_movingto_x, roambox_movingto_y, new_z, walksp, true))
|
||||||
{
|
{
|
||||||
roambox_movingto_x = roambox_max_x + 1; // force update
|
roambox_movingto_x = roambox_max_x + 1; // force update
|
||||||
pLastFightingDelayMoving = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay);
|
pLastFightingDelayMoving = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay);
|
||||||
|
|||||||
@ -90,6 +90,7 @@ class Client;
|
|||||||
class Group;
|
class Group;
|
||||||
class Raid;
|
class Raid;
|
||||||
class Spawn2;
|
class Spawn2;
|
||||||
|
class Aura;
|
||||||
|
|
||||||
namespace EQEmu
|
namespace EQEmu
|
||||||
{
|
{
|
||||||
@ -425,6 +426,7 @@ protected:
|
|||||||
NPCType* NPCTypedata_ours; //special case for npcs with uniquely created data.
|
NPCType* NPCTypedata_ours; //special case for npcs with uniquely created data.
|
||||||
|
|
||||||
friend class EntityList;
|
friend class EntityList;
|
||||||
|
friend class Aura;
|
||||||
std::list<struct NPCFaction*> faction_list;
|
std::list<struct NPCFaction*> faction_list;
|
||||||
uint32 copper;
|
uint32 copper;
|
||||||
uint32 silver;
|
uint32 silver;
|
||||||
|
|||||||
@ -491,6 +491,14 @@ uint32 Raid::GetPlayerIndex(const char *name){
|
|||||||
return 0; //should never get to here if we do everything else right, set it to 0 so we never crash things that rely on it.
|
return 0; //should never get to here if we do everything else right, set it to 0 so we never crash things that rely on it.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 Raid::GetPlayerIndex(Client *c)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_RAID_MEMBERS; ++i)
|
||||||
|
if (c == members[i].member)
|
||||||
|
return i;
|
||||||
|
return 0xFFFFFFFF; // return sentinel value, make sure you check it unlike the above function
|
||||||
|
}
|
||||||
|
|
||||||
Client *Raid::GetClientByIndex(uint16 index)
|
Client *Raid::GetClientByIndex(uint16 index)
|
||||||
{
|
{
|
||||||
if(index > MAX_RAID_MEMBERS)
|
if(index > MAX_RAID_MEMBERS)
|
||||||
|
|||||||
@ -142,6 +142,7 @@ public:
|
|||||||
//keeps me from having to keep iterating through the list
|
//keeps me from having to keep iterating through the list
|
||||||
//when I want lots of data from the same entry
|
//when I want lots of data from the same entry
|
||||||
uint32 GetPlayerIndex(const char *name);
|
uint32 GetPlayerIndex(const char *name);
|
||||||
|
uint32 GetPlayerIndex(Client *c);
|
||||||
//for perl interface
|
//for perl interface
|
||||||
Client *GetClientByIndex(uint16 index);
|
Client *GetClientByIndex(uint16 index);
|
||||||
const char *GetClientNameByIndex(uint8 index);
|
const char *GetClientNameByIndex(uint8 index);
|
||||||
|
|||||||
@ -2791,6 +2791,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SE_PersistentEffect:
|
||||||
|
MakeAura(spell_id);
|
||||||
|
break;
|
||||||
|
|
||||||
// Handled Elsewhere
|
// Handled Elsewhere
|
||||||
case SE_ImmuneFleeing:
|
case SE_ImmuneFleeing:
|
||||||
case SE_NegateSpellEffect:
|
case SE_NegateSpellEffect:
|
||||||
@ -5959,7 +5963,8 @@ bool Mob::TryDeathSave() {
|
|||||||
|
|
||||||
bool Mob::AffectedBySpellExcludingSlot(int slot, int effect)
|
bool Mob::AffectedBySpellExcludingSlot(int slot, int effect)
|
||||||
{
|
{
|
||||||
for (int i = 0; i <= EFFECT_COUNT; i++)
|
int buff_count = GetMaxTotalSlots();
|
||||||
|
for (int i = 0; i < buff_count; i++)
|
||||||
{
|
{
|
||||||
if (i == slot)
|
if (i == slot)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -3447,7 +3447,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
|||||||
if(spelltar->IsClient() && spelltar->CastToClient()->IsHoveringForRespawn())
|
if(spelltar->IsClient() && spelltar->CastToClient()->IsHoveringForRespawn())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(IsDetrimentalSpell(spell_id) && !IsAttackAllowed(spelltar) && !IsResurrectionEffects(spell_id)) {
|
if(IsDetrimentalSpell(spell_id) && !IsAttackAllowed(spelltar, true) && !IsResurrectionEffects(spell_id)) {
|
||||||
if(!IsClient() || !CastToClient()->GetGM()) {
|
if(!IsClient() || !CastToClient()->GetGM()) {
|
||||||
Message_StringID(MT_SpellFailure, SPELL_NO_HOLD);
|
Message_StringID(MT_SpellFailure, SPELL_NO_HOLD);
|
||||||
return false;
|
return false;
|
||||||
@ -4189,6 +4189,21 @@ void Mob::BuffFadeBySpellID(uint16 spell_id)
|
|||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mob::BuffFadeBySpellIDAndCaster(uint16 spell_id, uint16 caster_id)
|
||||||
|
{
|
||||||
|
bool recalc_bonus = false;
|
||||||
|
auto buff_count = GetMaxTotalSlots();
|
||||||
|
for (int i = 0; i < buff_count; ++i) {
|
||||||
|
if (buffs[i].spellid == spell_id && buffs[i].casterid == caster_id) {
|
||||||
|
BuffFadeBySlot(i, false);
|
||||||
|
recalc_bonus = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recalc_bonus)
|
||||||
|
CalcBonuses();
|
||||||
|
}
|
||||||
|
|
||||||
// removes buffs containing effectid, skipping skipslot
|
// removes buffs containing effectid, skipping skipslot
|
||||||
void Mob::BuffFadeByEffect(int effectid, int skipslot)
|
void Mob::BuffFadeByEffect(int effectid, int skipslot)
|
||||||
{
|
{
|
||||||
@ -4207,6 +4222,16 @@ void Mob::BuffFadeByEffect(int effectid, int skipslot)
|
|||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Mob::IsAffectedByBuff(uint16 spell_id)
|
||||||
|
{
|
||||||
|
int buff_count = GetMaxTotalSlots();
|
||||||
|
for (int i = 0; i < buff_count; ++i)
|
||||||
|
if (buffs[i].spellid == spell_id)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// checks if 'this' can be affected by spell_id from caster
|
// checks if 'this' can be affected by spell_id from caster
|
||||||
// returns true if the spell should fail, false otherwise
|
// returns true if the spell should fail, false otherwise
|
||||||
bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||||
|
|||||||
@ -286,6 +286,7 @@
|
|||||||
#define TRADESKILL_LEARN_RECIPE 3457 //You have learned the recipe %1!
|
#define TRADESKILL_LEARN_RECIPE 3457 //You have learned the recipe %1!
|
||||||
#define EXPEDITION_MIN_REMAIN 3551 //You only have %1 minutes remaining before this expedition comes to an end.
|
#define EXPEDITION_MIN_REMAIN 3551 //You only have %1 minutes remaining before this expedition comes to an end.
|
||||||
#define LOOT_NOT_ALLOWED 3562 //You are not allowed to loot the item: %1.
|
#define LOOT_NOT_ALLOWED 3562 //You are not allowed to loot the item: %1.
|
||||||
|
#define NOT_YOUR_TRAP 3671 //You cannot remove this, you are only allowed to remove traps you have set.
|
||||||
#define NO_CAST_ON_PET 4045 //You cannot cast this spell on your pet.
|
#define NO_CAST_ON_PET 4045 //You cannot cast this spell on your pet.
|
||||||
#define REWIND_WAIT 4059 //You must wait a bit longer before using the rewind command again.
|
#define REWIND_WAIT 4059 //You must wait a bit longer before using the rewind command again.
|
||||||
#define CORPSEDRAG_LIMIT 4061 //You are already dragging as much as you can!
|
#define CORPSEDRAG_LIMIT 4061 //You are already dragging as much as you can!
|
||||||
@ -361,6 +362,7 @@
|
|||||||
#define GAIN_GROUP_LEADERSHIP_EXP 8788 //
|
#define GAIN_GROUP_LEADERSHIP_EXP 8788 //
|
||||||
#define GAIN_RAID_LEADERSHIP_EXP 8789 //
|
#define GAIN_RAID_LEADERSHIP_EXP 8789 //
|
||||||
#define BUFF_MINUTES_REMAINING 8799 //%1 (%2 minutes remaining)
|
#define BUFF_MINUTES_REMAINING 8799 //%1 (%2 minutes remaining)
|
||||||
|
#define NO_MORE_TRAPS 9002 //You have already placed your maximum number of traps.
|
||||||
#define FEAR_TOO_HIGH 9035 //Your target is too high of a level for your fear spell.
|
#define FEAR_TOO_HIGH 9035 //Your target is too high of a level for your fear spell.
|
||||||
#define SLOW_MOSTLY_SUCCESSFUL 9029 //Your spell was mostly successful.
|
#define SLOW_MOSTLY_SUCCESSFUL 9029 //Your spell was mostly successful.
|
||||||
#define SLOW_PARTIALLY_SUCCESSFUL 9030 // Your spell was partially successful.
|
#define SLOW_PARTIALLY_SUCCESSFUL 9030 // Your spell was partially successful.
|
||||||
@ -375,6 +377,7 @@
|
|||||||
#define SHAKE_OFF_STUN 9077 //You shake off the stun effect!
|
#define SHAKE_OFF_STUN 9077 //You shake off the stun effect!
|
||||||
#define STRIKETHROUGH_STRING 9078 //You strike through your opponent's defenses!
|
#define STRIKETHROUGH_STRING 9078 //You strike through your opponent's defenses!
|
||||||
#define SPELL_REFLECT 9082 //%1's spell has been reflected by %2.
|
#define SPELL_REFLECT 9082 //%1's spell has been reflected by %2.
|
||||||
|
#define NO_MORE_AURAS 9160 //You do not have sufficient focus to maintain that ability.
|
||||||
#define NEW_SPELLS_AVAIL 9149 //You have new spells available to you. Check the merchants near your guild master.
|
#define NEW_SPELLS_AVAIL 9149 //You have new spells available to you. Check the merchants near your guild master.
|
||||||
#define FD_CAST_ON_NO_BREAK 9174 //The strength of your will allows you to resume feigning death.
|
#define FD_CAST_ON_NO_BREAK 9174 //The strength of your will allows you to resume feigning death.
|
||||||
#define SNEAK_RESTRICT 9240 //You can not use this ability because you have not been hidden for long enough.
|
#define SNEAK_RESTRICT 9240 //You can not use this ability because you have not been hidden for long enough.
|
||||||
|
|||||||
@ -451,7 +451,7 @@ float Mob::CalculateHeadingToTarget(float in_x, float in_y) {
|
|||||||
return (256 * (360 - angle) / 360.0f);
|
return (256 * (360 - angle) / 360.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, bool checkZ) {
|
bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed) {
|
||||||
if (GetID() == 0)
|
if (GetID() == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -495,7 +495,8 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
|||||||
m_Position.y = new_y;
|
m_Position.y = new_y;
|
||||||
m_Position.z = new_z;
|
m_Position.z = new_z;
|
||||||
|
|
||||||
if(fix_z_timer.Check() && !this->IsEngaged())
|
if(fix_z_timer.Check() &&
|
||||||
|
(!this->IsEngaged() || flee_mode || currently_fleeing))
|
||||||
this->FixZ();
|
this->FixZ();
|
||||||
|
|
||||||
tar_ndx++;
|
tar_ndx++;
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include "merc.h"
|
#include "merc.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
#include "zonedb.h"
|
#include "zonedb.h"
|
||||||
|
#include "aura.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -3152,6 +3153,37 @@ void ZoneDatabase::LoadBuffs(Client *client)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZoneDatabase::SaveAuras(Client *c)
|
||||||
|
{
|
||||||
|
auto query = StringFormat("DELETE FROM `character_auras` WHERE `id` = %u", c->CharacterID());
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto &auras = c->GetAuraMgr();
|
||||||
|
for (int i = 0; i < auras.count; ++i) {
|
||||||
|
auto aura = auras.auras[i].aura;
|
||||||
|
if (aura && aura->AuraZones()) {
|
||||||
|
query = StringFormat("INSERT INTO `character_auras` (id, slot, spell_id) VALUES(%u, %d, %d)",
|
||||||
|
c->CharacterID(), i, aura->GetAuraID());
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneDatabase::LoadAuras(Client *c)
|
||||||
|
{
|
||||||
|
auto query = StringFormat("SELECT `spell_id` FROM `character_auras` WHERE `id` = %u ORDER BY `slot`", c->CharacterID());
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
|
c->MakeAura(atoi(row[0]));
|
||||||
|
}
|
||||||
|
|
||||||
void ZoneDatabase::SavePetInfo(Client *client)
|
void ZoneDatabase::SavePetInfo(Client *client)
|
||||||
{
|
{
|
||||||
PetInfo *petinfo = nullptr;
|
PetInfo *petinfo = nullptr;
|
||||||
|
|||||||
@ -123,6 +123,19 @@ struct PetRecord {
|
|||||||
uint32 equipmentset; // default equipment for the pet
|
uint32 equipmentset; // default equipment for the pet
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AuraRecord {
|
||||||
|
uint32 npc_type;
|
||||||
|
char name[64]; // name shown in UI if shown and spawn name
|
||||||
|
int spell_id;
|
||||||
|
int distance;
|
||||||
|
int aura_type;
|
||||||
|
int spawn_type;
|
||||||
|
int movement;
|
||||||
|
int duration; // seconds some live for 90 mins (normal) others for 2 mins (traps)
|
||||||
|
int icon; // -1 will use the buffs NEW_ICON
|
||||||
|
int cast_time; // seconds some auras recast on a timer, most seem to be every 12 seconds
|
||||||
|
};
|
||||||
|
|
||||||
// Actual pet info for a client.
|
// Actual pet info for a client.
|
||||||
struct PetInfo {
|
struct PetInfo {
|
||||||
uint16 SpellID;
|
uint16 SpellID;
|
||||||
@ -260,6 +273,8 @@ public:
|
|||||||
|
|
||||||
void SaveBuffs(Client *c);
|
void SaveBuffs(Client *c);
|
||||||
void LoadBuffs(Client *c);
|
void LoadBuffs(Client *c);
|
||||||
|
void SaveAuras(Client *c);
|
||||||
|
void LoadAuras(Client *c);
|
||||||
void LoadPetInfo(Client *c);
|
void LoadPetInfo(Client *c);
|
||||||
void SavePetInfo(Client *c);
|
void SavePetInfo(Client *c);
|
||||||
void RemoveTempFactions(Client *c);
|
void RemoveTempFactions(Client *c);
|
||||||
@ -404,6 +419,7 @@ public:
|
|||||||
void AddLootDropToNPC(NPC* npc, uint32 lootdrop_id, ItemList* itemlist, uint8 droplimit, uint8 mindrop);
|
void AddLootDropToNPC(NPC* npc, uint32 lootdrop_id, ItemList* itemlist, uint8 droplimit, uint8 mindrop);
|
||||||
uint32 GetMaxNPCSpellsID();
|
uint32 GetMaxNPCSpellsID();
|
||||||
uint32 GetMaxNPCSpellsEffectsID();
|
uint32 GetMaxNPCSpellsEffectsID();
|
||||||
|
bool GetAuraEntry(uint16 spell_id, AuraRecord &record);
|
||||||
|
|
||||||
DBnpcspells_Struct* GetNPCSpells(uint32 iDBSpellsID);
|
DBnpcspells_Struct* GetNPCSpells(uint32 iDBSpellsID);
|
||||||
DBnpcspellseffects_Struct* GetNPCSpellsEffects(uint32 iDBSpellsEffectsID);
|
DBnpcspellseffects_Struct* GetNPCSpellsEffects(uint32 iDBSpellsEffectsID);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user