Merge remote-tracking branch 'upstream/master' into spa395fix2

This commit is contained in:
KayenEQ 2021-10-01 14:28:45 -04:00
commit 08a85c5dae
55 changed files with 6196 additions and 5682 deletions

View File

@ -384,7 +384,9 @@ struct NewZone_Struct {
/*0716*/ uint32 FastRegenEndurance; /*0716*/ uint32 FastRegenEndurance;
/*0720*/ uint32 NPCAggroMaxDist; /*0720*/ uint32 NPCAggroMaxDist;
/*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld /*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld
/*0728*/ /*0728*/ uint32 LavaDamage; // Seen 50
/*0732*/ uint32 MinLavaDamage; // Seen 10
/*0736*/
}; };
/* /*

View File

@ -1863,8 +1863,8 @@ namespace RoF
/*fill in some unknowns with observed values, hopefully it will help */ /*fill in some unknowns with observed values, hopefully it will help */
eq->unknown800 = -1; eq->unknown800 = -1;
eq->unknown844 = 600; eq->unknown844 = 600;
eq->unknown880 = 50; OUT(LavaDamage);
eq->unknown884 = 10; OUT(MinLavaDamage);
eq->unknown888 = 1; eq->unknown888 = 1;
eq->unknown889 = 0; eq->unknown889 = 0;
eq->unknown890 = 1; eq->unknown890 = 1;

View File

@ -1919,8 +1919,8 @@ namespace RoF2
eq->SkyRelated2 = -1; eq->SkyRelated2 = -1;
eq->NPCAggroMaxDist = 600; eq->NPCAggroMaxDist = 600;
eq->FilterID = 2008; // Guild Lobby observed value eq->FilterID = 2008; // Guild Lobby observed value
eq->LavaDamage = 50; OUT(LavaDamage);
eq->MinLavaDamage = 10; OUT(MinLavaDamage);
eq->bDisallowManaStone = 1; eq->bDisallowManaStone = 1;
eq->bNoBind = 0; eq->bNoBind = 0;
eq->bNoAttack = 0; eq->bNoAttack = 0;

View File

@ -581,8 +581,8 @@ struct NewZone_Struct {
/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions /*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0872*/ uint32 scriptIDSomething3; /*0872*/ uint32 scriptIDSomething3;
/*0876*/ uint32 SuspendBuffs; /*0876*/ uint32 SuspendBuffs;
/*0880*/ uint32 unknown880; // Seen 50 /*0880*/ uint32 LavaDamage; // Seen 50
/*0884*/ uint32 unknown884; // Seen 10 /*0884*/ uint32 MinLavaDamage; // Seen 10
/*0888*/ uint8 unknown888; // Seen 1 /*0888*/ uint8 unknown888; // Seen 1
/*0889*/ uint8 unknown889; // Seen 0 (POK) or 1 (rujj) /*0889*/ uint8 unknown889; // Seen 0 (POK) or 1 (rujj)
/*0890*/ uint8 unknown890; // Seen 1 /*0890*/ uint8 unknown890; // Seen 1

View File

@ -1388,8 +1388,8 @@ namespace SoD
/*fill in some unknowns with observed values, hopefully it will help */ /*fill in some unknowns with observed values, hopefully it will help */
eq->unknown800 = -1; eq->unknown800 = -1;
eq->unknown844 = 600; eq->unknown844 = 600;
eq->unknown880 = 50; OUT(LavaDamage);
eq->unknown884 = 10; OUT(MinLavaDamage);
eq->unknown888 = 1; eq->unknown888 = 1;
eq->unknown889 = 0; eq->unknown889 = 0;
eq->unknown890 = 1; eq->unknown890 = 1;

View File

@ -450,8 +450,8 @@ struct NewZone_Struct {
/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions /*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0872*/ uint32 scriptIDSomething3; /*0872*/ uint32 scriptIDSomething3;
/*0876*/ uint32 SuspendBuffs; /*0876*/ uint32 SuspendBuffs;
/*0880*/ uint32 unknown880; //seen 50 /*0880*/ uint32 LavaDamage; //seen 50
/*0884*/ uint32 unknown884; //seen 10 /*0884*/ uint32 MinLavaDamage; //seen 10
/*0888*/ uint8 unknown888; //seen 1 /*0888*/ uint8 unknown888; //seen 1
/*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj) /*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj)
/*0890*/ uint8 unknown890; //seen 1 /*0890*/ uint8 unknown890; //seen 1

View File

@ -1066,8 +1066,8 @@ namespace SoF
/*fill in some unknowns with observed values, hopefully it will help */ /*fill in some unknowns with observed values, hopefully it will help */
eq->unknown796 = -1; eq->unknown796 = -1;
eq->unknown840 = 600; eq->unknown840 = 600;
eq->unknown876 = 50; OUT(LavaDamage);
eq->unknown880 = 10; OUT(MinLavaDamage);
eq->unknown884 = 1; eq->unknown884 = 1;
eq->unknown885 = 0; eq->unknown885 = 0;
eq->unknown886 = 1; eq->unknown886 = 1;

View File

@ -454,8 +454,8 @@ struct NewZone_Struct {
/*0864*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions /*0864*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0868*/ uint32 scriptIDSomething3; /*0868*/ uint32 scriptIDSomething3;
/*0872*/ uint32 SuspendBuffs; /*0872*/ uint32 SuspendBuffs;
/*0876*/ uint32 unknown876; //seen 50 /*0876*/ uint32 LavaDamage; //seen 50
/*0880*/ uint32 unknown880; //seen 10 /*0880*/ uint32 MinLavaDamage; //seen 10
/*0884*/ uint8 unknown884; //seen 1 /*0884*/ uint8 unknown884; //seen 1
/*0885*/ uint8 unknown885; //seen 0 (POK) or 1 (rujj) /*0885*/ uint8 unknown885; //seen 0 (POK) or 1 (rujj)
/*0886*/ uint8 unknown886; //seen 1 /*0886*/ uint8 unknown886; //seen 1

View File

@ -1614,8 +1614,8 @@ namespace UF
/*fill in some unknowns with observed values, hopefully it will help */ /*fill in some unknowns with observed values, hopefully it will help */
eq->unknown800 = -1; eq->unknown800 = -1;
eq->unknown844 = 600; eq->unknown844 = 600;
eq->unknown880 = 50; OUT(LavaDamage);
eq->unknown884 = 10; OUT(MinLavaDamage);
eq->unknown888 = 1; eq->unknown888 = 1;
eq->unknown889 = 0; eq->unknown889 = 0;
eq->unknown890 = 1; eq->unknown890 = 1;

View File

@ -450,8 +450,8 @@ struct NewZone_Struct {
/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions /*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions
/*0872*/ uint32 scriptIDSomething3; /*0872*/ uint32 scriptIDSomething3;
/*0876*/ uint32 SuspendBuffs; /*0876*/ uint32 SuspendBuffs;
/*0880*/ uint32 unknown880; //seen 50 /*0880*/ uint32 LavaDamage; //seen 50
/*0884*/ uint32 unknown884; //seen 10 /*0884*/ uint32 MinLavaDamage; //seen 10
/*0888*/ uint8 unknown888; //seen 1 /*0888*/ uint8 unknown888; //seen 1
/*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj) /*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj)
/*0890*/ uint8 unknown890; //seen 1 /*0890*/ uint8 unknown890; //seen 1

View File

@ -2232,3 +2232,15 @@ bool PlayerAppearance::IsValidWoad(uint16 race_id, uint8 gender_id, uint8 woad_v
} }
return false; return false;
} }
const char* GetGenderName(uint32 gender_id) {
const char* gender_name = "Unknown";
if (gender_id == MALE) {
gender_name = "Male";
} else if (gender_id == FEMALE) {
gender_name = "Female";
} else if (gender_id == NEUTER) {
gender_name = "Neuter";
}
return gender_name;
}

View File

@ -851,6 +851,7 @@
const char* GetRaceIDName(uint16 race_id); const char* GetRaceIDName(uint16 race_id);
const char* GetPlayerRaceName(uint32 player_race_value); const char* GetPlayerRaceName(uint32 player_race_value);
const char* GetGenderName(uint32 gender_id);
uint32 GetPlayerRaceValue(uint16 race_id); uint32 GetPlayerRaceValue(uint16 race_id);
uint32 GetPlayerRaceBit(uint16 race_id); uint32 GetPlayerRaceBit(uint16 race_id);

View File

@ -110,6 +110,8 @@ public:
std::string content_flags; std::string content_flags;
std::string content_flags_disabled; std::string content_flags_disabled;
int underworld_teleport_index; int underworld_teleport_index;
int lava_damage;
int min_lava_damage;
}; };
static std::string PrimaryKey() static std::string PrimaryKey()
@ -212,6 +214,8 @@ public:
"content_flags", "content_flags",
"content_flags_disabled", "content_flags_disabled",
"underworld_teleport_index", "underworld_teleport_index",
"lava_damage",
"min_lava_damage",
}; };
} }
@ -339,6 +343,8 @@ public:
entry.content_flags = ""; entry.content_flags = "";
entry.content_flags_disabled = ""; entry.content_flags_disabled = "";
entry.underworld_teleport_index = 0; entry.underworld_teleport_index = 0;
entry.lava_damage = 50;
entry.min_lava_damage = 10;
return entry; return entry;
} }
@ -466,6 +472,8 @@ public:
entry.content_flags = row[89] ? row[89] : ""; entry.content_flags = row[89] ? row[89] : "";
entry.content_flags_disabled = row[90] ? row[90] : ""; entry.content_flags_disabled = row[90] ? row[90] : "";
entry.underworld_teleport_index = atoi(row[91]); entry.underworld_teleport_index = atoi(row[91]);
entry.lava_damage = atoi(row[92]);
entry.min_lava_damage = atoi(row[93]);
return entry; return entry;
} }
@ -590,6 +598,8 @@ public:
update_values.push_back(columns[89] + " = '" + EscapeString(zone_entry.content_flags) + "'"); update_values.push_back(columns[89] + " = '" + EscapeString(zone_entry.content_flags) + "'");
update_values.push_back(columns[90] + " = '" + EscapeString(zone_entry.content_flags_disabled) + "'"); update_values.push_back(columns[90] + " = '" + EscapeString(zone_entry.content_flags_disabled) + "'");
update_values.push_back(columns[91] + " = " + std::to_string(zone_entry.underworld_teleport_index)); update_values.push_back(columns[91] + " = " + std::to_string(zone_entry.underworld_teleport_index));
update_values.push_back(columns[92] + " = " + std::to_string(zone_entry.lava_damage));
update_values.push_back(columns[93] + " = " + std::to_string(zone_entry.min_lava_damage));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -703,6 +713,8 @@ public:
insert_values.push_back("'" + EscapeString(zone_entry.content_flags) + "'"); insert_values.push_back("'" + EscapeString(zone_entry.content_flags) + "'");
insert_values.push_back("'" + EscapeString(zone_entry.content_flags_disabled) + "'"); insert_values.push_back("'" + EscapeString(zone_entry.content_flags_disabled) + "'");
insert_values.push_back(std::to_string(zone_entry.underworld_teleport_index)); insert_values.push_back(std::to_string(zone_entry.underworld_teleport_index));
insert_values.push_back(std::to_string(zone_entry.lava_damage));
insert_values.push_back(std::to_string(zone_entry.min_lava_damage));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -824,6 +836,8 @@ public:
insert_values.push_back("'" + EscapeString(zone_entry.content_flags) + "'"); insert_values.push_back("'" + EscapeString(zone_entry.content_flags) + "'");
insert_values.push_back("'" + EscapeString(zone_entry.content_flags_disabled) + "'"); insert_values.push_back("'" + EscapeString(zone_entry.content_flags_disabled) + "'");
insert_values.push_back(std::to_string(zone_entry.underworld_teleport_index)); insert_values.push_back(std::to_string(zone_entry.underworld_teleport_index));
insert_values.push_back(std::to_string(zone_entry.lava_damage));
insert_values.push_back(std::to_string(zone_entry.min_lava_damage));
insert_chunks.push_back("(" + implode(",", insert_values) + ")"); insert_chunks.push_back("(" + implode(",", insert_values) + ")");
} }
@ -949,6 +963,8 @@ public:
entry.content_flags = row[89] ? row[89] : ""; entry.content_flags = row[89] ? row[89] : "";
entry.content_flags_disabled = row[90] ? row[90] : ""; entry.content_flags_disabled = row[90] ? row[90] : "";
entry.underworld_teleport_index = atoi(row[91]); entry.underworld_teleport_index = atoi(row[91]);
entry.lava_damage = atoi(row[92]);
entry.min_lava_damage = atoi(row[93]);
all_entries.push_back(entry); all_entries.push_back(entry);
} }
@ -1065,6 +1081,8 @@ public:
entry.content_flags = row[89] ? row[89] : ""; entry.content_flags = row[89] ? row[89] : "";
entry.content_flags_disabled = row[90] ? row[90] : ""; entry.content_flags_disabled = row[90] ? row[90] : "";
entry.underworld_teleport_index = atoi(row[91]); entry.underworld_teleport_index = atoi(row[91]);
entry.lava_damage = atoi(row[92]);
entry.min_lava_damage = atoi(row[93]);
all_entries.push_back(entry); all_entries.push_back(entry);
} }

View File

@ -227,90 +227,24 @@
#define ServerOP_HotReloadQuests 0x4011 #define ServerOP_HotReloadQuests 0x4011
#define ServerOP_UpdateSchedulerEvents 0x4012 #define ServerOP_UpdateSchedulerEvents 0x4012
#define ServerOP_CZCastSpellPlayer 0x4500 #define ServerOP_CZLDoNUpdate 0x4500
#define ServerOP_CZCastSpellGroup 0x4501 #define ServerOP_CZMarquee 0x4501
#define ServerOP_CZCastSpellRaid 0x4502 #define ServerOP_CZMessage 0x4502
#define ServerOP_CZCastSpellGuild 0x4503 #define ServerOP_CZMove 0x4503
#define ServerOP_CZMarqueePlayer 0x4504 #define ServerOP_CZSetEntityVariable 0x4504
#define ServerOP_CZMarqueeGroup 0x4505 #define ServerOP_CZSignal 0x4505
#define ServerOP_CZMarqueeRaid 0x4506 #define ServerOP_CZSpell 0x4506
#define ServerOP_CZMarqueeGuild 0x4507 #define ServerOP_CZTaskUpdate 0x4507
#define ServerOP_CZMessagePlayer 0x4508 #define ServerOP_CZClientMessageString 0x4508
#define ServerOP_CZMessageGroup 0x4509
#define ServerOP_CZMessageRaid 0x4510
#define ServerOP_CZMessageGuild 0x4511
#define ServerOP_CZMovePlayer 0x4512
#define ServerOP_CZMoveGroup 0x4513
#define ServerOP_CZMoveRaid 0x4514
#define ServerOP_CZMoveGuild 0x4515
#define ServerOP_CZMoveInstancePlayer 0x4516
#define ServerOP_CZMoveInstanceGroup 0x4517
#define ServerOP_CZMoveInstanceRaid 0x4518
#define ServerOP_CZMoveInstanceGuild 0x4519
#define ServerOP_CZRemoveSpellPlayer 0x4520
#define ServerOP_CZRemoveSpellGroup 0x4521
#define ServerOP_CZRemoveSpellRaid 0x4522
#define ServerOP_CZRemoveSpellGuild 0x4523
#define ServerOP_CZSetEntityVariableByClientName 0x4524
#define ServerOP_CZSetEntityVariableByNPCTypeID 0x4525
#define ServerOP_CZSetEntityVariableByGroupID 0x4526
#define ServerOP_CZSetEntityVariableByRaidID 0x4527
#define ServerOP_CZSetEntityVariableByGuildID 0x4528
#define ServerOP_CZSignalClient 0x4529
#define ServerOP_CZSignalClientByName 0x4530
#define ServerOP_CZSignalNPC 0x4531
#define ServerOP_CZSignalGroup 0x4532
#define ServerOP_CZSignalRaid 0x4533
#define ServerOP_CZSignalGuild 0x4534
#define ServerOP_CZTaskActivityResetPlayer 0x4535
#define ServerOP_CZTaskActivityResetGroup 0x4536
#define ServerOP_CZTaskActivityResetRaid 0x4537
#define ServerOP_CZTaskActivityResetGuild 0x4538
#define ServerOP_CZTaskActivityUpdatePlayer 0x4539
#define ServerOP_CZTaskActivityUpdateGroup 0x4540
#define ServerOP_CZTaskActivityUpdateRaid 0x4541
#define ServerOP_CZTaskActivityUpdateGuild 0x4542
#define ServerOP_CZTaskAssignPlayer 0x4543
#define ServerOP_CZTaskAssignGroup 0x4544
#define ServerOP_CZTaskAssignRaid 0x4545
#define ServerOP_CZTaskAssignGuild 0x4546
#define ServerOP_CZTaskDisablePlayer 0x4547
#define ServerOP_CZTaskDisableGroup 0x4548
#define ServerOP_CZTaskDisableRaid 0x4549
#define ServerOP_CZTaskDisableGuild 0x4550
#define ServerOP_CZTaskEnablePlayer 0x4551
#define ServerOP_CZTaskEnableGroup 0x4552
#define ServerOP_CZTaskEnableRaid 0x4553
#define ServerOP_CZTaskEnableGuild 0x4554
#define ServerOP_CZTaskFailPlayer 0x4555
#define ServerOP_CZTaskFailGroup 0x4556
#define ServerOP_CZTaskFailRaid 0x4557
#define ServerOP_CZTaskFailGuild 0x4558
#define ServerOP_CZTaskRemovePlayer 0x4559
#define ServerOP_CZTaskRemoveGroup 0x4560
#define ServerOP_CZTaskRemoveRaid 0x4561
#define ServerOP_CZTaskRemoveGuild 0x4562
#define ServerOP_CZClientMessageString 0x4563
#define ServerOP_CZLDoNUpdate 0x4564
#define ServerOP_WWAssignTask 0x4750 #define ServerOP_WWLDoNUpdate 0x4750
#define ServerOP_WWCastSpell 0x4751 #define ServerOP_WWMarquee 0x4751
#define ServerOP_WWCompleteActivity 0x4752 #define ServerOP_WWMessage 0x4752
#define ServerOP_WWDisableTask 0x4753 #define ServerOP_WWMove 0x4753
#define ServerOP_WWEnableTask 0x4754 #define ServerOP_WWSetEntityVariable 0x4754
#define ServerOP_WWFailTask 0x4755 #define ServerOP_WWSignal 0x4755
#define ServerOP_WWMarquee 0x4756 #define ServerOP_WWSpell 0x4756
#define ServerOP_WWMessage 0x4757 #define ServerOP_WWTaskUpdate 0x4757
#define ServerOP_WWMove 0x4758
#define ServerOP_WWMoveInstance 0x4759
#define ServerOP_WWRemoveSpell 0x4760
#define ServerOP_WWRemoveTask 0x4761
#define ServerOP_WWResetActivity 0x4762
#define ServerOP_WWSetEntityVariableClient 0x4763
#define ServerOP_WWSetEntityVariableNPC 0x4764
#define ServerOP_WWSignalClient 0x4765
#define ServerOP_WWSignalNPC 0x4766
#define ServerOP_WWUpdateActivity 0x4767
/** /**
* QueryServer * QueryServer
@ -325,17 +259,75 @@
#define ServerOP_QSPlayerDropItem 0x5007 #define ServerOP_QSPlayerDropItem 0x5007
enum { enum {
CZLDoNUpdateType_Character = 0, CZUpdateType_Character,
CZLDoNUpdateType_Group, CZUpdateType_Group,
CZLDoNUpdateType_Raid, CZUpdateType_Raid,
CZLDoNUpdateType_Guild, CZUpdateType_Guild,
CZLDoNUpdateType_Expedition CZUpdateType_Expedition,
CZUpdateType_ClientName,
CZUpdateType_NPC
}; };
enum { enum {
CZLDoNUpdateSubtype_Win = 0,
CZLDoNUpdateSubtype_Loss, CZLDoNUpdateSubtype_Loss,
CZLDoNUpdateSubtype_Points CZLDoNUpdateSubtype_Points,
CZLDoNUpdateSubtype_Win
};
enum {
CZMoveUpdateSubtype_MoveZone,
CZMoveUpdateSubtype_MoveZoneInstance
};
enum {
CZSpellUpdateSubtype_Cast,
CZSpellUpdateSubtype_Remove
};
enum {
CZTaskUpdateSubtype_ActivityReset,
CZTaskUpdateSubtype_ActivityUpdate,
CZTaskUpdateSubtype_AssignTask,
CZTaskUpdateSubtype_DisableTask,
CZTaskUpdateSubtype_EnableTask,
CZTaskUpdateSubtype_FailTask,
CZTaskUpdateSubtype_RemoveTask
};
enum {
WWLDoNUpdateType_Loss,
WWLDoNUpdateType_Points,
WWLDoNUpdateType_Win
};
enum {
WWMoveUpdateType_MoveZone,
WWMoveUpdateType_MoveZoneInstance
};
enum {
WWSetEntityVariableUpdateType_Character,
WWSetEntityVariableUpdateType_NPC
};
enum {
WWSignalUpdateType_Character,
WWSignalUpdateType_NPC
};
enum {
WWSpellUpdateType_Cast,
WWSpellUpdateType_Remove
};
enum {
WWTaskUpdateType_ActivityReset,
WWTaskUpdateType_ActivityUpdate,
WWTaskUpdateType_AssignTask,
WWTaskUpdateType_DisableTask,
WWTaskUpdateType_EnableTask,
WWTaskUpdateType_FailTask,
WWTaskUpdateType_RemoveTask
}; };
/* Query Serv Generic Packet Flag/Type Enumeration */ /* Query Serv Generic Packet Flag/Type Enumeration */
@ -1440,489 +1432,94 @@ struct QSGeneralQuery_Struct {
char QueryString[0]; char QueryString[0];
}; };
struct CZCastSpellPlayer_Struct {
int character_id;
uint32 spell_id;
};
struct CZCastSpellGroup_Struct {
int group_id;
uint32 spell_id;
};
struct CZCastSpellRaid_Struct {
int raid_id;
uint32 spell_id;
};
struct CZCastSpellGuild_Struct {
int guild_id;
uint32 spell_id;
};
struct CZClientSignal_Struct {
int character_id;
uint32 signal;
};
struct CZGroupSignal_Struct {
int group_id;
uint32 signal;
};
struct CZRaidSignal_Struct {
int raid_id;
uint32 signal;
};
struct CZGuildSignal_Struct {
int guild_id;
uint32 signal;
};
struct CZNPCSignal_Struct {
uint32 npctype_id;
uint32 signal;
};
struct CZClientMessageString_Struct { struct CZClientMessageString_Struct {
uint32 string_id; uint32 string_id;
uint16 chat_type; uint16 chat_type;
char character_name[64]; char client_name[64];
uint32 args_size; uint32 args_size;
char args[1]; // null delimited char args[1]; // null delimited
}; };
struct CZClientSignalByName_Struct {
char character_name[64];
uint32 signal;
};
struct CZCompleteActivityPlayer_Struct {
int character_id;
uint32 task_id;
int activity_id;
};
struct CZCompleteActivityGroup_Struct {
int group_id;
uint32 task_id;
int activity_id;
};
struct CZCompleteActivityRaid_Struct {
int raid_id;
uint32 task_id;
int activity_id;
};
struct CZCompleteActivityGuild_Struct {
int guild_id;
uint32 task_id;
int activity_id;
};
struct CZMovePlayer_Struct {
int character_id;
char zone_short_name[32];
};
struct CZMarqueePlayer_Struct {
int character_id;
uint32 type;
uint32 priority;
uint32 fade_in;
uint32 fade_out;
uint32 duration;
char message[512];
};
struct CZMarqueeGroup_Struct {
int group_id;
uint32 type;
uint32 priority;
uint32 fade_in;
uint32 fade_out;
uint32 duration;
char message[512];
};
struct CZMarqueeRaid_Struct {
int raid_id;
uint32 type;
uint32 priority;
uint32 fade_in;
uint32 fade_out;
uint32 duration;
char message[512];
};
struct CZMarqueeGuild_Struct {
int guild_id;
uint32 type;
uint32 priority;
uint32 fade_in;
uint32 fade_out;
uint32 duration;
char message[512];
};
struct CZMessagePlayer_Struct {
uint32 type;
char character_name[64];
char message[512];
};
struct CZMessageGroup_Struct {
uint32 type;
int group_id;
char message[512];
};
struct CZMessageRaid_Struct {
uint32 type;
int raid_id;
char message[512];
};
struct CZMessageGuild_Struct {
uint32 type;
int guild_id;
char message[512];
};
struct CZMoveGroup_Struct {
int group_id;
char zone_short_name[32];
};
struct CZMoveRaid_Struct {
int raid_id;
char zone_short_name[32];
};
struct CZMoveGuild_Struct {
int guild_id;
char zone_short_name[32];
};
struct CZMoveInstancePlayer_Struct {
int character_id;
uint16 instance_id;
};
struct CZMoveInstanceGroup_Struct {
int group_id;
uint16 instance_id;
};
struct CZMoveInstanceRaid_Struct {
int raid_id;
uint16 instance_id;
};
struct CZMoveInstanceGuild_Struct {
int guild_id;
uint16 instance_id;
};
struct CZRemoveSpellPlayer_Struct {
int character_id;
uint32 spell_id;
};
struct CZRemoveSpellGroup_Struct {
int group_id;
uint32 spell_id;
};
struct CZRemoveSpellRaid_Struct {
int raid_id;
uint32 spell_id;
};
struct CZRemoveSpellGuild_Struct {
int guild_id;
uint32 spell_id;
};
struct CZRemoveTaskPlayer_Struct {
int character_id;
uint32 task_id;
};
struct CZRemoveTaskGroup_Struct {
int group_id;
uint32 task_id;
};
struct CZRemoveTaskRaid_Struct {
int raid_id;
uint32 task_id;
};
struct CZRemoveTaskGuild_Struct {
int guild_id;
uint32 task_id;
};
struct CZResetActivityPlayer_Struct {
int character_id;
uint32 task_id;
int activity_id;
};
struct CZResetActivityGroup_Struct {
int group_id;
uint32 task_id;
int activity_id;
};
struct CZResetActivityRaid_Struct {
int raid_id;
uint32 task_id;
int activity_id;
};
struct CZResetActivityGuild_Struct {
int guild_id;
uint32 task_id;
int activity_id;
};
struct CZSetEntVarByNPCTypeID_Struct {
uint32 npctype_id;
char variable_name[256];
char variable_value[256];
};
struct CZSetEntVarByClientName_Struct {
char character_name[64];
char variable_name[256];
char variable_value[256];
};
struct CZSetEntVarByGroupID_Struct {
int group_id;
char variable_name[256];
char variable_value[256];
};
struct CZSetEntVarByRaidID_Struct {
int raid_id;
char variable_name[256];
char variable_value[256];
};
struct CZSetEntVarByGuildID_Struct {
int guild_id;
char variable_name[256];
char variable_value[256];
};
struct CZTaskActivityResetPlayer_Struct {
int character_id;
uint32 task_id;
int activity_id;
};
struct CZTaskActivityResetGroup_Struct {
int group_id;
uint32 task_id;
int activity_id;
};
struct CZTaskActivityResetRaid_Struct {
int raid_id;
uint32 task_id;
int activity_id;
};
struct CZTaskActivityResetGuild_Struct {
int guild_id;
uint32 task_id;
int activity_id;
};
struct CZTaskActivityUpdatePlayer_Struct {
int character_id;
uint32 task_id;
int activity_id;
int activity_count;
};
struct CZTaskActivityUpdateGroup_Struct {
int group_id;
uint32 task_id;
int activity_id;
int activity_count;
};
struct CZTaskActivityUpdateRaid_Struct {
int raid_id;
uint32 task_id;
int activity_id;
int activity_count;
};
struct CZTaskActivityUpdateGuild_Struct {
int guild_id;
uint32 task_id;
int activity_id;
int activity_count;
};
struct CZTaskAssignPlayer_Struct {
uint16 npc_entity_id;
int character_id;
uint32 task_id;
bool enforce_level_requirement;
};
struct CZTaskAssignGroup_Struct {
uint16 npc_entity_id;
int group_id;
uint32 task_id;
bool enforce_level_requirement;
};
struct CZTaskAssignRaid_Struct {
uint16 npc_entity_id;
int raid_id;
uint32 task_id;
bool enforce_level_requirement;
};
struct CZTaskAssignGuild_Struct {
uint16 npc_entity_id;
int guild_id;
uint32 task_id;
bool enforce_level_requirement;
};
struct CZTaskDisablePlayer_Struct {
int character_id;
uint32 task_id;
};
struct CZTaskDisableGroup_Struct {
int group_id;
uint32 task_id;
};
struct CZTaskDisableRaid_Struct {
int raid_id;
uint32 task_id;
};
struct CZTaskDisableGuild_Struct {
int guild_id;
uint32 task_id;
};
struct CZTaskEnablePlayer_Struct {
int character_id;
uint32 task_id;
};
struct CZTaskEnableGroup_Struct {
int group_id;
uint32 task_id;
};
struct CZTaskEnableRaid_Struct {
int raid_id;
uint32 task_id;
};
struct CZTaskEnableGuild_Struct {
int guild_id;
uint32 task_id;
};
struct CZTaskFailPlayer_Struct {
int character_id;
uint32 task_id;
};
struct CZTaskFailGroup_Struct {
int group_id;
uint32 task_id;
};
struct CZTaskFailRaid_Struct {
int raid_id;
uint32 task_id;
};
struct CZTaskFailGuild_Struct {
int guild_id;
uint32 task_id;
};
struct CZTaskRemovePlayer_Struct {
uint16 npc_entity_id;
int character_id;
uint32 task_id;
};
struct CZTaskRemoveGroup_Struct {
uint16 npc_entity_id;
int group_id;
uint32 task_id;
};
struct CZTaskRemoveRaid_Struct {
uint16 npc_entity_id;
int raid_id;
uint32 task_id;
};
struct CZTaskRemoveGuild_Struct {
uint16 npc_entity_id;
int guild_id;
uint32 task_id;
};
struct CZLDoNUpdate_Struct { struct CZLDoNUpdate_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Win, 1 - Loss, 2 - Points uint8 update_subtype; // 0 - Loss, 1 - Points, 2 - Win
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint32 theme_id; uint32 theme_id;
int points; // Always 1, except for when Points are used int points; // Only used in Points Subtype, else 1
char client_name[64]; // Only used by Character Name Type, else empty
}; };
struct WWAssignTask_Struct { struct CZMarquee_Struct {
uint16 npc_entity_id; uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint32 task_id; int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
bool enforce_level_requirement; uint32 type;
uint8 min_status; uint32 priority;
uint8 max_status; uint32 fade_in;
uint32 fade_out;
uint32 duration;
char message[512];
char client_name[64]; // Only used by Character Name Type, else empty
}; };
struct WWCastSpell_Struct { struct CZMessage_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
int update_identifier; // Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint32 type;
char message[512];
char client_name[64]; // Only used by Character Name Type, else empty
};
struct CZMove_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Move Zone, 1 - Move Zone Instance
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint16 instance_id; // Only used by Move Zone Instance, else 0
char zone_short_name[32]; // Only by with Move Zone, else empty
char client_name[64]; // Only used by Character Name Type, else empty
};
struct CZSetEntityVariable_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name, 6 - NPC
int update_identifier; // Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
char variable_name[256];
char variable_value[256];
char client_name[64]; // Only used by Character Type, else empty
};
struct CZSignal_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name, 6 - NPC
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
uint32 signal;
char client_name[64]; // Only used by Character Name Type, else empty
};
struct CZSpell_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Cast Spell, 1 - Remove Spell
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint32 spell_id; uint32 spell_id;
char client_name[64]; // Only used by Character Name Type, else empty
};
struct CZTaskUpdate_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Activity Reset, 1 - Activity Update, 2 - Assign Task, 3 - Disable Task, 4 - Enable Task, 5 - Fail Task, 6 - Remove Task
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint32 task_identifier;
int task_subidentifier; // Activity ID for Activity Reset and Activity Update, NPC Entity ID for Assign Task, else -1
int update_count; // Only used by Activity Update, else 1
bool enforce_level_requirement; // Only used by Assign Task
char client_name[64]; // Only used by Character Name Type, else empty
};
struct WWLDoNUpdate_Struct {
uint8 update_type; // 0 - Loss, 1 - Points, 2 - Win
uint32 theme_id;
int points; // Only used in Points Subtype, else 1
uint8 min_status; uint8 min_status;
uint8 max_status; uint8 max_status;
}; };
struct WWDisableTask_Struct {
uint32 task_id;
uint8 min_status;
uint8 max_status;
};
struct WWEnableTask_Struct {
uint32 task_id;
uint8 min_status;
uint8 max_status;
};
struct WWFailTask_Struct {
uint32 task_id;
uint8 min_status;
uint8 max_status;
};
struct WWMarquee_Struct { struct WWMarquee_Struct {
uint32 type; uint32 type;
uint32 priority; uint32 priority;
@ -1942,63 +1539,41 @@ struct WWMessage_Struct {
}; };
struct WWMove_Struct { struct WWMove_Struct {
char zone_short_name[32]; uint8 update_type; // 0 - Move Zone, 1 - Move Zone Instance
char zone_short_name[32]; // Used with Move Zone
uint16 instance_id; // Used with Move Zone Instance
uint8 min_status; uint8 min_status;
uint8 max_status; uint8 max_status;
}; };
struct WWMoveInstance_Struct { struct WWSetEntityVariable_Struct {
uint16 instance_id; uint8 update_type; // 0 - Character, 1 - NPC
char variable_name[256];
char variable_value[256];
uint8 min_status; uint8 min_status;
uint8 max_status; uint8 max_status;
}; };
struct WWRemoveSpell_Struct { struct WWSignal_Struct {
uint8 update_type; // 0 - Character, 1 - NPC
uint32 signal;
uint8 min_status;
uint8 max_status;
};
struct WWSpell_Struct {
uint8 update_type; // 0 - Cast Spell, 1 - Remove Spell
uint32 spell_id; uint32 spell_id;
uint8 min_status; uint8 min_status;
uint8 max_status; uint8 max_status;
}; };
struct WWRemoveTask_Struct { struct WWTaskUpdate_Struct {
uint32 task_id; uint8 update_type; // 0 - Activity Reset, 1 - Activity Update, 2 - Assign Task, 3 - Disable Task, 4 - Enable Task, 5 - Fail Task, 6 - Remove Task
uint8 min_status; uint32 task_identifier;
uint8 max_status; int task_subidentifier; // Activity ID for Activity Reset and Activity Update, NPC Entity ID for Assign Task, else -1
int update_count; // Update Count for Activity Update, else 1
}; bool enforce_level_requirement; // Only used by Assign Task, else false
struct WWResetActivity_Struct {
uint32 task_id;
int activity_id;
uint8 min_status;
uint8 max_status;
};
struct WWSetEntVarClient_Struct {
char variable_name[256];
char variable_value[256];
uint8 min_status;
uint8 max_status;
};
struct WWSetEntVarNPC_Struct {
char variable_name[256];
char variable_value[256];
};
struct WWSignalClient_Struct {
uint32 signal;
uint8 min_status;
uint8 max_status;
};
struct WWSignalNPC_Struct {
uint32 signal;
};
struct WWUpdateActivity_Struct {
uint32 task_id;
int activity_id;
int activity_count;
uint8 min_status; uint8 min_status;
uint8 max_status; uint8 max_status;
}; };

View File

@ -1390,7 +1390,7 @@ int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot)
if (slot < 4) { if (slot < 4) {
if (id == "components") { return spells[spell_id].components[slot]; } if (id == "components") { return spells[spell_id].components[slot]; }
else if (id == "component_counts") { return spells[spell_id].component_counts[slot]; } else if (id == "component_counts") { return spells[spell_id].component_counts[slot]; }
else if (id == "NoexpendReagent") { return spells[spell_id].NoexpendReagent[slot]; } else if (id == "noexpendreagent") { return spells[spell_id].NoexpendReagent[slot]; }
} }
if (id == "range") { return static_cast<int32>(spells[spell_id].range); } if (id == "range") { return static_cast<int32>(spells[spell_id].range); }
@ -1402,26 +1402,26 @@ int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot)
else if (id == "recast_time") { return spells[spell_id].recast_time; } else if (id == "recast_time") { return spells[spell_id].recast_time; }
else if (id == "buffdurationformula") { return spells[spell_id].buffdurationformula; } else if (id == "buffdurationformula") { return spells[spell_id].buffdurationformula; }
else if (id == "buffduration") { return spells[spell_id].buffduration; } else if (id == "buffduration") { return spells[spell_id].buffduration; }
else if (id == "AEDuration") { return spells[spell_id].AEDuration; } else if (id == "aeduration") { return spells[spell_id].AEDuration; }
else if (id == "mana") { return spells[spell_id].mana; } else if (id == "mana") { return spells[spell_id].mana; }
//else if (id == "LightType") {stat = spells[spell_id].LightType; } - Not implemented //else if (id == "LightType") {stat = spells[spell_id].LightType; } - Not implemented
else if (id == "goodEffect") { return spells[spell_id].goodEffect; } else if (id == "goodeffect") { return spells[spell_id].goodEffect; }
else if (id == "Activated") { return spells[spell_id].Activated; } else if (id == "activated") { return spells[spell_id].Activated; }
else if (id == "resisttype") { return spells[spell_id].resisttype; } else if (id == "resisttype") { return spells[spell_id].resisttype; }
else if (id == "targettype") { return spells[spell_id].targettype; } else if (id == "targettype") { return spells[spell_id].targettype; }
else if (id == "basediff") { return spells[spell_id].basediff; } else if (id == "basediff") { return spells[spell_id].basediff; }
else if (id == "skill") { return spells[spell_id].skill; } else if (id == "skill") { return spells[spell_id].skill; }
else if (id == "zonetype") { return spells[spell_id].zonetype; } else if (id == "zonetype") { return spells[spell_id].zonetype; }
else if (id == "EnvironmentType") { return spells[spell_id].EnvironmentType; } else if (id == "environmenttype") { return spells[spell_id].EnvironmentType; }
else if (id == "TimeOfDay") { return spells[spell_id].TimeOfDay; } else if (id == "timeofday") { return spells[spell_id].TimeOfDay; }
else if (id == "CastingAnim") { return spells[spell_id].CastingAnim; } else if (id == "castinganim") { return spells[spell_id].CastingAnim; }
else if (id == "SpellAffectIndex") { return spells[spell_id].SpellAffectIndex; } else if (id == "spellaffectindex") { return spells[spell_id].SpellAffectIndex; }
else if (id == "disallow_sit") { return spells[spell_id].disallow_sit; } else if (id == "disallow_sit") { return spells[spell_id].disallow_sit; }
//else if (id == "spellanim") {stat = spells[spell_id].spellanim; } - Not implemented //else if (id == "spellanim") {stat = spells[spell_id].spellanim; } - Not implemented
else if (id == "uninterruptable") { return spells[spell_id].uninterruptable; } else if (id == "uninterruptable") { return spells[spell_id].uninterruptable; }
else if (id == "ResistDiff") { return spells[spell_id].ResistDiff; } else if (id == "resistdiff") { return spells[spell_id].ResistDiff; }
else if (id == "dot_stacking_exempt") { return spells[spell_id].dot_stacking_exempt; } else if (id == "dot_stacking_exempt") { return spells[spell_id].dot_stacking_exempt; }
else if (id == "RecourseLink") { return spells[spell_id].RecourseLink; } else if (id == "recourselink") { return spells[spell_id].RecourseLink; }
else if (id == "no_partial_resist") { return spells[spell_id].no_partial_resist; } else if (id == "no_partial_resist") { return spells[spell_id].no_partial_resist; }
else if (id == "short_buff_box") { return spells[spell_id].short_buff_box; } else if (id == "short_buff_box") { return spells[spell_id].short_buff_box; }
else if (id == "descnum") { return spells[spell_id].descnum; } else if (id == "descnum") { return spells[spell_id].descnum; }
@ -1429,11 +1429,11 @@ int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot)
else if (id == "npc_no_los") { return spells[spell_id].npc_no_los; } else if (id == "npc_no_los") { return spells[spell_id].npc_no_los; }
else if (id == "reflectable") { return spells[spell_id].reflectable; } else if (id == "reflectable") { return spells[spell_id].reflectable; }
else if (id == "bonushate") { return spells[spell_id].bonushate; } else if (id == "bonushate") { return spells[spell_id].bonushate; }
else if (id == "EndurCost") { return spells[spell_id].EndurCost; } else if (id == "endurcost") { return spells[spell_id].EndurCost; }
else if (id == "EndurTimerIndex") { return spells[spell_id].EndurTimerIndex; } else if (id == "endurtimerindex") { return spells[spell_id].EndurTimerIndex; }
else if (id == "IsDisciplineBuff") { return spells[spell_id].IsDisciplineBuff; } else if (id == "isdisciplinebuff") { return spells[spell_id].IsDisciplineBuff; }
else if (id == "HateAdded") { return spells[spell_id].HateAdded; } else if (id == "hateadded") { return spells[spell_id].HateAdded; }
else if (id == "EndurUpkeep") { return spells[spell_id].EndurUpkeep; } else if (id == "endurupkeep") { return spells[spell_id].EndurUpkeep; }
else if (id == "numhitstype") { return spells[spell_id].numhitstype; } else if (id == "numhitstype") { return spells[spell_id].numhitstype; }
else if (id == "numhits") { return spells[spell_id].numhits; } else if (id == "numhits") { return spells[spell_id].numhits; }
else if (id == "pvpresistbase") { return spells[spell_id].pvpresistbase; } else if (id == "pvpresistbase") { return spells[spell_id].pvpresistbase; }
@ -1442,11 +1442,11 @@ int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot)
else if (id == "spell_category") { return spells[spell_id].spell_category; } else if (id == "spell_category") { return spells[spell_id].spell_category; }
else if (id == "can_mgb") { return spells[spell_id].can_mgb; } else if (id == "can_mgb") { return spells[spell_id].can_mgb; }
else if (id == "dispel_flag") { return spells[spell_id].dispel_flag; } else if (id == "dispel_flag") { return spells[spell_id].dispel_flag; }
else if (id == "MinResist") { return spells[spell_id].MinResist; } else if (id == "minresist") { return spells[spell_id].MinResist; }
else if (id == "MaxResist") { return spells[spell_id].MaxResist; } else if (id == "maxresist") { return spells[spell_id].MaxResist; }
else if (id == "viral_targets") { return spells[spell_id].viral_targets; } else if (id == "viral_targets") { return spells[spell_id].viral_targets; }
else if (id == "viral_timer") { return spells[spell_id].viral_timer; } else if (id == "viral_timer") { return spells[spell_id].viral_timer; }
else if (id == "NimbusEffect") { return spells[spell_id].NimbusEffect; } else if (id == "nimbuseffect") { return spells[spell_id].NimbusEffect; }
else if (id == "directional_start") { return static_cast<int32>(spells[spell_id].directional_start); } else if (id == "directional_start") { return static_cast<int32>(spells[spell_id].directional_start); }
else if (id == "directional_end") { return static_cast<int32>(spells[spell_id].directional_end); } else if (id == "directional_end") { return static_cast<int32>(spells[spell_id].directional_end); }
else if (id == "not_focusable") { return spells[spell_id].not_focusable; } else if (id == "not_focusable") { return spells[spell_id].not_focusable; }
@ -1455,10 +1455,10 @@ int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot)
else if (id == "spellgroup") { return spells[spell_id].spellgroup; } else if (id == "spellgroup") { return spells[spell_id].spellgroup; }
else if (id == "rank") { return spells[spell_id].rank; } else if (id == "rank") { return spells[spell_id].rank; }
else if (id == "no_resist") { return spells[spell_id].no_resist; } else if (id == "no_resist") { return spells[spell_id].no_resist; }
else if (id == "CastRestriction") { return spells[spell_id].CastRestriction; } else if (id == "castrestriction") { return spells[spell_id].CastRestriction; }
else if (id == "AllowRest") { return spells[spell_id].AllowRest; } else if (id == "allowrest") { return spells[spell_id].AllowRest; }
else if (id == "InCombat") { return spells[spell_id].InCombat; } else if (id == "incombat") { return spells[spell_id].InCombat; }
else if (id == "OutofCombat") { return spells[spell_id].OutofCombat; } else if (id == "outofcombat") { return spells[spell_id].OutofCombat; }
else if (id == "aemaxtargets") { return spells[spell_id].aemaxtargets; } else if (id == "aemaxtargets") { return spells[spell_id].aemaxtargets; }
else if (id == "no_heal_damage_item_mod") { return spells[spell_id].no_heal_damage_item_mod; } else if (id == "no_heal_damage_item_mod") { return spells[spell_id].no_heal_damage_item_mod; }
else if (id == "persistdeath") { return spells[spell_id].persistdeath; } else if (id == "persistdeath") { return spells[spell_id].persistdeath; }
@ -1466,7 +1466,7 @@ int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot)
else if (id == "min_dist_mod") { return static_cast<int32>(spells[spell_id].min_dist_mod); } else if (id == "min_dist_mod") { return static_cast<int32>(spells[spell_id].min_dist_mod); }
else if (id == "max_dist") { return static_cast<int32>(spells[spell_id].max_dist); } else if (id == "max_dist") { return static_cast<int32>(spells[spell_id].max_dist); }
else if (id == "min_range") { return static_cast<int32>(spells[spell_id].min_range); } else if (id == "min_range") { return static_cast<int32>(spells[spell_id].min_range); }
else if (id == "DamageShieldType") { return spells[spell_id].DamageShieldType; } else if (id == "damageshieldtype") { return spells[spell_id].DamageShieldType; }
return 0; return 0;
} }

View File

@ -153,8 +153,10 @@
#define SPELL_ACTING_SPIRIT_I 1921 #define SPELL_ACTING_SPIRIT_I 1921
#define SPELL_ACTING_SPIRIT_II 1922 #define SPELL_ACTING_SPIRIT_II 1922
#define SPELL_RESURRECTION_SICKNESS 756 #define SPELL_RESURRECTION_SICKNESS 756
#define SPELL_RESURRECTION_SICKNESS4 757
#define SPELL_RESURRECTION_SICKNESS2 5249 #define SPELL_RESURRECTION_SICKNESS2 5249
#define SPELL_REVIVAL_SICKNESS 13087 #define SPELL_REVIVAL_SICKNESS 13087
#define SPELL_RESURRECTION_SICKNESS3 37624
#define SPELL_PACT_OF_HATE_RECOURSE 40375 #define SPELL_PACT_OF_HATE_RECOURSE 40375
#define SPELL_INCENDIARY_OOZE_BUFF 32513 #define SPELL_INCENDIARY_OOZE_BUFF 32513
@ -746,7 +748,7 @@ typedef enum {
//#define SE_TransferItem 60 // not used //#define SE_TransferItem 60 // not used
#define SE_Identify 61 // implemented #define SE_Identify 61 // implemented
//#define SE_ItemID 62 // not used //#define SE_ItemID 62 // not used
#define SE_WipeHateList 63 // implemented #define SE_WipeHateList 63 // implemented, @Memblur, chance to wipe hate list of target, base: pct chance, limit: none, max: ? (not implemented), Note: caster level and CHA add to pct chance
#define SE_SpinTarget 64 // implemented - TO DO: Not sure stun portion is working correctly #define SE_SpinTarget 64 // implemented - TO DO: Not sure stun portion is working correctly
#define SE_InfraVision 65 // implemented #define SE_InfraVision 65 // implemented
#define SE_UltraVision 66 // implemented #define SE_UltraVision 66 // implemented
@ -925,7 +927,7 @@ typedef enum {
#define SE_FeignedCastOnChance 239 // implemented - ability gives you an increasing chance for your feigned deaths to not be revealed by spells cast upon you. #define SE_FeignedCastOnChance 239 // implemented - ability gives you an increasing chance for your feigned deaths to not be revealed by spells cast upon you.
//#define SE_StringUnbreakable 240 // not used [Likely related to above - you become immune to feign breaking on a resisted spell and have a good chance of feigning through a spell that successfully lands upon you.] //#define SE_StringUnbreakable 240 // not used [Likely related to above - you become immune to feign breaking on a resisted spell and have a good chance of feigning through a spell that successfully lands upon you.]
#define SE_ImprovedReclaimEnergy 241 // implemented - increase the amount of mana returned to you when reclaiming your pet. #define SE_ImprovedReclaimEnergy 241 // implemented - increase the amount of mana returned to you when reclaiming your pet.
#define SE_IncreaseChanceMemwipe 242 // implemented - increases the chance to wipe hate with memory blurr #define SE_IncreaseChanceMemwipe 242 // implemented - @Memblur, increases the chance to wipe hate with memory blurr, base: chance pct, limit: none, max: none, Note: Mods final blur chance after other bonuses added.
#define SE_CharmBreakChance 243 // implemented - Total Domination #define SE_CharmBreakChance 243 // implemented - Total Domination
#define SE_RootBreakChance 244 // implemented[AA] reduce the chance that your root will break. #define SE_RootBreakChance 244 // implemented[AA] reduce the chance that your root will break.
#define SE_TrapCircumvention 245 // *not implemented[AA] - decreases the chance that you will set off a trap when opening a chest #define SE_TrapCircumvention 245 // *not implemented[AA] - decreases the chance that you will set off a trap when opening a chest
@ -974,7 +976,7 @@ typedef enum {
#define SE_SkillAttackProc 288 // implemented[AA] - Chance to proc spell on skill attack usage (ex. Dragon Punch) #define SE_SkillAttackProc 288 // implemented[AA] - Chance to proc spell on skill attack usage (ex. Dragon Punch)
#define SE_CastOnFadeEffect 289 // implemented - Triggers only if fades after natural duration. #define SE_CastOnFadeEffect 289 // implemented - Triggers only if fades after natural duration.
#define SE_IncreaseRunSpeedCap 290 // implemented[AA] - increases run speed over the hard cap #define SE_IncreaseRunSpeedCap 290 // implemented[AA] - increases run speed over the hard cap
#define SE_Purify 291 // implemented - Removes determental effects #define SE_Purify 291 // implemented, @Dispel, remove up specified amount of detiremental spells, base: amt removed, limit: none, max: none, Note: excluding charm, fear, resurrection, and revival sickness
#define SE_StrikeThrough2 292 // implemented[AA] - increasing chance of bypassing an opponent's special defenses, such as dodge, block, parry, and riposte. #define SE_StrikeThrough2 292 // implemented[AA] - increasing chance of bypassing an opponent's special defenses, such as dodge, block, parry, and riposte.
#define SE_FrontalStunResist 293 // implemented[AA] - Reduce chance to be stunned from front. -- live descriptions sounds like this isn't limited to frontal anymore #define SE_FrontalStunResist 293 // implemented[AA] - Reduce chance to be stunned from front. -- live descriptions sounds like this isn't limited to frontal anymore
#define SE_CriticalSpellChance 294 // implemented - increase chance to critical hit and critical damage modifier. #define SE_CriticalSpellChance 294 // implemented - increase chance to critical hit and critical damage modifier.
@ -1125,8 +1127,8 @@ typedef enum {
#define SE_Assassinate 439 // implemented[AA] - Assassinate damage #define SE_Assassinate 439 // implemented[AA] - Assassinate damage
#define SE_FinishingBlowLvl 440 // implemented[AA] - Sets the level Finishing blow can be triggered on an NPC #define SE_FinishingBlowLvl 440 // implemented[AA] - Sets the level Finishing blow can be triggered on an NPC
#define SE_DistanceRemoval 441 // implemented - Buff is removed from target when target moves X amount of distance away from where initially hit. #define SE_DistanceRemoval 441 // implemented - Buff is removed from target when target moves X amount of distance away from where initially hit.
#define SE_TriggerOnReqTarget 442 // implemented - triggers a spell which a certain criteria are met (below X amount of hp,mana,end, number of pets on hatelist) #define SE_TriggerOnReqTarget 442 // implemented, @SpellTrigger, triggers a spell when Target Requirement conditions are met (see enum SpellRestriction for IDs), base: spellid, limit: SpellRestriction ID, max: none, Note: Usually cast on a target
#define SE_TriggerOnReqCaster 443 // implemented - triggers a spell which a certain criteria are met (below X amount of hp,mana,end, number of pets on hatelist) #define SE_TriggerOnReqCaster 443 // implemented, @SpellTrigger, triggers a spell when Caster Requirement conditions are met (see enum SpellRestriction for IDs), base: spellid, limit: SpellRestriction ID, max: none, Note: Usually self only
#define SE_ImprovedTaunt 444 // implemented - Locks Aggro On Caster and Decrease other Players Aggro by X% on NPC targets below level Y #define SE_ImprovedTaunt 444 // implemented - Locks Aggro On Caster and Decrease other Players Aggro by X% on NPC targets below level Y
//#define SE_AddMercSlot 445 // *not implemented[AA] - [Hero's Barracks] Allows you to conscript additional mercs. //#define SE_AddMercSlot 445 // *not implemented[AA] - [Hero's Barracks] Allows you to conscript additional mercs.
#define SE_AStacker 446 // implementet - bufff stacking blocker (26219 | Qirik's Watch) #define SE_AStacker 446 // implementet - bufff stacking blocker (26219 | Qirik's Watch)

View File

@ -34,7 +34,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 9172 #define CURRENT_BINARY_DATABASE_VERSION 9173
#ifdef BOTS #ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9028 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9028

View File

@ -426,6 +426,7 @@
9170|2021_03_03_instance_safereturns.sql|SHOW TABLES LIKE 'character_instance_safereturns'|empty| 9170|2021_03_03_instance_safereturns.sql|SHOW TABLES LIKE 'character_instance_safereturns'|empty|
9171|2021_03_30_remove_dz_is_current_member.sql|SHOW COLUMNS FROM `dynamic_zone_members` LIKE 'is_current_member'|not_empty| 9171|2021_03_30_remove_dz_is_current_member.sql|SHOW COLUMNS FROM `dynamic_zone_members` LIKE 'is_current_member'|not_empty|
9172|2021_05_21_shared_tasks.sql|SHOW TABLES LIKE 'shared_tasks'|empty| 9172|2021_05_21_shared_tasks.sql|SHOW TABLES LIKE 'shared_tasks'|empty|
9173|2021_09_14_zone_lava_damage.sql|SHOW COLUMNS FROM `zone` LIKE 'lava_damage'|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

View File

@ -0,0 +1 @@
ALTER TABLE zone ADD lava_damage INT(11) NULL DEFAULT '50' AFTER underworld_teleport_index, ADD min_lava_damage INT(11) NOT NULL DEFAULT '10' AFTER lava_damage;

View File

@ -1589,12 +1589,14 @@ void ClientList::SendCharacterMessage(ClientListEntry* character, int chat_type,
return; return;
} }
uint32_t pack_size = sizeof(CZMessagePlayer_Struct); uint32_t pack_size = sizeof(CZMessage_Struct);
auto pack = std::make_unique<ServerPacket>(ServerOP_CZMessagePlayer, pack_size); auto pack = std::make_unique<ServerPacket>(ServerOP_CZMessage, pack_size);
auto buf = reinterpret_cast<CZMessagePlayer_Struct*>(pack->pBuffer); auto buf = reinterpret_cast<CZMessage_Struct*>(pack->pBuffer);
buf->update_type = CZUpdateType_ClientName;
buf->update_identifier = 0;
buf->type = chat_type; buf->type = chat_type;
strn0cpy(buf->character_name, character->name(), sizeof(buf->character_name));
strn0cpy(buf->message, message.c_str(), sizeof(buf->message)); strn0cpy(buf->message, message.c_str(), sizeof(buf->message));
strn0cpy(buf->client_name, character->name(), sizeof(buf->client_name));
character->Server()->SendPacket(pack.get()); character->Server()->SendPacket(pack.get());
} }
@ -1633,7 +1635,7 @@ void ClientList::SendCharacterMessageID(ClientListEntry* character,
auto buf = reinterpret_cast<CZClientMessageString_Struct*>(pack->pBuffer); auto buf = reinterpret_cast<CZClientMessageString_Struct*>(pack->pBuffer);
buf->string_id = eqstr_id; buf->string_id = eqstr_id;
buf->chat_type = chat_type; buf->chat_type = chat_type;
strn0cpy(buf->character_name, character->name(), sizeof(buf->character_name)); strn0cpy(buf->client_name, character->name(), sizeof(buf->client_name));
buf->args_size = args_size; buf->args_size = args_size;
memcpy(buf->args, serialized_args.buffer(), serialized_args.size()); memcpy(buf->args, serialized_args.buffer(), serialized_args.size());

View File

@ -826,13 +826,14 @@ void ConsoleSignalCharByName(
connection->SendLine(StringFormat("Signal Sent to %s with ID %i", (char *) args[0].c_str(), atoi(args[1].c_str()))); connection->SendLine(StringFormat("Signal Sent to %s with ID %i", (char *) args[0].c_str(), atoi(args[1].c_str())));
uint32 message_len = strlen((char *) args[0].c_str()) + 1; uint32 message_len = strlen((char *) args[0].c_str()) + 1;
auto pack = new ServerPacket( auto pack = new ServerPacket(ServerOP_CZSignal, sizeof(CZSignal_Struct) + message_len);
ServerOP_CZSignalClientByName, CZSignal_Struct* CZS = (CZSignal_Struct*) pack->pBuffer;
sizeof(CZClientSignalByName_Struct) + message_len uint8 update_type = CZUpdateType_ClientName;
); int update_identifier = 0;
CZClientSignalByName_Struct *CZSC = (CZClientSignalByName_Struct *) pack->pBuffer; CZS->update_type = update_type;
strn0cpy(CZSC->character_name, (char *) args[0].c_str(), 64); CZS->update_identifier = update_identifier;
CZSC->signal = atoi(args[1].c_str()); CZS->signal = atoi(args[1].c_str());
strn0cpy(CZS->client_name, (char *) args[0].c_str(), 64);
zoneserver_list.SendPacket(pack); zoneserver_list.SendPacket(pack);
safe_delete(pack); safe_delete(pack);
} }

View File

@ -1311,7 +1311,7 @@ void SharedTaskManager::SendMembersMessageID(
for (const auto &member : shared_task->GetMembers()) { for (const auto &member : shared_task->GetMembers()) {
auto character = client_list.FindCLEByCharacterID(member.character_id); auto character = client_list.FindCLEByCharacterID(member.character_id);
if (character && character->Server()) { if (character && character->Server()) {
strn0cpy(buf->character_name, character->name(), sizeof(buf->character_name)); strn0cpy(buf->client_name, character->name(), sizeof(buf->client_name));
character->Server()->SendPacket(pack.get()); character->Server()->SendPacket(pack.get());
} }
} }

View File

@ -1240,87 +1240,22 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
QSLink.SendPacket(pack); QSLink.SendPacket(pack);
break; break;
} }
case ServerOP_CZCastSpellPlayer:
case ServerOP_CZCastSpellGroup:
case ServerOP_CZCastSpellRaid:
case ServerOP_CZCastSpellGuild:
case ServerOP_CZMarqueePlayer:
case ServerOP_CZMarqueeGroup:
case ServerOP_CZMarqueeRaid:
case ServerOP_CZMarqueeGuild:
case ServerOP_CZMessagePlayer:
case ServerOP_CZMessageGroup:
case ServerOP_CZMessageRaid:
case ServerOP_CZMessageGuild:
case ServerOP_CZMovePlayer:
case ServerOP_CZMoveGroup:
case ServerOP_CZMoveRaid:
case ServerOP_CZMoveGuild:
case ServerOP_CZMoveInstancePlayer:
case ServerOP_CZMoveInstanceGroup:
case ServerOP_CZMoveInstanceRaid:
case ServerOP_CZMoveInstanceGuild:
case ServerOP_CZRemoveSpellPlayer:
case ServerOP_CZRemoveSpellGroup:
case ServerOP_CZRemoveSpellRaid:
case ServerOP_CZRemoveSpellGuild:
case ServerOP_CZSetEntityVariableByClientName:
case ServerOP_CZSetEntityVariableByNPCTypeID:
case ServerOP_CZSetEntityVariableByGroupID:
case ServerOP_CZSetEntityVariableByRaidID:
case ServerOP_CZSetEntityVariableByGuildID:
case ServerOP_CZSignalNPC:
case ServerOP_CZSignalClient:
case ServerOP_CZSignalClientByName:
case ServerOP_CZSignalGroup:
case ServerOP_CZSignalRaid:
case ServerOP_CZSignalGuild:
case ServerOP_CZTaskActivityResetPlayer:
case ServerOP_CZTaskActivityResetGroup:
case ServerOP_CZTaskActivityResetRaid:
case ServerOP_CZTaskActivityResetGuild:
case ServerOP_CZTaskActivityUpdatePlayer:
case ServerOP_CZTaskActivityUpdateGroup:
case ServerOP_CZTaskActivityUpdateRaid:
case ServerOP_CZTaskActivityUpdateGuild:
case ServerOP_CZTaskAssignPlayer:
case ServerOP_CZTaskAssignGroup:
case ServerOP_CZTaskAssignRaid:
case ServerOP_CZTaskAssignGuild:
case ServerOP_CZTaskDisablePlayer:
case ServerOP_CZTaskDisableGroup:
case ServerOP_CZTaskDisableRaid:
case ServerOP_CZTaskDisableGuild:
case ServerOP_CZTaskEnablePlayer:
case ServerOP_CZTaskEnableGroup:
case ServerOP_CZTaskEnableRaid:
case ServerOP_CZTaskEnableGuild:
case ServerOP_CZTaskFailPlayer:
case ServerOP_CZTaskFailGroup:
case ServerOP_CZTaskFailRaid:
case ServerOP_CZTaskFailGuild:
case ServerOP_CZTaskRemovePlayer:
case ServerOP_CZTaskRemoveGroup:
case ServerOP_CZTaskRemoveRaid:
case ServerOP_CZTaskRemoveGuild:
case ServerOP_CZLDoNUpdate: case ServerOP_CZLDoNUpdate:
case ServerOP_WWAssignTask: case ServerOP_CZMarquee:
case ServerOP_WWCastSpell: case ServerOP_CZMessage:
case ServerOP_WWDisableTask: case ServerOP_CZMove:
case ServerOP_WWEnableTask: case ServerOP_CZSetEntityVariable:
case ServerOP_WWFailTask: case ServerOP_CZSignal:
case ServerOP_CZSpell:
case ServerOP_CZTaskUpdate:
case ServerOP_WWLDoNUpdate:
case ServerOP_WWMarquee: case ServerOP_WWMarquee:
case ServerOP_WWMessage: case ServerOP_WWMessage:
case ServerOP_WWMove: case ServerOP_WWMove:
case ServerOP_WWMoveInstance: case ServerOP_WWSetEntityVariable:
case ServerOP_WWRemoveSpell: case ServerOP_WWSignal:
case ServerOP_WWRemoveTask: case ServerOP_WWSpell:
case ServerOP_WWResetActivity: case ServerOP_WWTaskUpdate:
case ServerOP_WWSetEntityVariableClient:
case ServerOP_WWSetEntityVariableNPC:
case ServerOP_WWSignalClient:
case ServerOP_WWSignalNPC:
case ServerOP_WWUpdateActivity:
case ServerOP_DepopAllPlayersCorpses: case ServerOP_DepopAllPlayersCorpses:
case ServerOP_DepopPlayerCorpse: case ServerOP_DepopPlayerCorpse:
case ServerOP_ReloadTitles: case ServerOP_ReloadTitles:
@ -1362,7 +1297,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
case ServerOP_CZClientMessageString: case ServerOP_CZClientMessageString:
{ {
auto buf = reinterpret_cast<CZClientMessageString_Struct*>(pack->pBuffer); auto buf = reinterpret_cast<CZClientMessageString_Struct*>(pack->pBuffer);
client_list.SendPacket(buf->character_name, pack); client_list.SendPacket(buf->client_name, pack);
break; break;
} }
case ServerOP_ExpeditionLockout: case ServerOP_ExpeditionLockout:

View File

@ -2701,8 +2701,9 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
} }
} }
if (other->IsNPC() && (other->IsPet() || other->CastToNPC()->GetSwarmOwner() > 0)) if (other->IsNPC() && (other->IsPet() || other->CastToNPC()->GetSwarmOwner() > 0)) {
TryTriggerOnValueAmount(false, false, false, true); TryTriggerOnCastRequirement();
}
if (IsClient() && !IsAIControlled()) if (IsClient() && !IsAIControlled())
return; return;
@ -3343,7 +3344,7 @@ int32 Mob::ReduceAllDamage(int32 damage)
if (GetMana() >= mana_reduced) { if (GetMana() >= mana_reduced) {
damage -= mana_reduced; damage -= mana_reduced;
SetMana(GetMana() - mana_reduced); SetMana(GetMana() - mana_reduced);
TryTriggerOnValueAmount(false, true); TryTriggerOnCastRequirement();
} }
} }
@ -3356,7 +3357,7 @@ int32 Mob::ReduceAllDamage(int32 damage)
if (IsClient() && CastToClient()->GetEndurance() >= endurance_drain) { if (IsClient() && CastToClient()->GetEndurance() >= endurance_drain) {
damage -= damage_reduced; damage -= damage_reduced;
CastToClient()->SetEndurance(CastToClient()->GetEndurance() - endurance_drain); CastToClient()->SetEndurance(CastToClient()->GetEndurance() - endurance_drain);
TryTriggerOnValueAmount(false, false, true); TryTriggerOnCastRequirement();
} }
} }
@ -3646,7 +3647,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
TryDeathSave(); TryDeathSave();
} }
TryTriggerOnValueAmount(true); TryTriggerOnCastRequirement();
//fade mez if we are mezzed //fade mez if we are mezzed
if (IsMezzed() && attacker) { if (IsMezzed() && attacker) {

View File

@ -1256,8 +1256,11 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
} }
case SE_MitigateDamageShield: { case SE_MitigateDamageShield: {
if (base1 < 0)
//AA that increase mitigation are set to negative.
if (base1 < 0) {
base1 = base1 * (-1); base1 = base1 * (-1);
}
newbon->DSMitigationOffHand += base1; newbon->DSMitigationOffHand += base1;
break; break;
@ -2663,8 +2666,15 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
case SE_MitigateDamageShield: case SE_MitigateDamageShield:
{ {
if (effect_value < 0) /*
effect_value = effect_value*-1; Bard songs have identical negative base value and positive max
The effect for the songs should increase mitigation. There are
spells that do decrease the mitigation with just negative base values.
To be consistent all values that increase mitigation will be set to positives
*/
if (max > 0 && effect_value < 0) {
effect_value = max;
}
new_bonus->DSMitigationOffHand += effect_value; new_bonus->DSMitigationOffHand += effect_value;
break; break;
@ -3198,7 +3208,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
case SE_TriggerOnReqTarget: case SE_TriggerOnReqTarget:
case SE_TriggerOnReqCaster: case SE_TriggerOnReqCaster:
new_bonus->TriggerOnValueAmount = true; new_bonus->TriggerOnCastRequirement = true;
break; break;
case SE_DivineAura: case SE_DivineAura:
@ -3661,6 +3671,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
new_bonus->ZoneSuspendMinion = effect_value; new_bonus->ZoneSuspendMinion = effect_value;
break; break;
case SE_CompleteHeal:
new_bonus->CompleteHealBuffBlocker = true;
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) {

View File

@ -9191,7 +9191,7 @@ void Client::SetDisplayMobInfoWindow(bool display_mob_info_window)
bool Client::IsDevToolsEnabled() const bool Client::IsDevToolsEnabled() const
{ {
return dev_tools_enabled && RuleB(World, EnableDevTools); return dev_tools_enabled && GetGM() && RuleB(World, EnableDevTools);
} }
void Client::SetDevToolsEnabled(bool in_dev_tools_enabled) void Client::SetDevToolsEnabled(bool in_dev_tools_enabled)
@ -9481,12 +9481,16 @@ void Client::SendCrossZoneMessage(
} }
else if (!character_name.empty() && !message.empty()) else if (!character_name.empty() && !message.empty())
{ {
uint32_t pack_size = sizeof(CZMessagePlayer_Struct); uint32_t pack_size = sizeof(CZMessage_Struct);
auto pack = std::make_unique<ServerPacket>(ServerOP_CZMessagePlayer, pack_size); auto pack = std::make_unique<ServerPacket>(ServerOP_CZMessage, pack_size);
auto buf = reinterpret_cast<CZMessagePlayer_Struct*>(pack->pBuffer); auto buf = reinterpret_cast<CZMessage_Struct*>(pack->pBuffer);
uint8 update_type = CZUpdateType_Character;
int update_identifier = 0;
buf->update_type = update_type;
buf->update_identifier = update_identifier;
buf->type = chat_type; buf->type = chat_type;
strn0cpy(buf->character_name, character_name.c_str(), sizeof(buf->character_name));
strn0cpy(buf->message, message.c_str(), sizeof(buf->message)); strn0cpy(buf->message, message.c_str(), sizeof(buf->message));
strn0cpy(buf->client_name, character_name.c_str(), sizeof(buf->client_name));
worldserver.SendPacket(pack.get()); worldserver.SendPacket(pack.get());
} }
@ -9519,7 +9523,7 @@ void Client::SendCrossZoneMessageString(
auto buf = reinterpret_cast<CZClientMessageString_Struct*>(pack->pBuffer); auto buf = reinterpret_cast<CZClientMessageString_Struct*>(pack->pBuffer);
buf->string_id = string_id; buf->string_id = string_id;
buf->chat_type = chat_type; buf->chat_type = chat_type;
strn0cpy(buf->character_name, character_name.c_str(), sizeof(buf->character_name)); strn0cpy(buf->client_name, character_name.c_str(), sizeof(buf->client_name));
buf->args_size = args_size; buf->args_size = args_size;
memcpy(buf->args, argument_buffer.buffer(), argument_buffer.size()); memcpy(buf->args, argument_buffer.buffer(), argument_buffer.size());

View File

@ -203,8 +203,10 @@ enum eInnateSkill {
InnateDisabled = 255 InnateDisabled = 255
}; };
const std::string DIAWIND_RESPONSE_KEY = "diawind_npcresponse"; const std::string DIAWIND_RESPONSE_ONE_KEY = "diawind_npc_response_one";
const uint32 POPUPID_DIAWIND = 999; const std::string DIAWIND_RESPONSE_TWO_KEY = "diawind_npc_response_two";
const uint32 POPUPID_DIAWIND_ONE = 99999;
const uint32 POPUPID_DIAWIND_TWO = 100000;
const uint32 POPUPID_UPDATE_SHOWSTATSWINDOW = 1000000; const uint32 POPUPID_UPDATE_SHOWSTATSWINDOW = 1000000;
struct ClientReward struct ClientReward

View File

@ -11155,9 +11155,18 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
return; return;
break; break;
case POPUPID_DIAWIND: case POPUPID_DIAWIND_ONE:
if (EntityVariableExists(DIAWIND_RESPONSE_KEY.c_str())) { if (EntityVariableExists(DIAWIND_RESPONSE_ONE_KEY.c_str())) {
response = GetEntityVariable(DIAWIND_RESPONSE_KEY.c_str()); response = GetEntityVariable(DIAWIND_RESPONSE_ONE_KEY.c_str());
if (!response.empty()) {
ChannelMessageReceived(8, 0, 100, response.c_str());
}
}
break;
case POPUPID_DIAWIND_TWO:
if (EntityVariableExists(DIAWIND_RESPONSE_TWO_KEY.c_str())) {
response = GetEntityVariable(DIAWIND_RESPONSE_TWO_KEY.c_str());
if (!response.empty()) { if (!response.empty()) {
ChannelMessageReceived(8, 0, 100, response.c_str()); ChannelMessageReceived(8, 0, 100, response.c_str());
} }
@ -12189,7 +12198,8 @@ void Client::Handle_OP_RecipesFavorite(const EQApplicationPacket *app)
tr.name, tr.name,
tr.trivial, tr.trivial,
SUM(tre.componentcount), SUM(tre.componentcount),
tr.tradeskill tr.tradeskill,
tr.must_learn
FROM FROM
tradeskill_recipe AS tr tradeskill_recipe AS tr
LEFT JOIN tradeskill_recipe_entries AS tre ON tr.id = tre.recipe_id LEFT JOIN tradeskill_recipe_entries AS tre ON tr.id = tre.recipe_id
@ -12289,7 +12299,8 @@ void Client::Handle_OP_RecipesSearch(const EQApplicationPacket *app)
tr.name, tr.name,
tr.trivial, tr.trivial,
SUM(tre.componentcount), SUM(tre.componentcount),
tr.tradeskill tr.tradeskill,
tr.must_learn
FROM FROM
tradeskill_recipe AS tr tradeskill_recipe AS tr
LEFT JOIN tradeskill_recipe_entries AS tre ON tr.id = tre.recipe_id LEFT JOIN tradeskill_recipe_entries AS tre ON tr.id = tre.recipe_id

View File

@ -183,6 +183,8 @@ bool Client::Process() {
SetDynamicZoneMemberStatus(DynamicZoneMemberStatus::Offline); SetDynamicZoneMemberStatus(DynamicZoneMemberStatus::Offline);
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
return false; //delete client return false; //delete client
} }
@ -1864,7 +1866,7 @@ void Client::DoEnduranceUpkeep() {
if(upkeep_sum != 0){ if(upkeep_sum != 0){
SetEndurance(GetEndurance() - upkeep_sum); SetEndurance(GetEndurance() - upkeep_sum);
TryTriggerOnValueAmount(false, false, true); TryTriggerOnCastRequirement();
} }
if (!has_effect) if (!has_effect)

File diff suppressed because it is too large Load Diff

View File

@ -554,6 +554,7 @@ struct StatBonuses {
int32 ItemEnduranceRegenCap; // modify endurance regen cap int32 ItemEnduranceRegenCap; // modify endurance regen cap
int32 WeaponStance[WEAPON_STANCE_TYPE_MAX +1];// base = trigger spell id, base2 = 0 is 2h, 1 is shield, 2 is dual wield, [0]spid 2h, [1]spid shield, [2]spid DW int32 WeaponStance[WEAPON_STANCE_TYPE_MAX +1];// base = trigger spell id, base2 = 0 is 2h, 1 is shield, 2 is dual wield, [0]spid 2h, [1]spid shield, [2]spid DW
bool ZoneSuspendMinion; // base 1 allows suspended minions to zone bool ZoneSuspendMinion; // base 1 allows suspended minions to zone
bool CompleteHealBuffBlocker; // Use in SPA 101 to prevent recast of complete heal from this effect till blocker buff is removed.
// AAs // AAs
uint16 SecondaryForte; // allow a second skill to be specialized with a cap of this value. uint16 SecondaryForte; // allow a second skill to be specialized with a cap of this value.
@ -602,7 +603,7 @@ struct StatBonuses {
int32 FinishingBlow[2]; // Chance to do a finishing blow for specified damage amount. int32 FinishingBlow[2]; // Chance to do a finishing blow for specified damage amount.
uint32 FinishingBlowLvl[2]; // Sets max level an NPC can be affected by FB. (base1 = lv, base2= ???) uint32 FinishingBlowLvl[2]; // Sets max level an NPC can be affected by FB. (base1 = lv, base2= ???)
int32 ShieldEquipDmgMod; // Increases weapon's base damage by base1 % when shield is equipped (indirectly increasing hate) int32 ShieldEquipDmgMod; // Increases weapon's base damage by base1 % when shield is equipped (indirectly increasing hate)
bool TriggerOnValueAmount; // Triggers off various different conditions, bool to check if client has effect. bool TriggerOnCastRequirement; // Triggers off various different conditions defined as emum SpellRestrictions
int8 StunBashChance; // chance to stun with bash. int8 StunBashChance; // chance to stun with bash.
int8 IncreaseChanceMemwipe; // increases chance to memory wipe int8 IncreaseChanceMemwipe; // increases chance to memory wipe
int8 CriticalMend; // chance critical monk mend int8 CriticalMend; // chance critical monk mend

View File

@ -11,7 +11,8 @@ void DialogueWindow::Render(Client *c, std::string markdown)
} }
// zero this out // zero this out
c->SetEntityVariable(DIAWIND_RESPONSE_KEY.c_str(), ""); c->SetEntityVariable(DIAWIND_RESPONSE_ONE_KEY.c_str(), "");
c->SetEntityVariable(DIAWIND_RESPONSE_TWO_KEY.c_str(), "");
// simple find and replace for the markdown // simple find and replace for the markdown
find_replace(output, "~", "</c>"); find_replace(output, "~", "</c>");
@ -32,10 +33,10 @@ void DialogueWindow::Render(Client *c, std::string markdown)
// mysterious voice // mysterious voice
bool render_mysterious_voice = false; bool render_mysterious_voice = false;
if (markdown.find("mysterious") != std::string::npos) { if (markdown.find("{mysterious}") != std::string::npos) {
render_mysterious_voice = true; render_mysterious_voice = true;
LogDiaWind("Client [{}] Rendering mysterious voice", c->GetCleanName()); LogDiaWind("Client [{}] Rendering mysterious voice", c->GetCleanName());
find_replace(output, "mysterious", ""); find_replace(output, "{mysterious}", "");
} }
// noquotes // noquotes
@ -98,10 +99,10 @@ void DialogueWindow::Render(Client *c, std::string markdown)
} }
} }
uint32 popup_id = POPUPID_DIAWIND; uint32 popup_id = POPUPID_DIAWIND_ONE;
uint32 negative_id = 0; uint32 negative_id = POPUPID_DIAWIND_TWO;
char *button_name_0 = nullptr; std::string button_one_name;
char *button_name_1 = nullptr; std::string button_two_name;
uint32 sound_controls = 0; uint32 sound_controls = 0;
// window type // window type
@ -171,6 +172,96 @@ void DialogueWindow::Render(Client *c, std::string markdown)
} }
} }
// secondresponseid
std::string secondresponseid;
if (markdown.find("secondresponseid") != std::string::npos) {
LogDiaWind("Client [{}] Rendering secondresponseid option", c->GetCleanName());
auto first_split = split_string(output, "secondresponseid:");
if (!first_split.empty()) {
auto second_split = split_string(first_split[1], " ");
if (!second_split.empty()) {
secondresponseid = second_split[0];
LogDiaWindDetail("Client [{}] Rendering secondresponseid option secondresponseid [{}]", c->GetCleanName(), secondresponseid);
}
if (first_split[1].length() == 1) {
secondresponseid = first_split[1];
LogDiaWindDetail(
"Client [{}] Rendering secondresponseid (end) option secondresponseid [{}]",
c->GetCleanName(),
secondresponseid
);
}
find_replace(output, fmt::format("secondresponseid:{}", secondresponseid), "");
if (!secondresponseid.empty()) {
negative_id = (StringIsNumber(secondresponseid) ? std::atoi(secondresponseid.c_str()) : 0);
}
}
}
// Buttons Text
std::string button_one;
std::string button_two;
if (
markdown.find("button_one") != std::string::npos &&
markdown.find("button_two") != std::string::npos
) {
LogDiaWind("Client [{}] Rendering button_one option.", c->GetCleanName());
auto one_first_split = split_string(output, "button_one:");
if (!one_first_split.empty()) {
auto one_second_split = split_string(one_first_split[1], " ");
if (!one_second_split.empty()) {
button_one = one_second_split[0];
LogDiaWindDetail("Client [{}] Rendering button_one option button_one [{}]", c->GetCleanName(), button_one);
}
if (one_first_split[1].length() == 1) {
button_one = one_first_split[1];
LogDiaWindDetail(
"Client [{}] Rendering button_one (end) option button_one [{}]",
c->GetCleanName(),
button_one
);
}
find_replace(output, fmt::format("button_one:{}", button_one), "");
if (!button_one.empty()) {
button_one_name = button_one.c_str();
}
}
LogDiaWind("Client [{}] Rendering button_two option.", c->GetCleanName());
auto two_first_split = split_string(output, "button_two:");
if (!two_first_split.empty()) {
auto two_second_split = split_string(two_first_split[1], " ");
if (!two_second_split.empty()) {
button_two = two_second_split[0];
LogDiaWindDetail("Client [{}] Rendering button_two option button_two [{}]", c->GetCleanName(), button_two);
}
if (two_first_split[1].length() == 1) {
button_two = two_first_split[1];
LogDiaWindDetail(
"Client [{}] Rendering button_two (end) option button_two [{}]",
c->GetCleanName(),
button_two
);
}
find_replace(output, fmt::format("button_two:{}", button_two), "");
if (!button_two.empty()) {
button_two_name = button_two.c_str();
}
}
}
// bracket responses // bracket responses
std::vector<std::string> responses; std::vector<std::string> responses;
std::vector<std::string> bracket_responses; std::vector<std::string> bracket_responses;
@ -209,13 +300,25 @@ void DialogueWindow::Render(Client *c, std::string markdown)
} }
} }
// Placed here to allow silent message or other message to override default for custom values.
if (!button_one_name.empty() && !button_two_name.empty()) {
c->SetEntityVariable(
DIAWIND_RESPONSE_ONE_KEY.c_str(),
button_one_name.c_str()
);
c->SetEntityVariable(
DIAWIND_RESPONSE_TWO_KEY.c_str(),
button_two_name.c_str()
);
}
// handle silent prompts from the [> silent syntax // handle silent prompts from the [> silent syntax
std::string silent_message; std::string silent_message;
if (responses.empty() && markdown.find('[') != std::string::npos && markdown.find('>') != std::string::npos) { if (responses.empty() && markdown.find('[') != std::string::npos && markdown.find('>') != std::string::npos) {
silent_message = get_between(output, "[", ">"); silent_message = get_between(output, "[", ">");
// temporary and used during the response // temporary and used during the response
c->SetEntityVariable(DIAWIND_RESPONSE_KEY.c_str(), silent_message.c_str()); c->SetEntityVariable(DIAWIND_RESPONSE_ONE_KEY.c_str(), silent_message.c_str());
// pop the silent message off // pop the silent message off
find_replace(output, fmt::format("[{}>", silent_message), ""); find_replace(output, fmt::format("[{}>", silent_message), "");
@ -225,7 +328,7 @@ void DialogueWindow::Render(Client *c, std::string markdown)
silent_message = responses[0]; silent_message = responses[0];
// temporary and used during the response // temporary and used during the response
c->SetEntityVariable(DIAWIND_RESPONSE_KEY.c_str(), silent_message.c_str()); c->SetEntityVariable(DIAWIND_RESPONSE_ONE_KEY.c_str(), silent_message.c_str());
// pop the silent message off // pop the silent message off
find_replace(output, fmt::format("[{}]", silent_message), ""); find_replace(output, fmt::format("[{}]", silent_message), "");
@ -282,6 +385,17 @@ void DialogueWindow::Render(Client *c, std::string markdown)
); );
} }
if (!button_one_name.empty() && !button_two_name.empty()) {
click_response = fmt::format(
"<c \"#F07F00\">Click [{}] to respond with [{}]...<br>"
"Click [{}] to respond with [{}]...</c>",
button_one_name,
button_one_name,
button_two_name,
button_two_name
);
}
// post processing of color markdowns // post processing of color markdowns
// {spring_green_1} = <c "#5EFB6E"> // {spring_green_1} = <c "#5EFB6E">
if (markdown.find('{') != std::string::npos && markdown.find('}') != std::string::npos) { if (markdown.find('{') != std::string::npos && markdown.find('}') != std::string::npos) {
@ -325,8 +439,8 @@ void DialogueWindow::Render(Client *c, std::string markdown)
negative_id, negative_id,
window_type, window_type,
window_expire_seconds, window_expire_seconds,
button_name_0, button_one_name.c_str(),
button_name_1, button_two_name.c_str(),
sound_controls sound_controls
); );

View File

@ -122,6 +122,7 @@ const char *QuestEventSubroutines[_LargestEventID] = {
"EVENT_BOT_COMMAND", "EVENT_BOT_COMMAND",
"EVENT_WARP", "EVENT_WARP",
"EVENT_TEST_BUFF", "EVENT_TEST_BUFF",
"EVENT_COMBINE",
"EVENT_CONSIDER", "EVENT_CONSIDER",
"EVENT_CONSIDER_CORPSE" "EVENT_CONSIDER_CORPSE"
}; };
@ -1657,6 +1658,11 @@ void PerlembParser::ExportEventVariables(
break; break;
} }
case EVENT_COMBINE: {
ExportVar(package_name.c_str(), "container_slot", std::stoi(data));
break;
}
default: { default: {
break; break;
} }

File diff suppressed because it is too large Load Diff

View File

@ -90,6 +90,7 @@ typedef enum {
EVENT_BOT_COMMAND, EVENT_BOT_COMMAND,
EVENT_WARP, EVENT_WARP,
EVENT_TEST_BUFF, EVENT_TEST_BUFF,
EVENT_COMBINE,
EVENT_CONSIDER, EVENT_CONSIDER,
EVENT_CONSIDER_CORPSE, EVENT_CONSIDER_CORPSE,
_LargestEventID _LargestEventID

View File

@ -165,7 +165,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
EQ::SayLinkEngine::GenerateQuestSaylink( EQ::SayLinkEngine::GenerateQuestSaylink(
fmt::format("#door edit {} -.25", move_option), fmt::format("#door edit {} -.25", move_option),
false, false,
"-.25" ".25"
) )
); );
} }
@ -190,7 +190,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
} }
for (int move_index = -15; move_index <= 0; move_index += 5) { for (int move_index = -15; move_index <= 0; move_index += 5) {
int value = (move_index == 0 ? 1 : move_index); int value = (move_index == 0 ? -1 : move_index);
move_y_options_negative.emplace_back( move_y_options_negative.emplace_back(
EQ::SayLinkEngine::GenerateQuestSaylink( EQ::SayLinkEngine::GenerateQuestSaylink(
fmt::format("#door edit {} {}", move_option, value), fmt::format("#door edit {} {}", move_option, value),
@ -204,7 +204,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
EQ::SayLinkEngine::GenerateQuestSaylink( EQ::SayLinkEngine::GenerateQuestSaylink(
fmt::format("#door edit {} -.25", move_option), fmt::format("#door edit {} -.25", move_option),
false, false,
"-.25" ".25"
) )
); );
} }
@ -229,7 +229,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
} }
for (int move_index = -15; move_index <= 0; move_index += 5) { for (int move_index = -15; move_index <= 0; move_index += 5) {
int value = (move_index == 0 ? 1 : move_index); int value = (move_index == 0 ? -1 : move_index);
move_z_options_negative.emplace_back( move_z_options_negative.emplace_back(
EQ::SayLinkEngine::GenerateQuestSaylink( EQ::SayLinkEngine::GenerateQuestSaylink(
fmt::format("#door edit {} {}", move_option, value), fmt::format("#door edit {} {}", move_option, value),
@ -243,7 +243,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
EQ::SayLinkEngine::GenerateQuestSaylink( EQ::SayLinkEngine::GenerateQuestSaylink(
fmt::format("#door edit {} -.25", move_option), fmt::format("#door edit {} -.25", move_option),
false, false,
"-.25" ".25"
) )
); );
} }
@ -260,7 +260,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
} }
for (int move_index = -50; move_index <= 0; move_index += 5) { for (int move_index = -50; move_index <= 0; move_index += 5) {
int value = (move_index == 0 ? 1 : move_index); int value = (move_index == 0 ? -1 : move_index);
move_h_options_negative.emplace_back( move_h_options_negative.emplace_back(
EQ::SayLinkEngine::GenerateQuestSaylink( EQ::SayLinkEngine::GenerateQuestSaylink(
fmt::format("#door edit {} {}", move_option, value), fmt::format("#door edit {} {}", move_option, value),
@ -283,7 +283,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
} }
for (int move_index = -100; move_index <= 0; move_index += 10) { for (int move_index = -100; move_index <= 0; move_index += 10) {
int value = (move_index == 0 ? 1 : move_index); int value = (move_index == 0 ? -1 : move_index);
set_size_options_negative.emplace_back( set_size_options_negative.emplace_back(
EQ::SayLinkEngine::GenerateQuestSaylink( EQ::SayLinkEngine::GenerateQuestSaylink(
fmt::format("#door edit {} {}", move_option, value), fmt::format("#door edit {} {}", move_option, value),
@ -297,26 +297,30 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
// we're passing a move action here // we're passing a move action here
if (!arg3.empty() && StringIsNumber(arg3)) { if (!arg3.empty() && StringIsNumber(arg3)) {
int x_move = 0; float x_move = 0.0f;
int y_move = 0; float y_move = 0.0f;
int z_move = 0; float z_move = 0.0f;
int h_move = 0; float h_move = 0.0f;
int set_size = 0; float set_size = 0.0f;
if (arg2 == move_x_action) { if (arg2 == move_x_action) {
x_move = std::atoi(arg3.c_str()); x_move = std::atof(arg3.c_str());
} }
if (arg2 == move_y_action) { if (arg2 == move_y_action) {
y_move = std::atoi(arg3.c_str()); y_move = std::atof(arg3.c_str());
} }
if (arg2 == move_z_action) { if (arg2 == move_z_action) {
z_move = std::atoi(arg3.c_str()); z_move = std::atof(arg3.c_str());
} }
if (arg2 == move_h_action) { if (arg2 == move_h_action) {
h_move = std::atoi(arg3.c_str()); h_move = std::atof(arg3.c_str());
} }
if (arg2 == set_size_action) { if (arg2 == set_size_action) {
set_size = std::atoi(arg3.c_str()); set_size = std::atof(arg3.c_str());
} }
door->SetLocation( door->SetLocation(

File diff suppressed because it is too large Load Diff

View File

@ -133,6 +133,7 @@ const char *LuaEvents[_LargestEventID] = {
"event_bot_command", "event_bot_command",
"event_warp", "event_warp",
"event_test_buff", "event_test_buff",
"event_combine",
"event_consider", "event_consider",
"event_consider_corpse" "event_consider_corpse"
}; };
@ -222,6 +223,7 @@ LuaParser::LuaParser() {
PlayerArgumentDispatch[EVENT_COMBINE_VALIDATE] = handle_player_combine_validate; PlayerArgumentDispatch[EVENT_COMBINE_VALIDATE] = handle_player_combine_validate;
PlayerArgumentDispatch[EVENT_BOT_COMMAND] = handle_player_bot_command; PlayerArgumentDispatch[EVENT_BOT_COMMAND] = handle_player_bot_command;
PlayerArgumentDispatch[EVENT_WARP] = handle_player_warp; PlayerArgumentDispatch[EVENT_WARP] = handle_player_warp;
PlayerArgumentDispatch[EVENT_COMBINE] = handle_player_quest_combine;
PlayerArgumentDispatch[EVENT_CONSIDER] = handle_player_consider; PlayerArgumentDispatch[EVENT_CONSIDER] = handle_player_consider;
PlayerArgumentDispatch[EVENT_CONSIDER_CORPSE] = handle_player_consider_corpse; PlayerArgumentDispatch[EVENT_CONSIDER_CORPSE] = handle_player_consider_corpse;

View File

@ -573,6 +573,11 @@ void handle_player_warp(QuestInterface* parse, lua_State* L, Client* client, std
lua_setfield(L, -2, "from_z"); lua_setfield(L, -2, "from_z");
} }
void handle_player_quest_combine(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector<EQ::Any>* extra_pointers) {
lua_pushinteger(L, std::stoi(data));
lua_setfield(L, -2, "container_slot");
}
void handle_player_consider(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector<EQ::Any>* extra_pointers) { void handle_player_consider(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector<EQ::Any>* extra_pointers) {
lua_pushinteger(L, std::stoi(data)); lua_pushinteger(L, std::stoi(data));
lua_setfield(L, -2, "entity_id"); lua_setfield(L, -2, "entity_id");

View File

@ -105,6 +105,8 @@ void handle_player_bot_command(QuestInterface *parse, lua_State* L, Client* clie
std::vector<EQ::Any> *extra_pointers); std::vector<EQ::Any> *extra_pointers);
void handle_player_warp(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, void handle_player_warp(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
std::vector<EQ::Any>* extra_pointers); std::vector<EQ::Any>* extra_pointers);
void handle_player_quest_combine(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
std::vector<EQ::Any>* extra_pointers);
void handle_player_consider(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, void handle_player_consider(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
std::vector<EQ::Any>* extra_pointers); std::vector<EQ::Any>* extra_pointers);
void handle_player_consider_corpse(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, void handle_player_consider_corpse(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data,

View File

@ -987,7 +987,7 @@ int32 Lua_StatBonuses::GetShieldEquipDmgMod() const {
bool Lua_StatBonuses::GetTriggerOnValueAmount() const { bool Lua_StatBonuses::GetTriggerOnValueAmount() const {
Lua_Safe_Call_Bool(); Lua_Safe_Call_Bool();
return self->TriggerOnValueAmount; return self->TriggerOnCastRequirement;
} }
int8 Lua_StatBonuses::GetStunBashChance() const { int8 Lua_StatBonuses::GetStunBashChance() const {

View File

@ -2838,10 +2838,17 @@ bool Mob::HateSummon() {
if(summon_level == 1) { if(summon_level == 1) {
entity_list.MessageClose(this, true, 500, Chat::Say, "%s says 'You will not evade me, %s!' ", GetCleanName(), target->GetCleanName() ); entity_list.MessageClose(this, true, 500, Chat::Say, "%s says 'You will not evade me, %s!' ", GetCleanName(), target->GetCleanName() );
auto new_pos = m_Position;
float angle = new_pos.w - target->GetHeading();
new_pos.w = target->GetHeading();
// probably should be like half melee range, but we can't get melee range nicely because reasons :)
new_pos = target->TryMoveAlong(new_pos, 5.0f, angle);
if (target->IsClient()) if (target->IsClient())
target->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Position.x, m_Position.y, m_Position.z, target->GetHeading(), 0, SummonPC); target->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), new_pos.x, new_pos.y, new_pos.z, new_pos.w, 0, SummonPC);
else else
target->GMMove(m_Position.x, m_Position.y, m_Position.z, target->GetHeading()); target->GMMove(new_pos.x, new_pos.y, new_pos.z, new_pos.w);
return true; return true;
} else if(summon_level == 2) { } else if(summon_level == 2) {
@ -3602,80 +3609,18 @@ bool Mob::TrySpellTrigger(Mob *target, uint32 spell_id, int effect)
return false; return false;
} }
void Mob::TryTriggerOnCastRequirement()
void Mob::TryTriggerOnValueAmount(bool IsHP, bool IsMana, bool IsEndur, bool IsPet)
{ {
/* if (spellbonuses.TriggerOnCastRequirement) {
At present time there is no obvious difference between ReqTarget and ReqCaster
ReqTarget is typically used in spells cast on a target where the trigger occurs on that target.
ReqCaster is typically self only spells where the triggers on self.
Regardless both trigger on the owner of the buff.
*/
/*
Base2 Range: 1004 = Below < 80% HP
Base2 Range: 500-520 = Below (base2 - 500)*5 HP
Base2 Range: 521 = Below (?) Mana UKNOWN - Will assume its 20% unless proven otherwise
Base2 Range: 522 = Below (40%) Endurance
Base2 Range: 523 = Below (40%) Mana
Base2 Range: 220-? = Number of pets on hatelist to trigger (base2 - 220) (Set at 30 pets max for now)
38311 = < 10% mana;
*/
if (!spellbonuses.TriggerOnValueAmount)
return;
if (spellbonuses.TriggerOnValueAmount){
int buff_count = GetMaxTotalSlots(); int buff_count = GetMaxTotalSlots();
for (int e = 0; e < buff_count; e++) { for (int e = 0; e < buff_count; e++) {
int spell_id = buffs[e].spellid;
uint32 spell_id = buffs[e].spellid;
if (IsValidSpell(spell_id)) { if (IsValidSpell(spell_id)) {
for (int i = 0; i < EFFECT_COUNT; i++) { for (int i = 0; i < EFFECT_COUNT; i++) {
if ((spells[spell_id].effectid[i] == SE_TriggerOnReqTarget) || (spells[spell_id].effectid[i] == SE_TriggerOnReqCaster)) { if ((spells[spell_id].effectid[i] == SE_TriggerOnReqTarget) || (spells[spell_id].effectid[i] == SE_TriggerOnReqCaster)) {
if (PassCastRestriction(spells[spell_id].base2[i])) {
int base2 = spells[spell_id].base2[i];
bool use_spell = false;
if (IsHP){
if ((base2 >= 500 && base2 <= 520) && GetHPRatio() < (base2 - 500)*5)
use_spell = true;
else if (base2 == 1004 && GetHPRatio() < 80)
use_spell = true;
}
else if (IsMana){
if ( (base2 = 521 && GetManaRatio() < 20) || (base2 = 523 && GetManaRatio() < 40))
use_spell = true;
else if (base2 == 38311 && GetManaRatio() < 10)
use_spell = true;
}
else if (IsEndur){
if (base2 == 522 && GetEndurancePercent() < 40){
use_spell = true;
}
}
else if (IsPet){
int count = hate_list.GetSummonedPetCountOnHateList(this);
if ((base2 >= 220 && base2 <= 250) && count >= (base2 - 220)){
use_spell = true;
}
}
if (use_spell){
SpellFinished(spells[spell_id].base[i], this, EQ::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff); SpellFinished(spells[spell_id].base[i], this, EQ::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
if (!TryFadeEffect(e)) {
if(!TryFadeEffect(e))
BuffFadeBySlot(e); BuffFadeBySlot(e);
} }
} }
@ -3684,7 +3629,7 @@ void Mob::TryTriggerOnValueAmount(bool IsHP, bool IsMana, bool IsEndur, bool IsP
} }
} }
} }
}
//Twincast Focus effects should stack across different types (Spell, AA - when implemented ect) //Twincast Focus effects should stack across different types (Spell, AA - when implemented ect)
void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id) void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id)

View File

@ -623,6 +623,7 @@ public:
void Teleport(const glm::vec3 &pos); void Teleport(const glm::vec3 &pos);
void Teleport(const glm::vec4 &pos); void Teleport(const glm::vec4 &pos);
void TryMoveAlong(float distance, float angle, bool send = true); void TryMoveAlong(float distance, float angle, bool send = true);
glm::vec4 TryMoveAlong(const glm::vec4 &start, float distance, float angle);
void ProcessForcedMovement(); void ProcessForcedMovement();
inline void IncDeltaX(float in) { m_Delta.x += in; } inline void IncDeltaX(float in) { m_Delta.x += in; }
inline void IncDeltaY(float in) { m_Delta.y += in; } inline void IncDeltaY(float in) { m_Delta.y += in; }
@ -796,7 +797,7 @@ public:
void TryTriggerOnCastFocusEffect(focusType type, uint16 spell_id); void TryTriggerOnCastFocusEffect(focusType type, uint16 spell_id);
bool TryTriggerOnCastProc(uint16 focusspellid, uint16 spell_id, uint16 proc_spellid); bool TryTriggerOnCastProc(uint16 focusspellid, uint16 spell_id, uint16 proc_spellid);
bool TrySpellTrigger(Mob *target, uint32 spell_id, int effect); bool TrySpellTrigger(Mob *target, uint32 spell_id, int effect);
void TryTriggerOnValueAmount(bool IsHP = false, bool IsMana = false, bool IsEndur = false, bool IsPet = false); void TryTriggerOnCastRequirement();
void TryTwincast(Mob *caster, Mob *target, uint32 spell_id); void TryTwincast(Mob *caster, Mob *target, uint32 spell_id);
void TrySympatheticProc(Mob *target, uint32 spell_id); void TrySympatheticProc(Mob *target, uint32 spell_id);
bool TryFadeEffect(int slot); bool TryFadeEffect(int slot);
@ -844,6 +845,8 @@ public:
bool CanFocusUseRandomEffectivenessByType(focusType type); bool CanFocusUseRandomEffectivenessByType(focusType type);
int GetFocusRandomEffectivenessValue(int focus_base, int focus_base2, bool best_focus = 0); int GetFocusRandomEffectivenessValue(int focus_base, int focus_base2, bool best_focus = 0);
int GetHealRate() const { return itembonuses.HealRate + spellbonuses.HealRate + aabonuses.HealRate; } int GetHealRate() const { return itembonuses.HealRate + spellbonuses.HealRate + aabonuses.HealRate; }
int GetMemoryBlurChance(int base_chance);
bool TryDoubleMeleeRoundEffect(); bool TryDoubleMeleeRoundEffect();
bool GetUseDoubleMeleeRoundDmgBonus() const { return use_double_melee_round_dmg_bonus; } bool GetUseDoubleMeleeRoundDmgBonus() const { return use_double_melee_round_dmg_bonus; }
@ -1532,6 +1535,7 @@ protected:
bool endur_upkeep; bool endur_upkeep;
bool degenerating_effects; // true if we have a buff that needs to be recalced every tick bool degenerating_effects; // true if we have a buff that needs to be recalced every tick
bool spawned_in_water; bool spawned_in_water;
public: public:
bool GetWasSpawnedInWater() const; bool GetWasSpawnedInWater() const;

View File

@ -4016,7 +4016,7 @@ XS(XS_Client_Freeze);
XS(XS_Client_Freeze) { XS(XS_Client_Freeze) {
dXSARGS; dXSARGS;
if (items != 1) if (items != 1)
Perl_croak(aTHX_ "Usage: Client:Freeze(THIS)"); Perl_croak(aTHX_ "Usage: Client::Freeze(THIS)");
{ {
Client *THIS; Client *THIS;
VALIDATE_THIS_IS_CLIENT; VALIDATE_THIS_IS_CLIENT;
@ -4029,7 +4029,7 @@ XS(XS_Client_UnFreeze);
XS(XS_Client_UnFreeze) { XS(XS_Client_UnFreeze) {
dXSARGS; dXSARGS;
if (items != 1) if (items != 1)
Perl_croak(aTHX_ "Usage: Client:UnFreeze(THIS)"); Perl_croak(aTHX_ "Usage: Client::UnFreeze(THIS)");
{ {
Client *THIS; Client *THIS;
VALIDATE_THIS_IS_CLIENT; VALIDATE_THIS_IS_CLIENT;

View File

@ -304,7 +304,7 @@ XS(XS_Raid_GetClientByIndex); /* prototype to pass -Wmissing-prototypes */
XS(XS_Raid_GetClientByIndex) { XS(XS_Raid_GetClientByIndex) {
dXSARGS; dXSARGS;
if (items != 2) if (items != 2)
Perl_croak(aTHX_ "Usage: Raid::GetClientByIndex(THIS, uint16 raid_indez)"); // @categories Raid Perl_croak(aTHX_ "Usage: Raid::GetClientByIndex(THIS, uint16 raid_index)"); // @categories Raid
{ {
Raid *THIS; Raid *THIS;
Client *RETVAL; Client *RETVAL;

File diff suppressed because it is too large Load Diff

View File

@ -290,87 +290,22 @@ public:
static std::string GetZoneLongName(std::string zone_short_name); static std::string GetZoneLongName(std::string zone_short_name);
static std::string GetZoneLongNameByID(uint32 zone_id); static std::string GetZoneLongNameByID(uint32 zone_id);
static std::string GetZoneShortName(uint32 zone_id); static std::string GetZoneShortName(uint32 zone_id);
void CrossZoneAssignTaskByCharID(int character_id, uint32 task_id, bool enforce_level_requirement = false); void CrossZoneLDoNUpdate(uint8 update_type, uint8 update_subtype, int update_identifier, uint32 theme_id, int points = 1, const char* client_name = "");
void CrossZoneAssignTaskByGroupID(int group_id, uint32 task_id, bool enforce_level_requirement = false); void CrossZoneMarquee(uint8 update_type, int update_identifier, uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, const char* message, const char* client_name = "");
void CrossZoneAssignTaskByRaidID(int raid_id, uint32 task_id, bool enforce_level_requirement = false); void CrossZoneMessage(uint8 update_type, int update_identifier, uint32 type, const char* message, const char* client_name = "");
void CrossZoneAssignTaskByGuildID(int guild_id, uint32 task_id, bool enforce_level_requirement = false); void CrossZoneMove(uint8 update_type, uint8 update_subtype, int update_identifier, const char* zone_short_name, uint16 instance_id, const char* client_name = "");
void CrossZoneCastSpellByCharID(int character_id, uint32 spell_id); void CrossZoneSetEntityVariable(uint8 update_type, int update_identifier, const char* variable_name, const char* variable_value, const char* client_name = "");
void CrossZoneCastSpellByGroupID(int group_id, uint32 spell_id); void CrossZoneSignal(uint8 update_type, int update_identifier, uint32 signal, const char* client_name = "");
void CrossZoneCastSpellByRaidID(int raid_id, uint32 spell_id); void CrossZoneSpell(uint8 update_type, uint8 update_subtype, int update_identifier, uint32 spell_id, const char* client_name = "");
void CrossZoneCastSpellByGuildID(int guild_id, uint32 spell_id); void CrossZoneTaskUpdate(uint8 update_type, uint8 update_subtype, int update_identifier, uint32 task_identifier, int task_subidentifier = -1, int update_count = 1, bool enforce_level_requirement = false, const char* client_name = "");
void CrossZoneDisableTaskByCharID(int character_id, uint32 task_id); void WorldWideLDoNUpdate(uint8 update_type, uint32 theme_id, int points = 1, uint8 min_status = 0, uint8 max_status = 0);
void CrossZoneDisableTaskByGroupID(int group_id, uint32 task_id);
void CrossZoneDisableTaskByRaidID(int raid_id, uint32 task_id);
void CrossZoneDisableTaskByGuildID(int guild_id, uint32 task_id);
void CrossZoneEnableTaskByCharID(int character_id, uint32 task_id);
void CrossZoneEnableTaskByGroupID(int group_id, uint32 task_id);
void CrossZoneEnableTaskByRaidID(int raid_id, uint32 task_id);
void CrossZoneEnableTaskByGuildID(int guild_id, uint32 task_id);
void CrossZoneFailTaskByCharID(int character_id, uint32 task_id);
void CrossZoneFailTaskByGroupID(int group_id, uint32 task_id);
void CrossZoneFailTaskByRaidID(int raid_id, uint32 task_id);
void CrossZoneFailTaskByGuildID(int guild_id, uint32 task_id);
void CrossZoneLDoNUpdate(uint8 type, uint8 subtype, int identifier, uint32 theme_id, int points = 1);
void CrossZoneMarqueeByCharID(int character_id, uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, const char *message);
void CrossZoneMarqueeByGroupID(int group_id, uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, const char *message);
void CrossZoneMarqueeByRaidID(int raid_id, uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, const char *message);
void CrossZoneMarqueeByGuildID(int guild_id, uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, const char *message);
void CrossZoneMessagePlayerByName(uint32 type, const char *character_name, const char *message);
void CrossZoneMessagePlayerByGroupID(uint32 type, int group_id, const char *message);
void CrossZoneMessagePlayerByRaidID(uint32 type, int raid_id, const char *message);
void CrossZoneMessagePlayerByGuildID(uint32 type, int guild_id, const char *message);
void CrossZoneMovePlayerByCharID(int character_id, const char *zone_short_name);
void CrossZoneMovePlayerByGroupID(int group_id, const char *zone_short_name);
void CrossZoneMovePlayerByRaidID(int raid_id, const char *zone_short_name);
void CrossZoneMovePlayerByGuildID(int guild_id, const char *zone_short_name);
void CrossZoneMoveInstanceByCharID(int character_id, uint16 instance_id);
void CrossZoneMoveInstanceByGroupID(int group_id, uint16 instance_id);
void CrossZoneMoveInstanceByRaidID(int raid_id, uint16 instance_id);
void CrossZoneMoveInstanceByGuildID(int guild_id, uint16 instance_id);
void CrossZoneRemoveSpellByCharID(int character_id, uint32 spell_id);
void CrossZoneRemoveSpellByGroupID(int group_id, uint32 spell_id);
void CrossZoneRemoveSpellByRaidID(int raid_id, uint32 spell_id);
void CrossZoneRemoveSpellByGuildID(int guild_id, uint32 spell_id);
void CrossZoneRemoveTaskByCharID(int character_id, uint32 task_id);
void CrossZoneRemoveTaskByGroupID(int group_id, uint32 task_id);
void CrossZoneRemoveTaskByRaidID(int raid_id, uint32 task_id);
void CrossZoneRemoveTaskByGuildID(int guild_id, uint32 task_id);
void CrossZoneResetActivityByCharID(int character_id, uint32 task_id, int activity_id);
void CrossZoneResetActivityByGroupID(int group_id, uint32 task_id, int activity_id);
void CrossZoneResetActivityByRaidID(int raid_id, uint32 task_id, int activity_id);
void CrossZoneResetActivityByGuildID(int guild_id, uint32 task_id, int activity_id);
void CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, const char *variable_name, const char *variable_value);
void CrossZoneSetEntityVariableByClientName(const char *character_name, const char *variable_name, const char *variable_value);
void CrossZoneSetEntityVariableByGroupID(int group_id, const char *variable_name, const char *variable_value);
void CrossZoneSetEntityVariableByRaidID(int raid_id, const char *variable_name, const char *variable_value);
void CrossZoneSetEntityVariableByGuildID(int guild_id, const char *variable_name, const char *variable_value);
void CrossZoneSignalPlayerByCharID(int charid, uint32 signal);
void CrossZoneSignalPlayerByGroupID(int group_id, uint32 signal);
void CrossZoneSignalPlayerByRaidID(int raid_id, uint32 signal);
void CrossZoneSignalPlayerByGuildID(int guild_id, uint32 signal);
void CrossZoneSignalNPCByNPCTypeID(uint32 npctype_id, uint32 signal);
void CrossZoneSignalPlayerByName(const char *character_name, uint32 signal);
void CrossZoneUpdateActivityByCharID(int character_id, uint32 task_id, int activity_id, int activity_count = 1);
void CrossZoneUpdateActivityByGroupID(int group_id, uint32 task_id, int activity_id, int activity_count = 1);
void CrossZoneUpdateActivityByRaidID(int raid_id, uint32 task_id, int activity_id, int activity_count = 1);
void CrossZoneUpdateActivityByGuildID(int guild_id, uint32 task_id, int activity_id, int activity_count = 1);
void WorldWideAssignTask(uint32 task_id, bool enforce_level_requirement = false, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideCastSpell(uint32 spell_id, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideDisableTask(uint32 task_id, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideEnableTask(uint32 task_id, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideFailTask(uint32 task_id, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideMarquee(uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, const char* message, uint8 min_status = 0, uint8 max_status = 0); void WorldWideMarquee(uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, const char* message, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideMessage(uint32 type, const char* message, uint8 min_status = 0, uint8 max_status = 0); void WorldWideMessage(uint32 type, const char* message, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideMove(const char *zone_short_name, uint8 min_status = 0, uint8 max_status = 0); void WorldWideMove(uint8 update_type, const char* zone_short_name, uint16 instance_id = 0, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideMoveInstance(uint16 instance_id, uint8 min_status = 0, uint8 max_status = 0); void WorldWideSetEntityVariable(uint8 update_type, const char* variable_name, const char* variable_value, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideRemoveSpell(uint32 spell_id, uint8 min_status = 0, uint8 max_status = 0); void WorldWideSignal(uint8 update_type, uint32 signal, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideRemoveTask(uint32 task_id, uint8 min_status = 0, uint8 max_status = 0); void WorldWideSpell(uint8 update_type, uint32 spell_id, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideResetActivity(uint32 task_id, int activity_id, uint8 min_status = 0, uint8 max_status = 0); void WorldWideTaskUpdate(uint8 update_type, uint32 task_identifier, int task_subidentifier = -1, int update_count = 1, bool enforce_level_requirement = false, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideSetEntityVariableClient(const char *variable_name, const char *variable_value, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideSetEntityVariableNPC(const char *variable_name, const char *variable_value);
void WorldWideSignalClient(uint32 signal, uint8 min_status = 0, uint8 max_status = 0);
void WorldWideSignalNPC(uint32 signal);
void WorldWideUpdateActivity(uint32 task_id, int activity_id, int activity_count = 1, uint8 min_status = 0, uint8 max_status = 0);
bool EnableRecipe(uint32 recipe_id); bool EnableRecipe(uint32 recipe_id);
bool DisableRecipe(uint32 recipe_id); bool DisableRecipe(uint32 recipe_id);
void ClearNPCTypeCache(int npctype_id); void ClearNPCTypeCache(int npctype_id);

View File

@ -63,6 +63,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if (spell.disallow_sit && IsBuffSpell(spell_id) && IsClient() && (CastToClient()->IsSitting() || CastToClient()->GetHorseId() != 0)) if (spell.disallow_sit && IsBuffSpell(spell_id) && IsClient() && (CastToClient()->IsSitting() || CastToClient()->GetHorseId() != 0))
return false; return false;
bool CanMemoryBlurFromMez = true;
if (IsMezzed()) { //Check for special memory blur behavior when on mez, this needs to be before buff override.
CanMemoryBlurFromMez = false;
}
bool c_override = false; bool c_override = false;
if (caster && caster->IsClient() && GetCastedSpellInvSlot() > 0) { if (caster && caster->IsClient() && GetCastedSpellInvSlot() > 0) {
const EQ::ItemInstance *inst = caster->CastToClient()->GetInv().GetItem(GetCastedSpellInvSlot()); const EQ::ItemInstance *inst = caster->CastToClient()->GetInv().GetItem(GetCastedSpellInvSlot());
@ -343,31 +348,13 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM #ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Complete Heal"); snprintf(effect_desc, _EDLEN, "Complete Heal");
#endif #endif
//make sure they are not allready affected by this... int val = 7500 * effect_value;
//I think that is the point of making this a buff. if (caster) {
//this is in the wrong spot, it should be in the immune
//section so the buff timer does not get refreshed!
int i;
bool inuse = false;
int buff_count = GetMaxTotalSlots();
for(i = 0; i < buff_count; i++) {
if(buffs[i].spellid == spell_id && i != buffslot) {
Message(0, "You must wait before you can be affected by this spell again.");
inuse = true;
break;
}
}
if(inuse)
break;
int32 val = 0;
val = 7500 * effect_value;
if (caster)
val = caster->GetActSpellHealing(spell_id, val, this); val = caster->GetActSpellHealing(spell_id, val, this);
}
if (val > 0) if (val > 0) {
HealDamage(val, caster); HealDamage(val, caster);
}
break; break;
} }
@ -387,7 +374,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
caster->SetMana(caster->GetMana() + std::abs(effect_value)); caster->SetMana(caster->GetMana() + std::abs(effect_value));
if (effect_value < 0) if (effect_value < 0)
TryTriggerOnValueAmount(false, true); TryTriggerOnCastRequirement();
#ifdef SPELL_EFFECT_SPAM #ifdef SPELL_EFFECT_SPAM
if (caster) if (caster)
caster->Message(Chat::White, "You have gained %+i mana!", effect_value); caster->Message(Chat::White, "You have gained %+i mana!", effect_value);
@ -403,7 +390,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
SetMana(GetMana() + effect_value); SetMana(GetMana() + effect_value);
if (effect_value < 0) if (effect_value < 0)
TryTriggerOnValueAmount(false, true); TryTriggerOnCastRequirement();
} }
break; break;
@ -600,7 +587,6 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
snprintf(effect_desc, _EDLEN, "Invisibility to Animals"); snprintf(effect_desc, _EDLEN, "Invisibility to Animals");
#endif #endif
invisible_animals = true; invisible_animals = true;
SetInvisible(0);
break; break;
} }
@ -611,7 +597,6 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
snprintf(effect_desc, _EDLEN, "Invisibility to Undead"); snprintf(effect_desc, _EDLEN, "Invisibility to Undead");
#endif #endif
invisible_undead = true; invisible_undead = true;
SetInvisible(0);
break; break;
} }
case SE_SeeInvis: case SE_SeeInvis:
@ -1136,13 +1121,23 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
case SE_Purify: case SE_Purify:
{ {
//Attempt to remove all Deterimental buffs. //Attempt to remove up to base amount of detrimental effects (excluding charm, fear, resurrection, and revival sickness).
int buff_count = GetMaxTotalSlots(); int purify_count = spells[spell_id].base[i];
for(int slot = 0; slot < buff_count; slot++) { if (purify_count > GetMaxTotalSlots()) {
if (buffs[slot].spellid != SPELL_UNKNOWN && purify_count = GetMaxTotalSlots();
IsDetrimentalSpell(buffs[slot].spellid) && spells[buffs[slot].spellid].dispel_flag == 0) }
for(int slot = 0; slot < purify_count; slot++) {
if (IsValidSpell(buffs[slot].spellid) && IsDetrimentalSpell(buffs[slot].spellid)){
if (!IsEffectInSpell(buffs[slot].spellid, SE_Charm) &&
!IsEffectInSpell(buffs[slot].spellid, SE_Fear) &&
buffs[slot].spellid != SPELL_RESURRECTION_SICKNESS &&
buffs[slot].spellid != SPELL_RESURRECTION_SICKNESS2 &&
buffs[slot].spellid != SPELL_RESURRECTION_SICKNESS3 &&
buffs[slot].spellid != SPELL_RESURRECTION_SICKNESS4 &&
buffs[slot].spellid != SPELL_REVIVAL_SICKNESS)
{ {
if (caster && TryDispel(caster->GetLevel(),buffs[slot].casterlevel, effect_value)){
BuffFadeBySlot(slot); BuffFadeBySlot(slot);
} }
} }
@ -1531,16 +1526,16 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM #ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Memory Blur: %d", effect_value); snprintf(effect_desc, _EDLEN, "Memory Blur: %d", effect_value);
#endif #endif
int wipechance = spells[spell_id].base[i]; //Memory blur component of Mez spells is not checked again if Mez is recast on a target that is already mezed
int bonus = 0; if (!CanMemoryBlurFromMez && IsEffectInSpell(spell_id, SE_Mez)) {
break;
if (caster){
bonus = caster->spellbonuses.IncreaseChanceMemwipe +
caster->itembonuses.IncreaseChanceMemwipe +
caster->aabonuses.IncreaseChanceMemwipe;
} }
wipechance += wipechance*bonus/100; int wipechance = 0;
if (caster) {
wipechance = caster->GetMemoryBlurChance(effect_value);
}
if(zone->random.Roll(wipechance)) if(zone->random.Roll(wipechance))
{ {
@ -2458,8 +2453,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#endif #endif
if(IsClient()) { if(IsClient()) {
CastToClient()->SetEndurance(CastToClient()->GetEndurance() + effect_value); CastToClient()->SetEndurance(CastToClient()->GetEndurance() + effect_value);
if (effect_value < 0) if (effect_value < 0) {
TryTriggerOnValueAmount(false, false, true); TryTriggerOnCastRequirement();
}
} }
break; break;
} }
@ -2472,8 +2468,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if (IsClient()) { if (IsClient()) {
CastToClient()->SetEndurance(CastToClient()->GetEndurance() + effect_value); CastToClient()->SetEndurance(CastToClient()->GetEndurance() + effect_value);
if (effect_value < 0) if (effect_value < 0) {
TryTriggerOnValueAmount(false, false, true); TryTriggerOnCastRequirement();
}
} }
break; break;
} }
@ -2652,7 +2649,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
int32 mana_to_use = GetMana() - spell.base[i]; int32 mana_to_use = GetMana() - spell.base[i];
if(mana_to_use > -1) { if(mana_to_use > -1) {
SetMana(GetMana() - spell.base[i]); SetMana(GetMana() - spell.base[i]);
TryTriggerOnValueAmount(false, true); TryTriggerOnCastRequirement();
// we take full dmg(-10 to make the damage the right sign) // we take full dmg(-10 to make the damage the right sign)
mana_damage = spell.base[i] / -10 * spell.base2[i]; mana_damage = spell.base[i] / -10 * spell.base2[i];
Damage(caster, mana_damage, spell_id, spell.skill, false, i, true); Damage(caster, mana_damage, spell_id, spell.skill, false, i, true);
@ -2672,7 +2669,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
int32 end_to_use = CastToClient()->GetEndurance() - spell.base[i]; int32 end_to_use = CastToClient()->GetEndurance() - spell.base[i];
if(end_to_use > -1) { if(end_to_use > -1) {
CastToClient()->SetEndurance(CastToClient()->GetEndurance() - spell.base[i]); CastToClient()->SetEndurance(CastToClient()->GetEndurance() - spell.base[i]);
TryTriggerOnValueAmount(false, false, true); TryTriggerOnCastRequirement();
// we take full dmg(-10 to make the damage the right sign) // we take full dmg(-10 to make the damage the right sign)
end_damage = spell.base[i] / -10 * spell.base2[i]; end_damage = spell.base[i] / -10 * spell.base2[i];
Damage(caster, end_damage, spell_id, spell.skill, false, i, true); Damage(caster, end_damage, spell_id, spell.skill, false, i, true);
@ -2754,7 +2751,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
else { else {
dmg = ratio*max_mana/10; dmg = ratio*max_mana/10;
caster->SetMana(caster->GetMana() - max_mana); caster->SetMana(caster->GetMana() - max_mana);
TryTriggerOnValueAmount(false, true); TryTriggerOnCastRequirement();
} }
if(IsDetrimentalSpell(spell_id)) { if(IsDetrimentalSpell(spell_id)) {
@ -3858,19 +3855,15 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
} }
case SE_WipeHateList: { case SE_WipeHateList: {
if (IsMezSpell(buff.spellid)) if (IsMezSpell(buff.spellid)) {
break; break;
int wipechance = spells[buff.spellid].base[i];
int bonus = 0;
if (caster) {
bonus = caster->spellbonuses.IncreaseChanceMemwipe +
caster->itembonuses.IncreaseChanceMemwipe +
caster->aabonuses.IncreaseChanceMemwipe;
} }
wipechance += wipechance * bonus / 100; int wipechance = 0;
if (caster) {
wipechance = caster->GetMemoryBlurChance(effect_value);
}
if (zone->random.Roll(wipechance)) { if (zone->random.Roll(wipechance)) {
if (IsAIControlled()) { if (IsAIControlled()) {
@ -8528,3 +8521,42 @@ int Mob::GetFocusRandomEffectivenessValue(int focus_base, int focus_base2, bool
return zone->random.Int(focus_base, focus_base2); return zone->random.Int(focus_base, focus_base2);
} }
int Mob::GetMemoryBlurChance(int base_chance)
{
/*
Memory Blur mechanic for SPA 62
Chance formula is effect chance + charisma modifer + caster level modifier
Effect chance is base value of spell
Charisma modifier is CHA/10 = %, with MAX of 15% (thus 150 cha gives you max bonus)
Caster level modifier. +100% if caster < level 17 which scales down to 25% at > 53. **
(Yes the above gets worse as you level. Behavior was confirmed on live.)
Memory blur is applied to mez on initial cast using same formula. However, recasting on a target that
is already mezed will not give a chance to memory blur. The blur is not checked on buff ticks.
SPA 242 SE_IncreaseChanceMemwipe modifies the final chance after all bonuses are applied.
This is also applied to memory blur from mez spells.
this = caster
*/
int cha_mod = int(GetCHA() / 10);
cha_mod = std::min(cha_mod, 15);
int lvl_mod = 0;
if (GetLevel() < 17) {
lvl_mod = 100;
}
else if (GetLevel() > 53) {
lvl_mod = 25;
}
else {
lvl_mod = 100 + ((GetLevel() - 16)*-2);//Derived from above range of values.**
}
int chance = cha_mod + lvl_mod + base_chance;
int chance_mod = spellbonuses.IncreaseChanceMemwipe + itembonuses.IncreaseChanceMemwipe + aabonuses.IncreaseChanceMemwipe;
chance += chance * chance_mod / 100;
return chance;
}

View File

@ -383,7 +383,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
GetName() GetName()
); );
TryTriggerOnValueAmount(false, true); TryTriggerOnCastRequirement();
return(false); return(false);
} }
@ -2467,7 +2467,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
LogSpells("Spell [{}]: consuming [{}] mana", spell_id, mana_used); LogSpells("Spell [{}]: consuming [{}] mana", spell_id, mana_used);
if (!DoHPToManaCovert(mana_used)) { if (!DoHPToManaCovert(mana_used)) {
SetMana(GetMana() - mana_used); SetMana(GetMana() - mana_used);
TryTriggerOnValueAmount(false, true); TryTriggerOnCastRequirement();
} }
} }
// one may want to check if this is a disc or not, but we actually don't, there are non disc stuff that have end cost // one may want to check if this is a disc or not, but we actually don't, there are non disc stuff that have end cost
@ -2478,7 +2478,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
if (mgb) if (mgb)
end_cost *= 2; end_cost *= 2;
SetEndurance(GetEndurance() - EQ::ClampUpper(end_cost, GetEndurance())); SetEndurance(GetEndurance() - EQ::ClampUpper(end_cost, GetEndurance()));
TryTriggerOnValueAmount(false, false, true); TryTriggerOnCastRequirement();
} }
if (mgb) if (mgb)
SetMGB(false); SetMGB(false);
@ -2931,6 +2931,11 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2,
LogSpells("Check Stacking on old [{}] ([{}]) @ lvl [{}] (by [{}]) vs. new [{}] ([{}]) @ lvl [{}] (by [{}])", sp1.name, spellid1, caster_level1, (caster1==nullptr)?"Nobody":caster1->GetName(), sp2.name, spellid2, caster_level2, (caster2==nullptr)?"Nobody":caster2->GetName()); LogSpells("Check Stacking on old [{}] ([{}]) @ lvl [{}] (by [{}]) vs. new [{}] ([{}]) @ lvl [{}] (by [{}])", sp1.name, spellid1, caster_level1, (caster1==nullptr)?"Nobody":caster1->GetName(), sp2.name, spellid2, caster_level2, (caster2==nullptr)?"Nobody":caster2->GetName());
if (spellbonuses.CompleteHealBuffBlocker && IsEffectInSpell(spellid2, SE_CompleteHeal)) {
Message(0, "You must wait before you can be affected by this spell again.");
return -1;
}
if (spellid1 == spellid2 ) { if (spellid1 == spellid2 ) {
if (!IsStackableDot(spellid1) && !IsEffectInSpell(spellid1, SE_ManaBurn)) { // mana burn spells we need to use the stacking command blocks live actually checks those first, we should probably rework to that too if (!IsStackableDot(spellid1) && !IsEffectInSpell(spellid1, SE_ManaBurn)) { // mana burn spells we need to use the stacking command blocks live actually checks those first, we should probably rework to that too
if (caster_level1 > caster_level2) { // cur buff higher level than new if (caster_level1 > caster_level2) { // cur buff higher level than new
@ -3401,7 +3406,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid
buffs[emptyslot].focusproclimit_procamt = 0; buffs[emptyslot].focusproclimit_procamt = 0;
buffs[emptyslot].instrument_mod = caster ? caster->GetInstrumentMod(spell_id) : 10; buffs[emptyslot].instrument_mod = caster ? caster->GetInstrumentMod(spell_id) : 10;
if (level_override > 0) { if (level_override > 0 || buffs[emptyslot].numhits > 0) {
buffs[emptyslot].UpdateClient = true; buffs[emptyslot].UpdateClient = true;
} else { } else {
if (buffs[emptyslot].ticsremaining > (1 + CalcBuffDuration_formula(caster_level, spells[spell_id].buffdurationformula, spells[spell_id].buffduration))) if (buffs[emptyslot].ticsremaining > (1 + CalcBuffDuration_formula(caster_level, spells[spell_id].buffdurationformula, spells[spell_id].buffduration)))

View File

@ -375,6 +375,14 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob
} }
DBTradeskillRecipe_Struct spec; DBTradeskillRecipe_Struct spec;
if (parse->EventPlayer(EVENT_COMBINE, user, std::to_string(in_combine->container_slot), 0) == 1) {
auto outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0);
user->QueuePacket(outapp);
safe_delete(outapp);
return;
}
if (!content_db.GetTradeRecipe(container, c_type, some_id, user->CharacterID(), &spec)) { if (!content_db.GetTradeRecipe(container, c_type, some_id, user->CharacterID(), &spec)) {
LogTradeskillsDetail("[HandleCombine] Check 2"); LogTradeskillsDetail("[HandleCombine] Check 2");
@ -774,7 +782,7 @@ void Client::SendTradeskillSearchResults(
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
if (row == nullptr || row[0] == nullptr || row[1] == nullptr || row[2] == nullptr || row[3] == nullptr || if (row == nullptr || row[0] == nullptr || row[1] == nullptr || row[2] == nullptr || row[3] == nullptr ||
row[5] == nullptr) { row[4] == nullptr || row[5] == nullptr) {
continue; continue;
} }
@ -782,27 +790,36 @@ void Client::SendTradeskillSearchResults(
const char *name = row[1]; const char *name = row[1];
uint32 trivial = (uint32) atoi(row[2]); uint32 trivial = (uint32) atoi(row[2]);
uint32 comp_count = (uint32) atoi(row[3]); uint32 comp_count = (uint32) atoi(row[3]);
uint32 tradeskill = (uint16) atoi(row[5]); uint32 tradeskill = (uint16) atoi(row[4]);
uint32 must_learn = (uint16) atoi(row[5]);
// Skip the recipes that exceed the threshold in skill difference // Skip the recipes that exceed the threshold in skill difference
// Recipes that have either been made before or were // Recipes that have either been made before or were
// explicitly learned are excempt from that limit // explicitly learned are excempt from that limit
if (RuleB(Skills, UseLimitTradeskillSearchSkillDiff) &&
((int32) trivial - (int32) GetSkill((EQ::skills::SkillType) tradeskill)) >
RuleI(Skills, MaxTradeskillSearchSkillDiff)) {
LogTradeskills("Checking limit recipe_id [{}] name [{}]", recipe_id, name);
auto character_learned_recipe = CharacterRecipeListRepository::GetRecipe( auto character_learned_recipe = CharacterRecipeListRepository::GetRecipe(
character_learned_recipe_list, character_learned_recipe_list,
recipe_id recipe_id
); );
if (RuleB(Skills, UseLimitTradeskillSearchSkillDiff) &&
((int32) trivial - (int32) GetSkill((EQ::skills::SkillType) tradeskill)) >
RuleI(Skills, MaxTradeskillSearchSkillDiff)) {
LogTradeskills("Checking limit recipe_id [{}] name [{}]", recipe_id, name);
if (character_learned_recipe.made_count == 0) { if (character_learned_recipe.made_count == 0) {
continue; continue;
} }
} }
//Skip recipes that must be learned
if ((must_learn & 0xf) && !character_learned_recipe.recipe_id) {
continue;
}
auto outapp = new EQApplicationPacket(OP_RecipeReply, sizeof(RecipeReply_Struct)); auto outapp = new EQApplicationPacket(OP_RecipeReply, sizeof(RecipeReply_Struct));
RecipeReply_Struct *reply = (RecipeReply_Struct *) outapp->pBuffer; RecipeReply_Struct *reply = (RecipeReply_Struct *) outapp->pBuffer;
@ -1481,7 +1498,7 @@ bool ZoneDatabase::GetTradeRecipe(
recipe_id recipe_id
); );
if (character_learned_recipe.made_count > 0) { if (character_learned_recipe.recipe_id) { //If this exists we learned it
LogTradeskills("[GetTradeRecipe] made_count [{}]", character_learned_recipe.made_count); LogTradeskills("[GetTradeRecipe] made_count [{}]", character_learned_recipe.made_count);
spec->has_learnt = true; spec->has_learnt = true;

View File

@ -935,6 +935,32 @@ void Mob::TryMoveAlong(float distance, float angle, bool send)
Teleport(new_pos); Teleport(new_pos);
} }
// like above, but takes a starting position and returns a new location instead of actually moving
glm::vec4 Mob::TryMoveAlong(const glm::vec4 &start, float distance, float angle)
{
angle += start.w;
angle = FixHeading(angle);
glm::vec3 tmp_pos;
glm::vec3 new_pos = start;
new_pos.x += distance * g_Math.FastSin(angle);
new_pos.y += distance * g_Math.FastCos(angle);
new_pos.z += GetZOffset();
if (zone->HasMap()) {
auto new_z = zone->zonemap->FindClosestZ(new_pos, nullptr);
if (new_z != BEST_Z_INVALID)
new_pos.z = new_z;
if (zone->zonemap->LineIntersectsZone(start, new_pos, 0.0f, &tmp_pos))
new_pos = tmp_pos;
}
new_pos.z = GetFixedZ(new_pos);
return {new_pos.x, new_pos.y, new_pos.z, start.w};
}
int ZoneDatabase::GetHighestGrid(uint32 zoneid) { int ZoneDatabase::GetHighestGrid(uint32 zoneid) {
std::string query = StringFormat("SELECT COALESCE(MAX(id), 0) FROM grid WHERE zoneid = %i", zoneid); std::string query = StringFormat("SELECT COALESCE(MAX(id), 0) FROM grid WHERE zoneid = %i", zoneid);

File diff suppressed because it is too large Load Diff

View File

@ -153,7 +153,6 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
LogInfo("Zone Bootup: [{}] ([{}]: [{}])", zonename, iZoneID, iInstanceID); LogInfo("Zone Bootup: [{}] ([{}]: [{}])", zonename, iZoneID, iInstanceID);
parse->Init(); parse->Init();
UpdateWindowTitle(nullptr); UpdateWindowTitle(nullptr);
zone->GetTimeSync();
zone->RequestUCSServerStatus(); zone->RequestUCSServerStatus();
@ -1818,7 +1817,8 @@ void Zone::Repop(uint32 delay)
void Zone::GetTimeSync() void Zone::GetTimeSync()
{ {
if (worldserver.Connected() && !zone_has_current_time) { if (!zone_has_current_time) {
LogInfo("Requesting world time");
auto pack = new ServerPacket(ServerOP_GetWorldTime, 1); auto pack = new ServerPacket(ServerOP_GetWorldTime, 1);
worldserver.SendPacket(pack); worldserver.SendPacket(pack);
safe_delete(pack); safe_delete(pack);

View File

@ -167,7 +167,9 @@ bool ZoneDatabase::GetZoneCFG(
"fast_regen_endurance, " // 59 "fast_regen_endurance, " // 59
"npc_max_aggro_dist, " // 60 "npc_max_aggro_dist, " // 60
"max_movement_update_range, " // 61 "max_movement_update_range, " // 61
"underworld_teleport_index " // 62 "underworld_teleport_index, " // 62
"lava_damage, " // 63
"min_lava_damage " // 64
"FROM zone WHERE zoneidnumber = %i AND version = %i %s", "FROM zone WHERE zoneidnumber = %i AND version = %i %s",
zoneid, zoneid,
instance_id, instance_id,
@ -220,6 +222,8 @@ bool ZoneDatabase::GetZoneCFG(
zone_data->FastRegenEndurance = atoi(row[59]); zone_data->FastRegenEndurance = atoi(row[59]);
zone_data->NPCAggroMaxDist = atoi(row[60]); zone_data->NPCAggroMaxDist = atoi(row[60]);
zone_data->underworld_teleport_index = atoi(row[62]); zone_data->underworld_teleport_index = atoi(row[62]);
zone_data->LavaDamage = atoi(row[63]);
zone_data->MinLavaDamage = atoi(row[64]);
int bindable = 0; int bindable = 0;
bindable = atoi(row[31]); bindable = atoi(row[31]);