mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-24 15:52:26 +00:00
Merge from master, probably wont compile but will fix that soon
This commit is contained in:
commit
5995afa1b8
@ -1,5 +1,43 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 06/12/2015 ==
|
||||||
|
Uleat: Adjusted SessionStats to better reflect a sister implementation
|
||||||
|
|
||||||
|
== 06/07/2015 ==
|
||||||
|
Uleat: Implemented optional rule for using disenchanted bags. Action triggers at the same point that temporary items are removed.
|
||||||
|
Optional SQL: utils/sql/git/optional/2015_06_07_TransformSummonedBagsRule.sql
|
||||||
|
mackal: changes to AA packets since more fields have been identified
|
||||||
|
mackal: fix exploit with expendable AAs punching holes in the aa_array and staying around longer than they are welcomed
|
||||||
|
|
||||||
|
== 05/25/2015 ==
|
||||||
|
Akkadius: Implemented disjointed zone based time, this can be triggered via quest methods
|
||||||
|
Akkadius: Added parameter to LUA and Perl method settime(hour, minute, [update_world = true])
|
||||||
|
- If update_world is false, the zone will then unsubscribe itself from regular worldserver time synchronizations
|
||||||
|
- Basically this localizes the zones time and keeps it from syncing with world updates
|
||||||
|
Akkadius: Added DB ver 9082 with update to add npc_types texture columns if table does not currently have them
|
||||||
|
|
||||||
|
== 05/22/2015 ==
|
||||||
|
Uleat: Added null-term declaration for character names in ENCODE(OP_CharInfo) - where appropriate
|
||||||
|
|
||||||
|
== 05/20/2015 ==
|
||||||
|
demonstar55: Bard instrument mods should be more consistent with live. Zoning will keep instrument mod for long duration buffs (selo's)
|
||||||
|
Still need to have procs/doom effects to inherit the instrument mods from their source buff/whatever
|
||||||
|
|
||||||
|
== 05/18/2015 ==
|
||||||
|
KLS: Changed how fishing locates water to hopefully be a bit more accurate at the expense of a bit more cpu power per line cast.
|
||||||
|
|
||||||
|
== 05/15/2015 ==
|
||||||
|
Uleat: Added check to EntityList::CheckSpawnQueue() to bypass dereference if returned iterator is npc_list.end() - should fix the debug assertion failure crash
|
||||||
|
|
||||||
|
== 04/30/2015 ==
|
||||||
|
demonstar55: Implement mob and client melee push
|
||||||
|
You can set Combat:MeleePush to false to turn off or change Combat:MeleePushChance to increase the chance an NPC can be pushed
|
||||||
|
PCs are always pushed, need to do more testing to verify.
|
||||||
|
|
||||||
|
== 04/22/2015 ==
|
||||||
|
Uleat: Probable fix for 'Debug Assertion Failure' in Client::GarbleMessage() when calling the 'isalpha' macro.
|
||||||
|
ref: https://connect.microsoft.com/VisualStudio/feedback/details/932876/calling-isdigit-with-a-signed-char-1-results-in-a-assert-failure-in-debug-compiles
|
||||||
|
|
||||||
== 03/29/2015 ==
|
== 03/29/2015 ==
|
||||||
Secrets: Identified the Target Ring fields for RoF/RoF2.
|
Secrets: Identified the Target Ring fields for RoF/RoF2.
|
||||||
Secrets: Added a perl accessor for the last target ring position received from the client. Usage: $client->GetTargetRingX(), $client->GetTargetRingY(), $client->GetTargetRingZ()
|
Secrets: Added a perl accessor for the last target ring position received from the client. Usage: $client->GetTargetRingX(), $client->GetTargetRingY(), $client->GetTargetRingZ()
|
||||||
|
|||||||
@ -32,6 +32,7 @@ EQEmuLogSys Log;
|
|||||||
void ExportSpells(SharedDatabase *db);
|
void ExportSpells(SharedDatabase *db);
|
||||||
void ExportSkillCaps(SharedDatabase *db);
|
void ExportSkillCaps(SharedDatabase *db);
|
||||||
void ExportBaseData(SharedDatabase *db);
|
void ExportBaseData(SharedDatabase *db);
|
||||||
|
void ExportDBStrings(SharedDatabase *db);
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
RegisterExecutablePlatform(ExePlatformClientExport);
|
RegisterExecutablePlatform(ExePlatformClientExport);
|
||||||
@ -62,6 +63,7 @@ int main(int argc, char **argv) {
|
|||||||
ExportSpells(&database);
|
ExportSpells(&database);
|
||||||
ExportSkillCaps(&database);
|
ExportSkillCaps(&database);
|
||||||
ExportBaseData(&database);
|
ExportBaseData(&database);
|
||||||
|
ExportDBStrings(&database);
|
||||||
|
|
||||||
Log.CloseFileLogs();
|
Log.CloseFileLogs();
|
||||||
|
|
||||||
@ -194,7 +196,38 @@ void ExportBaseData(SharedDatabase *db) {
|
|||||||
|
|
||||||
fprintf(f, "%s\n", line.c_str());
|
fprintf(f, "%s\n", line.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExportDBStrings(SharedDatabase *db) {
|
||||||
|
Log.Out(Logs::General, Logs::Status, "Exporting DB Strings...");
|
||||||
|
|
||||||
|
FILE *f = fopen("export/dbstr_us.txt", "w");
|
||||||
|
if(!f) {
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Unable to open export/dbstr_us.txt to write, skipping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(f, "Major^Minor^String(New)\n");
|
||||||
|
const std::string query = "SELECT * FROM db_str ORDER BY id, type";
|
||||||
|
auto results = db->QueryDatabase(query);
|
||||||
|
if(results.Success()) {
|
||||||
|
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
std::string line;
|
||||||
|
unsigned int fields = results.ColumnCount();
|
||||||
|
for(unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
|
||||||
|
if(rowIndex != 0)
|
||||||
|
line.push_back('^');
|
||||||
|
|
||||||
|
if(row[rowIndex] != nullptr) {
|
||||||
|
line += row[rowIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(f, "%s\n", line.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|||||||
@ -30,6 +30,7 @@ EQEmuLogSys Log;
|
|||||||
void ImportSpells(SharedDatabase *db);
|
void ImportSpells(SharedDatabase *db);
|
||||||
void ImportSkillCaps(SharedDatabase *db);
|
void ImportSkillCaps(SharedDatabase *db);
|
||||||
void ImportBaseData(SharedDatabase *db);
|
void ImportBaseData(SharedDatabase *db);
|
||||||
|
void ImportDBStrings(SharedDatabase *db);
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
RegisterExecutablePlatform(ExePlatformClientImport);
|
RegisterExecutablePlatform(ExePlatformClientImport);
|
||||||
@ -59,6 +60,7 @@ int main(int argc, char **argv) {
|
|||||||
ImportSpells(&database);
|
ImportSpells(&database);
|
||||||
ImportSkillCaps(&database);
|
ImportSkillCaps(&database);
|
||||||
ImportBaseData(&database);
|
ImportBaseData(&database);
|
||||||
|
ImportDBStrings(&database);
|
||||||
|
|
||||||
Log.CloseFileLogs();
|
Log.CloseFileLogs();
|
||||||
|
|
||||||
@ -202,7 +204,6 @@ void ImportSkillCaps(SharedDatabase *db) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int class_id, skill_id, level, cap;
|
int class_id, skill_id, level, cap;
|
||||||
class_id = atoi(split[0].c_str());
|
class_id = atoi(split[0].c_str());
|
||||||
skill_id = atoi(split[1].c_str());
|
skill_id = atoi(split[1].c_str());
|
||||||
@ -262,3 +263,56 @@ void ImportBaseData(SharedDatabase *db) {
|
|||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImportDBStrings(SharedDatabase *db) {
|
||||||
|
Log.Out(Logs::General, Logs::Status, "Importing DB Strings...");
|
||||||
|
|
||||||
|
FILE *f = fopen("import/dbstr_us.txt", "r");
|
||||||
|
if(!f) {
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Unable to open import/dbstr_us.txt to read, skipping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string delete_sql = "DELETE FROM db_str";
|
||||||
|
db->QueryDatabase(delete_sql);
|
||||||
|
|
||||||
|
char buffer[2048];
|
||||||
|
bool first = true;
|
||||||
|
while(fgets(buffer, 2048, f)) {
|
||||||
|
if(first) {
|
||||||
|
first = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 2048; ++i) {
|
||||||
|
if(buffer[i] == '\n') {
|
||||||
|
buffer[i] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto split = SplitString(buffer, '^');
|
||||||
|
|
||||||
|
if(split.size() < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sql;
|
||||||
|
int id, type;
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
id = atoi(split[0].c_str());
|
||||||
|
type = atoi(split[1].c_str());
|
||||||
|
|
||||||
|
if(split.size() >= 3) {
|
||||||
|
value = ::EscapeString(split[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = StringFormat("INSERT INTO db_str(id, type, value) VALUES(%u, %u, '%s')",
|
||||||
|
id, type, value.c_str());
|
||||||
|
|
||||||
|
db->QueryDatabase(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|||||||
@ -348,6 +348,7 @@ N(OP_OpenTributeMaster),
|
|||||||
N(OP_PDeletePetition),
|
N(OP_PDeletePetition),
|
||||||
N(OP_PetBuffWindow),
|
N(OP_PetBuffWindow),
|
||||||
N(OP_PetCommands),
|
N(OP_PetCommands),
|
||||||
|
N(OP_PetHoTT),
|
||||||
N(OP_Petition),
|
N(OP_Petition),
|
||||||
N(OP_PetitionBug),
|
N(OP_PetitionBug),
|
||||||
N(OP_PetitionCheckIn),
|
N(OP_PetitionCheckIn),
|
||||||
@ -364,6 +365,8 @@ N(OP_PetitionUnCheckout),
|
|||||||
N(OP_PetitionUpdate),
|
N(OP_PetitionUpdate),
|
||||||
N(OP_PickPocket),
|
N(OP_PickPocket),
|
||||||
N(OP_PlayerProfile),
|
N(OP_PlayerProfile),
|
||||||
|
N(OP_PlayerStateAdd),
|
||||||
|
N(OP_PlayerStateRemove),
|
||||||
N(OP_PlayEverquestRequest),
|
N(OP_PlayEverquestRequest),
|
||||||
N(OP_PlayEverquestResponse),
|
N(OP_PlayEverquestResponse),
|
||||||
N(OP_PlayMP3),
|
N(OP_PlayMP3),
|
||||||
@ -519,8 +522,6 @@ N(OP_VetRewardsAvaliable),
|
|||||||
N(OP_VoiceMacroIn),
|
N(OP_VoiceMacroIn),
|
||||||
N(OP_VoiceMacroOut),
|
N(OP_VoiceMacroOut),
|
||||||
N(OP_WeaponEquip1),
|
N(OP_WeaponEquip1),
|
||||||
N(OP_WeaponEquip2),
|
|
||||||
N(OP_WeaponUnequip2),
|
|
||||||
N(OP_WearChange),
|
N(OP_WearChange),
|
||||||
N(OP_Weather),
|
N(OP_Weather),
|
||||||
N(OP_Weblink),
|
N(OP_Weblink),
|
||||||
|
|||||||
@ -281,7 +281,8 @@ struct Spawn_Struct {
|
|||||||
/*0146*/ uint8 beard; // Beard style (not totally, sure but maybe!)
|
/*0146*/ uint8 beard; // Beard style (not totally, sure but maybe!)
|
||||||
/*0147*/ uint8 unknown0147[4];
|
/*0147*/ uint8 unknown0147[4];
|
||||||
/*0151*/ uint8 level; // Spawn Level
|
/*0151*/ uint8 level; // Spawn Level
|
||||||
/*0152*/ uint8 unknown0259[4]; // ***Placeholder
|
// None = 0, Open = 1, WeaponSheathed = 2, Aggressive = 4, ForcedAggressive = 8, InstrumentEquipped = 16, Stunned = 32, PrimaryWeaponEquipped = 64, SecondaryWeaponEquipped = 128
|
||||||
|
/*0152*/ uint32 PlayerState; // Controls animation stuff
|
||||||
/*0156*/ uint8 beardcolor; // Beard color
|
/*0156*/ uint8 beardcolor; // Beard color
|
||||||
/*0157*/ char suffix[32]; // Player's suffix (of Veeshan, etc.)
|
/*0157*/ char suffix[32]; // Player's suffix (of Veeshan, etc.)
|
||||||
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
|
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
|
||||||
@ -374,6 +375,11 @@ union
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PlayerState_Struct {
|
||||||
|
/*00*/ uint32 spawn_id;
|
||||||
|
/*04*/ uint32 state;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** New Spawn
|
** New Spawn
|
||||||
** Length: 176 Bytes
|
** Length: 176 Bytes
|
||||||
@ -555,7 +561,7 @@ struct SpellBuff_Struct
|
|||||||
/*002*/ uint8 bard_modifier;
|
/*002*/ uint8 bard_modifier;
|
||||||
/*003*/ uint8 effect; //not real
|
/*003*/ uint8 effect; //not real
|
||||||
/*004*/ uint32 spellid;
|
/*004*/ uint32 spellid;
|
||||||
/*008*/ uint32 duration;
|
/*008*/ int32 duration;
|
||||||
/*012*/ uint32 counters;
|
/*012*/ uint32 counters;
|
||||||
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
|
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
|
||||||
/*020*/
|
/*020*/
|
||||||
@ -568,7 +574,7 @@ struct SpellBuffFade_Struct {
|
|||||||
/*006*/ uint8 effect;
|
/*006*/ uint8 effect;
|
||||||
/*007*/ uint8 unknown7;
|
/*007*/ uint8 unknown7;
|
||||||
/*008*/ uint32 spellid;
|
/*008*/ uint32 spellid;
|
||||||
/*012*/ uint32 duration;
|
/*012*/ int32 duration;
|
||||||
/*016*/ uint32 num_hits;
|
/*016*/ uint32 num_hits;
|
||||||
/*020*/ uint32 unknown020; //prolly global player ID
|
/*020*/ uint32 unknown020; //prolly global player ID
|
||||||
/*024*/ uint32 slotid;
|
/*024*/ uint32 slotid;
|
||||||
@ -586,14 +592,8 @@ struct BuffRemoveRequest_Struct
|
|||||||
|
|
||||||
struct PetBuff_Struct {
|
struct PetBuff_Struct {
|
||||||
/*000*/ uint32 petid;
|
/*000*/ uint32 petid;
|
||||||
/*004*/ uint32 spellid[BUFF_COUNT];
|
/*004*/ uint32 spellid[BUFF_COUNT+5];
|
||||||
/*104*/ uint32 unknown700;
|
/*124*/ int32 ticsremaining[BUFF_COUNT+5];
|
||||||
/*108*/ uint32 unknown701;
|
|
||||||
/*112*/ uint32 unknown702;
|
|
||||||
/*116*/ uint32 unknown703;
|
|
||||||
/*120*/ uint32 unknown704;
|
|
||||||
/*124*/ uint32 ticsremaining[BUFF_COUNT];
|
|
||||||
/*224*/ uchar unknown705[20];
|
|
||||||
/*244*/ uint32 buffcount;
|
/*244*/ uint32 buffcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -734,6 +734,7 @@ struct AA_Array
|
|||||||
{
|
{
|
||||||
uint32 AA;
|
uint32 AA;
|
||||||
uint32 value;
|
uint32 value;
|
||||||
|
uint32 charges;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1168,7 +1169,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*000*/ uint32 command;
|
/*000*/ uint32 command;
|
||||||
/*004*/ uint32 unknown;
|
/*004*/ uint32 target;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1326,9 +1327,9 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ uint32 damage;
|
/* 07 */ uint32 damage;
|
||||||
/* 11 */ uint32 unknown11;
|
/* 11 */ float force;
|
||||||
/* 15 */ uint32 sequence; // see above notes in Action_Struct
|
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 19 */ uint32 unknown19;
|
/* 19 */ float meleepush_z;
|
||||||
/* 23 */
|
/* 23 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2167,24 +2168,24 @@ struct Illusion_Struct_Old {
|
|||||||
// OP_Sound - Size: 68
|
// OP_Sound - Size: 68
|
||||||
struct QuestReward_Struct
|
struct QuestReward_Struct
|
||||||
{
|
{
|
||||||
/*000*/ uint32 from_mob; // ID of mob awarding the client
|
/*000*/ uint32 mob_id; // ID of mob awarding the client
|
||||||
/*004*/ uint32 unknown004;
|
/*004*/ uint32 target_id;
|
||||||
/*008*/ uint32 unknown008;
|
/*008*/ uint32 exp_reward;
|
||||||
/*012*/ uint32 unknown012;
|
/*012*/ uint32 faction;
|
||||||
/*016*/ uint32 unknown016;
|
/*016*/ int32 faction_mod;
|
||||||
/*020*/ uint32 unknown020;
|
/*020*/ uint32 copper; // Gives copper to the client
|
||||||
/*024*/ uint32 silver; // Gives silver to the client
|
/*024*/ uint32 silver; // Gives silver to the client
|
||||||
/*028*/ uint32 gold; // Gives gold to the client
|
/*028*/ uint32 gold; // Gives gold to the client
|
||||||
/*032*/ uint32 platinum; // Gives platinum to the client
|
/*032*/ uint32 platinum; // Gives platinum to the client
|
||||||
/*036*/ uint32 unknown036;
|
/*036*/ uint32 item_id;
|
||||||
/*040*/ uint32 unknown040;
|
/*040*/ uint32 unknown040;
|
||||||
/*044*/ uint32 unknown044;
|
/*044*/ uint32 unknown044;
|
||||||
/*048*/ uint32 unknown048;
|
/*048*/ uint32 unknown048;
|
||||||
/*052*/ uint32 unknown052;
|
/*052*/ uint32 unknown052;
|
||||||
/*056*/ uint32 unknown056;
|
/*056*/ uint32 unknown056;
|
||||||
/*060*/ uint32 unknown060;
|
/*060*/ uint32 unknown060;
|
||||||
/*064*/ uint32 unknown064;
|
/*064*/ uint32 unknown064;
|
||||||
/*068*/
|
/*068*/
|
||||||
};
|
};
|
||||||
|
|
||||||
// Size: 8
|
// Size: 8
|
||||||
@ -2554,8 +2555,8 @@ struct BookRequest_Struct {
|
|||||||
*/
|
*/
|
||||||
struct Object_Struct {
|
struct Object_Struct {
|
||||||
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
||||||
/*08*/ uint16 unknown008; //
|
/*08*/ uint16 size; //
|
||||||
/*10*/ uint16 unknown010; //
|
/*10*/ uint16 solidtype; //
|
||||||
/*12*/ uint32 drop_id; // Unique object id for zone
|
/*12*/ uint32 drop_id; // Unique object id for zone
|
||||||
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
||||||
/*18*/ uint16 zone_instance; //
|
/*18*/ uint16 zone_instance; //
|
||||||
@ -4049,7 +4050,7 @@ struct MarkNPC_Struct
|
|||||||
|
|
||||||
struct InspectBuffs_Struct {
|
struct InspectBuffs_Struct {
|
||||||
/*000*/ uint32 spell_id[BUFF_COUNT];
|
/*000*/ uint32 spell_id[BUFF_COUNT];
|
||||||
/*100*/ uint32 tics_remaining[BUFF_COUNT];
|
/*100*/ int32 tics_remaining[BUFF_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidGeneral_Struct {
|
struct RaidGeneral_Struct {
|
||||||
@ -4295,14 +4296,6 @@ struct AA_Action {
|
|||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct AA_Skills { //this should be removed and changed to AA_Array
|
|
||||||
/*00*/ uint32 aa_skill; // Total AAs Spent
|
|
||||||
/*04*/ uint32 aa_value;
|
|
||||||
/*08*/ uint32 unknown08;
|
|
||||||
/*12*/
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAExpUpdate_Struct {
|
struct AAExpUpdate_Struct {
|
||||||
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
||||||
/*04*/ uint32 aapoints_unspent;
|
/*04*/ uint32 aapoints_unspent;
|
||||||
@ -4320,12 +4313,12 @@ struct AltAdvStats_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerAA_Struct { // Is this still used?
|
struct PlayerAA_Struct { // Is this still used?
|
||||||
AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AATable_Struct {
|
struct AATable_Struct {
|
||||||
/*00*/ int32 aa_spent; // Total AAs Spent
|
/*00*/ int32 aa_spent; // Total AAs Spent
|
||||||
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
/*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Weather_Struct {
|
struct Weather_Struct {
|
||||||
@ -4750,7 +4743,7 @@ struct BuffIconEntry_Struct
|
|||||||
{
|
{
|
||||||
uint32 buff_slot;
|
uint32 buff_slot;
|
||||||
uint32 spell_id;
|
uint32 spell_id;
|
||||||
uint32 tics_remaining;
|
int32 tics_remaining;
|
||||||
uint32 num_hits;
|
uint32 num_hits;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4759,6 +4752,7 @@ struct BuffIcon_Struct
|
|||||||
uint32 entity_id;
|
uint32 entity_id;
|
||||||
uint8 all_buffs;
|
uint8 all_buffs;
|
||||||
uint16 count;
|
uint16 count;
|
||||||
|
uint8 type; // 0 = self buff window, 1 = self target window, 4 = group, 5 = PC, 7 = NPC
|
||||||
BuffIconEntry_Struct entries[0];
|
BuffIconEntry_Struct entries[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -72,6 +72,8 @@ void EQStream::init(bool resetSession) {
|
|||||||
RateThreshold=RATEBASE/250;
|
RateThreshold=RATEBASE/250;
|
||||||
DecayRate=DECAYBASE/250;
|
DecayRate=DECAYBASE/250;
|
||||||
BytesWritten=0;
|
BytesWritten=0;
|
||||||
|
sent_packet_count = 0;
|
||||||
|
received_packet_count = 0;
|
||||||
SequencedBase = 0;
|
SequencedBase = 0;
|
||||||
NextSequencedSend = 0;
|
NextSequencedSend = 0;
|
||||||
|
|
||||||
@ -464,37 +466,45 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_SessionStatRequest: {
|
case OP_SessionStatRequest: {
|
||||||
if(p->Size() < sizeof(SessionStats))
|
if(p->Size() < sizeof(ClientSessionStats))
|
||||||
{
|
{
|
||||||
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L);
|
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef COLLECTOR
|
#ifndef COLLECTOR
|
||||||
SessionStats *Stats=(SessionStats *)p->pBuffer;
|
ClientSessionStats *ClientStats=(ClientSessionStats *)p->pBuffer;
|
||||||
Log.Out(Logs::Detail, Logs::Netcode, _L "Received Stats: %lu packets received, %lu packets sent, Deltas: local %lu, (%lu <- %lu -> %lu) remote %lu" __L,
|
Log.Out(Logs::Detail, Logs::Netcode, _L "Received Stats: %lu packets received, %lu packets sent, Deltas: local %lu, (%lu <- %lu -> %lu) remote %lu" __L,
|
||||||
(unsigned long)ntohl(Stats->packets_received), (unsigned long)ntohl(Stats->packets_sent), (unsigned long)ntohl(Stats->last_local_delta),
|
(unsigned long)ntohl(ClientStats->packets_received), (unsigned long)ntohl(ClientStats->packets_sent), (unsigned long)ntohl(ClientStats->last_local_delta),
|
||||||
(unsigned long)ntohl(Stats->low_delta), (unsigned long)ntohl(Stats->average_delta),
|
(unsigned long)ntohl(ClientStats->low_delta), (unsigned long)ntohl(ClientStats->average_delta),
|
||||||
(unsigned long)ntohl(Stats->high_delta), (unsigned long)ntohl(Stats->last_remote_delta));
|
(unsigned long)ntohl(ClientStats->high_delta), (unsigned long)ntohl(ClientStats->last_remote_delta));
|
||||||
uint64 x=Stats->packets_received;
|
|
||||||
Stats->packets_received=Stats->packets_sent;
|
AdjustRates(ntohl(ClientStats->average_delta));
|
||||||
Stats->packets_sent=x;
|
|
||||||
NonSequencedPush(new EQProtocolPacket(OP_SessionStatResponse,p->pBuffer,p->size));
|
|
||||||
AdjustRates(ntohl(Stats->average_delta));
|
|
||||||
|
|
||||||
if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) {
|
if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) {
|
||||||
if(RETRANSMIT_TIMEOUT_MULT && ntohl(Stats->average_delta)) {
|
if (RETRANSMIT_TIMEOUT_MULT && ntohl(ClientStats->average_delta)) {
|
||||||
//recalculate retransmittimeout using the larger of the last rtt or average rtt, which is multiplied by the rule value
|
//recalculate retransmittimeout using the larger of the last rtt or average rtt, which is multiplied by the rule value
|
||||||
if((ntohl(Stats->last_local_delta) + ntohl(Stats->last_remote_delta)) > (ntohl(Stats->average_delta) * 2)) {
|
if ((ntohl(ClientStats->last_local_delta) + ntohl(ClientStats->last_remote_delta)) > (ntohl(ClientStats->average_delta) * 2)) {
|
||||||
retransmittimeout = (ntohl(Stats->last_local_delta) + ntohl(Stats->last_remote_delta))
|
retransmittimeout = (ntohl(ClientStats->last_local_delta) + ntohl(ClientStats->last_remote_delta))
|
||||||
* RETRANSMIT_TIMEOUT_MULT;
|
* RETRANSMIT_TIMEOUT_MULT;
|
||||||
} else {
|
} else {
|
||||||
retransmittimeout = ntohl(Stats->average_delta) * 2 * RETRANSMIT_TIMEOUT_MULT;
|
retransmittimeout = ntohl(ClientStats->average_delta) * 2 * RETRANSMIT_TIMEOUT_MULT;
|
||||||
}
|
}
|
||||||
if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX)
|
if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX)
|
||||||
retransmittimeout = RETRANSMIT_TIMEOUT_MAX;
|
retransmittimeout = RETRANSMIT_TIMEOUT_MAX;
|
||||||
Log.Out(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout);
|
Log.Out(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerSessionStats *ServerStats = (ServerSessionStats *)p->pBuffer;
|
||||||
|
|
||||||
|
//ServerStats->RequestID = ClientStats->RequestID; // no change
|
||||||
|
ServerStats->ServerTime = htonl(Timer::GetCurrentTime());
|
||||||
|
ServerStats->packets_sent_echo = ClientStats->packets_sent; // still in htonll format
|
||||||
|
ServerStats->packets_received_echo = ClientStats->packets_received; // still in htonll format
|
||||||
|
ServerStats->packets_sent = htonll(GetPacketsSent());
|
||||||
|
ServerStats->packets_received = htonll(GetPacketsReceived());
|
||||||
|
|
||||||
|
NonSequencedPush(new EQProtocolPacket(OP_SessionStatResponse, p->pBuffer, p->size));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -573,16 +583,18 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
|
|||||||
|
|
||||||
// Convert the EQApplicationPacket to 1 or more EQProtocolPackets
|
// Convert the EQApplicationPacket to 1 or more EQProtocolPackets
|
||||||
if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2)
|
if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2)
|
||||||
Log.Out(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->size);
|
Log.Out(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->Size());
|
||||||
|
|
||||||
unsigned char *tmpbuff=new unsigned char[p->size+3];
|
unsigned char *tmpbuff=new unsigned char[p->size+3];
|
||||||
length=p->serialize(opcode, tmpbuff);
|
length=p->serialize(opcode, tmpbuff);
|
||||||
|
if (length != p->Size())
|
||||||
|
Log.Out(Logs::Detail, Logs::Netcode, _L "Packet adjustment, len %d to %d" __L, p->Size(), length);
|
||||||
|
|
||||||
EQProtocolPacket *out=new EQProtocolPacket(OP_Fragment,nullptr,MaxLen-4);
|
EQProtocolPacket *out=new EQProtocolPacket(OP_Fragment,nullptr,MaxLen-4);
|
||||||
*(uint32 *)(out->pBuffer+2)=htonl(p->Size());
|
*(uint32 *)(out->pBuffer+2)=htonl(length);
|
||||||
used=MaxLen-10;
|
used=MaxLen-10;
|
||||||
memcpy(out->pBuffer+6,tmpbuff,used);
|
memcpy(out->pBuffer+6,tmpbuff,used);
|
||||||
Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Put size %d in the packet" __L, used, p->size, p->Size());
|
Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Payload size %d in the packet" __L, used, length, p->size);
|
||||||
SequencedPush(out);
|
SequencedPush(out);
|
||||||
|
|
||||||
|
|
||||||
@ -593,7 +605,7 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
|
|||||||
out->size=chunksize+2;
|
out->size=chunksize+2;
|
||||||
SequencedPush(out);
|
SequencedPush(out);
|
||||||
used+=chunksize;
|
used+=chunksize;
|
||||||
Log.Out(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, p->size);
|
Log.Out(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, length);
|
||||||
}
|
}
|
||||||
delete p;
|
delete p;
|
||||||
delete[] tmpbuff;
|
delete[] tmpbuff;
|
||||||
@ -1101,8 +1113,8 @@ EQProtocolPacket *p=nullptr;
|
|||||||
|
|
||||||
void EQStream::Process(const unsigned char *buffer, const uint32 length)
|
void EQStream::Process(const unsigned char *buffer, const uint32 length)
|
||||||
{
|
{
|
||||||
static unsigned char newbuffer[2048];
|
static unsigned char newbuffer[2048];
|
||||||
uint32 newlength=0;
|
uint32 newlength=0;
|
||||||
if (EQProtocolPacket::ValidateCRC(buffer,length,Key)) {
|
if (EQProtocolPacket::ValidateCRC(buffer,length,Key)) {
|
||||||
if (compressed) {
|
if (compressed) {
|
||||||
newlength=EQProtocolPacket::Decompress(buffer,length,newbuffer,2048);
|
newlength=EQProtocolPacket::Decompress(buffer,length,newbuffer,2048);
|
||||||
|
|||||||
@ -71,7 +71,7 @@ struct SessionResponse {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Deltas are in ms, representing round trip times
|
//Deltas are in ms, representing round trip times
|
||||||
struct SessionStats {
|
struct ClientSessionStats {
|
||||||
/*000*/ uint16 RequestID;
|
/*000*/ uint16 RequestID;
|
||||||
/*002*/ uint32 last_local_delta;
|
/*002*/ uint32 last_local_delta;
|
||||||
/*006*/ uint32 average_delta;
|
/*006*/ uint32 average_delta;
|
||||||
@ -83,6 +83,16 @@ struct SessionStats {
|
|||||||
/*038*/
|
/*038*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ServerSessionStats {
|
||||||
|
/*000*/ uint16 RequestID;
|
||||||
|
/*002*/ uint32 ServerTime;
|
||||||
|
/*006*/ uint64 packets_sent_echo;
|
||||||
|
/*014*/ uint64 packets_received_echo;
|
||||||
|
/*022*/ uint64 packets_sent;
|
||||||
|
/*030*/ uint64 packets_received;
|
||||||
|
/*038*/
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
class OpcodeManager;
|
class OpcodeManager;
|
||||||
@ -158,6 +168,9 @@ class EQStream : public EQStreamInterface {
|
|||||||
|
|
||||||
int32 BytesWritten;
|
int32 BytesWritten;
|
||||||
|
|
||||||
|
uint64 sent_packet_count;
|
||||||
|
uint64 received_packet_count;
|
||||||
|
|
||||||
Mutex MRate;
|
Mutex MRate;
|
||||||
int32 RateThreshold;
|
int32 RateThreshold;
|
||||||
int32 DecayRate;
|
int32 DecayRate;
|
||||||
@ -265,11 +278,13 @@ class EQStream : public EQStreamInterface {
|
|||||||
void AddBytesSent(uint32 bytes)
|
void AddBytesSent(uint32 bytes)
|
||||||
{
|
{
|
||||||
bytes_sent += bytes;
|
bytes_sent += bytes;
|
||||||
|
++sent_packet_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddBytesRecv(uint32 bytes)
|
void AddBytesRecv(uint32 bytes)
|
||||||
{
|
{
|
||||||
bytes_recv += bytes;
|
bytes_recv += bytes;
|
||||||
|
++received_packet_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const uint32 GetBytesSent() const { return bytes_sent; }
|
virtual const uint32 GetBytesSent() const { return bytes_sent; }
|
||||||
@ -288,6 +303,9 @@ class EQStream : public EQStreamInterface {
|
|||||||
return bytes_recv / (Timer::GetTimeSeconds() - create_time);
|
return bytes_recv / (Timer::GetTimeSeconds() - create_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint64 GetPacketsSent() { return sent_packet_count; }
|
||||||
|
const uint64 GetPacketsReceived() { return received_packet_count; }
|
||||||
|
|
||||||
//used for dynamic stream identification
|
//used for dynamic stream identification
|
||||||
class Signature {
|
class Signature {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -43,19 +43,19 @@ EQTime::EQTime(TimeOfDay_Struct start_eq, time_t start_real)
|
|||||||
|
|
||||||
EQTime::EQTime()
|
EQTime::EQTime()
|
||||||
{
|
{
|
||||||
timezone=0;
|
timezone = 0;
|
||||||
memset(&eqTime, 0, sizeof(eqTime));
|
memset(&eqTime, 0, sizeof(eqTime));
|
||||||
//Defaults for time
|
//Defaults for time
|
||||||
TimeOfDay_Struct start;
|
TimeOfDay_Struct start;
|
||||||
start.day=1;
|
start.day = 1;
|
||||||
start.hour=9;
|
start.hour = 9;
|
||||||
start.minute=0;
|
start.minute = 0;
|
||||||
start.month=1;
|
start.month = 1;
|
||||||
start.year=3100;
|
start.year = 3100;
|
||||||
//Set default time zone
|
//Set default time zone
|
||||||
timezone=0;
|
timezone = 0;
|
||||||
//Start EQTimer
|
//Start EQTimer
|
||||||
setEQTimeOfDay(start, time(0));
|
SetCurrentEQTimeOfDay(start, time(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
EQTime::~EQTime()
|
EQTime::~EQTime()
|
||||||
@ -67,10 +67,10 @@ EQTime::~EQTime()
|
|||||||
//Input: Current Time (as a time_t), a pointer to the TimeOfDay_Struct that will be written to.
|
//Input: Current Time (as a time_t), a pointer to the TimeOfDay_Struct that will be written to.
|
||||||
//Output: 0=Error, 1=Sucess
|
//Output: 0=Error, 1=Sucess
|
||||||
|
|
||||||
int EQTime::getEQTimeOfDay( time_t timeConvert, struct TimeOfDay_Struct *eqTimeOfDay )
|
int EQTime::GetCurrentEQTimeOfDay(time_t timeConvert, struct TimeOfDay_Struct *eqTimeOfDay)
|
||||||
{
|
{
|
||||||
/* check to see if we have a reference time to go by. */
|
/* check to see if we have a reference time to go by. */
|
||||||
if( eqTime.start_realtime == 0 )
|
if (eqTime.start_realtime == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unsigned long diff = timeConvert - eqTime.start_realtime;
|
unsigned long diff = timeConvert - eqTime.start_realtime;
|
||||||
@ -83,7 +83,7 @@ int EQTime::getEQTimeOfDay( time_t timeConvert, struct TimeOfDay_Struct *eqTimeO
|
|||||||
int32 ntz = timezone;
|
int32 ntz = timezone;
|
||||||
|
|
||||||
/* The minutes range from 0 - 59 */
|
/* The minutes range from 0 - 59 */
|
||||||
diff += eqTime.start_eqtime.minute + (ntz%60);
|
diff += eqTime.start_eqtime.minute + (ntz % 60);
|
||||||
eqTimeOfDay->minute = diff % 60;
|
eqTimeOfDay->minute = diff % 60;
|
||||||
diff /= 60;
|
diff /= 60;
|
||||||
ntz /= 60;
|
ntz /= 60;
|
||||||
@ -97,24 +97,24 @@ int EQTime::getEQTimeOfDay( time_t timeConvert, struct TimeOfDay_Struct *eqTimeO
|
|||||||
//
|
//
|
||||||
// Modify it so that it works from
|
// Modify it so that it works from
|
||||||
// 0-23 for our calculations
|
// 0-23 for our calculations
|
||||||
diff += ( eqTime.start_eqtime.hour - 1) + (ntz%24);
|
diff += (eqTime.start_eqtime.hour - 1) + (ntz % 24);
|
||||||
eqTimeOfDay->hour = (diff%24) + 1;
|
eqTimeOfDay->hour = (diff % 24) + 1;
|
||||||
diff /= 24;
|
diff /= 24;
|
||||||
ntz /= 24;
|
ntz /= 24;
|
||||||
|
|
||||||
// The days range from 1-28
|
// The days range from 1-28
|
||||||
// Modify it so that it works from
|
// Modify it so that it works from
|
||||||
// 0-27 for our calculations
|
// 0-27 for our calculations
|
||||||
diff += ( eqTime.start_eqtime.day - 1 ) + (ntz%28);
|
diff += (eqTime.start_eqtime.day - 1) + (ntz % 28);
|
||||||
eqTimeOfDay->day = (diff%28) + 1;
|
eqTimeOfDay->day = (diff % 28) + 1;
|
||||||
diff /= 28;
|
diff /= 28;
|
||||||
ntz /= 28;
|
ntz /= 28;
|
||||||
|
|
||||||
// The months range from 1-12
|
// The months range from 1-12
|
||||||
// Modify it so that it works from
|
// Modify it so that it works from
|
||||||
// 0-11 for our calculations
|
// 0-11 for our calculations
|
||||||
diff += ( eqTime.start_eqtime.month - 1 ) + (ntz%12);
|
diff += (eqTime.start_eqtime.month - 1) + (ntz % 12);
|
||||||
eqTimeOfDay->month = (diff%12) + 1;
|
eqTimeOfDay->month = (diff % 12) + 1;
|
||||||
diff /= 12;
|
diff /= 12;
|
||||||
ntz /= 12;
|
ntz /= 12;
|
||||||
|
|
||||||
@ -124,12 +124,12 @@ int EQTime::getEQTimeOfDay( time_t timeConvert, struct TimeOfDay_Struct *eqTimeO
|
|||||||
}
|
}
|
||||||
|
|
||||||
//setEQTimeOfDay
|
//setEQTimeOfDay
|
||||||
int EQTime::setEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real)
|
int EQTime::SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real)
|
||||||
{
|
{
|
||||||
if(start_real==0)
|
if (start_real == 0)
|
||||||
return 0;
|
return 0;
|
||||||
eqTime.start_eqtime=start_eq;
|
eqTime.start_eqtime = start_eq;
|
||||||
eqTime.start_realtime=start_real;
|
eqTime.start_realtime = start_real;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ bool EQTime::saveFile(const char *filename)
|
|||||||
{
|
{
|
||||||
std::ofstream of;
|
std::ofstream of;
|
||||||
of.open(filename);
|
of.open(filename);
|
||||||
if(!of)
|
if (!of)
|
||||||
{
|
{
|
||||||
Log.Out(Logs::General, Logs::Error, "EQTime::saveFile failed: Unable to open file '%s'", filename);
|
Log.Out(Logs::General, Logs::Error, "EQTime::saveFile failed: Unable to open file '%s'", filename);
|
||||||
return false;
|
return false;
|
||||||
@ -200,24 +200,24 @@ bool EQTime::loadFile(const char *filename)
|
|||||||
|
|
||||||
|
|
||||||
bool EQTime::IsTimeBefore(TimeOfDay_Struct *base, TimeOfDay_Struct *test) {
|
bool EQTime::IsTimeBefore(TimeOfDay_Struct *base, TimeOfDay_Struct *test) {
|
||||||
if(base->year > test->year)
|
if (base->year > test->year)
|
||||||
return(true);
|
return(true);
|
||||||
if(base->year < test->year)
|
if (base->year < test->year)
|
||||||
return(false);
|
return(false);
|
||||||
//same years
|
//same years
|
||||||
if(base->month > test->month)
|
if (base->month > test->month)
|
||||||
return(true);
|
return(true);
|
||||||
if(base->month < test->month)
|
if (base->month < test->month)
|
||||||
return(false);
|
return(false);
|
||||||
//same month
|
//same month
|
||||||
if(base->day > test->day)
|
if (base->day > test->day)
|
||||||
return(true);
|
return(true);
|
||||||
if(base->day < test->day)
|
if (base->day < test->day)
|
||||||
return(false);
|
return(false);
|
||||||
//same day
|
//same day
|
||||||
if(base->hour > test->hour)
|
if (base->hour > test->hour)
|
||||||
return(true);
|
return(true);
|
||||||
if(base->hour < test->hour)
|
if (base->hour < test->hour)
|
||||||
return(false);
|
return(false);
|
||||||
//same hour...
|
//same hour...
|
||||||
return(base->minute > test->minute);
|
return(base->minute > test->minute);
|
||||||
@ -230,7 +230,7 @@ void EQTime::AddMinutes(uint32 minutes, TimeOfDay_Struct *to) {
|
|||||||
//minutes start at 0, everything else starts at 1
|
//minutes start at 0, everything else starts at 1
|
||||||
cur = to->minute;
|
cur = to->minute;
|
||||||
cur += minutes;
|
cur += minutes;
|
||||||
if(cur < 60) {
|
if (cur < 60) {
|
||||||
to->minute = cur;
|
to->minute = cur;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -238,29 +238,29 @@ void EQTime::AddMinutes(uint32 minutes, TimeOfDay_Struct *to) {
|
|||||||
//carry hours
|
//carry hours
|
||||||
cur /= 60;
|
cur /= 60;
|
||||||
cur += to->hour;
|
cur += to->hour;
|
||||||
if(cur <= 24) {
|
if (cur <= 24) {
|
||||||
to->hour = cur;
|
to->hour = cur;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
to->hour = ((cur-1) % 24) + 1;
|
to->hour = ((cur - 1) % 24) + 1;
|
||||||
//carry days
|
//carry days
|
||||||
cur = (cur-1) / 24;
|
cur = (cur - 1) / 24;
|
||||||
cur += to->day;
|
cur += to->day;
|
||||||
if(cur <= 28) {
|
if (cur <= 28) {
|
||||||
to->day = cur;
|
to->day = cur;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
to->day = ((cur-1) % 28) + 1;
|
to->day = ((cur - 1) % 28) + 1;
|
||||||
//carry months
|
//carry months
|
||||||
cur = (cur-1) / 28;
|
cur = (cur - 1) / 28;
|
||||||
cur += to->month;
|
cur += to->month;
|
||||||
if(cur <= 12) {
|
if (cur <= 12) {
|
||||||
to->month = cur;
|
to->month = cur;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
to->month = ((cur-1) % 12) + 1;
|
to->month = ((cur - 1) % 12) + 1;
|
||||||
//carry years
|
//carry years
|
||||||
to->year += (cur-1) / 12;
|
to->year += (cur - 1) / 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
|
void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
|
||||||
@ -270,4 +270,3 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
|
|||||||
buf[127] = '\0';
|
buf[127] = '\0';
|
||||||
str = buf;
|
str = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,8 @@ public:
|
|||||||
~EQTime();
|
~EQTime();
|
||||||
|
|
||||||
//Get functions
|
//Get functions
|
||||||
int getEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(getEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
|
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
|
||||||
int getEQTimeOfDay( time_t timeConvert, TimeOfDay_Struct *eqTimeOfDay );
|
int GetCurrentEQTimeOfDay( time_t timeConvert, TimeOfDay_Struct *eqTimeOfDay );
|
||||||
TimeOfDay_Struct getStartEQTime() { return eqTime.start_eqtime; }
|
TimeOfDay_Struct getStartEQTime() { return eqTime.start_eqtime; }
|
||||||
time_t getStartRealTime() { return eqTime.start_realtime; }
|
time_t getStartRealTime() { return eqTime.start_realtime; }
|
||||||
uint32 getEQTimeZone() { return timezone; }
|
uint32 getEQTimeZone() { return timezone; }
|
||||||
@ -30,7 +30,7 @@ public:
|
|||||||
uint32 getEQTimeZoneMin() { return timezone%60; }
|
uint32 getEQTimeZoneMin() { return timezone%60; }
|
||||||
|
|
||||||
//Set functions
|
//Set functions
|
||||||
int setEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
|
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
|
||||||
void setEQTimeZone(int32 in_timezone) { timezone=in_timezone; }
|
void setEQTimeZone(int32 in_timezone) { timezone=in_timezone; }
|
||||||
|
|
||||||
//Time math/logic functions
|
//Time math/logic functions
|
||||||
|
|||||||
@ -183,7 +183,7 @@ struct ItemData {
|
|||||||
uint32 AugType;
|
uint32 AugType;
|
||||||
uint8 AugSlotType[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Type
|
uint8 AugSlotType[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Type
|
||||||
uint8 AugSlotVisible[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Visible
|
uint8 AugSlotVisible[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Visible
|
||||||
uint8 AugSlotUnk2[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Unknown
|
uint8 AugSlotUnk2[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
|
||||||
uint32 LDoNTheme;
|
uint32 LDoNTheme;
|
||||||
uint32 LDoNPrice;
|
uint32 LDoNPrice;
|
||||||
uint32 LDoNSold;
|
uint32 LDoNSold;
|
||||||
|
|||||||
@ -417,7 +417,7 @@ namespace RoF
|
|||||||
outapp->WriteUInt32(0); // Duration
|
outapp->WriteUInt32(0); // Duration
|
||||||
outapp->WriteUInt32(0); // ?
|
outapp->WriteUInt32(0); // ?
|
||||||
outapp->WriteUInt8(0); // Caster name
|
outapp->WriteUInt8(0); // Caster name
|
||||||
outapp->WriteUInt8(0); // Terminating byte
|
outapp->WriteUInt8(0); // Type
|
||||||
}
|
}
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
|
|
||||||
@ -454,7 +454,7 @@ namespace RoF
|
|||||||
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
|
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
|
||||||
__packet->WriteString("");
|
__packet->WriteString("");
|
||||||
}
|
}
|
||||||
__packet->WriteUInt8(!emu->all_buffs); // Unknown
|
__packet->WriteUInt8(emu->type); // Unknown
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -659,7 +659,9 @@ namespace RoF
|
|||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force)
|
||||||
|
OUT(meleepush_xy);
|
||||||
|
OUT(meleepush_z)
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -974,8 +976,8 @@ namespace RoF
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading);
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading);
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Normally 0, but seen (float)255.0 as well
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Normally 0, but seen (float)255.0 as well
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Unknown
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->solidtype); // Unknown
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 1); // Need to add emu->size to struct
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt.
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y);
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y);
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x);
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x);
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->z);
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->z);
|
||||||
@ -2119,7 +2121,7 @@ namespace RoF
|
|||||||
{
|
{
|
||||||
outapp->WriteUInt32(emu->aa_array[r].AA);
|
outapp->WriteUInt32(emu->aa_array[r].AA);
|
||||||
outapp->WriteUInt32(emu->aa_array[r].value);
|
outapp->WriteUInt32(emu->aa_array[r].value);
|
||||||
outapp->WriteUInt32(0);
|
outapp->WriteUInt32(emu->aa_array[r].charges);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill the other 60 AAs with zeroes
|
// Fill the other 60 AAs with zeroes
|
||||||
@ -2817,9 +2819,9 @@ namespace RoF
|
|||||||
|
|
||||||
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
|
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
|
||||||
{
|
{
|
||||||
eq->aa_list[i].aa_skill = emu->aa_list[i].aa_skill;
|
eq->aa_list[i].AA = emu->aa_list[i].AA;
|
||||||
eq->aa_list[i].aa_value = emu->aa_list[i].aa_value;
|
eq->aa_list[i].value = emu->aa_list[i].value;
|
||||||
eq->aa_list[i].unknown08 = emu->aa_list[i].unknown08;
|
eq->aa_list[i].charges = emu->aa_list[i].charges;
|
||||||
}
|
}
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -2851,7 +2853,7 @@ namespace RoF
|
|||||||
|
|
||||||
// Check clientver field to verify this AA should be sent for SoF
|
// Check clientver field to verify this AA should be sent for SoF
|
||||||
// clientver 1 is for all clients and 5 is for Live
|
// clientver 1 is for all clients and 5 is for Live
|
||||||
if (emu->clientver <= 5)
|
if (emu->clientver <= 7)
|
||||||
{
|
{
|
||||||
OUT(id);
|
OUT(id);
|
||||||
eq->unknown004 = 1;
|
eq->unknown004 = 1;
|
||||||
@ -2867,9 +2869,9 @@ namespace RoF
|
|||||||
OUT(cost);
|
OUT(cost);
|
||||||
OUT(seq);
|
OUT(seq);
|
||||||
OUT(current_level);
|
OUT(current_level);
|
||||||
eq->unknown037 = 1; // Introduced during HoT
|
eq->prereq_skill_count = 1; // min 1
|
||||||
OUT(prereq_skill);
|
OUT(prereq_skill);
|
||||||
eq->unknown045 = 1; // New Mar 21 2012 - Seen 1
|
eq->prereq_minpoints_count = 1; // min 1
|
||||||
OUT(prereq_minpoints);
|
OUT(prereq_minpoints);
|
||||||
eq->type = emu->sof_type;
|
eq->type = emu->sof_type;
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
@ -2885,6 +2887,7 @@ namespace RoF
|
|||||||
OUT(cost2);
|
OUT(cost2);
|
||||||
eq->aa_expansion = emu->aa_expansion;
|
eq->aa_expansion = emu->aa_expansion;
|
||||||
eq->special_category = emu->special_category;
|
eq->special_category = emu->special_category;
|
||||||
|
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
||||||
OUT(total_abilities);
|
OUT(total_abilities);
|
||||||
unsigned int r;
|
unsigned int r;
|
||||||
for (r = 0; r < emu->total_abilities; r++) {
|
for (r = 0; r < emu->total_abilities; r++) {
|
||||||
@ -2945,11 +2948,12 @@ namespace RoF
|
|||||||
|
|
||||||
for (int counter = 0; counter < character_count; ++counter) {
|
for (int counter = 0; counter < character_count; ++counter) {
|
||||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
|
||||||
|
|
||||||
strcpy(eq_cse->Name, emu_cse->Name);
|
strcpy(eq_cse->Name, emu_cse->Name);
|
||||||
eq_ptr += strlen(eq_cse->Name);
|
eq_ptr += strlen(emu_cse->Name);
|
||||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
|
||||||
|
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
|
||||||
|
|
||||||
eq_cse->Class = emu_cse->Class;
|
eq_cse->Class = emu_cse->Class;
|
||||||
eq_cse->Race = emu_cse->Race;
|
eq_cse->Race = emu_cse->Race;
|
||||||
@ -3989,7 +3993,7 @@ namespace RoF
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
||||||
@ -4390,7 +4394,7 @@ namespace RoF
|
|||||||
IN(type);
|
IN(type);
|
||||||
IN(spellid);
|
IN(spellid);
|
||||||
IN(damage);
|
IN(damage);
|
||||||
emu->sequence = eq->sequence;
|
IN(meleepush_xy);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -4718,7 +4722,7 @@ namespace RoF
|
|||||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||||
|
|
||||||
IN(command);
|
IN(command);
|
||||||
emu->unknown = eq->unknown04;
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -485,7 +485,7 @@ namespace RoF2
|
|||||||
outapp->WriteUInt32(0); // Duration
|
outapp->WriteUInt32(0); // Duration
|
||||||
outapp->WriteUInt32(0); // ?
|
outapp->WriteUInt32(0); // ?
|
||||||
outapp->WriteUInt8(0); // Caster name
|
outapp->WriteUInt8(0); // Caster name
|
||||||
outapp->WriteUInt8(0); // Terminating byte
|
outapp->WriteUInt8(0); // Type
|
||||||
}
|
}
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
|
|
||||||
@ -527,7 +527,7 @@ namespace RoF2
|
|||||||
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
|
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
|
||||||
__packet->WriteString("");
|
__packet->WriteString("");
|
||||||
}
|
}
|
||||||
__packet->WriteUInt8(!emu->all_buffs); // Unknown
|
__packet->WriteUInt8(emu->type); // Unknown
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -700,7 +700,9 @@ namespace RoF2
|
|||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force)
|
||||||
|
OUT(meleepush_xy);
|
||||||
|
OUT(meleepush_z)
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -1015,8 +1017,8 @@ namespace RoF2
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading);
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading);
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Normally 0, but seen (float)255.0 as well
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Normally 0, but seen (float)255.0 as well
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Unknown
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->solidtype); // Unknown
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 1); // Need to add emu->size to struct
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt.
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y);
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y);
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x);
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x);
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->z);
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->z);
|
||||||
@ -2185,7 +2187,7 @@ namespace RoF2
|
|||||||
{
|
{
|
||||||
outapp->WriteUInt32(emu->aa_array[r].AA);
|
outapp->WriteUInt32(emu->aa_array[r].AA);
|
||||||
outapp->WriteUInt32(emu->aa_array[r].value);
|
outapp->WriteUInt32(emu->aa_array[r].value);
|
||||||
outapp->WriteUInt32(0);
|
outapp->WriteUInt32(emu->aa_array[r].charges);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill the other 60 AAs with zeroes
|
// Fill the other 60 AAs with zeroes
|
||||||
@ -2892,9 +2894,9 @@ namespace RoF2
|
|||||||
|
|
||||||
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
|
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
|
||||||
{
|
{
|
||||||
eq->aa_list[i].aa_skill = emu->aa_list[i].aa_skill;
|
eq->aa_list[i].AA = emu->aa_list[i].AA;
|
||||||
eq->aa_list[i].aa_value = emu->aa_list[i].aa_value;
|
eq->aa_list[i].value = emu->aa_list[i].value;
|
||||||
eq->aa_list[i].unknown08 = emu->aa_list[i].unknown08;
|
eq->aa_list[i].charges = emu->aa_list[i].charges;
|
||||||
}
|
}
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -2926,7 +2928,7 @@ namespace RoF2
|
|||||||
|
|
||||||
// Check clientver field to verify this AA should be sent for SoF
|
// Check clientver field to verify this AA should be sent for SoF
|
||||||
// clientver 1 is for all clients and 5 is for Live
|
// clientver 1 is for all clients and 5 is for Live
|
||||||
if (emu->clientver <= 5)
|
if (emu->clientver <= 8)
|
||||||
{
|
{
|
||||||
OUT(id);
|
OUT(id);
|
||||||
eq->unknown004 = 1;
|
eq->unknown004 = 1;
|
||||||
@ -2942,9 +2944,9 @@ namespace RoF2
|
|||||||
OUT(cost);
|
OUT(cost);
|
||||||
OUT(seq);
|
OUT(seq);
|
||||||
OUT(current_level);
|
OUT(current_level);
|
||||||
eq->unknown037 = 1; // Introduced during HoT
|
eq->prereq_skill_count = 1; // min 1
|
||||||
OUT(prereq_skill);
|
OUT(prereq_skill);
|
||||||
eq->unknown045 = 1; // New Mar 21 2012 - Seen 1
|
eq->prereq_minpoints_count = 1; // min 1
|
||||||
OUT(prereq_minpoints);
|
OUT(prereq_minpoints);
|
||||||
eq->type = emu->sof_type;
|
eq->type = emu->sof_type;
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
@ -2961,6 +2963,7 @@ namespace RoF2
|
|||||||
eq->aa_expansion = emu->aa_expansion;
|
eq->aa_expansion = emu->aa_expansion;
|
||||||
eq->special_category = emu->special_category;
|
eq->special_category = emu->special_category;
|
||||||
OUT(total_abilities);
|
OUT(total_abilities);
|
||||||
|
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
||||||
unsigned int r;
|
unsigned int r;
|
||||||
for (r = 0; r < emu->total_abilities; r++) {
|
for (r = 0; r < emu->total_abilities; r++) {
|
||||||
OUT(abilities[r].skill_id);
|
OUT(abilities[r].skill_id);
|
||||||
@ -3020,11 +3023,12 @@ namespace RoF2
|
|||||||
|
|
||||||
for (int counter = 0; counter < character_count; ++counter) {
|
for (int counter = 0; counter < character_count; ++counter) {
|
||||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
|
||||||
|
|
||||||
strcpy(eq_cse->Name, emu_cse->Name);
|
strcpy(eq_cse->Name, emu_cse->Name);
|
||||||
eq_ptr += strlen(eq_cse->Name);
|
eq_ptr += strlen(emu_cse->Name);
|
||||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
|
||||||
|
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
|
||||||
|
|
||||||
eq_cse->Class = emu_cse->Class;
|
eq_cse->Class = emu_cse->Class;
|
||||||
eq_cse->Race = emu_cse->Race;
|
eq_cse->Race = emu_cse->Race;
|
||||||
@ -4125,7 +4129,7 @@ namespace RoF2
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
||||||
@ -4525,7 +4529,7 @@ namespace RoF2
|
|||||||
IN(type);
|
IN(type);
|
||||||
IN(spellid);
|
IN(spellid);
|
||||||
IN(damage);
|
IN(damage);
|
||||||
emu->sequence = eq->sequence;
|
IN(meleepush_xy);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -4856,7 +4860,7 @@ namespace RoF2
|
|||||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||||
|
|
||||||
IN(command);
|
IN(command);
|
||||||
emu->unknown = eq->unknown04;
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -416,7 +416,7 @@ struct Spawn_Struct
|
|||||||
/*0000*/ uint8 unknown12;
|
/*0000*/ uint8 unknown12;
|
||||||
/*0000*/ uint32 petOwnerId;
|
/*0000*/ uint32 petOwnerId;
|
||||||
/*0000*/ uint8 unknown13;
|
/*0000*/ uint8 unknown13;
|
||||||
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||||
/*0000*/ uint32 unknown15;
|
/*0000*/ uint32 unknown15;
|
||||||
/*0000*/ uint32 unknown16;
|
/*0000*/ uint32 unknown16;
|
||||||
/*0000*/ uint32 unknown17;
|
/*0000*/ uint32 unknown17;
|
||||||
@ -687,7 +687,7 @@ struct SpellBuff_Struct
|
|||||||
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
||||||
/*009*/ uint32 unknown016;
|
/*009*/ uint32 unknown016;
|
||||||
/*013*/ uint8 bard_modifier;
|
/*013*/ uint8 bard_modifier;
|
||||||
/*014*/ uint32 duration;
|
/*014*/ int32 duration;
|
||||||
/*018*/ uint8 level;
|
/*018*/ uint8 level;
|
||||||
/*019*/ uint32 spellid;
|
/*019*/ uint32 spellid;
|
||||||
/*023*/ uint32 counters;
|
/*023*/ uint32 counters;
|
||||||
@ -703,7 +703,7 @@ struct SpellBuff_Struct_Old
|
|||||||
/*003*/ uint8 effect; // not real
|
/*003*/ uint8 effect; // not real
|
||||||
/*004*/ float unknown004; // Seen 1 for no buff
|
/*004*/ float unknown004; // Seen 1 for no buff
|
||||||
/*008*/ uint32 spellid;
|
/*008*/ uint32 spellid;
|
||||||
/*012*/ uint32 duration;
|
/*012*/ int32 duration;
|
||||||
/*016*/ uint32 unknown016;
|
/*016*/ uint32 unknown016;
|
||||||
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
||||||
/*024*/ uint32 counters;
|
/*024*/ uint32 counters;
|
||||||
@ -720,7 +720,7 @@ struct SpellBuffFade_Struct_Live {
|
|||||||
/*007*/ uint8 unknown007;
|
/*007*/ uint8 unknown007;
|
||||||
/*008*/ float unknown008;
|
/*008*/ float unknown008;
|
||||||
/*012*/ uint32 spellid;
|
/*012*/ uint32 spellid;
|
||||||
/*016*/ uint32 duration;
|
/*016*/ int32 duration;
|
||||||
/*020*/ uint32 playerId; // Global player ID?
|
/*020*/ uint32 playerId; // Global player ID?
|
||||||
/*024*/ uint32 num_hits;
|
/*024*/ uint32 num_hits;
|
||||||
/*028*/ uint8 unknown0028[64];
|
/*028*/ uint8 unknown0028[64];
|
||||||
@ -736,7 +736,7 @@ struct SpellBuffFade_Struct {
|
|||||||
/*006*/ uint8 effect;
|
/*006*/ uint8 effect;
|
||||||
/*007*/ uint8 unknown7;
|
/*007*/ uint8 unknown7;
|
||||||
/*008*/ uint32 spellid;
|
/*008*/ uint32 spellid;
|
||||||
/*012*/ uint32 duration;
|
/*012*/ int32 duration;
|
||||||
/*016*/ uint32 num_hits;
|
/*016*/ uint32 num_hits;
|
||||||
/*020*/ uint32 unknown020; // Global player ID?
|
/*020*/ uint32 unknown020; // Global player ID?
|
||||||
/*024*/ uint32 playerId; // Player id who cast the buff
|
/*024*/ uint32 playerId; // Player id who cast the buff
|
||||||
@ -877,7 +877,7 @@ struct AA_Array
|
|||||||
{
|
{
|
||||||
uint32 AA;
|
uint32 AA;
|
||||||
uint32 value;
|
uint32 value;
|
||||||
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
|
uint32 charges; // expendable charges
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Disciplines_Struct {
|
struct Disciplines_Struct {
|
||||||
@ -1293,7 +1293,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*00*/ uint32 command;
|
/*00*/ uint32 command;
|
||||||
/*04*/ uint32 unknown04;
|
/*04*/ uint32 target;
|
||||||
/*08*/ uint32 unknown08;
|
/*08*/ uint32 unknown08;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1484,9 +1484,10 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint32 spellid;
|
/* 05 */ uint32 spellid;
|
||||||
/* 09 */ int32 damage;
|
/* 09 */ int32 damage;
|
||||||
/* 13 */ float unknown11; // cd cc cc 3d
|
/* 13 */ float force; // cd cc cc 3d
|
||||||
/* 17 */ float sequence; // see above notes in Action_Struct
|
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 21 */ uint8 unknown19[9]; // was [9]
|
/* 21 */ float meleepush_z;
|
||||||
|
/* 25 */ uint8 unknown25[5]; // was [9]
|
||||||
/* 30 */
|
/* 30 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2472,7 +2473,7 @@ struct GroupFollow_Struct { // Live Follow Struct
|
|||||||
|
|
||||||
struct InspectBuffs_Struct {
|
struct InspectBuffs_Struct {
|
||||||
/*000*/ uint32 spell_id[BUFF_COUNT];
|
/*000*/ uint32 spell_id[BUFF_COUNT];
|
||||||
/*168*/ uint32 tics_remaining[BUFF_COUNT];
|
/*168*/ int32 tics_remaining[BUFF_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LFG_Struct {
|
struct LFG_Struct {
|
||||||
@ -4252,9 +4253,9 @@ struct SendAA_Struct {
|
|||||||
/*0025*/ uint32 cost;
|
/*0025*/ uint32 cost;
|
||||||
/*0029*/ uint32 seq;
|
/*0029*/ uint32 seq;
|
||||||
/*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired
|
/*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired
|
||||||
/*0037*/ uint32 unknown037; // Introduced during HoT
|
/*0037*/ uint32 prereq_skill_count; // mutliple prereqs at least 1, even no prereqs
|
||||||
/*0041*/ uint32 prereq_skill; //is < 0, abs() is category #
|
/*0041*/ uint32 prereq_skill; //is < 0, abs() is category #
|
||||||
/*0045*/ uint32 unknown045; // New Mar 21 2012 - Seen 1
|
/*0045*/ uint32 prereq_minpoints_count; // mutliple prereqs at least 1, even no prereqs
|
||||||
/*0049*/ uint32 prereq_minpoints; //min points in the prereq
|
/*0049*/ uint32 prereq_minpoints; //min points in the prereq
|
||||||
/*0053*/ uint32 type;
|
/*0053*/ uint32 type;
|
||||||
/*0057*/ uint32 spellid;
|
/*0057*/ uint32 spellid;
|
||||||
@ -4267,10 +4268,16 @@ struct SendAA_Struct {
|
|||||||
/*0081*/ uint32 last_id;
|
/*0081*/ uint32 last_id;
|
||||||
/*0085*/ uint32 next_id;
|
/*0085*/ uint32 next_id;
|
||||||
/*0089*/ uint32 cost2;
|
/*0089*/ uint32 cost2;
|
||||||
/*0093*/ uint8 unknown80[7];
|
/*0093*/ uint8 unknown93;
|
||||||
|
/*0094*/ uint8 grant_only; // VetAAs, progression, etc
|
||||||
|
/*0095*/ uint8 unknown95; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
|
||||||
|
/*0096*/ uint32 expendable_charges; // max charges of the AA
|
||||||
/*0100*/ uint32 aa_expansion;
|
/*0100*/ uint32 aa_expansion;
|
||||||
/*0104*/ uint32 special_category;
|
/*0104*/ uint32 special_category;
|
||||||
/*0108*/ uint32 unknown0096;
|
/*0108*/ uint8 shroud;
|
||||||
|
/*0109*/ uint8 unknown109;
|
||||||
|
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
|
||||||
|
/*0111*/ uint8 unknown111;
|
||||||
/*0112*/ uint32 total_abilities;
|
/*0112*/ uint32 total_abilities;
|
||||||
/*0116*/ AA_Ability abilities[0];
|
/*0116*/ AA_Ability abilities[0];
|
||||||
};
|
};
|
||||||
@ -4287,12 +4294,6 @@ struct AA_Action {
|
|||||||
/*16*/
|
/*16*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AA_Skills { //this should be removed and changed to AA_Array
|
|
||||||
/*00*/ uint32 aa_skill; // Total AAs Spent
|
|
||||||
/*04*/ uint32 aa_value;
|
|
||||||
/*08*/ uint32 unknown08;
|
|
||||||
/*12*/
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAExpUpdate_Struct {
|
struct AAExpUpdate_Struct {
|
||||||
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
||||||
@ -4312,14 +4313,7 @@ struct AltAdvStats_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerAA_Struct { // Is this still used?
|
struct PlayerAA_Struct { // Is this still used?
|
||||||
AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
|
||||||
|
|
||||||
struct AA_Values {
|
|
||||||
/*00*/ uint32 aa_skill;
|
|
||||||
/*04*/ uint32 aa_value;
|
|
||||||
/*08*/ uint32 unknown08;
|
|
||||||
/*12*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AATable_Struct {
|
struct AATable_Struct {
|
||||||
@ -4329,7 +4323,7 @@ struct AATable_Struct {
|
|||||||
/*12*/ uint32 aa_spent_archetype; // Seen 40
|
/*12*/ uint32 aa_spent_archetype; // Seen 40
|
||||||
/*16*/ uint32 aa_spent_class; // Seen 103
|
/*16*/ uint32 aa_spent_class; // Seen 103
|
||||||
/*20*/ uint32 aa_spent_special; // Seen 0
|
/*20*/ uint32 aa_spent_special; // Seen 0
|
||||||
/*24*/ AA_Values aa_list[MAX_PP_AA_ARRAY];
|
/*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Weather_Struct {
|
struct Weather_Struct {
|
||||||
|
|||||||
@ -410,7 +410,7 @@ struct Spawn_Struct
|
|||||||
/*0000*/ uint8 unknown12;
|
/*0000*/ uint8 unknown12;
|
||||||
/*0000*/ uint32 petOwnerId;
|
/*0000*/ uint32 petOwnerId;
|
||||||
/*0000*/ uint8 unknown13;
|
/*0000*/ uint8 unknown13;
|
||||||
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||||
/*0000*/ uint32 unknown15;
|
/*0000*/ uint32 unknown15;
|
||||||
/*0000*/ uint32 unknown16;
|
/*0000*/ uint32 unknown16;
|
||||||
/*0000*/ uint32 unknown17;
|
/*0000*/ uint32 unknown17;
|
||||||
@ -676,7 +676,7 @@ struct SpellBuff_Struct
|
|||||||
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
||||||
/*009*/ uint32 unknown016;
|
/*009*/ uint32 unknown016;
|
||||||
/*013*/ uint8 bard_modifier;
|
/*013*/ uint8 bard_modifier;
|
||||||
/*014*/ uint32 duration;
|
/*014*/ int32 duration;
|
||||||
/*018*/ uint8 level;
|
/*018*/ uint8 level;
|
||||||
/*019*/ uint32 spellid;
|
/*019*/ uint32 spellid;
|
||||||
/*023*/ uint32 counters;
|
/*023*/ uint32 counters;
|
||||||
@ -692,7 +692,7 @@ struct SpellBuff_Struct_Old
|
|||||||
/*003*/ uint8 effect; // not real
|
/*003*/ uint8 effect; // not real
|
||||||
/*004*/ float unknown004; // Seen 1 for no buff
|
/*004*/ float unknown004; // Seen 1 for no buff
|
||||||
/*008*/ uint32 spellid;
|
/*008*/ uint32 spellid;
|
||||||
/*012*/ uint32 duration;
|
/*012*/ int32 duration;
|
||||||
/*016*/ uint32 unknown016;
|
/*016*/ uint32 unknown016;
|
||||||
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
||||||
/*024*/ uint32 counters;
|
/*024*/ uint32 counters;
|
||||||
@ -709,7 +709,7 @@ struct SpellBuffFade_Struct_Live {
|
|||||||
/*007*/ uint8 unknown007;
|
/*007*/ uint8 unknown007;
|
||||||
/*008*/ float unknown008;
|
/*008*/ float unknown008;
|
||||||
/*012*/ uint32 spellid;
|
/*012*/ uint32 spellid;
|
||||||
/*016*/ uint32 duration;
|
/*016*/ int32 duration;
|
||||||
/*020*/ uint32 playerId; // Global player ID?
|
/*020*/ uint32 playerId; // Global player ID?
|
||||||
/*024*/ uint32 num_hits;
|
/*024*/ uint32 num_hits;
|
||||||
/*028*/ uint8 unknown0028[64];
|
/*028*/ uint8 unknown0028[64];
|
||||||
@ -725,7 +725,7 @@ struct SpellBuffFade_Struct {
|
|||||||
/*006*/ uint8 effect;
|
/*006*/ uint8 effect;
|
||||||
/*007*/ uint8 unknown7;
|
/*007*/ uint8 unknown7;
|
||||||
/*008*/ uint32 spellid;
|
/*008*/ uint32 spellid;
|
||||||
/*012*/ uint32 duration;
|
/*012*/ int32 duration;
|
||||||
/*016*/ uint32 num_hits;
|
/*016*/ uint32 num_hits;
|
||||||
/*020*/ uint32 unknown020; // Global player ID?
|
/*020*/ uint32 unknown020; // Global player ID?
|
||||||
/*024*/ uint32 playerId; // Player id who cast the buff
|
/*024*/ uint32 playerId; // Player id who cast the buff
|
||||||
@ -866,7 +866,7 @@ struct AA_Array
|
|||||||
{
|
{
|
||||||
uint32 AA;
|
uint32 AA;
|
||||||
uint32 value;
|
uint32 value;
|
||||||
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
|
uint32 charges; // expendable charges
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Disciplines_Struct {
|
struct Disciplines_Struct {
|
||||||
@ -1323,7 +1323,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*00*/ uint32 command;
|
/*00*/ uint32 command;
|
||||||
/*04*/ uint32 unknown04;
|
/*04*/ uint32 target;
|
||||||
/*08*/ uint32 unknown08;
|
/*08*/ uint32 unknown08;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1514,9 +1514,10 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint32 spellid;
|
/* 05 */ uint32 spellid;
|
||||||
/* 09 */ int32 damage;
|
/* 09 */ int32 damage;
|
||||||
/* 13 */ float unknown11; // cd cc cc 3d
|
/* 13 */ float force; // cd cc cc 3d
|
||||||
/* 17 */ float sequence; // see above notes in Action_Struct
|
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 21 */ uint8 unknown19[9]; // was [9]
|
/* 21 */ float meleepush_z;
|
||||||
|
/* 25 */ uint8 unknown25[5]; // was [9]
|
||||||
/* 30 */
|
/* 30 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2500,7 +2501,7 @@ struct GroupFollow_Struct { // Live Follow Struct
|
|||||||
|
|
||||||
struct InspectBuffs_Struct {
|
struct InspectBuffs_Struct {
|
||||||
/*000*/ uint32 spell_id[BUFF_COUNT];
|
/*000*/ uint32 spell_id[BUFF_COUNT];
|
||||||
/*168*/ uint32 tics_remaining[BUFF_COUNT];
|
/*168*/ int32 tics_remaining[BUFF_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LFG_Struct {
|
struct LFG_Struct {
|
||||||
@ -4251,9 +4252,9 @@ struct SendAA_Struct {
|
|||||||
/*0025*/ uint32 cost;
|
/*0025*/ uint32 cost;
|
||||||
/*0029*/ uint32 seq;
|
/*0029*/ uint32 seq;
|
||||||
/*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired
|
/*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired
|
||||||
/*0037*/ uint32 unknown037; // Introduced during HoT
|
/*0037*/ uint32 prereq_skill_count; // mutliple prereqs at least 1, even no prereqs
|
||||||
/*0041*/ uint32 prereq_skill; //is < 0, abs() is category #
|
/*0041*/ uint32 prereq_skill; //is < 0, abs() is category #
|
||||||
/*0045*/ uint32 unknown045; // New Mar 21 2012 - Seen 1
|
/*0045*/ uint32 prereq_minpoints_count; // mutliple prereqs at least 1, even no prereqs
|
||||||
/*0049*/ uint32 prereq_minpoints; //min points in the prereq
|
/*0049*/ uint32 prereq_minpoints; //min points in the prereq
|
||||||
/*0053*/ uint32 type;
|
/*0053*/ uint32 type;
|
||||||
/*0057*/ uint32 spellid;
|
/*0057*/ uint32 spellid;
|
||||||
@ -4266,10 +4267,16 @@ struct SendAA_Struct {
|
|||||||
/*0081*/ uint32 last_id;
|
/*0081*/ uint32 last_id;
|
||||||
/*0085*/ uint32 next_id;
|
/*0085*/ uint32 next_id;
|
||||||
/*0089*/ uint32 cost2;
|
/*0089*/ uint32 cost2;
|
||||||
/*0093*/ uint8 unknown80[7];
|
/*0093*/ uint8 unknown93;
|
||||||
|
/*0094*/ uint8 grant_only; // VetAAs, progression, etc
|
||||||
|
/*0095*/ uint8 unknown95; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
|
||||||
|
/*0096*/ uint32 expendable_charges; // max charges of the AA
|
||||||
/*0100*/ uint32 aa_expansion;
|
/*0100*/ uint32 aa_expansion;
|
||||||
/*0104*/ uint32 special_category;
|
/*0104*/ uint32 special_category;
|
||||||
/*0108*/ uint32 unknown0096;
|
/*0108*/ uint8 shroud;
|
||||||
|
/*0109*/ uint8 unknown109;
|
||||||
|
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
|
||||||
|
/*0111*/ uint8 unknown111;
|
||||||
/*0112*/ uint32 total_abilities;
|
/*0112*/ uint32 total_abilities;
|
||||||
/*0116*/ AA_Ability abilities[0];
|
/*0116*/ AA_Ability abilities[0];
|
||||||
};
|
};
|
||||||
@ -4286,13 +4293,6 @@ struct AA_Action {
|
|||||||
/*16*/
|
/*16*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AA_Skills { //this should be removed and changed to AA_Array
|
|
||||||
/*00*/ uint32 aa_skill; // Total AAs Spent
|
|
||||||
/*04*/ uint32 aa_value;
|
|
||||||
/*08*/ uint32 unknown08;
|
|
||||||
/*12*/
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAExpUpdate_Struct {
|
struct AAExpUpdate_Struct {
|
||||||
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
||||||
/*04*/ uint32 aapoints_unspent;
|
/*04*/ uint32 aapoints_unspent;
|
||||||
@ -4311,14 +4311,7 @@ struct AltAdvStats_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerAA_Struct { // Is this still used?
|
struct PlayerAA_Struct { // Is this still used?
|
||||||
AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
|
||||||
|
|
||||||
struct AA_Values {
|
|
||||||
/*00*/ uint32 aa_skill;
|
|
||||||
/*04*/ uint32 aa_value;
|
|
||||||
/*08*/ uint32 unknown08;
|
|
||||||
/*12*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AATable_Struct {
|
struct AATable_Struct {
|
||||||
@ -4328,7 +4321,7 @@ struct AATable_Struct {
|
|||||||
/*12*/ uint32 aa_spent_archetype; // Seen 40
|
/*12*/ uint32 aa_spent_archetype; // Seen 40
|
||||||
/*16*/ uint32 aa_spent_class; // Seen 103
|
/*16*/ uint32 aa_spent_class; // Seen 103
|
||||||
/*20*/ uint32 aa_spent_special; // Seen 0
|
/*20*/ uint32 aa_spent_special; // Seen 0
|
||||||
/*24*/ AA_Values aa_list[MAX_PP_AA_ARRAY];
|
/*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Weather_Struct {
|
struct Weather_Struct {
|
||||||
|
|||||||
@ -447,7 +447,9 @@ namespace SoD
|
|||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force)
|
||||||
|
OUT(meleepush_xy);
|
||||||
|
OUT(meleepush_z)
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -1557,6 +1559,7 @@ namespace SoD
|
|||||||
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
||||||
OUT(aa_array[r].AA);
|
OUT(aa_array[r].AA);
|
||||||
OUT(aa_array[r].value);
|
OUT(aa_array[r].value);
|
||||||
|
OUT(aa_array[r].charges);
|
||||||
}
|
}
|
||||||
// OUT(unknown02220[4]);
|
// OUT(unknown02220[4]);
|
||||||
OUT(mana);
|
OUT(mana);
|
||||||
@ -1897,6 +1900,7 @@ namespace SoD
|
|||||||
OUT(cost2);
|
OUT(cost2);
|
||||||
eq->aa_expansion = emu->aa_expansion;
|
eq->aa_expansion = emu->aa_expansion;
|
||||||
eq->special_category = emu->special_category;
|
eq->special_category = emu->special_category;
|
||||||
|
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
||||||
OUT(total_abilities);
|
OUT(total_abilities);
|
||||||
unsigned int r;
|
unsigned int r;
|
||||||
for (r = 0; r < emu->total_abilities; r++) {
|
for (r = 0; r < emu->total_abilities; r++) {
|
||||||
@ -1961,15 +1965,16 @@ namespace SoD
|
|||||||
|
|
||||||
for (int counter = 0; counter < character_count; ++counter) {
|
for (int counter = 0; counter < character_count; ++counter) {
|
||||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
|
||||||
|
|
||||||
eq_cse->Level = emu_cse->Level;
|
eq_cse->Level = emu_cse->Level;
|
||||||
eq_cse->HairStyle = emu_cse->HairStyle;
|
eq_cse->HairStyle = emu_cse->HairStyle;
|
||||||
eq_cse->Gender = emu_cse->Gender;
|
eq_cse->Gender = emu_cse->Gender;
|
||||||
|
|
||||||
strcpy(eq_cse->Name, emu_cse->Name);
|
strcpy(eq_cse->Name, emu_cse->Name);
|
||||||
eq_ptr += strlen(eq_cse->Name);
|
eq_ptr += strlen(emu_cse->Name);
|
||||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
|
||||||
|
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
|
||||||
|
|
||||||
eq_cse->Beard = emu_cse->Beard;
|
eq_cse->Beard = emu_cse->Beard;
|
||||||
eq_cse->HairColor = emu_cse->HairColor;
|
eq_cse->HairColor = emu_cse->HairColor;
|
||||||
@ -2736,7 +2741,7 @@ namespace SoD
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown12
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown12
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
||||||
@ -3350,7 +3355,7 @@ namespace SoD
|
|||||||
default:
|
default:
|
||||||
emu->command = eq->command;
|
emu->command = eq->command;
|
||||||
}
|
}
|
||||||
OUT(unknown);
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -286,7 +286,7 @@ struct Spawn_Struct
|
|||||||
/*0000*/ uint8 unknown12;
|
/*0000*/ uint8 unknown12;
|
||||||
/*0000*/ uint32 petOwnerId;
|
/*0000*/ uint32 petOwnerId;
|
||||||
/*0000*/ uint8 unknown13;
|
/*0000*/ uint8 unknown13;
|
||||||
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||||
/*0000*/ uint32 unknown15;
|
/*0000*/ uint32 unknown15;
|
||||||
/*0000*/ uint32 unknown16;
|
/*0000*/ uint32 unknown16;
|
||||||
/*0000*/ uint32 unknown17;
|
/*0000*/ uint32 unknown17;
|
||||||
@ -547,7 +547,7 @@ struct SpellBuff_Struct
|
|||||||
/*002*/ uint8 bard_modifier;
|
/*002*/ uint8 bard_modifier;
|
||||||
/*003*/ uint8 effect; //not real
|
/*003*/ uint8 effect; //not real
|
||||||
/*004*/ uint32 spellid;
|
/*004*/ uint32 spellid;
|
||||||
/*008*/ uint32 duration;
|
/*008*/ int32 duration;
|
||||||
/*012*/ uint32 counters;
|
/*012*/ uint32 counters;
|
||||||
/*016*/ uint32 unknown004; //Might need to be swapped with player_id
|
/*016*/ uint32 unknown004; //Might need to be swapped with player_id
|
||||||
/*020*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
|
/*020*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
|
||||||
@ -564,7 +564,7 @@ struct SpellBuffFade_Struct {
|
|||||||
/*006*/ uint8 effect;
|
/*006*/ uint8 effect;
|
||||||
/*007*/ uint8 unknown7;
|
/*007*/ uint8 unknown7;
|
||||||
/*008*/ uint32 spellid;
|
/*008*/ uint32 spellid;
|
||||||
/*012*/ uint32 duration;
|
/*012*/ int32 duration;
|
||||||
/*016*/ uint32 unknown016;
|
/*016*/ uint32 unknown016;
|
||||||
/*020*/ uint32 unknown020; //prolly global player ID
|
/*020*/ uint32 unknown020; //prolly global player ID
|
||||||
/*024*/ uint32 playerId; // Player id who cast the buff
|
/*024*/ uint32 playerId; // Player id who cast the buff
|
||||||
@ -666,7 +666,7 @@ struct AA_Array
|
|||||||
{
|
{
|
||||||
uint32 AA;
|
uint32 AA;
|
||||||
uint32 value;
|
uint32 value;
|
||||||
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
|
uint32 charges; // expendable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1091,7 +1091,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*000*/ uint32 command;
|
/*000*/ uint32 command;
|
||||||
/*004*/ uint32 unknown;
|
/*004*/ uint32 target;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1272,9 +1272,10 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ int32 damage;
|
/* 07 */ int32 damage;
|
||||||
/* 11 */ float unknown11; // cd cc cc 3d
|
/* 11 */ float force; // cd cc cc 3d
|
||||||
/* 15 */ float sequence; // see above notes in Action_Struct
|
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 19 */ uint8 unknown19[9]; // was [9]
|
/* 19 */ float meleepush_z;
|
||||||
|
/* 23 */ uint8 unknown23[5]; // was [9]
|
||||||
/* 28 */
|
/* 28 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3818,10 +3819,16 @@ struct SendAA_Struct {
|
|||||||
/*0069*/ uint32 last_id;
|
/*0069*/ uint32 last_id;
|
||||||
/*0073*/ uint32 next_id;
|
/*0073*/ uint32 next_id;
|
||||||
/*0077*/ uint32 cost2;
|
/*0077*/ uint32 cost2;
|
||||||
/*0081*/ uint8 unknown80[7];
|
/*0081*/ uint8 unknown81;
|
||||||
|
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
|
||||||
|
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
|
||||||
|
/*0084*/ uint32 expendable_charges; // max charges of the AA
|
||||||
/*0088*/ uint32 aa_expansion;
|
/*0088*/ uint32 aa_expansion;
|
||||||
/*0092*/ uint32 special_category;
|
/*0092*/ uint32 special_category;
|
||||||
/*0096*/ uint32 unknown0096;
|
/*0096*/ uint8 shroud;
|
||||||
|
/*0097*/ uint8 unknown97;
|
||||||
|
/*0098*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
|
||||||
|
/*0099*/ uint8 unknown99;
|
||||||
/*0100*/ uint32 total_abilities;
|
/*0100*/ uint32 total_abilities;
|
||||||
/*0104*/ AA_Ability abilities[0];
|
/*0104*/ AA_Ability abilities[0];
|
||||||
};
|
};
|
||||||
@ -3837,12 +3844,6 @@ struct AA_Action {
|
|||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AA_Skills { //this should be removed and changed to AA_Array
|
|
||||||
/*00*/ uint32 aa_skill; // Total AAs Spent
|
|
||||||
/*04*/ uint32 aa_value;
|
|
||||||
/*08*/ uint32 unknown08;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAExpUpdate_Struct {
|
struct AAExpUpdate_Struct {
|
||||||
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
||||||
/*04*/ uint32 aapoints_unspent;
|
/*04*/ uint32 aapoints_unspent;
|
||||||
@ -3860,12 +3861,12 @@ struct AltAdvStats_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerAA_Struct { // Is this still used?
|
struct PlayerAA_Struct { // Is this still used?
|
||||||
AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AATable_Struct {
|
struct AATable_Struct {
|
||||||
/*00*/ int32 aa_spent; // Total AAs Spent
|
/*00*/ int32 aa_spent; // Total AAs Spent
|
||||||
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
/*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Weather_Struct {
|
struct Weather_Struct {
|
||||||
|
|||||||
@ -427,7 +427,9 @@ namespace SoF
|
|||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force)
|
||||||
|
OUT(meleepush_xy);
|
||||||
|
OUT(meleepush_z)
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -1215,6 +1217,7 @@ namespace SoF
|
|||||||
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
||||||
OUT(aa_array[r].AA);
|
OUT(aa_array[r].AA);
|
||||||
OUT(aa_array[r].value);
|
OUT(aa_array[r].value);
|
||||||
|
OUT(aa_array[r].charges);
|
||||||
}
|
}
|
||||||
// OUT(unknown02220[4]);
|
// OUT(unknown02220[4]);
|
||||||
OUT(mana);
|
OUT(mana);
|
||||||
@ -1556,6 +1559,7 @@ namespace SoF
|
|||||||
OUT(cost2);
|
OUT(cost2);
|
||||||
eq->aa_expansion = emu->aa_expansion;
|
eq->aa_expansion = emu->aa_expansion;
|
||||||
eq->special_category = emu->special_category;
|
eq->special_category = emu->special_category;
|
||||||
|
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
||||||
OUT(total_abilities);
|
OUT(total_abilities);
|
||||||
unsigned int r;
|
unsigned int r;
|
||||||
for (r = 0; r < emu->total_abilities; r++) {
|
for (r = 0; r < emu->total_abilities; r++) {
|
||||||
@ -1620,15 +1624,16 @@ namespace SoF
|
|||||||
|
|
||||||
for (int counter = 0; counter < character_count; ++counter) {
|
for (int counter = 0; counter < character_count; ++counter) {
|
||||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
|
||||||
|
|
||||||
eq_cse->Level = emu_cse->Level;
|
eq_cse->Level = emu_cse->Level;
|
||||||
eq_cse->HairStyle = emu_cse->HairStyle;
|
eq_cse->HairStyle = emu_cse->HairStyle;
|
||||||
eq_cse->Gender = emu_cse->Gender;
|
eq_cse->Gender = emu_cse->Gender;
|
||||||
|
|
||||||
strcpy(eq_cse->Name, emu_cse->Name);
|
strcpy(eq_cse->Name, emu_cse->Name);
|
||||||
eq_ptr += strlen(eq_cse->Name);
|
eq_ptr += strlen(emu_cse->Name);
|
||||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
|
||||||
|
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
|
||||||
|
|
||||||
eq_cse->Beard = emu_cse->Beard;
|
eq_cse->Beard = emu_cse->Beard;
|
||||||
eq_cse->HairColor = emu_cse->HairColor;
|
eq_cse->HairColor = emu_cse->HairColor;
|
||||||
@ -2087,6 +2092,7 @@ namespace SoF
|
|||||||
eq->runspeed = emu->runspeed;
|
eq->runspeed = emu->runspeed;
|
||||||
eq->light = emu->light;
|
eq->light = emu->light;
|
||||||
eq->level = emu->level;
|
eq->level = emu->level;
|
||||||
|
eq->PlayerState = emu->PlayerState;
|
||||||
eq->lfg = emu->lfg;
|
eq->lfg = emu->lfg;
|
||||||
eq->hairstyle = emu->hairstyle;
|
eq->hairstyle = emu->hairstyle;
|
||||||
eq->haircolor = emu->haircolor;
|
eq->haircolor = emu->haircolor;
|
||||||
@ -2688,7 +2694,7 @@ namespace SoF
|
|||||||
default:
|
default:
|
||||||
emu->command = eq->command;
|
emu->command = eq->command;
|
||||||
}
|
}
|
||||||
OUT(unknown);
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -241,7 +241,8 @@ struct Spawn_Struct {
|
|||||||
/*0506*/ uint8 light; // Spawn's lightsource
|
/*0506*/ uint8 light; // Spawn's lightsource
|
||||||
/*0507*/ uint8 unknown0507[4];
|
/*0507*/ uint8 unknown0507[4];
|
||||||
/*0511*/ uint8 level; // Spawn Level
|
/*0511*/ uint8 level; // Spawn Level
|
||||||
/*0512*/ uint8 unknown0512[16];
|
/*0512*/ uint32 PlayerState;
|
||||||
|
/*0516*/ uint8 unknown0516[12];
|
||||||
/*0528*/ uint8 lfg;
|
/*0528*/ uint8 lfg;
|
||||||
/*0529*/ uint8 unknown0529[4];
|
/*0529*/ uint8 unknown0529[4];
|
||||||
/*0533*/ uint8 hairstyle; // Sets the style of hair
|
/*0533*/ uint8 hairstyle; // Sets the style of hair
|
||||||
@ -525,7 +526,7 @@ struct SpellBuff_Struct
|
|||||||
/*002*/ uint8 bard_modifier;
|
/*002*/ uint8 bard_modifier;
|
||||||
/*003*/ uint8 effect; //not real
|
/*003*/ uint8 effect; //not real
|
||||||
/*004*/ uint32 spellid;
|
/*004*/ uint32 spellid;
|
||||||
/*008*/ uint32 duration;
|
/*008*/ int32 duration;
|
||||||
/*012*/ uint32 counters;
|
/*012*/ uint32 counters;
|
||||||
/*016*/ uint32 unknown004; //Might need to be swapped with player_id
|
/*016*/ uint32 unknown004; //Might need to be swapped with player_id
|
||||||
/*020*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
|
/*020*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
|
||||||
@ -542,7 +543,7 @@ struct SpellBuffFade_Struct {
|
|||||||
/*006*/ uint8 effect;
|
/*006*/ uint8 effect;
|
||||||
/*007*/ uint8 unknown7;
|
/*007*/ uint8 unknown7;
|
||||||
/*008*/ uint32 spellid;
|
/*008*/ uint32 spellid;
|
||||||
/*012*/ uint32 duration;
|
/*012*/ int32 duration;
|
||||||
/*016*/ uint32 unknown016;
|
/*016*/ uint32 unknown016;
|
||||||
/*020*/ uint32 unknown020; //prolly global player ID
|
/*020*/ uint32 unknown020; //prolly global player ID
|
||||||
/*024*/ uint32 playerId; // Player id who cast the buff
|
/*024*/ uint32 playerId; // Player id who cast the buff
|
||||||
@ -644,7 +645,7 @@ struct AA_Array
|
|||||||
{
|
{
|
||||||
uint32 AA;
|
uint32 AA;
|
||||||
uint32 value;
|
uint32 value;
|
||||||
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
|
uint32 charges; // expendable charges
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1068,7 +1069,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*000*/ uint32 command;
|
/*000*/ uint32 command;
|
||||||
/*004*/ uint32 unknown;
|
/*004*/ uint32 target;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1249,9 +1250,10 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ int32 damage;
|
/* 07 */ int32 damage;
|
||||||
/* 11 */ float unknown11; // cd cc cc 3d
|
/* 11 */ float force; // cd cc cc 3d
|
||||||
/* 15 */ float sequence; // see above notes in Action_Struct
|
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 19 */ uint8 unknown19[9]; // was [9]
|
/* 19 */ float meleepush_z;
|
||||||
|
/* 23 */ uint8 unknown23[5]; // was [9]
|
||||||
/* 28 */
|
/* 28 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3681,10 +3683,14 @@ struct SendAA_Struct {
|
|||||||
/*0069*/ uint32 last_id;
|
/*0069*/ uint32 last_id;
|
||||||
/*0073*/ uint32 next_id;
|
/*0073*/ uint32 next_id;
|
||||||
/*0077*/ uint32 cost2;
|
/*0077*/ uint32 cost2;
|
||||||
/*0081*/ uint8 unknown80[7];
|
/*0081*/ uint8 unknown81;
|
||||||
|
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
|
||||||
|
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
|
||||||
|
/*0084*/ uint32 expendable_charges; // max charges of the AA
|
||||||
/*0088*/ uint32 aa_expansion;
|
/*0088*/ uint32 aa_expansion;
|
||||||
/*0092*/ uint32 special_category;
|
/*0092*/ uint32 special_category;
|
||||||
/*0096*/ uint16 unknown0096;
|
/*0096*/ uint8 shroud;
|
||||||
|
/*0097*/ uint8 unknown97;
|
||||||
/*0098*/ uint32 total_abilities;
|
/*0098*/ uint32 total_abilities;
|
||||||
/*0102*/ AA_Ability abilities[0];
|
/*0102*/ AA_Ability abilities[0];
|
||||||
};
|
};
|
||||||
@ -3700,12 +3706,6 @@ struct AA_Action {
|
|||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AA_Skills { //this should be removed and changed to AA_Array
|
|
||||||
/*00*/ uint32 aa_skill; // Total AAs Spent
|
|
||||||
/*04*/ uint32 aa_value;
|
|
||||||
/*08*/ uint32 unknown08;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAExpUpdate_Struct {
|
struct AAExpUpdate_Struct {
|
||||||
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
||||||
/*04*/ uint32 aapoints_unspent;
|
/*04*/ uint32 aapoints_unspent;
|
||||||
@ -3723,12 +3723,12 @@ struct AltAdvStats_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerAA_Struct {
|
struct PlayerAA_Struct {
|
||||||
AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AATable_Struct {
|
struct AATable_Struct {
|
||||||
/*00*/ int32 aa_spent; // Total AAs Spent
|
/*00*/ int32 aa_spent; // Total AAs Spent
|
||||||
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
/*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Weather_Struct {
|
struct Weather_Struct {
|
||||||
|
|||||||
@ -1100,8 +1100,8 @@ namespace Titanium
|
|||||||
|
|
||||||
unsigned int r;
|
unsigned int r;
|
||||||
for (r = 0; r < structs::MAX_PP_AA_ARRAY; r++) {
|
for (r = 0; r < structs::MAX_PP_AA_ARRAY; r++) {
|
||||||
OUT(aa_list[r].aa_skill);
|
OUT(aa_list[r].AA);
|
||||||
OUT(aa_list[r].aa_value);
|
OUT(aa_list[r].value);
|
||||||
}
|
}
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -1551,7 +1551,7 @@ namespace Titanium
|
|||||||
eq->beardcolor = emu->beardcolor;
|
eq->beardcolor = emu->beardcolor;
|
||||||
// eq->unknown0147[4] = emu->unknown0147[4];
|
// eq->unknown0147[4] = emu->unknown0147[4];
|
||||||
eq->level = emu->level;
|
eq->level = emu->level;
|
||||||
// eq->unknown0259[4] = emu->unknown0259[4];
|
eq->PlayerState = emu->PlayerState;
|
||||||
eq->beard = emu->beard;
|
eq->beard = emu->beard;
|
||||||
strcpy(eq->suffix, emu->suffix);
|
strcpy(eq->suffix, emu->suffix);
|
||||||
eq->petOwnerId = emu->petOwnerId;
|
eq->petOwnerId = emu->petOwnerId;
|
||||||
@ -1944,7 +1944,7 @@ namespace Titanium
|
|||||||
default:
|
default:
|
||||||
emu->command = eq->command;
|
emu->command = eq->command;
|
||||||
}
|
}
|
||||||
OUT(unknown);
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -212,7 +212,7 @@ struct Spawn_Struct {
|
|||||||
/*0146*/ uint8 beardcolor; // Beard color
|
/*0146*/ uint8 beardcolor; // Beard color
|
||||||
/*0147*/ uint8 unknown0147[4];
|
/*0147*/ uint8 unknown0147[4];
|
||||||
/*0151*/ uint8 level; // Spawn Level
|
/*0151*/ uint8 level; // Spawn Level
|
||||||
/*0152*/ uint8 unknown0259[4]; // ***Placeholder
|
/*0152*/ uint32 PlayerState; // PlayerState controls some animation stuff
|
||||||
/*0156*/ uint8 beard; // Beard style
|
/*0156*/ uint8 beard; // Beard style
|
||||||
/*0157*/ char suffix[32]; // Player's suffix (of Veeshan, etc.)
|
/*0157*/ char suffix[32]; // Player's suffix (of Veeshan, etc.)
|
||||||
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
|
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
|
||||||
@ -445,7 +445,7 @@ struct SpellBuff_Struct
|
|||||||
/*002*/ uint8 bard_modifier;
|
/*002*/ uint8 bard_modifier;
|
||||||
/*003*/ uint8 effect; //not real
|
/*003*/ uint8 effect; //not real
|
||||||
/*004*/ uint32 spellid;
|
/*004*/ uint32 spellid;
|
||||||
/*008*/ uint32 duration;
|
/*008*/ int32 duration;
|
||||||
/*012*/ uint32 counters;
|
/*012*/ uint32 counters;
|
||||||
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
|
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
|
||||||
};
|
};
|
||||||
@ -457,7 +457,7 @@ struct SpellBuffFade_Struct {
|
|||||||
/*006*/ uint8 effect;
|
/*006*/ uint8 effect;
|
||||||
/*007*/ uint8 unknown7;
|
/*007*/ uint8 unknown7;
|
||||||
/*008*/ uint32 spellid;
|
/*008*/ uint32 spellid;
|
||||||
/*012*/ uint32 duration;
|
/*012*/ int32 duration;
|
||||||
/*016*/ uint32 unknown016;
|
/*016*/ uint32 unknown016;
|
||||||
/*020*/ uint32 unknown020; //prolly global player ID
|
/*020*/ uint32 unknown020; //prolly global player ID
|
||||||
/*024*/ uint32 slotid;
|
/*024*/ uint32 slotid;
|
||||||
@ -950,7 +950,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*000*/ uint32 command;
|
/*000*/ uint32 command;
|
||||||
/*004*/ uint32 unknown;
|
/*004*/ uint32 target;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1101,9 +1101,9 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ uint32 damage;
|
/* 07 */ uint32 damage;
|
||||||
/* 11 */ uint32 unknown11;
|
/* 11 */ float force;
|
||||||
/* 15 */ uint32 sequence; // see above notes in Action_Struct
|
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 19 */ uint32 unknown19;
|
/* 19 */ float meleepush_z;
|
||||||
/* 23 */
|
/* 23 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3179,11 +3179,6 @@ struct AA_Action {
|
|||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AA_Skills { //this should be removed and changed to AA_Array
|
|
||||||
/*00*/ uint32 aa_skill;
|
|
||||||
/*04*/ uint32 aa_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAExpUpdate_Struct {
|
struct AAExpUpdate_Struct {
|
||||||
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
||||||
/*04*/ uint32 aapoints_unspent;
|
/*04*/ uint32 aapoints_unspent;
|
||||||
@ -3201,11 +3196,11 @@ struct AltAdvStats_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerAA_Struct {
|
struct PlayerAA_Struct {
|
||||||
AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AATable_Struct {
|
struct AATable_Struct {
|
||||||
AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Weather_Struct {
|
struct Weather_Struct {
|
||||||
|
|||||||
@ -387,7 +387,7 @@ namespace UF
|
|||||||
__packet->WriteUInt32(emu->entries[i].num_hits);
|
__packet->WriteUInt32(emu->entries[i].num_hits);
|
||||||
__packet->WriteString("");
|
__packet->WriteString("");
|
||||||
}
|
}
|
||||||
__packet->WriteUInt8(!emu->all_buffs);
|
__packet->WriteUInt8(emu->type);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
/*
|
/*
|
||||||
@ -582,7 +582,9 @@ namespace UF
|
|||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force)
|
||||||
|
OUT(meleepush_xy);
|
||||||
|
OUT(meleepush_z)
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -856,8 +858,8 @@ namespace UF
|
|||||||
// field to be set to (float)255.0 to appear at all, and also the size field below to be 5, to be the correct size. I think SoD has the same
|
// field to be set to (float)255.0 to appear at all, and also the size field below to be 5, to be the correct size. I think SoD has the same
|
||||||
// issue.
|
// issue.
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown, observed 0
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->solidtype); // Unknown, observed 0
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // This appears to be the size field.
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt.
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y);
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y);
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x);
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x);
|
||||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->z);
|
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->z);
|
||||||
@ -1806,6 +1808,7 @@ namespace UF
|
|||||||
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
|
||||||
OUT(aa_array[r].AA);
|
OUT(aa_array[r].AA);
|
||||||
OUT(aa_array[r].value);
|
OUT(aa_array[r].value);
|
||||||
|
OUT(aa_array[r].charges);
|
||||||
}
|
}
|
||||||
// OUT(unknown02220[4]);
|
// OUT(unknown02220[4]);
|
||||||
OUT(mana);
|
OUT(mana);
|
||||||
@ -2133,9 +2136,9 @@ namespace UF
|
|||||||
|
|
||||||
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
|
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
|
||||||
{
|
{
|
||||||
eq->aa_list[i].aa_skill = emu->aa_list[i].aa_skill;
|
eq->aa_list[i].AA = emu->aa_list[i].AA;
|
||||||
eq->aa_list[i].aa_value = emu->aa_list[i].aa_value;
|
eq->aa_list[i].value = emu->aa_list[i].value;
|
||||||
eq->aa_list[i].unknown08 = emu->aa_list[i].unknown08;
|
eq->aa_list[i].charges = emu->aa_list[i].charges;
|
||||||
}
|
}
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -2180,6 +2183,7 @@ namespace UF
|
|||||||
OUT(cost2);
|
OUT(cost2);
|
||||||
eq->aa_expansion = emu->aa_expansion;
|
eq->aa_expansion = emu->aa_expansion;
|
||||||
eq->special_category = emu->special_category;
|
eq->special_category = emu->special_category;
|
||||||
|
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
|
||||||
OUT(total_abilities);
|
OUT(total_abilities);
|
||||||
unsigned int r;
|
unsigned int r;
|
||||||
for (r = 0; r < emu->total_abilities; r++) {
|
for (r = 0; r < emu->total_abilities; r++) {
|
||||||
@ -2252,15 +2256,16 @@ namespace UF
|
|||||||
|
|
||||||
for (int counter = 0; counter < character_count; ++counter) {
|
for (int counter = 0; counter < character_count; ++counter) {
|
||||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
|
||||||
|
|
||||||
eq_cse->Level = emu_cse->Level;
|
eq_cse->Level = emu_cse->Level;
|
||||||
eq_cse->HairStyle = emu_cse->HairStyle;
|
eq_cse->HairStyle = emu_cse->HairStyle;
|
||||||
eq_cse->Gender = emu_cse->Gender;
|
eq_cse->Gender = emu_cse->Gender;
|
||||||
|
|
||||||
strcpy(eq_cse->Name, emu_cse->Name);
|
strcpy(eq_cse->Name, emu_cse->Name);
|
||||||
eq_ptr += strlen(eq_cse->Name);
|
eq_ptr += strlen(emu_cse->Name);
|
||||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
|
||||||
|
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
|
||||||
|
|
||||||
eq_cse->Beard = emu_cse->Beard;
|
eq_cse->Beard = emu_cse->Beard;
|
||||||
eq_cse->HairColor = emu_cse->HairColor;
|
eq_cse->HairColor = emu_cse->HairColor;
|
||||||
@ -3004,7 +3009,7 @@ namespace UF
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown12
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown12
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
||||||
@ -3357,7 +3362,7 @@ namespace UF
|
|||||||
IN(type);
|
IN(type);
|
||||||
IN(spellid);
|
IN(spellid);
|
||||||
IN(damage);
|
IN(damage);
|
||||||
emu->sequence = eq->sequence;
|
IN(meleepush_xy);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -3600,7 +3605,7 @@ namespace UF
|
|||||||
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
|
||||||
|
|
||||||
IN(command);
|
IN(command);
|
||||||
IN(unknown);
|
IN(target);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -286,7 +286,7 @@ struct Spawn_Struct
|
|||||||
/*0000*/ uint8 unknown12;
|
/*0000*/ uint8 unknown12;
|
||||||
/*0000*/ uint32 petOwnerId;
|
/*0000*/ uint32 petOwnerId;
|
||||||
/*0000*/ uint8 unknown13;
|
/*0000*/ uint8 unknown13;
|
||||||
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||||
/*0000*/ uint32 unknown15;
|
/*0000*/ uint32 unknown15;
|
||||||
/*0000*/ uint32 unknown16;
|
/*0000*/ uint32 unknown16;
|
||||||
/*0000*/ uint32 unknown17;
|
/*0000*/ uint32 unknown17;
|
||||||
@ -551,7 +551,7 @@ struct SpellBuff_Struct
|
|||||||
/*003*/ uint8 effect; // not real
|
/*003*/ uint8 effect; // not real
|
||||||
/*004*/ uint32 unknown004; // Seen 1 for no buff
|
/*004*/ uint32 unknown004; // Seen 1 for no buff
|
||||||
/*008*/ uint32 spellid;
|
/*008*/ uint32 spellid;
|
||||||
/*012*/ uint32 duration;
|
/*012*/ int32 duration;
|
||||||
/*016*/ uint32 unknown016;
|
/*016*/ uint32 unknown016;
|
||||||
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
|
||||||
/*024*/ uint32 counters;
|
/*024*/ uint32 counters;
|
||||||
@ -568,7 +568,7 @@ struct SpellBuffFade_Struct_Underfoot {
|
|||||||
/*007*/ uint8 unknown7;
|
/*007*/ uint8 unknown7;
|
||||||
/*008*/ float unknown008;
|
/*008*/ float unknown008;
|
||||||
/*012*/ uint32 spellid;
|
/*012*/ uint32 spellid;
|
||||||
/*016*/ uint32 duration;
|
/*016*/ int32 duration;
|
||||||
/*020*/ uint32 num_hits;
|
/*020*/ uint32 num_hits;
|
||||||
/*024*/ uint32 playerId; // Global player ID?
|
/*024*/ uint32 playerId; // Global player ID?
|
||||||
/*028*/ uint32 unknown020;
|
/*028*/ uint32 unknown020;
|
||||||
@ -585,7 +585,7 @@ struct SpellBuffFade_Struct {
|
|||||||
/*006*/ uint8 effect;
|
/*006*/ uint8 effect;
|
||||||
/*007*/ uint8 unknown7;
|
/*007*/ uint8 unknown7;
|
||||||
/*008*/ uint32 spellid;
|
/*008*/ uint32 spellid;
|
||||||
/*012*/ uint32 duration;
|
/*012*/ int32 duration;
|
||||||
/*016*/ uint32 unknown016;
|
/*016*/ uint32 unknown016;
|
||||||
/*020*/ uint32 unknown020; // Global player ID?
|
/*020*/ uint32 unknown020; // Global player ID?
|
||||||
/*024*/ uint32 playerId; // Player id who cast the buff
|
/*024*/ uint32 playerId; // Player id who cast the buff
|
||||||
@ -713,7 +713,7 @@ struct AA_Array
|
|||||||
{
|
{
|
||||||
uint32 AA;
|
uint32 AA;
|
||||||
uint32 value;
|
uint32 value;
|
||||||
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Underfoot
|
uint32 charges; // expendable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1146,7 +1146,7 @@ struct TargetReject_Struct {
|
|||||||
|
|
||||||
struct PetCommand_Struct {
|
struct PetCommand_Struct {
|
||||||
/*000*/ uint32 command;
|
/*000*/ uint32 command;
|
||||||
/*004*/ uint32 unknown;
|
/*004*/ uint32 target;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1330,9 +1330,10 @@ struct CombatDamage_Struct
|
|||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ int32 damage;
|
/* 07 */ int32 damage;
|
||||||
/* 11 */ float unknown11; // cd cc cc 3d
|
/* 11 */ float force; // cd cc cc 3d
|
||||||
/* 15 */ float sequence; // see above notes in Action_Struct
|
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||||
/* 19 */ uint8 unknown19[9]; // was [9]
|
/* 19 */ float meleepush_z;
|
||||||
|
/* 23 */ uint8 unknown23[5]; // was [9]
|
||||||
/* 28 */
|
/* 28 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2187,7 +2188,7 @@ struct GroupFollow_Struct { // Underfoot Follow Struct
|
|||||||
struct InspectBuffs_Struct {
|
struct InspectBuffs_Struct {
|
||||||
/*000*/ uint32 spell_id[BUFF_COUNT];
|
/*000*/ uint32 spell_id[BUFF_COUNT];
|
||||||
/*100*/ uint32 filler100[5]; // BUFF_COUNT is really 30...
|
/*100*/ uint32 filler100[5]; // BUFF_COUNT is really 30...
|
||||||
/*120*/ uint32 tics_remaining[BUFF_COUNT];
|
/*120*/ int32 tics_remaining[BUFF_COUNT];
|
||||||
/*220*/ uint32 filler220[5]; // BUFF_COUNT is really 30...
|
/*220*/ uint32 filler220[5]; // BUFF_COUNT is really 30...
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3891,10 +3892,16 @@ struct SendAA_Struct {
|
|||||||
/*0069*/ uint32 last_id;
|
/*0069*/ uint32 last_id;
|
||||||
/*0073*/ uint32 next_id;
|
/*0073*/ uint32 next_id;
|
||||||
/*0077*/ uint32 cost2;
|
/*0077*/ uint32 cost2;
|
||||||
/*0081*/ uint8 unknown80[7];
|
/*0081*/ uint8 unknown81;
|
||||||
|
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
|
||||||
|
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
|
||||||
|
/*0084*/ uint32 expendable_charges; // max charges of the AA
|
||||||
/*0088*/ uint32 aa_expansion;
|
/*0088*/ uint32 aa_expansion;
|
||||||
/*0092*/ uint32 special_category;
|
/*0092*/ uint32 special_category;
|
||||||
/*0096*/ uint32 unknown0096;
|
/*0096*/ uint8 shroud;
|
||||||
|
/*0097*/ uint8 unknown97;
|
||||||
|
/*0098*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
|
||||||
|
/*0099*/ uint8 unknown99;
|
||||||
/*0100*/ uint32 total_abilities;
|
/*0100*/ uint32 total_abilities;
|
||||||
/*0104*/ AA_Ability abilities[0];
|
/*0104*/ AA_Ability abilities[0];
|
||||||
};
|
};
|
||||||
@ -3910,11 +3917,6 @@ struct AA_Action {
|
|||||||
/*12*/ uint32 exp_value;
|
/*12*/ uint32 exp_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AA_Skills { //this should be removed and changed to AA_Array
|
|
||||||
/*00*/ uint32 aa_skill; // Total AAs Spent
|
|
||||||
/*04*/ uint32 aa_value;
|
|
||||||
/*08*/ uint32 unknown08;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAExpUpdate_Struct {
|
struct AAExpUpdate_Struct {
|
||||||
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
|
||||||
@ -3933,7 +3935,7 @@ struct AltAdvStats_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerAA_Struct { // Is this still used?
|
struct PlayerAA_Struct { // Is this still used?
|
||||||
AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AATable_Struct {
|
struct AATable_Struct {
|
||||||
@ -3943,7 +3945,7 @@ struct AATable_Struct {
|
|||||||
/*12*/ int32 unknown012;
|
/*12*/ int32 unknown012;
|
||||||
/*16*/ int32 unknown016;
|
/*16*/ int32 unknown016;
|
||||||
/*20*/ int32 unknown020;
|
/*20*/ int32 unknown020;
|
||||||
/*24*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
|
/*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Weather_Struct {
|
struct Weather_Struct {
|
||||||
|
|||||||
@ -39,7 +39,8 @@ enum { //values for pTimerType
|
|||||||
pTimerDisciplineReuseStart = 14,
|
pTimerDisciplineReuseStart = 14,
|
||||||
pTimerDisciplineReuseEnd = 24,
|
pTimerDisciplineReuseEnd = 24,
|
||||||
pTimerCombatAbility = 25,
|
pTimerCombatAbility = 25,
|
||||||
pTimerBeggingPickPocket = 26,
|
pTimerCombatAbility2 = 26, // RoF2+ Tiger Claw is unlinked from other monk skills, generic in case other classes ever need it
|
||||||
|
pTimerBeggingPickPocket = 27,
|
||||||
|
|
||||||
pTimerLayHands = 87, //these IDs are used by client too
|
pTimerLayHands = 87, //these IDs are used by client too
|
||||||
pTimerHarmTouch = 89, //so dont change them
|
pTimerHarmTouch = 89, //so dont change them
|
||||||
|
|||||||
@ -47,6 +47,8 @@
|
|||||||
#define IKSAR 128
|
#define IKSAR 128
|
||||||
#define VAHSHIR 130
|
#define VAHSHIR 130
|
||||||
#define CONTROLLED_BOAT 141
|
#define CONTROLLED_BOAT 141
|
||||||
|
#define MINOR_ILL_OBJ 142
|
||||||
|
#define TREE 143
|
||||||
#define IKSAR_SKELETON 161
|
#define IKSAR_SKELETON 161
|
||||||
#define FROGLOK 330
|
#define FROGLOK 330
|
||||||
#define FROGLOK2 74 // Not sure why /who all reports race as 74 for frogloks
|
#define FROGLOK2 74 // Not sure why /who all reports race as 74 for frogloks
|
||||||
|
|||||||
1027
common/ruletypes.h
1027
common/ruletypes.h
File diff suppressed because it is too large
Load Diff
@ -55,3 +55,54 @@ bool EQEmu::IsSpecializedSkill(SkillUseTypes skill)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float EQEmu::GetSkillMeleePushForce(SkillUseTypes skill)
|
||||||
|
{
|
||||||
|
// This is the force/magnitude of the push from an attack of this skill type
|
||||||
|
// You can find these numbers in the clients skill struct
|
||||||
|
switch (skill) {
|
||||||
|
case Skill1HBlunt:
|
||||||
|
case Skill1HSlashing:
|
||||||
|
case SkillHandtoHand:
|
||||||
|
case SkillThrowing:
|
||||||
|
return 0.1f;
|
||||||
|
case Skill2HBlunt:
|
||||||
|
case Skill2HSlashing:
|
||||||
|
case SkillEagleStrike:
|
||||||
|
case SkillKick:
|
||||||
|
case SkillTigerClaw:
|
||||||
|
//case Skill2HPiercing:
|
||||||
|
return 0.2f;
|
||||||
|
case SkillArchery:
|
||||||
|
return 0.15f;
|
||||||
|
case SkillBackstab:
|
||||||
|
case SkillBash:
|
||||||
|
return 0.3f;
|
||||||
|
case SkillDragonPunch:
|
||||||
|
case SkillRoundKick:
|
||||||
|
return 0.25f;
|
||||||
|
case SkillFlyingKick:
|
||||||
|
return 0.4f;
|
||||||
|
case Skill1HPiercing:
|
||||||
|
case SkillFrenzy:
|
||||||
|
return 0.05f;
|
||||||
|
case SkillIntimidation:
|
||||||
|
return 2.5f;
|
||||||
|
default:
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EQEmu::IsBardInstrumentSkill(SkillUseTypes skill)
|
||||||
|
{
|
||||||
|
switch (skill) {
|
||||||
|
case SkillBrassInstruments:
|
||||||
|
case SkillSinging:
|
||||||
|
case SkillStringedInstruments:
|
||||||
|
case SkillWindInstruments:
|
||||||
|
case SkillPercussionInstruments:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -270,6 +270,8 @@ typedef enum {
|
|||||||
namespace EQEmu {
|
namespace EQEmu {
|
||||||
bool IsTradeskill(SkillUseTypes skill);
|
bool IsTradeskill(SkillUseTypes skill);
|
||||||
bool IsSpecializedSkill(SkillUseTypes skill);
|
bool IsSpecializedSkill(SkillUseTypes skill);
|
||||||
|
float GetSkillMeleePushForce(SkillUseTypes skill);
|
||||||
|
bool IsBardInstrumentSkill(SkillUseTypes skill);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -447,7 +447,7 @@ bool IsTGBCompatibleSpell(uint16 spell_id)
|
|||||||
|
|
||||||
bool IsBardSong(uint16 spell_id)
|
bool IsBardSong(uint16 spell_id)
|
||||||
{
|
{
|
||||||
if (IsValidSpell(spell_id) && spells[spell_id].classes[BARD - 1] < 255)
|
if (IsValidSpell(spell_id) && spells[spell_id].classes[BARD - 1] < 127 && !spells[spell_id].IsDisciplineBuff)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -151,7 +151,7 @@ typedef enum {
|
|||||||
} DmgShieldType;
|
} DmgShieldType;
|
||||||
|
|
||||||
//Spell Effect IDs
|
//Spell Effect IDs
|
||||||
// full listing: https://forums.station.sony.com/eq/index.php?threads/enumerated-spa-list.206288/
|
// https://forums.daybreakgames.com/eq/index.php?threads/enumerated-spa-list.206288/
|
||||||
// mirror: http://pastebin.com/MYeQqGwe
|
// mirror: http://pastebin.com/MYeQqGwe
|
||||||
#define SE_CurrentHP 0 // implemented - Heals and nukes, repeates every tic if in a buff
|
#define SE_CurrentHP 0 // implemented - Heals and nukes, repeates every tic if in a buff
|
||||||
#define SE_ArmorClass 1 // implemented
|
#define SE_ArmorClass 1 // implemented
|
||||||
@ -618,6 +618,7 @@ typedef enum {
|
|||||||
|
|
||||||
|
|
||||||
#define DF_Permanent 50
|
#define DF_Permanent 50
|
||||||
|
#define DF_Aura 51
|
||||||
|
|
||||||
// note this struct is historical, we don't actually need it to be
|
// note this struct is historical, we don't actually need it to be
|
||||||
// aligned to anything, but for maintaining it it is kept in the order that
|
// aligned to anything, but for maintaining it it is kept in the order that
|
||||||
|
|||||||
@ -83,4 +83,20 @@ typedef const char Const_char; //for perl XS
|
|||||||
#define DLLFUNC extern "C"
|
#define DLLFUNC extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// htonll and ntohll already defined on windows
|
||||||
|
#ifndef WIN32
|
||||||
|
# if defined(__linux__)
|
||||||
|
# include <endian.h>
|
||||||
|
# elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||||
|
# include <sys/endian.h>
|
||||||
|
# elif defined (__OpenBSD__)
|
||||||
|
# include <sys/types.h>
|
||||||
|
# define be16toh(x) betoh16(x)
|
||||||
|
# define be32toh(x) betoh32(x)
|
||||||
|
# define be64toh(x) betoh64(x)
|
||||||
|
# endif
|
||||||
|
# define htonll(x) htobe64(x)
|
||||||
|
# define ntohll(x) be64toh(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9077
|
#define CURRENT_BINARY_DATABASE_VERSION 9083
|
||||||
#define COMPILE_DATE __DATE__
|
#define COMPILE_DATE __DATE__
|
||||||
#define COMPILE_TIME __TIME__
|
#define COMPILE_TIME __TIME__
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
|||||||
@ -113,8 +113,8 @@ bool DatabaseMySQL::GetWorldRegistration(string long_name, string short_name, un
|
|||||||
length = mysql_real_escape_string(db, escaped_short_name, short_name.substr(0, 100).c_str(), short_name.substr(0, 100).length());
|
length = mysql_real_escape_string(db, escaped_short_name, short_name.substr(0, 100).c_str(), short_name.substr(0, 100).length());
|
||||||
escaped_short_name[length+1] = 0;
|
escaped_short_name[length+1] = 0;
|
||||||
stringstream query(stringstream::in | stringstream::out);
|
stringstream query(stringstream::in | stringstream::out);
|
||||||
query << "SELECT WSR.ServerID, WSR.ServerTagDescription, WSR.ServerTrusted, SLT.ServerListTypeID, ";
|
query << "SELECT ifnull(WSR.ServerID,999999) AS ServerID, WSR.ServerTagDescription, ifnull(WSR.ServerTrusted,0) AS ServerTrusted, ifnull(SLT.ServerListTypeID,3) AS ServerListTypeID, ";
|
||||||
query << "SLT.ServerListTypeDescription, WSR.ServerAdminID FROM " << server.options.GetWorldRegistrationTable();
|
query << "SLT.ServerListTypeDescription, ifnull(WSR.ServerAdminID,0) AS ServerAdminID FROM " << server.options.GetWorldRegistrationTable();
|
||||||
query << " AS WSR JOIN " << server.options.GetWorldServerTypeTable() << " AS SLT ON WSR.ServerListTypeID = SLT.ServerListTypeID";
|
query << " AS WSR JOIN " << server.options.GetWorldServerTypeTable() << " AS SLT ON WSR.ServerListTypeID = SLT.ServerListTypeID";
|
||||||
query << " WHERE WSR.ServerShortName = '";
|
query << " WHERE WSR.ServerShortName = '";
|
||||||
query << escaped_short_name;
|
query << escaped_short_name;
|
||||||
@ -254,7 +254,7 @@ bool DatabaseMySQL::CreateWorldRegistration(string long_name, string short_name,
|
|||||||
length = mysql_real_escape_string(db, escaped_short_name, short_name.substr(0, 100).c_str(), short_name.substr(0, 100).length());
|
length = mysql_real_escape_string(db, escaped_short_name, short_name.substr(0, 100).c_str(), short_name.substr(0, 100).length());
|
||||||
escaped_short_name[length+1] = 0;
|
escaped_short_name[length+1] = 0;
|
||||||
stringstream query(stringstream::in | stringstream::out);
|
stringstream query(stringstream::in | stringstream::out);
|
||||||
query << "SELECT max(ServerID) FROM " << server.options.GetWorldRegistrationTable();
|
query << "SELECT ifnull(max(ServerID),0) FROM " << server.options.GetWorldRegistrationTable();
|
||||||
|
|
||||||
if(mysql_query(db, query.str().c_str()) != 0)
|
if(mysql_query(db, query.str().c_str()) != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -194,6 +194,7 @@ OP_Consent=0x400e
|
|||||||
OP_ConsentDeny=0x34c1
|
OP_ConsentDeny=0x34c1
|
||||||
OP_AutoFire=0x314e
|
OP_AutoFire=0x314e
|
||||||
OP_PetCommands=0x0093
|
OP_PetCommands=0x0093
|
||||||
|
OP_PetHoTT=0x0df4
|
||||||
OP_DeleteSpell=0x305c
|
OP_DeleteSpell=0x305c
|
||||||
OP_Surname=0x1a87
|
OP_Surname=0x1a87
|
||||||
OP_ClearSurname=0x17b6
|
OP_ClearSurname=0x17b6
|
||||||
@ -269,8 +270,8 @@ OP_RequestDuel=0x1ea9
|
|||||||
OP_MobRename=0x5040
|
OP_MobRename=0x5040
|
||||||
OP_AugmentItem=0x1627 # Was 0x37cb
|
OP_AugmentItem=0x1627 # Was 0x37cb
|
||||||
OP_WeaponEquip1=0x35c3
|
OP_WeaponEquip1=0x35c3
|
||||||
OP_WeaponEquip2=0x012f # Was 0x6022
|
OP_PlayerStateAdd=0x012f # Was 0x6022
|
||||||
OP_WeaponUnequip2=0x1076 # Was 0x0110
|
OP_PlayerStateRemove=0x1076 # Was 0x0110
|
||||||
OP_ApplyPoison=0x1499
|
OP_ApplyPoison=0x1499
|
||||||
OP_Save=0x2e6f
|
OP_Save=0x2e6f
|
||||||
OP_TestBuff=0x046e # Was 0x3772
|
OP_TestBuff=0x046e # Was 0x3772
|
||||||
|
|||||||
@ -193,6 +193,7 @@ OP_Consent=0x1fd1
|
|||||||
OP_ConsentDeny=0x7a45
|
OP_ConsentDeny=0x7a45
|
||||||
OP_AutoFire=0x241e
|
OP_AutoFire=0x241e
|
||||||
OP_PetCommands=0x0159
|
OP_PetCommands=0x0159
|
||||||
|
OP_PetHoTT=0x794a
|
||||||
OP_DeleteSpell=0x3358
|
OP_DeleteSpell=0x3358
|
||||||
OP_Surname=0x0423
|
OP_Surname=0x0423
|
||||||
OP_ClearSurname=0x3fb0
|
OP_ClearSurname=0x3fb0
|
||||||
@ -268,8 +269,8 @@ OP_RequestDuel=0x3af1
|
|||||||
OP_MobRename=0x2c57
|
OP_MobRename=0x2c57
|
||||||
OP_AugmentItem=0x661b
|
OP_AugmentItem=0x661b
|
||||||
OP_WeaponEquip1=0x34a7
|
OP_WeaponEquip1=0x34a7
|
||||||
OP_WeaponEquip2=0x559a
|
OP_PlayerStateAdd=0x559a
|
||||||
OP_WeaponUnequip2=0x2d25
|
OP_PlayerStateRemove=0x2d25
|
||||||
OP_ApplyPoison=0x31e6
|
OP_ApplyPoison=0x31e6
|
||||||
OP_Save=0x4a39
|
OP_Save=0x4a39
|
||||||
OP_TestBuff=0x7cb8
|
OP_TestBuff=0x7cb8
|
||||||
@ -294,8 +295,8 @@ OP_MarkNPC=0x1fb5
|
|||||||
OP_MarkRaidNPC=0x5a58 #unimplemented
|
OP_MarkRaidNPC=0x5a58 #unimplemented
|
||||||
OP_ClearNPCMarks=0x2003
|
OP_ClearNPCMarks=0x2003
|
||||||
OP_ClearRaidNPCMarks=0x20d3 #unimplemented
|
OP_ClearRaidNPCMarks=0x20d3 #unimplemented
|
||||||
OP_DelegateAbility=0x4c9d
|
OP_DelegateAbility=0x76b8
|
||||||
OP_SetGroupTarget=0x026
|
OP_SetGroupTarget=0x2814
|
||||||
OP_Charm=0x5d92
|
OP_Charm=0x5d92
|
||||||
OP_Stun=0x36a4
|
OP_Stun=0x36a4
|
||||||
OP_SendFindableNPCs=0x4613
|
OP_SendFindableNPCs=0x4613
|
||||||
|
|||||||
@ -266,8 +266,8 @@ OP_RequestDuel=0x79e0 # C
|
|||||||
OP_MobRename=0x0a1d # C
|
OP_MobRename=0x0a1d # C
|
||||||
OP_AugmentItem=0x0370 # C
|
OP_AugmentItem=0x0370 # C
|
||||||
OP_WeaponEquip1=0x719e # C
|
OP_WeaponEquip1=0x719e # C
|
||||||
OP_WeaponEquip2=0x7b6e # C
|
OP_PlayerStateAdd=0x7b6e # C
|
||||||
OP_WeaponUnequip2=0x19a8 # C
|
OP_PlayerStateRemove=0x19a8 # C
|
||||||
OP_ApplyPoison=0x405b # C
|
OP_ApplyPoison=0x405b # C
|
||||||
OP_Save=0x5c85 # C
|
OP_Save=0x5c85 # C
|
||||||
OP_TestBuff=0x5fc7 # C
|
OP_TestBuff=0x5fc7 # C
|
||||||
|
|||||||
@ -262,8 +262,8 @@ OP_RequestDuel=0x3A2B #Xinu 02/22/09
|
|||||||
OP_MobRename=0x6be5 #Trevius 01/16/09
|
OP_MobRename=0x6be5 #Trevius 01/16/09
|
||||||
OP_AugmentItem=0x172A #Trevius 03/14/09
|
OP_AugmentItem=0x172A #Trevius 03/14/09
|
||||||
OP_WeaponEquip1=0x7260 #Trevius 02/27/09
|
OP_WeaponEquip1=0x7260 #Trevius 02/27/09
|
||||||
OP_WeaponEquip2=0x5C2F #Trevius 02/27/09
|
OP_PlayerStateAdd=0x5C2F #Trevius 02/27/09
|
||||||
OP_WeaponUnequip2=0x6213 #Trevius 02/27/09
|
OP_PlayerStateRemove=0x6213 #Trevius 02/27/09
|
||||||
OP_ApplyPoison=0x4543 #WildcardX 03/6/09
|
OP_ApplyPoison=0x4543 #WildcardX 03/6/09
|
||||||
OP_Save=0x72F2 #Trevius 03/15/09
|
OP_Save=0x72F2 #Trevius 03/15/09
|
||||||
OP_TestBuff=0x07BF #/testbuff
|
OP_TestBuff=0x07BF #/testbuff
|
||||||
|
|||||||
@ -534,8 +534,8 @@ OP_PVPLeaderBoardDetailsRequest=0x06a2
|
|||||||
OP_PVPLeaderBoardDetailsReply=0x246a
|
OP_PVPLeaderBoardDetailsReply=0x246a
|
||||||
OP_PickLockSuccess=0x40E7
|
OP_PickLockSuccess=0x40E7
|
||||||
OP_WeaponEquip1=0x6c5e
|
OP_WeaponEquip1=0x6c5e
|
||||||
OP_WeaponEquip2=0x63da
|
OP_PlayerStateAdd=0x63da
|
||||||
OP_WeaponUnequip2=0x381d
|
OP_PlayerStateRemove=0x381d
|
||||||
OP_VoiceMacroIn=0x2866 # Client to Server
|
OP_VoiceMacroIn=0x2866 # Client to Server
|
||||||
OP_VoiceMacroOut=0x2ec6 # Server to Client
|
OP_VoiceMacroOut=0x2ec6 # Server to Client
|
||||||
OP_CameraEffect=0x0937 # Correct
|
OP_CameraEffect=0x0937 # Correct
|
||||||
|
|||||||
@ -197,6 +197,7 @@ OP_Consent=0x6bb9 # C
|
|||||||
OP_ConsentDeny=0x4cd1 # C
|
OP_ConsentDeny=0x4cd1 # C
|
||||||
OP_AutoFire=0x5db5 # C
|
OP_AutoFire=0x5db5 # C
|
||||||
OP_PetCommands=0x7706 # C
|
OP_PetCommands=0x7706 # C
|
||||||
|
OP_PetHoTT=0x2528
|
||||||
OP_DeleteSpell=0x0698 # C
|
OP_DeleteSpell=0x0698 # C
|
||||||
OP_Surname=0x44ae # C
|
OP_Surname=0x44ae # C
|
||||||
OP_ClearSurname=0x6705 # C
|
OP_ClearSurname=0x6705 # C
|
||||||
@ -272,8 +273,8 @@ OP_RequestDuel=0x6cfe # C
|
|||||||
OP_MobRename=0x0507 # C
|
OP_MobRename=0x0507 # C
|
||||||
OP_AugmentItem=0x7c87 # C
|
OP_AugmentItem=0x7c87 # C
|
||||||
OP_WeaponEquip1=0x4572 # C
|
OP_WeaponEquip1=0x4572 # C
|
||||||
OP_WeaponEquip2=0x399b # C
|
OP_PlayerStateAdd=0x399b # C
|
||||||
OP_WeaponUnequip2=0x416b # C
|
OP_PlayerStateRemove=0x416b # C
|
||||||
OP_ApplyPoison=0x5cd3 # C
|
OP_ApplyPoison=0x5cd3 # C
|
||||||
OP_Save=0x6618 # C
|
OP_Save=0x6618 # C
|
||||||
OP_TestBuff=0x3415 # C
|
OP_TestBuff=0x3415 # C
|
||||||
|
|||||||
@ -331,6 +331,12 @@
|
|||||||
9075|2015_02_02_logsys_packet_logs_with_dump.sql|SELECT * FROM `logsys_categories` WHERE `log_category_description` LIKE 'Packet: Server -> Client With Dump'|empty|
|
9075|2015_02_02_logsys_packet_logs_with_dump.sql|SELECT * FROM `logsys_categories` WHERE `log_category_description` LIKE 'Packet: Server -> Client With Dump'|empty|
|
||||||
9076|2015_02_04_average_coin.sql|SHOW COLUMNS FROM `loottable` WHERE Field = 'avgcoin'|contains|smallint
|
9076|2015_02_04_average_coin.sql|SHOW COLUMNS FROM `loottable` WHERE Field = 'avgcoin'|contains|smallint
|
||||||
9077|2015_02_12_zone_gravity.sql|SHOW COLUMNS FROM `zone` LIKE 'gravity'|empty|
|
9077|2015_02_12_zone_gravity.sql|SHOW COLUMNS FROM `zone` LIKE 'gravity'|empty|
|
||||||
|
9078|2015_05_20_BuffInstrumentMod.sql|SHOW COLUMNS FROM `character_buffs` LIKE 'instrument_mod'|empty|
|
||||||
|
9079|2015_05_23_BuffDurations.sql|SHOW COLUMNS FROM `character_buffs` LIKE 'ticsremaining'|contains|unsigned|
|
||||||
|
9080|2015_05_23_PetBuffInstrumentMod.sql|SHOW COLUMNS FROM `character_pet_buffs` LIKE 'instrument_mod'|empty|
|
||||||
|
9081|2015_05_23_dbstr_us.sql|SHOW TABLES LIKE 'db_str'|empty|
|
||||||
|
9082|2015_05_25_npc_types_texture_fields.sql|SHOW COLUMNS FROM `npc_types` LIKE 'armtexture'|empty|
|
||||||
|
9083|2015_06_07_aa_update.sql|SHOW COLUMNS FROM `character_alternate_abilities` LIKE 'charges'|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
|
||||||
|
|||||||
2
utils/sql/git/optional/2015_04_30_MeleePush.sql
Normal file
2
utils/sql/git/optional/2015_04_30_MeleePush.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Combat:MeleePush', 'true', 'Turns on Melee Push.');
|
||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Combat:MeleePushChance', '50', 'Chance that an NPC can be pushed from melee.');
|
||||||
1
utils/sql/git/optional/2015_05_18_FishingLineLength.sql
Normal file
1
utils/sql/git/optional/2015_05_18_FishingLineLength.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
UPDATE rule_values SET rule_value=100 WHERE rule_name='Watermap:FishingLineLength';
|
||||||
@ -0,0 +1 @@
|
|||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AlwaysSendTargetBuffs', 'false', 'Allows the server to send the targets buffs ignoring the LAA.');
|
||||||
@ -0,0 +1 @@
|
|||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Inventory:TransformSummonedBags', 'true', 'Transforms summoned bags into disenchanted ones instead of deleting.');
|
||||||
1
utils/sql/git/required/2015_05_20_BuffInstrumentMod.sql
Normal file
1
utils/sql/git/required/2015_05_20_BuffInstrumentMod.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `character_buffs` ADD COLUMN `instrument_mod` int(10) DEFAULT 10 NOT NULL;
|
||||||
2
utils/sql/git/required/2015_05_23_BuffDurations.sql
Normal file
2
utils/sql/git/required/2015_05_23_BuffDurations.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE `character_buffs` CHANGE COLUMN `ticsremaining` `ticsremaining` INT(11) SIGNED NOT NULL;
|
||||||
|
ALTER TABLE `merc_buffs` CHANGE COLUMN `TicsRemaining` `TicsRemaining` INT(11) SIGNED NOT NULL DEFAULT 0;
|
||||||
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `character_pet_buffs` ADD COLUMN `instrument_mod` tinyint UNSIGNED DEFAULT 10 NOT NULL;
|
||||||
6
utils/sql/git/required/2015_05_23_dbstr_us.sql
Normal file
6
utils/sql/git/required/2015_05_23_dbstr_us.sql
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
CREATE TABLE `db_str` (
|
||||||
|
`id` INT(10) NOT NULL,
|
||||||
|
`type` INT(10) NOT NULL,
|
||||||
|
`value` TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (`id`, `type`)
|
||||||
|
);
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
ALTER TABLE npc_types
|
||||||
|
ADD COLUMN `armtexture` tinyint(2) NOT NULL DEFAULT '0' AFTER `raid_target`,
|
||||||
|
ADD COLUMN `bracertexture` tinyint(2) NOT NULL DEFAULT '0' AFTER `armtexture`,
|
||||||
|
ADD COLUMN `handtexture` tinyint(2) NOT NULL DEFAULT '0' AFTER `bracertexture`,
|
||||||
|
ADD COLUMN `legtexture` tinyint(2) NOT NULL DEFAULT '0' AFTER `handtexture`,
|
||||||
|
ADD COLUMN `feettexture` tinyint(2) NOT NULL DEFAULT '0' AFTER `legtexture`;
|
||||||
1
utils/sql/git/required/2015_06_07_aa_update.sql
Normal file
1
utils/sql/git/required/2015_06_07_aa_update.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE character_alternate_abilities ADD COLUMN charges SMALLINT(11) UNSIGNED NOT NULL DEFAULT 0;
|
||||||
@ -105,6 +105,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
|||||||
memset(&pp, 0, sizeof(PlayerProfile_Struct));
|
memset(&pp, 0, sizeof(PlayerProfile_Struct));
|
||||||
|
|
||||||
/* Fill CharacterSelectEntry_Struct */
|
/* Fill CharacterSelectEntry_Struct */
|
||||||
|
memset(cse->Name, 0, sizeof(cse->Name));
|
||||||
strcpy(cse->Name, row[1]);
|
strcpy(cse->Name, row[1]);
|
||||||
cse->Class = (uint8)atoi(row[4]);
|
cse->Class = (uint8)atoi(row[4]);
|
||||||
cse->Race = (uint32)atoi(row[3]);
|
cse->Race = (uint32)atoi(row[3]);
|
||||||
|
|||||||
@ -190,7 +190,7 @@ bool ZoneServer::Process() {
|
|||||||
Log.Out(Logs::Detail, Logs::World_Server,"Zone authorization failed.");
|
Log.Out(Logs::Detail, Logs::World_Server,"Zone authorization failed.");
|
||||||
auto pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
auto pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||||
SendPacket(pack);
|
SendPacket(pack);
|
||||||
delete pack;
|
safe_delete(pack);
|
||||||
Disconnect();
|
Disconnect();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -201,7 +201,7 @@ bool ZoneServer::Process() {
|
|||||||
Log.Out(Logs::Detail, Logs::World_Server,"Zone authorization failed.");
|
Log.Out(Logs::Detail, Logs::World_Server,"Zone authorization failed.");
|
||||||
auto pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
auto pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||||
SendPacket(pack);
|
SendPacket(pack);
|
||||||
delete pack;
|
safe_delete(pack);
|
||||||
Disconnect();
|
Disconnect();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -779,7 +779,7 @@ bool ZoneServer::Process() {
|
|||||||
whom->wrace = whoall->wrace;
|
whom->wrace = whoall->wrace;
|
||||||
strcpy(whom->whom,whoall->whom);
|
strcpy(whom->whom,whoall->whom);
|
||||||
client_list.SendWhoAll(whoall->fromid,whoall->from, whoall->admin, whom, this);
|
client_list.SendWhoAll(whoall->fromid,whoall->from, whoall->admin, whom, this);
|
||||||
delete whom;
|
safe_delete(whom);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_RequestOnlineGuildMembers: {
|
case ServerOP_RequestOnlineGuildMembers: {
|
||||||
@ -958,13 +958,13 @@ bool ZoneServer::Process() {
|
|||||||
tod->start_eqtime=zoneserver_list.worldclock.getStartEQTime();
|
tod->start_eqtime=zoneserver_list.worldclock.getStartEQTime();
|
||||||
tod->start_realtime=zoneserver_list.worldclock.getStartRealTime();
|
tod->start_realtime=zoneserver_list.worldclock.getStartRealTime();
|
||||||
SendPacket(pack);
|
SendPacket(pack);
|
||||||
delete pack;
|
safe_delete(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_SetWorldTime: {
|
case ServerOP_SetWorldTime: {
|
||||||
Log.Out(Logs::Detail, Logs::World_Server,"Received SetWorldTime");
|
Log.Out(Logs::Detail, Logs::World_Server,"Received SetWorldTime");
|
||||||
eqTimeOfDay* newtime = (eqTimeOfDay*) pack->pBuffer;
|
eqTimeOfDay* newtime = (eqTimeOfDay*) pack->pBuffer;
|
||||||
zoneserver_list.worldclock.setEQTimeOfDay(newtime->start_eqtime, newtime->start_realtime);
|
zoneserver_list.worldclock.SetCurrentEQTimeOfDay(newtime->start_eqtime, newtime->start_realtime);
|
||||||
Log.Out(Logs::Detail, Logs::World_Server,"New time = %d-%d-%d %d:%d (%d)\n", newtime->start_eqtime.year, newtime->start_eqtime.month, (int)newtime->start_eqtime.day, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.minute, (int)newtime->start_realtime);
|
Log.Out(Logs::Detail, Logs::World_Server,"New time = %d-%d-%d %d:%d (%d)\n", newtime->start_eqtime.year, newtime->start_eqtime.month, (int)newtime->start_eqtime.day, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.minute, (int)newtime->start_realtime);
|
||||||
zoneserver_list.worldclock.saveFile(WorldConfig::get()->EQTimeFile.c_str());
|
zoneserver_list.worldclock.saveFile(WorldConfig::get()->EQTimeFile.c_str());
|
||||||
zoneserver_list.SendTimeSync();
|
zoneserver_list.SendTimeSync();
|
||||||
@ -1059,8 +1059,7 @@ bool ZoneServer::Process() {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete pack;
|
auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
||||||
pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
|
||||||
ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer;
|
ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer;
|
||||||
strcpy(scs->grantname, s->grantname);
|
strcpy(scs->grantname, s->grantname);
|
||||||
strcpy(scs->ownername, s->ownername);
|
strcpy(scs->ownername, s->ownername);
|
||||||
@ -1076,6 +1075,7 @@ bool ZoneServer::Process() {
|
|||||||
else {
|
else {
|
||||||
Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for instance id %u in zoneserver list for ServerOP_Consent_Response operation.", s->instance_id);
|
Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for instance id %u in zoneserver list for ServerOP_Consent_Response operation.", s->instance_id);
|
||||||
}
|
}
|
||||||
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1091,8 +1091,7 @@ bool ZoneServer::Process() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// send target not found back to requester
|
// send target not found back to requester
|
||||||
delete pack;
|
auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
||||||
pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
|
||||||
ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer;
|
ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer;
|
||||||
strcpy(scs->grantname, s->grantname);
|
strcpy(scs->grantname, s->grantname);
|
||||||
strcpy(scs->ownername, s->ownername);
|
strcpy(scs->ownername, s->ownername);
|
||||||
@ -1107,13 +1106,13 @@ bool ZoneServer::Process() {
|
|||||||
else {
|
else {
|
||||||
Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id);
|
Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id);
|
||||||
}
|
}
|
||||||
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// send target not found back to requester
|
// send target not found back to requester
|
||||||
delete pack;
|
auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
||||||
pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct));
|
|
||||||
ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer;
|
ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer;
|
||||||
strcpy(scs->grantname, s->grantname);
|
strcpy(scs->grantname, s->grantname);
|
||||||
strcpy(scs->ownername, s->ownername);
|
strcpy(scs->ownername, s->ownername);
|
||||||
@ -1128,6 +1127,7 @@ bool ZoneServer::Process() {
|
|||||||
else {
|
else {
|
||||||
Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id);
|
Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id);
|
||||||
}
|
}
|
||||||
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1313,15 +1313,17 @@ bool ZoneServer::Process() {
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Log.Out(Logs::Detail, Logs::World_Server,"Unknown ServerOPcode from zone 0x%04x, size %d",pack->opcode,pack->size);
|
Log.Out(Logs::Detail, Logs::World_Server, "Unknown ServerOPcode from zone 0x%04x, size %d", pack->opcode, pack->size);
|
||||||
DumpPacket(pack->pBuffer, pack->size);
|
DumpPacket(pack->pBuffer, pack->size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pack)
|
if (pack) {
|
||||||
delete pack;
|
safe_delete(pack);
|
||||||
else
|
}
|
||||||
Log.Out(Logs::Detail, Logs::World_Server, "Zoneserver process tried to delete pack when pack does not exist.");
|
else {
|
||||||
|
Log.Out(Logs::Detail, Logs::World_Server, "Zoneserver process attempted to delete pack when pack does not exist.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ SET(zone_sources
|
|||||||
embparser_api.cpp
|
embparser_api.cpp
|
||||||
embperl.cpp
|
embperl.cpp
|
||||||
embxs.cpp
|
embxs.cpp
|
||||||
|
encounter.cpp
|
||||||
entity.cpp
|
entity.cpp
|
||||||
exp.cpp
|
exp.cpp
|
||||||
fearpath.cpp
|
fearpath.cpp
|
||||||
@ -35,6 +36,7 @@ SET(zone_sources
|
|||||||
lua_corpse.cpp
|
lua_corpse.cpp
|
||||||
lua_client.cpp
|
lua_client.cpp
|
||||||
lua_door.cpp
|
lua_door.cpp
|
||||||
|
lua_encounter.cpp
|
||||||
lua_entity.cpp
|
lua_entity.cpp
|
||||||
lua_entity_list.cpp
|
lua_entity_list.cpp
|
||||||
lua_general.cpp
|
lua_general.cpp
|
||||||
@ -137,6 +139,7 @@ SET(zone_headers
|
|||||||
embparser.h
|
embparser.h
|
||||||
embperl.h
|
embperl.h
|
||||||
embxs.h
|
embxs.h
|
||||||
|
encounter.h
|
||||||
entity.h
|
entity.h
|
||||||
errmsg.h
|
errmsg.h
|
||||||
event_codes.h
|
event_codes.h
|
||||||
@ -148,6 +151,7 @@ SET(zone_headers
|
|||||||
lua_bit.h
|
lua_bit.h
|
||||||
lua_client.h
|
lua_client.h
|
||||||
lua_corpse.h
|
lua_corpse.h
|
||||||
|
lua_encounter.h
|
||||||
lua_entity.h
|
lua_entity.h
|
||||||
lua_entity_list.h
|
lua_entity_list.h
|
||||||
lua_general.h
|
lua_general.h
|
||||||
|
|||||||
35
zone/aa.cpp
35
zone/aa.cpp
@ -1104,9 +1104,9 @@ void Client::SendAATable() {
|
|||||||
|
|
||||||
uint32 i;
|
uint32 i;
|
||||||
for(i=0;i < MAX_PP_AA_ARRAY;i++){
|
for(i=0;i < MAX_PP_AA_ARRAY;i++){
|
||||||
aa2->aa_list[i].aa_skill = aa[i]->AA;
|
aa2->aa_list[i].AA = aa[i]->value ? aa[i]->AA : 0; // bit of a hack to prevent expendables punching a hole
|
||||||
aa2->aa_list[i].aa_value = aa[i]->value;
|
aa2->aa_list[i].value = aa[i]->value;
|
||||||
aa2->aa_list[i].unknown08 = 0;
|
aa2->aa_list[i].charges = aa[i]->charges;
|
||||||
}
|
}
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
@ -1309,11 +1309,9 @@ void Client::SendAA(uint32 id, int seq) {
|
|||||||
SendAA_Struct* saa_next = nullptr;
|
SendAA_Struct* saa_next = nullptr;
|
||||||
saa_next = zone->FindAA(saa->sof_next_id);
|
saa_next = zone->FindAA(saa->sof_next_id);
|
||||||
|
|
||||||
// hard-coding values like this is dangerous and makes adding/updating clients a nightmare...
|
// this check should work as long as we continue to just add the clients and just increase
|
||||||
if (saa_next &&
|
// each number ....
|
||||||
(((GetClientVersionBit() == 4) && (saa_next->clientver > 4))
|
if (saa_next && static_cast<int>(GetClientVersion()) < saa_next->clientver - 1) {
|
||||||
|| ((GetClientVersionBit() == 8) && (saa_next->clientver > 5))
|
|
||||||
|| ((GetClientVersionBit() == 16) && (saa_next->clientver > 6)))){
|
|
||||||
saa->next_id=0xFFFFFFFF;
|
saa->next_id=0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1397,26 +1395,33 @@ uint32 Client::GetAA(uint32 aa_id) const {
|
|||||||
bool Client::SetAA(uint32 aa_id, uint32 new_value) {
|
bool Client::SetAA(uint32 aa_id, uint32 new_value) {
|
||||||
aa_points[aa_id] = new_value;
|
aa_points[aa_id] = new_value;
|
||||||
uint32 cur;
|
uint32 cur;
|
||||||
|
auto sendaa = zone->FindAA(aa_id); // this is a bit hacky
|
||||||
|
uint32 charges = sendaa->special_category == 7 && new_value ? 1 : 0;
|
||||||
for(cur=0;cur < MAX_PP_AA_ARRAY;cur++){
|
for(cur=0;cur < MAX_PP_AA_ARRAY;cur++){
|
||||||
if((aa[cur]->value > 1) && ((aa[cur]->AA - aa[cur]->value + 1)== aa_id)){
|
if((aa[cur]->value > 1) && ((aa[cur]->AA - aa[cur]->value + 1)== aa_id)){
|
||||||
aa[cur]->value = new_value;
|
aa[cur]->value = new_value;
|
||||||
if(new_value > 0)
|
if(new_value > 0)
|
||||||
aa[cur]->AA++;
|
aa[cur]->AA++;
|
||||||
else
|
aa[cur]->charges = charges;
|
||||||
aa[cur]->AA = 0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if((aa[cur]->value == 1) && (aa[cur]->AA == aa_id)){
|
else if((aa[cur]->value == 1) && (aa[cur]->AA == aa_id)){
|
||||||
aa[cur]->value = new_value;
|
aa[cur]->value = new_value;
|
||||||
if(new_value > 0)
|
if(new_value > 0)
|
||||||
aa[cur]->AA++;
|
aa[cur]->AA++;
|
||||||
else
|
aa[cur]->charges = charges;
|
||||||
aa[cur]->AA = 0;
|
return true;
|
||||||
|
}
|
||||||
|
// hack to prevent expendable exploit, we should probably be reshuffling the array to fix the hole
|
||||||
|
else if(aa[cur]->value == 0 && new_value == 1 && aa[cur]->AA == aa_id) {
|
||||||
|
aa[cur]->value = new_value;
|
||||||
|
aa[cur]->charges = charges;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(aa[cur]->AA==0){ //end of list
|
else if(aa[cur]->AA==0){ //end of list
|
||||||
aa[cur]->AA = aa_id;
|
aa[cur]->AA = aa_id;
|
||||||
aa[cur]->value = new_value;
|
aa[cur]->value = new_value;
|
||||||
|
aa[cur]->charges = charges;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1487,8 +1492,10 @@ void Client::ResetAA(){
|
|||||||
for (i=0; i < MAX_PP_AA_ARRAY; i++) {
|
for (i=0; i < MAX_PP_AA_ARRAY; i++) {
|
||||||
aa[i]->AA = 0;
|
aa[i]->AA = 0;
|
||||||
aa[i]->value = 0;
|
aa[i]->value = 0;
|
||||||
m_pp.aa_array[MAX_PP_AA_ARRAY].AA = 0;
|
aa[i]->charges = 0;
|
||||||
m_pp.aa_array[MAX_PP_AA_ARRAY].value = 0;
|
m_pp.aa_array[i].AA = 0;
|
||||||
|
m_pp.aa_array[i].value = 0;
|
||||||
|
m_pp.aa_array[i].charges= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<uint32,uint8>::iterator itr;
|
std::map<uint32,uint8>::iterator itr;
|
||||||
|
|||||||
@ -982,14 +982,24 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if((GetClass() == MONK || GetClass() == BEASTLORD) && GetLevel() >= 30){
|
bool MagicGloves=false;
|
||||||
dmg = GetMonkHandToHandDamage();
|
if (IsClient()) {
|
||||||
if (hate) *hate += dmg;
|
ItemInst *gloves=CastToClient()->GetInv().GetItem(MainHands);
|
||||||
|
if (gloves != nullptr) {
|
||||||
|
MagicGloves = gloves->GetItem()->Magic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((GetClass() == MONK || GetClass() == BEASTLORD)) {
|
||||||
|
if(MagicGloves || GetLevel() >= 30){
|
||||||
|
dmg = GetMonkHandToHandDamage();
|
||||||
|
if (hate) *hate += dmg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(GetOwner() && GetLevel() >= RuleI(Combat, PetAttackMagicLevel)){ //pets wouldn't actually use this but...
|
else if(GetOwner() && GetLevel() >= RuleI(Combat, PetAttackMagicLevel)){ //pets wouldn't actually use this but...
|
||||||
dmg = 1; //it gives us an idea if we can hit
|
dmg = 1; //it gives us an idea if we can hit
|
||||||
}
|
}
|
||||||
else if(GetSpecialAbility(SPECATK_MAGICAL)){
|
else if(MagicGloves || GetSpecialAbility(SPECATK_MAGICAL)){
|
||||||
dmg = 1;
|
dmg = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2134,6 +2144,10 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
if(give_exp && give_exp->IsClient())
|
if(give_exp && give_exp->IsClient())
|
||||||
give_exp_client = give_exp->CastToClient();
|
give_exp_client = give_exp->CastToClient();
|
||||||
|
|
||||||
|
//do faction hits even if we are a merchant, so long as a player killed us
|
||||||
|
if (give_exp_client && !RuleB(NPC, EnableMeritBasedFaction))
|
||||||
|
hate_list.DoFactionHits(GetNPCFactionID());
|
||||||
|
|
||||||
bool IsLdonTreasure = (this->GetClass() == LDON_TREASURE);
|
bool IsLdonTreasure = (this->GetClass() == LDON_TREASURE);
|
||||||
if (give_exp_client && !IsCorpse())
|
if (give_exp_client && !IsCorpse())
|
||||||
{
|
{
|
||||||
@ -2277,10 +2291,6 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//do faction hits even if we are a merchant, so long as a player killed us
|
|
||||||
if(give_exp_client && !RuleB(NPC, EnableMeritBasedFaction))
|
|
||||||
hate_list.DoFactionHits(GetNPCFactionID());
|
|
||||||
|
|
||||||
if (!HasOwner() && !IsMerc() && class_ != MERCHANT && class_ != ADVENTUREMERCHANT && !GetSwarmInfo()
|
if (!HasOwner() && !IsMerc() && class_ != MERCHANT && class_ != ADVENTUREMERCHANT && !GetSwarmInfo()
|
||||||
&& MerchantType == 0 && killer && (killer->IsClient() || (killer->HasOwner() && killer->GetUltimateOwner()->IsClient()) ||
|
&& MerchantType == 0 && killer && (killer->IsClient() || (killer->HasOwner() && killer->GetUltimateOwner()->IsClient()) ||
|
||||||
(killer->IsNPC() && killer->CastToNPC()->GetSwarmInfo() && killer->CastToNPC()->GetSwarmInfo()->GetOwner() && killer->CastToNPC()->GetSwarmInfo()->GetOwner()->IsClient())))
|
(killer->IsNPC() && killer->CastToNPC()->GetSwarmInfo() && killer->CastToNPC()->GetSwarmInfo()->GetOwner() && killer->CastToNPC()->GetSwarmInfo()->GetOwner()->IsClient())))
|
||||||
@ -3683,7 +3693,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
|||||||
|
|
||||||
//send an HP update if we are hurt
|
//send an HP update if we are hurt
|
||||||
if(GetHP() < GetMaxHP())
|
if(GetHP() < GetMaxHP())
|
||||||
SendHPUpdate();
|
SendHPUpdate(!iBuffTic); // the OP_Damage actually updates the client in these cases, so we skill them
|
||||||
} //end `if damage was done`
|
} //end `if damage was done`
|
||||||
|
|
||||||
//send damage packet...
|
//send damage packet...
|
||||||
@ -3700,6 +3710,23 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
|||||||
a->type = SkillDamageTypes[skill_used]; // was 0x1c
|
a->type = SkillDamageTypes[skill_used]; // was 0x1c
|
||||||
a->damage = damage;
|
a->damage = damage;
|
||||||
a->spellid = spell_id;
|
a->spellid = spell_id;
|
||||||
|
a->meleepush_xy = attacker->GetHeading() * 2.0f;
|
||||||
|
if (RuleB(Combat, MeleePush) && damage > 0 && !IsRooted() &&
|
||||||
|
(IsClient() || zone->random.Roll(RuleI(Combat, MeleePushChance)))) {
|
||||||
|
a->force = EQEmu::GetSkillMeleePushForce(skill_used);
|
||||||
|
// update NPC stuff
|
||||||
|
auto new_pos = glm::vec3(m_Position.x + (a->force * std::sin(a->meleepush_xy) + m_Delta.x),
|
||||||
|
m_Position.y + (a->force * std::cos(a->meleepush_xy) + m_Delta.y), m_Position.z);
|
||||||
|
if (zone->zonemap && zone->zonemap->CheckLoS(glm::vec3(m_Position), new_pos)) { // If we have LoS on the new loc it should be reachable.
|
||||||
|
if (IsNPC()) {
|
||||||
|
// Is this adequate?
|
||||||
|
Teleport(new_pos);
|
||||||
|
SendPosUpdate();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
a->force = 0.0f; // we couldn't move there, so lets not
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Note: if players can become pets, they will not receive damage messages of their own
|
//Note: if players can become pets, they will not receive damage messages of their own
|
||||||
//this was done to simplify the code here (since we can only effectively skip one mob on queue)
|
//this was done to simplify the code here (since we can only effectively skip one mob on queue)
|
||||||
@ -3968,7 +3995,7 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Innate + aug procs from weapons
|
// Innate + aug procs from weapons
|
||||||
// TODO: powersource procs
|
// TODO: powersource procs -- powersource procs are on invis augs, so shouldn't need anything extra
|
||||||
TryWeaponProc(weapon_g, weapon_g->GetItem(), on, hand);
|
TryWeaponProc(weapon_g, weapon_g->GetItem(), on, hand);
|
||||||
// Procs from Buffs and AA both melee and range
|
// Procs from Buffs and AA both melee and range
|
||||||
TrySpellProc(weapon_g, weapon_g->GetItem(), on, hand);
|
TrySpellProc(weapon_g, weapon_g->GetItem(), on, hand);
|
||||||
@ -4054,7 +4081,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const ItemData *weapon, Mob *on, u
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Powersource procs
|
// TODO: Powersource procs -- powersource procs are from augs so shouldn't need anything extra
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4116,7 +4143,7 @@ void Mob::TrySpellProc(const ItemInst *inst, const ItemData *weapon, Mob *on, ui
|
|||||||
outapp->priority = 3;
|
outapp->priority = 3;
|
||||||
entity_list.QueueCloseClients(this, outapp, false, 200, 0, true);
|
entity_list.QueueCloseClients(this, outapp, false, 200, 0, true);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
ExecWeaponProc(nullptr, SpellProcs[i].spellID, on);
|
ExecWeaponProc(nullptr, SpellProcs[i].spellID, on, SpellProcs[i].level_override);
|
||||||
CheckNumHitsRemaining(NumHit::OffensiveSpellProcs, 0,
|
CheckNumHitsRemaining(NumHit::OffensiveSpellProcs, 0,
|
||||||
SpellProcs[i].base_spellID);
|
SpellProcs[i].base_spellID);
|
||||||
} else {
|
} else {
|
||||||
@ -4222,7 +4249,7 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
if (this->IsPet() && this->GetOwner()->IsBot()) {
|
if (this->IsPet() && this->GetOwner() && this->GetOwner()->IsBot()) {
|
||||||
this->TryPetCriticalHit(defender,skill,damage);
|
this->TryPetCriticalHit(defender,skill,damage);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1449,7 +1449,7 @@ void Mob::CalcSpellBonuses(StatBonuses* newbon)
|
|||||||
int buff_count = GetMaxTotalSlots();
|
int buff_count = GetMaxTotalSlots();
|
||||||
for(i = 0; i < buff_count; i++) {
|
for(i = 0; i < buff_count; i++) {
|
||||||
if(buffs[i].spellid != SPELL_UNKNOWN){
|
if(buffs[i].spellid != SPELL_UNKNOWN){
|
||||||
ApplySpellsBonuses(buffs[i].spellid, buffs[i].casterlevel, newbon, buffs[i].casterid, 0, buffs[i].ticsremaining,i);
|
ApplySpellsBonuses(buffs[i].spellid, buffs[i].casterlevel, newbon, buffs[i].casterid, 0, buffs[i].ticsremaining, i, buffs[i].instrument_mod);
|
||||||
|
|
||||||
if (buffs[i].numhits > 0)
|
if (buffs[i].numhits > 0)
|
||||||
Numhits(true);
|
Numhits(true);
|
||||||
@ -1472,8 +1472,9 @@ void Mob::CalcSpellBonuses(StatBonuses* newbon)
|
|||||||
if (GetClass() == BARD) newbon->ManaRegen = 0; // Bards do not get mana regen from spells.
|
if (GetClass() == BARD) newbon->ManaRegen = 0; // Bards do not get mana regen from spells.
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* new_bonus, uint16 casterId, uint8 WornType, uint32 ticsremaining, int buffslot,
|
void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *new_bonus, uint16 casterId,
|
||||||
bool IsAISpellEffect, uint16 effect_id, int32 se_base, int32 se_limit, int32 se_max)
|
uint8 WornType, int32 ticsremaining, int buffslot, int instrument_mod,
|
||||||
|
bool IsAISpellEffect, uint16 effect_id, int32 se_base, int32 se_limit, int32 se_max)
|
||||||
{
|
{
|
||||||
int i, effect_value, base2, max, effectid;
|
int i, effect_value, base2, max, effectid;
|
||||||
bool AdditiveWornBonus = false;
|
bool AdditiveWornBonus = false;
|
||||||
@ -1511,7 +1512,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
|||||||
AdditiveWornBonus = true;
|
AdditiveWornBonus = true;
|
||||||
|
|
||||||
effectid = spells[spell_id].effectid[i];
|
effectid = spells[spell_id].effectid[i];
|
||||||
effect_value = CalcSpellEffectValue(spell_id, i, casterlevel, caster, ticsremaining);
|
effect_value = CalcSpellEffectValue(spell_id, i, casterlevel, instrument_mod, caster, ticsremaining);
|
||||||
base2 = spells[spell_id].base2[i];
|
base2 = spells[spell_id].base2[i];
|
||||||
max = spells[spell_id].max[i];
|
max = spells[spell_id].max[i];
|
||||||
}
|
}
|
||||||
|
|||||||
8755
zone/bot.cpp
8755
zone/bot.cpp
File diff suppressed because it is too large
Load Diff
12
zone/bot.h
12
zone/bot.h
@ -60,6 +60,7 @@ enum SpellTypeIndex {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class Bot : public NPC {
|
class Bot : public NPC {
|
||||||
|
friend class Mob;
|
||||||
public:
|
public:
|
||||||
// Class enums
|
// Class enums
|
||||||
enum BotfocusType { //focus types
|
enum BotfocusType { //focus types
|
||||||
@ -154,7 +155,7 @@ public:
|
|||||||
// Class Methods
|
// Class Methods
|
||||||
bool IsValidRaceClassCombo();
|
bool IsValidRaceClassCombo();
|
||||||
bool IsValidName();
|
bool IsValidName();
|
||||||
bool IsBotNameAvailable(std::string* errorMessage);
|
static bool IsBotNameAvailable(char *botName, std::string* errorMessage);
|
||||||
bool DeleteBot(std::string* errorMessage);
|
bool DeleteBot(std::string* errorMessage);
|
||||||
void Spawn(Client* botCharacterOwner, std::string* errorMessage);
|
void Spawn(Client* botCharacterOwner, std::string* errorMessage);
|
||||||
virtual void SetLevel(uint8 in_level, bool command = false);
|
virtual void SetLevel(uint8 in_level, bool command = false);
|
||||||
@ -190,7 +191,9 @@ public:
|
|||||||
bool CanDoSpecialAttack(Mob *other);
|
bool CanDoSpecialAttack(Mob *other);
|
||||||
virtual int32 CheckAggroAmount(uint16 spellid);
|
virtual int32 CheckAggroAmount(uint16 spellid);
|
||||||
virtual void CalcBonuses();
|
virtual void CalcBonuses();
|
||||||
void CalcItemBonuses();
|
void CalcItemBonuses(StatBonuses* newbon);
|
||||||
|
void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false);
|
||||||
|
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
|
||||||
virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr);
|
virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr);
|
||||||
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther);
|
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther);
|
||||||
inline virtual bool IsPet() { return false; }
|
inline virtual bool IsPet() { return false; }
|
||||||
@ -310,7 +313,7 @@ public:
|
|||||||
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration);
|
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration);
|
||||||
virtual float GetAOERange(uint16 spell_id);
|
virtual float GetAOERange(uint16 spell_id);
|
||||||
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100);
|
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100);
|
||||||
virtual void DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caster_level, Mob* caster = 0);
|
virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr);
|
||||||
virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr);
|
virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr);
|
||||||
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar);
|
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar);
|
||||||
virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster);
|
virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster);
|
||||||
@ -464,6 +467,7 @@ public:
|
|||||||
uint32 GetHealRotationNextHealTime() { return _healRotationNextHeal; }
|
uint32 GetHealRotationNextHealTime() { return _healRotationNextHeal; }
|
||||||
uint32 GetHealRotationTimer () { return _healRotationTimer; }
|
uint32 GetHealRotationTimer () { return _healRotationTimer; }
|
||||||
bool GetBardUseOutOfCombatSongs() { return _bardUseOutOfCombatSongs;}
|
bool GetBardUseOutOfCombatSongs() { return _bardUseOutOfCombatSongs;}
|
||||||
|
bool GetShowHelm() { return _showhelm; }
|
||||||
inline virtual int32 GetAC() const { return AC; }
|
inline virtual int32 GetAC() const { return AC; }
|
||||||
inline virtual int32 GetSTR() const { return STR; }
|
inline virtual int32 GetSTR() const { return STR; }
|
||||||
inline virtual int32 GetSTA() const { return STA; }
|
inline virtual int32 GetSTA() const { return STA; }
|
||||||
@ -547,6 +551,7 @@ public:
|
|||||||
void SetHealRotationTimer( uint32 timer ) { _healRotationTimer = timer; }
|
void SetHealRotationTimer( uint32 timer ) { _healRotationTimer = timer; }
|
||||||
void SetNumHealRotationMembers( uint8 numMembers ) { _numHealRotationMembers = numMembers; }
|
void SetNumHealRotationMembers( uint8 numMembers ) { _numHealRotationMembers = numMembers; }
|
||||||
void SetBardUseOutOfCombatSongs(bool useOutOfCombatSongs) { _bardUseOutOfCombatSongs = useOutOfCombatSongs;}
|
void SetBardUseOutOfCombatSongs(bool useOutOfCombatSongs) { _bardUseOutOfCombatSongs = useOutOfCombatSongs;}
|
||||||
|
void SetShowHelm(bool showhelm) { _showhelm = showhelm; }
|
||||||
|
|
||||||
// Class Destructors
|
// Class Destructors
|
||||||
virtual ~Bot();
|
virtual ~Bot();
|
||||||
@ -619,6 +624,7 @@ private:
|
|||||||
std::map<uint32, BotAA> botAAs;
|
std::map<uint32, BotAA> botAAs;
|
||||||
InspectMessage_Struct _botInspectMessage;
|
InspectMessage_Struct _botInspectMessage;
|
||||||
bool _bardUseOutOfCombatSongs;
|
bool _bardUseOutOfCombatSongs;
|
||||||
|
bool _showhelm;
|
||||||
|
|
||||||
// Private "base stats" Members
|
// Private "base stats" Members
|
||||||
int32 _baseMR;
|
int32 _baseMR;
|
||||||
|
|||||||
@ -116,7 +116,7 @@ Client::Client(EQStreamInterface* ieqs)
|
|||||||
),
|
),
|
||||||
//these must be listed in the order they appear in client.h
|
//these must be listed in the order they appear in client.h
|
||||||
position_timer(250),
|
position_timer(250),
|
||||||
hpupdate_timer(1800),
|
hpupdate_timer(2000),
|
||||||
camp_timer(29000),
|
camp_timer(29000),
|
||||||
process_timer(100),
|
process_timer(100),
|
||||||
stamina_timer(40000),
|
stamina_timer(40000),
|
||||||
@ -208,6 +208,7 @@ Client::Client(EQStreamInterface* ieqs)
|
|||||||
npclevel = 0;
|
npclevel = 0;
|
||||||
pQueuedSaveWorkID = 0;
|
pQueuedSaveWorkID = 0;
|
||||||
position_timer_counter = 0;
|
position_timer_counter = 0;
|
||||||
|
position_update_same_count = 0;
|
||||||
fishing_timer.Disable();
|
fishing_timer.Disable();
|
||||||
shield_timer.Disable();
|
shield_timer.Disable();
|
||||||
dead_timer.Disable();
|
dead_timer.Disable();
|
||||||
@ -549,17 +550,22 @@ bool Client::SaveAA(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_pp.aapoints_spent = spentpoints + m_epp.expended_aa;
|
m_pp.aapoints_spent = spentpoints + m_epp.expended_aa;
|
||||||
|
int highest = 0;
|
||||||
for (int a = 0; a < MAX_PP_AA_ARRAY; a++) {
|
for (int a = 0; a < MAX_PP_AA_ARRAY; a++) {
|
||||||
if (aa[a]->AA > 0 && aa[a]->value){
|
if (aa[a]->AA > 0) { // those with value 0 will be cleaned up on next load
|
||||||
if (first_entry != 1){
|
if (first_entry != 1){
|
||||||
rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, slot, aa_id, aa_value)"
|
rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, slot, aa_id, aa_value, charges)"
|
||||||
" VALUES (%u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value);
|
" VALUES (%u, %u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value, aa[a]->charges);
|
||||||
first_entry = 1;
|
first_entry = 1;
|
||||||
|
} else {
|
||||||
|
rquery = rquery + StringFormat(", (%u, %u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value, aa[a]->charges);
|
||||||
}
|
}
|
||||||
rquery = rquery + StringFormat(", (%u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value);
|
highest = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto results = database.QueryDatabase(rquery);
|
auto results = database.QueryDatabase(rquery);
|
||||||
|
/* This is another part of the hack to clean up holes left by expendable AAs */
|
||||||
|
rquery = StringFormat("DELETE FROM `character_alternate_abilities` WHERE `id` = %u AND `slot` > %d", character_id, highest);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1051,12 +1057,12 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
if(quest_manager.ProximitySayInUse())
|
if(quest_manager.ProximitySayInUse())
|
||||||
entity_list.ProcessProximitySay(message, this, language);
|
entity_list.ProcessProximitySay(message, this, language);
|
||||||
|
|
||||||
if (GetTarget() != 0 && GetTarget()->IsNPC()) {
|
if (GetTarget() != 0 && GetTarget()->IsNPC() &&
|
||||||
|
!IsInvisible(GetTarget())) {
|
||||||
if(!GetTarget()->CastToNPC()->IsEngaged()) {
|
if(!GetTarget()->CastToNPC()->IsEngaged()) {
|
||||||
CheckLDoNHail(GetTarget());
|
CheckLDoNHail(GetTarget());
|
||||||
CheckEmoteHail(GetTarget(), message);
|
CheckEmoteHail(GetTarget(), message);
|
||||||
|
|
||||||
|
|
||||||
if(DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
|
if(DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
|
||||||
NPC *tar = GetTarget()->CastToNPC();
|
NPC *tar = GetTarget()->CastToNPC();
|
||||||
parse->EventNPC(EVENT_SAY, tar->CastToNPC(), this, message, language);
|
parse->EventNPC(EVENT_SAY, tar->CastToNPC(), this, message, language);
|
||||||
@ -4991,7 +4997,7 @@ void Client::SetShadowStepExemption(bool v)
|
|||||||
if((cur_time - m_TimeSinceLastPositionCheck) > 1000)
|
if((cur_time - m_TimeSinceLastPositionCheck) > 1000)
|
||||||
{
|
{
|
||||||
float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck);
|
float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck);
|
||||||
float runs = GetRunspeed();
|
int runs = GetRunspeed();
|
||||||
if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor)))
|
if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor)))
|
||||||
{
|
{
|
||||||
printf("%s %i moving too fast! moved: %.2f in %ims, speed %.2f\n", __FILE__, __LINE__,
|
printf("%s %i moving too fast! moved: %.2f in %ims, speed %.2f\n", __FILE__, __LINE__,
|
||||||
@ -5048,7 +5054,7 @@ void Client::SetKnockBackExemption(bool v)
|
|||||||
if((cur_time - m_TimeSinceLastPositionCheck) > 1000)
|
if((cur_time - m_TimeSinceLastPositionCheck) > 1000)
|
||||||
{
|
{
|
||||||
float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck);
|
float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck);
|
||||||
float runs = GetRunspeed();
|
int runs = GetRunspeed();
|
||||||
if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor)))
|
if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor)))
|
||||||
{
|
{
|
||||||
if(!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor)))))
|
if(!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor)))))
|
||||||
@ -5105,7 +5111,7 @@ void Client::SetPortExemption(bool v)
|
|||||||
if((cur_time - m_TimeSinceLastPositionCheck) > 1000)
|
if((cur_time - m_TimeSinceLastPositionCheck) > 1000)
|
||||||
{
|
{
|
||||||
float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck);
|
float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck);
|
||||||
float runs = GetRunspeed();
|
int runs = GetRunspeed();
|
||||||
if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor)))
|
if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor)))
|
||||||
{
|
{
|
||||||
if(!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor)))))
|
if(!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor)))))
|
||||||
@ -7491,6 +7497,10 @@ void Client::GarbleMessage(char *message, uint8 variance)
|
|||||||
const char delimiter = 0x12;
|
const char delimiter = 0x12;
|
||||||
int delimiter_count = 0;
|
int delimiter_count = 0;
|
||||||
|
|
||||||
|
// Don't garble # commands
|
||||||
|
if (message[0] == '#')
|
||||||
|
return;
|
||||||
|
|
||||||
for (size_t i = 0; i < strlen(message); i++) {
|
for (size_t i = 0; i < strlen(message); i++) {
|
||||||
// Client expects hex values inside of a text link body
|
// Client expects hex values inside of a text link body
|
||||||
if (message[i] == delimiter) {
|
if (message[i] == delimiter) {
|
||||||
@ -7500,7 +7510,7 @@ void Client::GarbleMessage(char *message, uint8 variance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8 chance = (uint8)zone->random.Int(0, 115); // variation just over worst possible scrambling
|
uint8 chance = (uint8)zone->random.Int(0, 115); // variation just over worst possible scrambling
|
||||||
if (isalpha(message[i]) && (chance <= variance)) {
|
if (isalpha((unsigned char)message[i]) && (chance <= variance)) {
|
||||||
uint8 rand_char = (uint8)zone->random.Int(0,51); // choose a random character from the alpha list
|
uint8 rand_char = (uint8)zone->random.Int(0,51); // choose a random character from the alpha list
|
||||||
message[i] = alpha_list[rand_char];
|
message[i] = alpha_list[rand_char];
|
||||||
}
|
}
|
||||||
@ -7584,7 +7594,7 @@ FACTION_VALUE Client::GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 p_ra
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Sets the characters faction standing with the specified NPC.
|
//Sets the characters faction standing with the specified NPC.
|
||||||
void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity)
|
void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity, bool quest)
|
||||||
{
|
{
|
||||||
int32 faction_id[MAX_NPC_FACTIONS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
int32 faction_id[MAX_NPC_FACTIONS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
int32 npc_value[MAX_NPC_FACTIONS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
int32 npc_value[MAX_NPC_FACTIONS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
@ -7611,6 +7621,15 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui
|
|||||||
database.GetFactionData(&fm, GetClass(), GetRace(), GetDeity(),
|
database.GetFactionData(&fm, GetClass(), GetRace(), GetDeity(),
|
||||||
faction_id[i]);
|
faction_id[i]);
|
||||||
|
|
||||||
|
if (quest)
|
||||||
|
{
|
||||||
|
//The ole switcheroo
|
||||||
|
if (npc_value[i] > 0)
|
||||||
|
npc_value[i] = -abs(npc_value[i]);
|
||||||
|
else if (npc_value[i] < 0)
|
||||||
|
npc_value[i] = abs(npc_value[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust the amount you can go up or down so the resulting range
|
// Adjust the amount you can go up or down so the resulting range
|
||||||
// is PERSONAL_MAX - PERSONAL_MIN
|
// is PERSONAL_MAX - PERSONAL_MIN
|
||||||
//
|
//
|
||||||
@ -8428,7 +8447,6 @@ void Client::TextLink::generate_body()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
memset(&m_LinkBodyStruct, 0, sizeof(TextLinkBody_Struct));
|
memset(&m_LinkBodyStruct, 0, sizeof(TextLinkBody_Struct));
|
||||||
|
|
||||||
const ItemData* item_data = nullptr;
|
const ItemData* item_data = nullptr;
|
||||||
|
|
||||||
switch (m_LinkType) {
|
switch (m_LinkType) {
|
||||||
@ -8580,3 +8598,42 @@ bool Client::TextLink::GenerateLinkBody(std::string& textLinkBody, const TextLin
|
|||||||
if (textLinkBody.length() != EmuConstants::TEXT_LINK_BODY_LENGTH) { return false; }
|
if (textLinkBody.length() != EmuConstants::TEXT_LINK_BODY_LENGTH) { return false; }
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::QuestReward(Mob* target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid, uint32 exp, bool faction) {
|
||||||
|
|
||||||
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Sound, sizeof(QuestReward_Struct));
|
||||||
|
memset(outapp->pBuffer, 0, sizeof(outapp->pBuffer));
|
||||||
|
QuestReward_Struct* qr = (QuestReward_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
qr->mob_id = target->GetID(); // Entity ID for the from mob name
|
||||||
|
qr->target_id = GetID(); // The Client ID (this)
|
||||||
|
qr->copper = copper;
|
||||||
|
qr->silver = silver;
|
||||||
|
qr->gold = gold;
|
||||||
|
qr->platinum = platinum;
|
||||||
|
qr->item_id = itemid;
|
||||||
|
qr->exp_reward = exp;
|
||||||
|
|
||||||
|
if (copper > 0 || silver > 0 || gold > 0 || platinum > 0)
|
||||||
|
AddMoneyToPP(copper, silver, gold, platinum, false);
|
||||||
|
|
||||||
|
if (itemid > 0)
|
||||||
|
SummonItem(itemid, 0, 0, 0, 0, 0, 0, false, MainPowerSource);
|
||||||
|
|
||||||
|
if (faction)
|
||||||
|
{
|
||||||
|
if (target->IsNPC())
|
||||||
|
{
|
||||||
|
int32 nfl_id = target->CastToNPC()->GetNPCFactionID();
|
||||||
|
SetFactionLevel(CharacterID(), nfl_id, GetBaseClass(), GetBaseRace(), GetDeity(), true);
|
||||||
|
qr->faction = target->CastToNPC()->GetPrimaryFaction();
|
||||||
|
qr->faction_mod = 1; // Too lazy to get real value, not sure if this is even used by client anyhow.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exp > 0)
|
||||||
|
AddEXP(exp);
|
||||||
|
|
||||||
|
QueuePacket(outapp, false, Client::CLIENT_CONNECTED);
|
||||||
|
safe_delete(outapp);
|
||||||
|
}
|
||||||
|
|||||||
@ -559,6 +559,7 @@ public:
|
|||||||
void SendCrystalCounts();
|
void SendCrystalCounts();
|
||||||
|
|
||||||
void AddEXP(uint32 in_add_exp, uint8 conlevel = 0xFF, bool resexp = false);
|
void AddEXP(uint32 in_add_exp, uint8 conlevel = 0xFF, bool resexp = false);
|
||||||
|
uint32 CalcEXP(uint8 conlevel = 0xFF);
|
||||||
void SetEXP(uint32 set_exp, uint32 set_aaxp, bool resexp=false);
|
void SetEXP(uint32 set_exp, uint32 set_aaxp, bool resexp=false);
|
||||||
void AddLevelBasedExp(uint8 exp_percentage, uint8 max_level=0);
|
void AddLevelBasedExp(uint8 exp_percentage, uint8 max_level=0);
|
||||||
void SetLeadershipEXP(uint32 group_exp, uint32 raid_exp);
|
void SetLeadershipEXP(uint32 group_exp, uint32 raid_exp);
|
||||||
@ -613,7 +614,7 @@ public:
|
|||||||
void SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_before_hit, int32 totalvalue, uint8 temp, int32 this_faction_min, int32 this_faction_max);
|
void SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_before_hit, int32 totalvalue, uint8 temp, int32 this_faction_min, int32 this_faction_max);
|
||||||
|
|
||||||
void UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp, int32 this_faction_min, int32 this_faction_max);
|
void UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp, int32 this_faction_min, int32 this_faction_max);
|
||||||
void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity);
|
void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity, bool quest = false);
|
||||||
void SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp);
|
void SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp);
|
||||||
int32 GetRawItemAC();
|
int32 GetRawItemAC();
|
||||||
uint16 GetCombinedAC_TEST();
|
uint16 GetCombinedAC_TEST();
|
||||||
@ -930,6 +931,7 @@ public:
|
|||||||
bool DecreaseByID(uint32 type, uint8 amt);
|
bool DecreaseByID(uint32 type, uint8 amt);
|
||||||
uint8 SlotConvert2(uint8 slot); //Maybe not needed.
|
uint8 SlotConvert2(uint8 slot); //Maybe not needed.
|
||||||
void Escape(); //AA Escape
|
void Escape(); //AA Escape
|
||||||
|
void DisenchantSummonedBags(bool client_update = true);
|
||||||
void RemoveNoRent(bool client_update = true);
|
void RemoveNoRent(bool client_update = true);
|
||||||
void RemoveDuplicateLore(bool client_update = true);
|
void RemoveDuplicateLore(bool client_update = true);
|
||||||
void MoveSlotNotAllowed(bool client_update = true);
|
void MoveSlotNotAllowed(bool client_update = true);
|
||||||
@ -1154,6 +1156,7 @@ public:
|
|||||||
inline bool IsDraggingCorpse() { return (DraggedCorpses.size() > 0); }
|
inline bool IsDraggingCorpse() { return (DraggedCorpses.size() > 0); }
|
||||||
void DragCorpses();
|
void DragCorpses();
|
||||||
inline void ClearDraggedCorpses() { DraggedCorpses.clear(); }
|
inline void ClearDraggedCorpses() { DraggedCorpses.clear(); }
|
||||||
|
inline void ResetPositionTimer() { position_timer_counter = 0; }
|
||||||
void SendAltCurrencies();
|
void SendAltCurrencies();
|
||||||
void SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount);
|
void SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount);
|
||||||
void AddAlternateCurrencyValue(uint32 currency_id, int32 amount, int8 method = 0);
|
void AddAlternateCurrencyValue(uint32 currency_id, int32 amount, int8 method = 0);
|
||||||
@ -1279,6 +1282,9 @@ public:
|
|||||||
virtual int32 Tune_GetMeleeMitDmg(Mob* GM, Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
virtual int32 Tune_GetMeleeMitDmg(Mob* GM, Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||||
int32 GetMeleeDamage(Mob* other, bool GetMinDamage = false);
|
int32 GetMeleeDamage(Mob* other, bool GetMinDamage = false);
|
||||||
|
|
||||||
|
void QuestReward(Mob* target, uint32 copper = 0, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0, uint32 itemid = 0, uint32 exp = 0, bool faction = false);
|
||||||
|
|
||||||
|
void ResetHPUpdateTimer() { hpupdate_timer.Start(); }
|
||||||
protected:
|
protected:
|
||||||
friend class Mob;
|
friend class Mob;
|
||||||
void CalcItemBonuses(StatBonuses* newbon);
|
void CalcItemBonuses(StatBonuses* newbon);
|
||||||
@ -1466,6 +1472,9 @@ private:
|
|||||||
Timer position_timer;
|
Timer position_timer;
|
||||||
uint8 position_timer_counter;
|
uint8 position_timer_counter;
|
||||||
|
|
||||||
|
// this is used to try to cut back on position update reflections
|
||||||
|
int position_update_same_count;
|
||||||
|
|
||||||
PTimerList p_timers; //persistent timers
|
PTimerList p_timers; //persistent timers
|
||||||
Timer hpupdate_timer;
|
Timer hpupdate_timer;
|
||||||
Timer camp_timer;
|
Timer camp_timer;
|
||||||
|
|||||||
@ -1974,101 +1974,87 @@ int32 Client::CalcATK()
|
|||||||
|
|
||||||
uint32 Mob::GetInstrumentMod(uint16 spell_id) const
|
uint32 Mob::GetInstrumentMod(uint16 spell_id) const
|
||||||
{
|
{
|
||||||
if (GetClass() != BARD) {
|
if (GetClass() != BARD || spells[spell_id].IsDisciplineBuff) // Puretone is Singing but doesn't get any mod
|
||||||
return 10;
|
return 10;
|
||||||
}
|
|
||||||
uint32 effectmod = 10;
|
uint32 effectmod = 10;
|
||||||
int effectmodcap = RuleI(Character, BaseInstrumentSoftCap);
|
int effectmodcap = RuleI(Character, BaseInstrumentSoftCap);
|
||||||
//this should never use spell modifiers...
|
// this should never use spell modifiers...
|
||||||
//if a spell grants better modifers, they are copied into the item mods
|
// if a spell grants better modifers, they are copied into the item mods
|
||||||
//because the spells are supposed to act just like having the intrument.
|
// because the spells are supposed to act just like having the intrument.
|
||||||
//item mods are in 10ths of percent increases
|
// item mods are in 10ths of percent increases
|
||||||
|
// clickies (Symphony of Battle) that have a song skill don't get AA bonus for some reason
|
||||||
|
// but clickies that are songs (selo's on Composers Greaves) do get AA mod as well
|
||||||
switch (spells[spell_id].skill) {
|
switch (spells[spell_id].skill) {
|
||||||
case SkillPercussionInstruments:
|
case SkillPercussionInstruments:
|
||||||
if (itembonuses.percussionMod == 0 && spellbonuses.percussionMod == 0) {
|
if (itembonuses.percussionMod == 0 && spellbonuses.percussionMod == 0)
|
||||||
effectmod = 10;
|
|
||||||
}
|
|
||||||
else if (GetSkill(SkillPercussionInstruments) == 0) {
|
|
||||||
effectmod = 10;
|
|
||||||
}
|
|
||||||
else if (itembonuses.percussionMod > spellbonuses.percussionMod) {
|
|
||||||
effectmod = itembonuses.percussionMod;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
effectmod = spellbonuses.percussionMod;
|
|
||||||
}
|
|
||||||
effectmod += aabonuses.percussionMod;
|
|
||||||
break;
|
|
||||||
case SkillStringedInstruments:
|
|
||||||
if (itembonuses.stringedMod == 0 && spellbonuses.stringedMod == 0) {
|
|
||||||
effectmod = 10;
|
|
||||||
}
|
|
||||||
else if (GetSkill(SkillStringedInstruments) == 0) {
|
|
||||||
effectmod = 10;
|
|
||||||
}
|
|
||||||
else if (itembonuses.stringedMod > spellbonuses.stringedMod) {
|
|
||||||
effectmod = itembonuses.stringedMod;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
effectmod = spellbonuses.stringedMod;
|
|
||||||
}
|
|
||||||
effectmod += aabonuses.stringedMod;
|
|
||||||
break;
|
|
||||||
case SkillWindInstruments:
|
|
||||||
if (itembonuses.windMod == 0 && spellbonuses.windMod == 0) {
|
|
||||||
effectmod = 10;
|
|
||||||
}
|
|
||||||
else if (GetSkill(SkillWindInstruments) == 0) {
|
|
||||||
effectmod = 10;
|
|
||||||
}
|
|
||||||
else if (itembonuses.windMod > spellbonuses.windMod) {
|
|
||||||
effectmod = itembonuses.windMod;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
effectmod = spellbonuses.windMod;
|
|
||||||
}
|
|
||||||
effectmod += aabonuses.windMod;
|
|
||||||
break;
|
|
||||||
case SkillBrassInstruments:
|
|
||||||
if (itembonuses.brassMod == 0 && spellbonuses.brassMod == 0) {
|
|
||||||
effectmod = 10;
|
|
||||||
}
|
|
||||||
else if (GetSkill(SkillBrassInstruments) == 0) {
|
|
||||||
effectmod = 10;
|
|
||||||
}
|
|
||||||
else if (itembonuses.brassMod > spellbonuses.brassMod) {
|
|
||||||
effectmod = itembonuses.brassMod;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
effectmod = spellbonuses.brassMod;
|
|
||||||
}
|
|
||||||
effectmod += aabonuses.brassMod;
|
|
||||||
break;
|
|
||||||
case SkillSinging:
|
|
||||||
if (itembonuses.singingMod == 0 && spellbonuses.singingMod == 0) {
|
|
||||||
effectmod = 10;
|
|
||||||
}
|
|
||||||
else if (itembonuses.singingMod > spellbonuses.singingMod) {
|
|
||||||
effectmod = itembonuses.singingMod;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
effectmod = spellbonuses.singingMod;
|
|
||||||
}
|
|
||||||
effectmod += aabonuses.singingMod + spellbonuses.Amplification;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
effectmod = 10;
|
effectmod = 10;
|
||||||
break;
|
else if (GetSkill(SkillPercussionInstruments) == 0)
|
||||||
|
effectmod = 10;
|
||||||
|
else if (itembonuses.percussionMod > spellbonuses.percussionMod)
|
||||||
|
effectmod = itembonuses.percussionMod;
|
||||||
|
else
|
||||||
|
effectmod = spellbonuses.percussionMod;
|
||||||
|
if (IsBardSong(spell_id))
|
||||||
|
effectmod += aabonuses.percussionMod;
|
||||||
|
break;
|
||||||
|
case SkillStringedInstruments:
|
||||||
|
if (itembonuses.stringedMod == 0 && spellbonuses.stringedMod == 0)
|
||||||
|
effectmod = 10;
|
||||||
|
else if (GetSkill(SkillStringedInstruments) == 0)
|
||||||
|
effectmod = 10;
|
||||||
|
else if (itembonuses.stringedMod > spellbonuses.stringedMod)
|
||||||
|
effectmod = itembonuses.stringedMod;
|
||||||
|
else
|
||||||
|
effectmod = spellbonuses.stringedMod;
|
||||||
|
if (IsBardSong(spell_id))
|
||||||
|
effectmod += aabonuses.stringedMod;
|
||||||
|
break;
|
||||||
|
case SkillWindInstruments:
|
||||||
|
if (itembonuses.windMod == 0 && spellbonuses.windMod == 0)
|
||||||
|
effectmod = 10;
|
||||||
|
else if (GetSkill(SkillWindInstruments) == 0)
|
||||||
|
effectmod = 10;
|
||||||
|
else if (itembonuses.windMod > spellbonuses.windMod)
|
||||||
|
effectmod = itembonuses.windMod;
|
||||||
|
else
|
||||||
|
effectmod = spellbonuses.windMod;
|
||||||
|
if (IsBardSong(spell_id))
|
||||||
|
effectmod += aabonuses.windMod;
|
||||||
|
break;
|
||||||
|
case SkillBrassInstruments:
|
||||||
|
if (itembonuses.brassMod == 0 && spellbonuses.brassMod == 0)
|
||||||
|
effectmod = 10;
|
||||||
|
else if (GetSkill(SkillBrassInstruments) == 0)
|
||||||
|
effectmod = 10;
|
||||||
|
else if (itembonuses.brassMod > spellbonuses.brassMod)
|
||||||
|
effectmod = itembonuses.brassMod;
|
||||||
|
else
|
||||||
|
effectmod = spellbonuses.brassMod;
|
||||||
|
if (IsBardSong(spell_id))
|
||||||
|
effectmod += aabonuses.brassMod;
|
||||||
|
break;
|
||||||
|
case SkillSinging:
|
||||||
|
if (itembonuses.singingMod == 0 && spellbonuses.singingMod == 0)
|
||||||
|
effectmod = 10;
|
||||||
|
else if (itembonuses.singingMod > spellbonuses.singingMod)
|
||||||
|
effectmod = itembonuses.singingMod;
|
||||||
|
else
|
||||||
|
effectmod = spellbonuses.singingMod;
|
||||||
|
if (IsBardSong(spell_id))
|
||||||
|
effectmod += aabonuses.singingMod + spellbonuses.Amplification;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
effectmod = 10;
|
||||||
|
return effectmod;
|
||||||
}
|
}
|
||||||
effectmodcap += aabonuses.songModCap + spellbonuses.songModCap + itembonuses.songModCap;
|
effectmodcap += aabonuses.songModCap + spellbonuses.songModCap + itembonuses.songModCap;
|
||||||
if (effectmod < 10) {
|
if (effectmod < 10)
|
||||||
effectmod = 10;
|
effectmod = 10;
|
||||||
}
|
if (effectmod > effectmodcap)
|
||||||
if (effectmod > effectmodcap) {
|
|
||||||
effectmod = effectmodcap;
|
effectmod = effectmodcap;
|
||||||
}
|
Log.Out(Logs::Detail, Logs::Spells, "%s::GetInstrumentMod() spell=%d mod=%d modcap=%d\n", GetName(), spell_id,
|
||||||
Log.Out(Logs::Detail, Logs::Spells, "%s::GetInstrumentMod() spell=%d mod=%d modcap=%d\n",
|
effectmod, effectmodcap);
|
||||||
GetName(), spell_id, effectmod, effectmodcap);
|
|
||||||
return effectmod;
|
return effectmod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -306,6 +306,8 @@ void MapOpcodes()
|
|||||||
ConnectedOpcodes[OP_PetitionRefresh] = &Client::Handle_OP_PetitionRefresh;
|
ConnectedOpcodes[OP_PetitionRefresh] = &Client::Handle_OP_PetitionRefresh;
|
||||||
ConnectedOpcodes[OP_PetitionResolve] = &Client::Handle_OP_PetitionResolve;
|
ConnectedOpcodes[OP_PetitionResolve] = &Client::Handle_OP_PetitionResolve;
|
||||||
ConnectedOpcodes[OP_PetitionUnCheckout] = &Client::Handle_OP_PetitionUnCheckout;
|
ConnectedOpcodes[OP_PetitionUnCheckout] = &Client::Handle_OP_PetitionUnCheckout;
|
||||||
|
ConnectedOpcodes[OP_PlayerStateAdd] = &Client::Handle_OP_PlayerStateAdd;
|
||||||
|
ConnectedOpcodes[OP_PlayerStateRemove] = &Client::Handle_OP_PlayerStateRemove;
|
||||||
ConnectedOpcodes[OP_PickPocket] = &Client::Handle_OP_PickPocket;
|
ConnectedOpcodes[OP_PickPocket] = &Client::Handle_OP_PickPocket;
|
||||||
ConnectedOpcodes[OP_PopupResponse] = &Client::Handle_OP_PopupResponse;
|
ConnectedOpcodes[OP_PopupResponse] = &Client::Handle_OP_PopupResponse;
|
||||||
ConnectedOpcodes[OP_PotionBelt] = &Client::Handle_OP_PotionBelt;
|
ConnectedOpcodes[OP_PotionBelt] = &Client::Handle_OP_PotionBelt;
|
||||||
@ -703,7 +705,7 @@ void Client::CompleteConnect()
|
|||||||
case SE_AddMeleeProc:
|
case SE_AddMeleeProc:
|
||||||
case SE_WeaponProc:
|
case SE_WeaponProc:
|
||||||
{
|
{
|
||||||
AddProcToWeapon(GetProcID(buffs[j1].spellid, x1), false, 100 + spells[buffs[j1].spellid].base2[x1], buffs[j1].spellid);
|
AddProcToWeapon(GetProcID(buffs[j1].spellid, x1), false, 100 + spells[buffs[j1].spellid].base2[x1], buffs[j1].spellid, buffs[j1].casterlevel);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_DefensiveProc:
|
case SE_DefensiveProc:
|
||||||
@ -1444,22 +1446,32 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
if (m_pp.ldon_points_available < 0 || m_pp.ldon_points_available > 2000000000){ m_pp.ldon_points_available = 0; }
|
if (m_pp.ldon_points_available < 0 || m_pp.ldon_points_available > 2000000000){ m_pp.ldon_points_available = 0; }
|
||||||
|
|
||||||
/* Initialize AA's : Move to function eventually */
|
/* Initialize AA's : Move to function eventually */
|
||||||
for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++){ aa[a] = &m_pp.aa_array[a]; }
|
for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++)
|
||||||
|
aa[a] = &m_pp.aa_array[a];
|
||||||
query = StringFormat(
|
query = StringFormat(
|
||||||
"SELECT "
|
"SELECT "
|
||||||
"slot, "
|
"slot, "
|
||||||
"aa_id, "
|
"aa_id, "
|
||||||
"aa_value "
|
"aa_value, "
|
||||||
|
"charges "
|
||||||
"FROM "
|
"FROM "
|
||||||
"`character_alternate_abilities` "
|
"`character_alternate_abilities` "
|
||||||
"WHERE `id` = %u ORDER BY `slot`", this->CharacterID());
|
"WHERE `id` = %u ORDER BY `slot`", this->CharacterID());
|
||||||
results = database.QueryDatabase(query); i = 0;
|
results = database.QueryDatabase(query); i = 0;
|
||||||
|
int offset = 0; // offset to fix the hole from expendables
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
i = atoi(row[0]);
|
i = atoi(row[0]) - offset;
|
||||||
m_pp.aa_array[i].AA = atoi(row[1]);
|
m_pp.aa_array[i].AA = atoi(row[1]);
|
||||||
m_pp.aa_array[i].value = atoi(row[2]);
|
m_pp.aa_array[i].value = atoi(row[2]);
|
||||||
aa[i]->AA = atoi(row[1]);
|
m_pp.aa_array[i].charges = atoi(row[3]);
|
||||||
aa[i]->value = atoi(row[2]);
|
/* A used expendable could cause there to be a "hole" in the array, this is very bad. Bad things like keeping your expendable after use.
|
||||||
|
We could do a few things, one of them being reshuffling when the hole is created or defer the fixing until a later point, like during load!
|
||||||
|
Or just never making a hole in the array and just have hacks every where. Fixing the hole at load really just keeps 1 hack in Client::SendAATable
|
||||||
|
and keeping this offset that will cause the next AA to be pushed back over the hole. We also need to clean up on save so we don't have multiple
|
||||||
|
entries for a single AA.
|
||||||
|
*/
|
||||||
|
if (m_pp.aa_array[i].value == 0)
|
||||||
|
offset++;
|
||||||
}
|
}
|
||||||
for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++){
|
for (uint32 a = 0; a < MAX_PP_AA_ARRAY; a++){
|
||||||
uint32 id = aa[a]->AA;
|
uint32 id = aa[a]->AA;
|
||||||
@ -1498,7 +1510,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
for (int i = 0; i < max_slots; i++) {
|
for (int i = 0; i < max_slots; i++) {
|
||||||
if (buffs[i].spellid != SPELL_UNKNOWN) {
|
if (buffs[i].spellid != SPELL_UNKNOWN) {
|
||||||
m_pp.buffs[i].spellid = buffs[i].spellid;
|
m_pp.buffs[i].spellid = buffs[i].spellid;
|
||||||
m_pp.buffs[i].bard_modifier = 10;
|
m_pp.buffs[i].bard_modifier = buffs[i].instrument_mod;
|
||||||
m_pp.buffs[i].slotid = 2;
|
m_pp.buffs[i].slotid = 2;
|
||||||
m_pp.buffs[i].player_id = 0x2211;
|
m_pp.buffs[i].player_id = 0x2211;
|
||||||
m_pp.buffs[i].level = buffs[i].casterlevel;
|
m_pp.buffs[i].level = buffs[i].casterlevel;
|
||||||
@ -1707,7 +1719,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
/* Time of Day packet */
|
/* Time of Day packet */
|
||||||
outapp = new EQApplicationPacket(OP_TimeOfDay, sizeof(TimeOfDay_Struct));
|
outapp = new EQApplicationPacket(OP_TimeOfDay, sizeof(TimeOfDay_Struct));
|
||||||
TimeOfDay_Struct* tod = (TimeOfDay_Struct*)outapp->pBuffer;
|
TimeOfDay_Struct* tod = (TimeOfDay_Struct*)outapp->pBuffer;
|
||||||
zone->zone_time.getEQTimeOfDay(time(0), tod);
|
zone->zone_time.GetCurrentEQTimeOfDay(time(0), tod);
|
||||||
outapp->priority = 6;
|
outapp->priority = 6;
|
||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
|
|
||||||
@ -4129,7 +4141,7 @@ void Client::Handle_OP_ClickObject(const EQApplicationPacket *app)
|
|||||||
char buf[10];
|
char buf[10];
|
||||||
snprintf(buf, 9, "%u", click_object->drop_id);
|
snprintf(buf, 9, "%u", click_object->drop_id);
|
||||||
buf[9] = '\0';
|
buf[9] = '\0';
|
||||||
parse->EventPlayer(EVENT_CLICK_OBJECT, this, buf, 0, &args);
|
parse->EventPlayer(EVENT_CLICK_OBJECT, this, buf, GetID(), &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Observed in RoF after OP_ClickObjectAction:
|
// Observed in RoF after OP_ClickObjectAction:
|
||||||
@ -4267,7 +4279,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
|||||||
if((cur_time - m_TimeSinceLastPositionCheck) > 0)
|
if((cur_time - m_TimeSinceLastPositionCheck) > 0)
|
||||||
{
|
{
|
||||||
float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck);
|
float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck);
|
||||||
float runs = GetRunspeed();
|
int runs = GetRunspeed();
|
||||||
if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor)))
|
if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor)))
|
||||||
{
|
{
|
||||||
if(!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor)))))
|
if(!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor)))))
|
||||||
@ -4335,7 +4347,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
|||||||
if((cur_time - m_TimeSinceLastPositionCheck) > 2500)
|
if((cur_time - m_TimeSinceLastPositionCheck) > 2500)
|
||||||
{
|
{
|
||||||
float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck);
|
float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck);
|
||||||
float runs = GetRunspeed();
|
int runs = GetRunspeed();
|
||||||
if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor)))
|
if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor)))
|
||||||
{
|
{
|
||||||
if(!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor)))))
|
if(!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor)))))
|
||||||
@ -4448,9 +4460,20 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
// Outgoing client packet
|
// Outgoing client packet
|
||||||
float tmpheading = EQ19toFloat(ppu->heading);
|
float tmpheading = EQ19toFloat(ppu->heading);
|
||||||
|
/* The clients send an update at best every 1.3 seconds
|
||||||
|
* We want to avoid reflecting these updates to other clients as much as possible
|
||||||
|
* The client also sends an update every 280 ms while turning, if we prevent
|
||||||
|
* sending these by checking if the location is the same too aggressively, clients end up spinning
|
||||||
|
* so keep a count of how many packets are the same within a tolerance and stop when we get there */
|
||||||
|
|
||||||
if (!FCMP(ppu->y_pos, m_Position.y) || !FCMP(ppu->x_pos, m_Position.x) || !FCMP(tmpheading, m_Position.w) || ppu->animation != animation)
|
bool pos_same = FCMP(ppu->y_pos, m_Position.y) && FCMP(ppu->x_pos, m_Position.x) && FCMP(tmpheading, m_Position.w) && ppu->animation == animation;
|
||||||
|
if (!pos_same || (pos_same && position_update_same_count < 6))
|
||||||
{
|
{
|
||||||
|
if (pos_same)
|
||||||
|
position_update_same_count++;
|
||||||
|
else
|
||||||
|
position_update_same_count = 0;
|
||||||
|
|
||||||
m_Position.x = ppu->x_pos;
|
m_Position.x = ppu->x_pos;
|
||||||
m_Position.y = ppu->y_pos;
|
m_Position.y = ppu->y_pos;
|
||||||
m_Position.z = ppu->z_pos;
|
m_Position.z = ppu->z_pos;
|
||||||
@ -6355,15 +6378,25 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
|
|||||||
Bot::ProcessBotGroupDisband(this, std::string());
|
Bot::ProcessBotGroupDisband(this, std::string());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Mob* tempMember = entity_list.GetMob(gd->name2);
|
Mob* tempMember = entity_list.GetMob(gd->name1); //Name1 is the target you are disbanding
|
||||||
if (tempMember) {
|
if (tempMember && tempMember->IsBot()) {
|
||||||
if (tempMember->IsBot())
|
tempMember->CastToBot()->RemoveBotFromGroup(tempMember->CastToBot(), group);
|
||||||
Bot::ProcessBotGroupDisband(this, std::string(tempMember->GetCleanName()));
|
if (LFP)
|
||||||
|
{
|
||||||
|
// If we are looking for players, update to show we are on our own now.
|
||||||
|
UpdateLFP();
|
||||||
|
}
|
||||||
|
return; //No need to continue from here we were removing a bot from party
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group = GetGroup();
|
||||||
|
if (!group) //We must recheck this here.. incase the final bot disbanded the party..otherwise we crash
|
||||||
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (group->GroupCount() < 3)
|
if (group->GroupCount() < 3)
|
||||||
{
|
{
|
||||||
group->DisbandGroup();
|
group->DisbandGroup();
|
||||||
@ -9705,6 +9738,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
char val1[20] = { 0 };
|
char val1[20] = { 0 };
|
||||||
PetCommand_Struct* pet = (PetCommand_Struct*)app->pBuffer;
|
PetCommand_Struct* pet = (PetCommand_Struct*)app->pBuffer;
|
||||||
Mob* mypet = this->GetPet();
|
Mob* mypet = this->GetPet();
|
||||||
|
Mob *target = entity_list.GetMob(pet->target);
|
||||||
|
|
||||||
if (!mypet || pet->command == PET_LEADER)
|
if (!mypet || pet->command == PET_LEADER)
|
||||||
{
|
{
|
||||||
@ -9752,22 +9786,22 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
switch (PetCommand)
|
switch (PetCommand)
|
||||||
{
|
{
|
||||||
case PET_ATTACK: {
|
case PET_ATTACK: {
|
||||||
if (!GetTarget())
|
if (!target)
|
||||||
break;
|
break;
|
||||||
if (GetTarget()->IsMezzed()) {
|
if (target->IsMezzed()) {
|
||||||
Message_StringID(10, CANNOT_WAKE, mypet->GetCleanName(), GetTarget()->GetCleanName());
|
Message_StringID(10, CANNOT_WAKE, mypet->GetCleanName(), target->GetCleanName());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (mypet->IsFeared())
|
if (mypet->IsFeared())
|
||||||
break; //prevent pet from attacking stuff while feared
|
break; //prevent pet from attacking stuff while feared
|
||||||
|
|
||||||
if (!mypet->IsAttackAllowed(GetTarget())) {
|
if (!mypet->IsAttackAllowed(target)) {
|
||||||
mypet->Say_StringID(NOT_LEGAL_TARGET);
|
mypet->Say_StringID(NOT_LEGAL_TARGET);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
|
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
|
||||||
if (GetTarget() != this && DistanceSquaredNoZ(mypet->GetPosition(), GetTarget()->GetPosition()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
|
if (target != this && DistanceSquaredNoZ(mypet->GetPosition(), target->GetPosition()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
|
||||||
if (mypet->IsHeld()) {
|
if (mypet->IsHeld()) {
|
||||||
if (!mypet->IsFocused()) {
|
if (!mypet->IsFocused()) {
|
||||||
mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
|
mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
|
||||||
@ -9775,12 +9809,12 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
mypet->SetPetOrder(SPO_Follow);
|
mypet->SetPetOrder(SPO_Follow);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mypet->SetTarget(GetTarget());
|
mypet->SetTarget(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zone->AddAggroMob();
|
zone->AddAggroMob();
|
||||||
mypet->AddToHateList(GetTarget(), 1);
|
mypet->AddToHateList(target, 1);
|
||||||
Message_StringID(MT_PetResponse, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName());
|
Message_StringID(MT_PetResponse, PET_ATTACKING, mypet->GetCleanName(), target->GetCleanName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -10275,6 +10309,31 @@ void Client::Handle_OP_PetitionUnCheckout(const EQApplicationPacket *app)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::Handle_OP_PlayerStateAdd(const EQApplicationPacket *app)
|
||||||
|
{
|
||||||
|
if (app->size != sizeof(PlayerState_Struct)) {
|
||||||
|
std::cout << "Wrong size: OP_PlayerStateAdd, size=" << app->size << ", expected " << sizeof(PlayerState_Struct) << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerState_Struct *ps = (PlayerState_Struct *)app->pBuffer;
|
||||||
|
AddPlayerState(ps->state);
|
||||||
|
|
||||||
|
entity_list.QueueClients(this, app, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::Handle_OP_PlayerStateRemove(const EQApplicationPacket *app)
|
||||||
|
{
|
||||||
|
if (app->size != sizeof(PlayerState_Struct)) {
|
||||||
|
std::cout << "Wrong size: OP_PlayerStateRemove, size=" << app->size << ", expected " << sizeof(PlayerState_Struct) << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PlayerState_Struct *ps = (PlayerState_Struct *)app->pBuffer;
|
||||||
|
RemovePlayerState(ps->state);
|
||||||
|
|
||||||
|
entity_list.QueueClients(this, app, true);
|
||||||
|
}
|
||||||
|
|
||||||
void Client::Handle_OP_PickPocket(const EQApplicationPacket *app)
|
void Client::Handle_OP_PickPocket(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
if (app->size != sizeof(PickPocket_Struct))
|
if (app->size != sizeof(PickPocket_Struct))
|
||||||
@ -12745,7 +12804,7 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app)
|
|||||||
inspect_buffs = group->GetLeadershipAA(groupAAInspectBuffs);
|
inspect_buffs = group->GetLeadershipAA(groupAAInspectBuffs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nt == this || inspect_buffs || (nt->IsClient() && !nt->CastToClient()->GetPVP()) ||
|
if (GetGM() || RuleB(Spells, AlwaysSendTargetsBuffs) || nt == this || inspect_buffs || (nt->IsClient() && !nt->CastToClient()->GetPVP()) ||
|
||||||
(nt->IsPet() && nt->GetOwner() && nt->GetOwner()->IsClient() && !nt->GetOwner()->CastToClient()->GetPVP()) ||
|
(nt->IsPet() && nt->GetOwner() && nt->GetOwner()->IsClient() && !nt->GetOwner()->CastToClient()->GetPVP()) ||
|
||||||
(nt->IsMerc() && nt->GetOwner() && nt->GetOwner()->IsClient() && !nt->GetOwner()->CastToClient()->GetPVP()))
|
(nt->IsMerc() && nt->GetOwner() && nt->GetOwner()->IsClient() && !nt->GetOwner()->CastToClient()->GetPVP()))
|
||||||
nt->SendBuffsToClient(this);
|
nt->SendBuffsToClient(this);
|
||||||
|
|||||||
@ -218,6 +218,8 @@
|
|||||||
void Handle_OP_PetitionRefresh(const EQApplicationPacket *app);
|
void Handle_OP_PetitionRefresh(const EQApplicationPacket *app);
|
||||||
void Handle_OP_PetitionResolve(const EQApplicationPacket *app);
|
void Handle_OP_PetitionResolve(const EQApplicationPacket *app);
|
||||||
void Handle_OP_PetitionUnCheckout(const EQApplicationPacket *app);
|
void Handle_OP_PetitionUnCheckout(const EQApplicationPacket *app);
|
||||||
|
void Handle_OP_PlayerStateAdd(const EQApplicationPacket *app);
|
||||||
|
void Handle_OP_PlayerStateRemove(const EQApplicationPacket *app);
|
||||||
void Handle_OP_PickPocket(const EQApplicationPacket *app);
|
void Handle_OP_PickPocket(const EQApplicationPacket *app);
|
||||||
void Handle_OP_PopupResponse(const EQApplicationPacket *app);
|
void Handle_OP_PopupResponse(const EQApplicationPacket *app);
|
||||||
void Handle_OP_PotionBelt(const EQApplicationPacket *app);
|
void Handle_OP_PotionBelt(const EQApplicationPacket *app);
|
||||||
|
|||||||
@ -129,7 +129,9 @@ bool Client::Process() {
|
|||||||
if(IsTracking() && (GetClientVersion() >= ClientVersion::SoD) && TrackingTimer.Check())
|
if(IsTracking() && (GetClientVersion() >= ClientVersion::SoD) && TrackingTimer.Check())
|
||||||
DoTracking();
|
DoTracking();
|
||||||
|
|
||||||
if(hpupdate_timer.Check())
|
// SendHPUpdate calls hpupdate_timer.Start so it can delay this timer, so lets not reset with the check
|
||||||
|
// since the function will anyways
|
||||||
|
if(hpupdate_timer.Check(false))
|
||||||
SendHPUpdate();
|
SendHPUpdate();
|
||||||
|
|
||||||
if(mana_timer.Check())
|
if(mana_timer.Check())
|
||||||
@ -197,10 +199,8 @@ bool Client::Process() {
|
|||||||
instalog = true;
|
instalog = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsStunned() && stunned_timer.Check()) {
|
if (IsStunned() && stunned_timer.Check())
|
||||||
this->stunned = false;
|
Mob::UnStun();
|
||||||
this->stunned_timer.Disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!m_CheatDetectMoved)
|
if(!m_CheatDetectMoved)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1369,7 +1369,7 @@ void command_date(Client *c, const Seperator *sep)
|
|||||||
else {
|
else {
|
||||||
int h=0, m=0;
|
int h=0, m=0;
|
||||||
TimeOfDay_Struct eqTime;
|
TimeOfDay_Struct eqTime;
|
||||||
zone->zone_time.getEQTimeOfDay( time(0), &eqTime);
|
zone->zone_time.GetCurrentEQTimeOfDay( time(0), &eqTime);
|
||||||
if(!sep->IsNumber(4))
|
if(!sep->IsNumber(4))
|
||||||
h=eqTime.hour;
|
h=eqTime.hour;
|
||||||
else
|
else
|
||||||
@ -1402,7 +1402,7 @@ void command_timezone(Client *c, const Seperator *sep)
|
|||||||
// Update all clients with new TZ.
|
// Update all clients with new TZ.
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TimeOfDay, sizeof(TimeOfDay_Struct));
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TimeOfDay, sizeof(TimeOfDay_Struct));
|
||||||
TimeOfDay_Struct* tod = (TimeOfDay_Struct*)outapp->pBuffer;
|
TimeOfDay_Struct* tod = (TimeOfDay_Struct*)outapp->pBuffer;
|
||||||
zone->zone_time.getEQTimeOfDay(time(0), tod);
|
zone->zone_time.GetCurrentEQTimeOfDay(time(0), tod);
|
||||||
entity_list.QueueClients(c, outapp);
|
entity_list.QueueClients(c, outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
@ -1484,7 +1484,7 @@ void command_npcstats(Client *c, const Seperator *sep)
|
|||||||
c->Message(0, "Current HP: %i Max HP: %i", c->GetTarget()->GetHP(), c->GetTarget()->GetMaxHP());
|
c->Message(0, "Current HP: %i Max HP: %i", c->GetTarget()->GetHP(), c->GetTarget()->GetMaxHP());
|
||||||
//c->Message(0, "Weapon Item Number: %s", c->GetTarget()->GetWeapNo());
|
//c->Message(0, "Weapon Item Number: %s", c->GetTarget()->GetWeapNo());
|
||||||
c->Message(0, "Gender: %i Size: %f Bodytype: %d", c->GetTarget()->GetGender(), c->GetTarget()->GetSize(), c->GetTarget()->GetBodyType());
|
c->Message(0, "Gender: %i Size: %f Bodytype: %d", c->GetTarget()->GetGender(), c->GetTarget()->GetSize(), c->GetTarget()->GetBodyType());
|
||||||
c->Message(0, "Runspeed: %f Walkspeed: %f", c->GetTarget()->GetRunspeed(), c->GetTarget()->GetWalkspeed());
|
c->Message(0, "Runspeed: %i Walkspeed: %i", c->GetTarget()->GetRunspeed(), c->GetTarget()->GetWalkspeed());
|
||||||
c->Message(0, "Spawn Group: %i Grid: %i", c->GetTarget()->CastToNPC()->GetSp2(), c->GetTarget()->CastToNPC()->GetGrid());
|
c->Message(0, "Spawn Group: %i Grid: %i", c->GetTarget()->CastToNPC()->GetSp2(), c->GetTarget()->CastToNPC()->GetGrid());
|
||||||
c->Message(0, "EmoteID: %i", c->GetTarget()->CastToNPC()->GetEmoteID());
|
c->Message(0, "EmoteID: %i", c->GetTarget()->CastToNPC()->GetEmoteID());
|
||||||
c->GetTarget()->CastToNPC()->QueryLoot(c);
|
c->GetTarget()->CastToNPC()->QueryLoot(c);
|
||||||
@ -4393,7 +4393,7 @@ void command_time(Client *c, const Seperator *sep)
|
|||||||
else {
|
else {
|
||||||
c->Message(13, "To set the Time: #time HH [MM]");
|
c->Message(13, "To set the Time: #time HH [MM]");
|
||||||
TimeOfDay_Struct eqTime;
|
TimeOfDay_Struct eqTime;
|
||||||
zone->zone_time.getEQTimeOfDay( time(0), &eqTime);
|
zone->zone_time.GetCurrentEQTimeOfDay( time(0), &eqTime);
|
||||||
sprintf(timeMessage,"%02d:%s%d %s (Timezone: %ih %im)",
|
sprintf(timeMessage,"%02d:%s%d %s (Timezone: %ih %im)",
|
||||||
((eqTime.hour - 1) % 12) == 0 ? 12 : ((eqTime.hour - 1) % 12),
|
((eqTime.hour - 1) % 12) == 0 ? 12 : ((eqTime.hour - 1) % 12),
|
||||||
(eqTime.minute < 10) ? "0" : "",
|
(eqTime.minute < 10) ? "0" : "",
|
||||||
@ -8565,20 +8565,20 @@ void command_object(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
od.object_type = atoi(row[7]);
|
od.object_type = atoi(row[7]);
|
||||||
icon = atoi(row[8]);
|
icon = atoi(row[8]);
|
||||||
od.unknown008 = atoi(row[9]);
|
od.size = atoi(row[9]);
|
||||||
od.unknown010 = atoi(row[10]);
|
od.solidtype = atoi(row[10]);
|
||||||
od.unknown020 = atoi(row[11]);
|
od.unknown020 = atoi(row[11]);
|
||||||
|
|
||||||
switch (od.object_type) {
|
switch (od.object_type) {
|
||||||
case 0: // Static Object
|
case 0: // Static Object
|
||||||
case staticType: // Static Object unlocked for changes
|
case staticType: // Static Object unlocked for changes
|
||||||
if (od.unknown008 == 0) // Unknown08 field is optional Size parameter for static objects
|
if (od.size == 0) // Unknown08 field is optional Size parameter for static objects
|
||||||
od.unknown008 = 100; // Static object default Size is 100%
|
od.size = 100; // Static object default Size is 100%
|
||||||
|
|
||||||
c->Message(0, "- STATIC Object (%s): id %u, x %.1f, y %.1f, z %.1f, h %.1f, model %s, "
|
c->Message(0, "- STATIC Object (%s): id %u, x %.1f, y %.1f, z %.1f, h %.1f, model %s, "
|
||||||
"size %u, solidtype %u, incline %u",
|
"size %u, solidtype %u, incline %u",
|
||||||
(od.object_type == 0) ? "locked" : "unlocked", id, od.x, od.y, od.z,
|
(od.object_type == 0) ? "locked" : "unlocked", id, od.x, od.y, od.z,
|
||||||
od.heading, od.object_name, od.unknown008, od.unknown010, od.unknown020);
|
od.heading, od.object_name, od.size, od.solidtype, od.unknown020);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OT_DROPPEDITEM: // Ground Spawn
|
case OT_DROPPEDITEM: // Ground Spawn
|
||||||
@ -8636,10 +8636,10 @@ void command_object(Client *c, const Seperator *sep)
|
|||||||
switch (od.object_type) {
|
switch (od.object_type) {
|
||||||
case 0: // Static Object
|
case 0: // Static Object
|
||||||
if ((sep->argnum - col) > 3) {
|
if ((sep->argnum - col) > 3) {
|
||||||
od.unknown008 = atoi(sep->arg[4 + col]); // Size specified
|
od.size = atoi(sep->arg[4 + col]); // Size specified
|
||||||
|
|
||||||
if ((sep->argnum - col) > 4) {
|
if ((sep->argnum - col) > 4) {
|
||||||
od.unknown010 = atoi(sep->arg[5 + col]); // SolidType specified
|
od.solidtype = atoi(sep->arg[5 + col]); // SolidType specified
|
||||||
|
|
||||||
if ((sep->argnum - col) > 5)
|
if ((sep->argnum - col) > 5)
|
||||||
od.unknown020 = atoi(sep->arg[6 + col]); // Incline specified
|
od.unknown020 = atoi(sep->arg[6 + col]); // Incline specified
|
||||||
@ -8938,16 +8938,16 @@ void command_object(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
od.unknown008 = atoi(sep->arg[4]);
|
od.size = atoi(sep->arg[4]);
|
||||||
o->SetObjectData(&od);
|
o->SetObjectData(&od);
|
||||||
|
|
||||||
if (od.unknown008 == 0) // 0 == unspecified == 100%
|
if (od.size == 0) // 0 == unspecified == 100%
|
||||||
od.unknown008 = 100;
|
od.size = 100;
|
||||||
|
|
||||||
c->Message(0, "Static Object %u set to %u%% size. Size will take effect when you commit to the "
|
c->Message(0, "Static Object %u set to %u%% size. Size will take effect when you commit to the "
|
||||||
"database with '#object Save', after which the object will be unchangeable until "
|
"database with '#object Save', after which the object will be unchangeable until "
|
||||||
"you unlock it again with '#object Edit' and zone out and back in.",
|
"you unlock it again with '#object Edit' and zone out and back in.",
|
||||||
id, od.unknown008);
|
id, od.size);
|
||||||
} else if (strcmp(sep->arg[3], "solidtype") == 0) {
|
} else if (strcmp(sep->arg[3], "solidtype") == 0) {
|
||||||
|
|
||||||
if (od.object_type != staticType) {
|
if (od.object_type != staticType) {
|
||||||
@ -8962,13 +8962,13 @@ void command_object(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
od.unknown010 = atoi(sep->arg[4]);
|
od.solidtype = atoi(sep->arg[4]);
|
||||||
o->SetObjectData(&od);
|
o->SetObjectData(&od);
|
||||||
|
|
||||||
c->Message(0, "Static Object %u set to SolidType %u. Change will take effect when you commit "
|
c->Message(0, "Static Object %u set to SolidType %u. Change will take effect when you commit "
|
||||||
"to the database with '#object Save'. Support for this property is on a "
|
"to the database with '#object Save'. Support for this property is on a "
|
||||||
"per-model basis, mostly seen in smaller objects such as chests and tables.",
|
"per-model basis, mostly seen in smaller objects such as chests and tables.",
|
||||||
id, od.unknown010);
|
id, od.solidtype);
|
||||||
} else if (strcmp(sep->arg[3], "icon") == 0) {
|
} else if (strcmp(sep->arg[3], "icon") == 0) {
|
||||||
|
|
||||||
if ((od.object_type < 2) || (od.object_type == staticType)) {
|
if ((od.object_type < 2) || (od.object_type == staticType)) {
|
||||||
@ -9255,24 +9255,24 @@ void command_object(Client *c, const Seperator *sep)
|
|||||||
"unknown08 = %u, unknown10 = %u, unknown20 = %u "
|
"unknown08 = %u, unknown10 = %u, unknown20 = %u "
|
||||||
"WHERE ID = %u",
|
"WHERE ID = %u",
|
||||||
zone->GetZoneID(), zone->GetInstanceVersion(), od.x, od.y, od.z,
|
zone->GetZoneID(), zone->GetInstanceVersion(), od.x, od.y, od.z,
|
||||||
od.heading, od.object_name, od.object_type, icon, od.unknown008,
|
od.heading, od.object_name, od.object_type, icon, od.size,
|
||||||
od.unknown010, od.unknown020, id);
|
od.solidtype, od.unknown020, id);
|
||||||
else if (id == 0)
|
else if (id == 0)
|
||||||
query = StringFormat("INSERT INTO object "
|
query = StringFormat("INSERT INTO object "
|
||||||
"(zoneid, version, xpos, ypos, zpos, heading, objectname, "
|
"(zoneid, version, xpos, ypos, zpos, heading, objectname, "
|
||||||
"type, icon, unknown08, unknown10, unknown20) "
|
"type, icon, unknown08, unknown10, unknown20) "
|
||||||
"VALUES (%u, %u, %.1f, %.1f, %.1f, %.1f, '%s', %u, %u, %u, %u, %u)",
|
"VALUES (%u, %u, %.1f, %.1f, %.1f, %.1f, '%s', %u, %u, %u, %u, %u)",
|
||||||
zone->GetZoneID(), zone->GetInstanceVersion(), od.x, od.y, od.z,
|
zone->GetZoneID(), zone->GetInstanceVersion(), od.x, od.y, od.z,
|
||||||
od.heading, od.object_name, od.object_type, icon, od.unknown008,
|
od.heading, od.object_name, od.object_type, icon, od.size,
|
||||||
od.unknown010, od.unknown020);
|
od.solidtype, od.unknown020);
|
||||||
else
|
else
|
||||||
query = StringFormat("INSERT INTO object "
|
query = StringFormat("INSERT INTO object "
|
||||||
"(id, zoneid, version, xpos, ypos, zpos, heading, objectname, "
|
"(id, zoneid, version, xpos, ypos, zpos, heading, objectname, "
|
||||||
"type, icon, unknown08, unknown10, unknown20) "
|
"type, icon, unknown08, unknown10, unknown20) "
|
||||||
"VALUES (%u, %u, %u, %.1f, %.1f, %.1f, %.1f, '%s', %u, %u, %u, %u, %u)",
|
"VALUES (%u, %u, %u, %.1f, %.1f, %.1f, %.1f, '%s', %u, %u, %u, %u, %u)",
|
||||||
id, zone->GetZoneID(), zone->GetInstanceVersion(), od.x, od.y, od.z,
|
id, zone->GetZoneID(), zone->GetInstanceVersion(), od.x, od.y, od.z,
|
||||||
od.heading, od.object_name, od.object_type, icon, od.unknown008,
|
od.heading, od.object_name, od.object_type, icon, od.size,
|
||||||
od.unknown010, od.unknown020);
|
od.solidtype, od.unknown020);
|
||||||
|
|
||||||
results = database.QueryDatabase(query);
|
results = database.QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@ -9330,12 +9330,12 @@ void command_object(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
memcpy(door.dest_zone, "NONE", 5);
|
memcpy(door.dest_zone, "NONE", 5);
|
||||||
|
|
||||||
if ((door.size = od.unknown008) == 0) // unknown08 = optional size percentage
|
if ((door.size = od.size) == 0) // unknown08 = optional size percentage
|
||||||
door.size = 100;
|
door.size = 100;
|
||||||
|
|
||||||
switch (
|
switch (
|
||||||
door.opentype =
|
door.opentype =
|
||||||
od.unknown010) // unknown10 = optional request_nonsolid (0 or 1 or experimental number)
|
od.solidtype) // unknown10 = optional request_nonsolid (0 or 1 or experimental number)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
door.opentype = 31;
|
door.opentype = 31;
|
||||||
@ -9592,8 +9592,8 @@ void command_object(Client *c, const Seperator *sep)
|
|||||||
strn0cpy(od.object_name, row[4], sizeof(od.object_name));
|
strn0cpy(od.object_name, row[4], sizeof(od.object_name));
|
||||||
od.object_type = atoi(row[5]);
|
od.object_type = atoi(row[5]);
|
||||||
icon = atoi(row[6]);
|
icon = atoi(row[6]);
|
||||||
od.unknown008 = atoi(row[7]);
|
od.size = atoi(row[7]);
|
||||||
od.unknown010 = atoi(row[8]);
|
od.solidtype = atoi(row[8]);
|
||||||
od.unknown020 = atoi(row[9]);
|
od.unknown020 = atoi(row[9]);
|
||||||
|
|
||||||
if (od.object_type == 0)
|
if (od.object_type == 0)
|
||||||
|
|||||||
@ -173,6 +173,18 @@ enum class NumHit { // Numhits type
|
|||||||
OffensiveSpellProcs = 11 // Offensive buff procs
|
OffensiveSpellProcs = 11 // Offensive buff procs
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class PlayerState : uint32 {
|
||||||
|
None = 0,
|
||||||
|
Open = 1,
|
||||||
|
WeaponSheathed = 2,
|
||||||
|
Aggressive = 4,
|
||||||
|
ForcedAggressive = 8,
|
||||||
|
InstrumentEquipped = 16,
|
||||||
|
Stunned = 32,
|
||||||
|
PrimaryWeaponEquipped = 64,
|
||||||
|
SecondaryWeaponEquipped = 128
|
||||||
|
};
|
||||||
|
|
||||||
//this is our internal representation of the BUFF struct, can put whatever we want in it
|
//this is our internal representation of the BUFF struct, can put whatever we want in it
|
||||||
struct Buffs_Struct {
|
struct Buffs_Struct {
|
||||||
uint16 spellid;
|
uint16 spellid;
|
||||||
@ -190,6 +202,7 @@ struct Buffs_Struct {
|
|||||||
int32 caston_z;
|
int32 caston_z;
|
||||||
int32 ExtraDIChance;
|
int32 ExtraDIChance;
|
||||||
int16 RootBreakChance; //Not saved to dbase
|
int16 RootBreakChance; //Not saved to dbase
|
||||||
|
uint32 instrument_mod;
|
||||||
bool persistant_buff;
|
bool persistant_buff;
|
||||||
bool client; //True if the caster is a client
|
bool client; //True if the caster is a client
|
||||||
bool UpdateClient;
|
bool UpdateClient;
|
||||||
@ -455,6 +468,7 @@ typedef struct
|
|||||||
uint16 spellID;
|
uint16 spellID;
|
||||||
uint16 chance;
|
uint16 chance;
|
||||||
uint16 base_spellID;
|
uint16 base_spellID;
|
||||||
|
int level_override;
|
||||||
} tProc;
|
} tProc;
|
||||||
|
|
||||||
struct Shielders_Struct {
|
struct Shielders_Struct {
|
||||||
@ -507,7 +521,8 @@ typedef enum {
|
|||||||
petOther,
|
petOther,
|
||||||
petCharmed,
|
petCharmed,
|
||||||
petNPCFollow,
|
petNPCFollow,
|
||||||
petTargetLock //remain active as long something is on the hatelist. Don't listen to any commands
|
petTargetLock, //remain active as long something is on the hatelist. Don't listen to any commands
|
||||||
|
petNone = 0xFF // not a pet
|
||||||
} PetType;
|
} PetType;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
@ -421,16 +421,21 @@ int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
|
|||||||
int tic_inc = 0;
|
int tic_inc = 0;
|
||||||
tic_inc = GetFocusEffect(focusSpellDurByTic, spell_id);
|
tic_inc = GetFocusEffect(focusSpellDurByTic, spell_id);
|
||||||
|
|
||||||
// Only need this for clients, since the change was for bard songs, I assume we should keep non bard songs getting +1
|
// unsure on the exact details, but bard songs that don't cost mana at some point get an extra tick, 60 for now
|
||||||
// However if its bard or not and is mez, charm or fear, we need to add 1 so that client is in sync
|
// a level 53 bard reported getting 2 tics
|
||||||
if (IsClient() && !(IsShortDurationBuff(spell_id) && IsBardSong(spell_id)) ||
|
// bard DOTs do get this extra tick, but beneficial long bard songs don't? (invul, crescendo)
|
||||||
IsFearSpell(spell_id) ||
|
if ((IsShortDurationBuff(spell_id) || IsDetrimentalSpell(spell_id)) && IsBardSong(spell_id) &&
|
||||||
IsCharmSpell(spell_id) ||
|
spells[spell_id].mana == 0 && GetClass() == BARD && GetLevel() > 60)
|
||||||
IsMezSpell(spell_id) ||
|
tic_inc++;
|
||||||
IsBlindSpell(spell_id))
|
float focused = ((duration * increase) / 100.0f) + tic_inc;
|
||||||
tic_inc += 1;
|
int ifocused = static_cast<int>(focused);
|
||||||
|
|
||||||
return (((duration * increase) / 100) + tic_inc);
|
// 7.6 is rounded to 7, 8.6 is rounded to 9
|
||||||
|
// 6 is 6, etc
|
||||||
|
if (FCMP(focused, ifocused) || ifocused % 2) // equal or odd
|
||||||
|
return ifocused;
|
||||||
|
else // even and not equal round to odd
|
||||||
|
return ifocused + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 Client::GetActSpellCasttime(uint16 spell_id, int32 casttime)
|
int32 Client::GetActSpellCasttime(uint16 spell_id, int32 casttime)
|
||||||
|
|||||||
@ -1072,7 +1072,7 @@ void PerlembParser::ExportZoneVariables(std::string &package_name) {
|
|||||||
ExportVar(package_name.c_str(), "instanceid", zone->GetInstanceID());
|
ExportVar(package_name.c_str(), "instanceid", zone->GetInstanceID());
|
||||||
ExportVar(package_name.c_str(), "instanceversion", zone->GetInstanceVersion());
|
ExportVar(package_name.c_str(), "instanceversion", zone->GetInstanceVersion());
|
||||||
TimeOfDay_Struct eqTime;
|
TimeOfDay_Struct eqTime;
|
||||||
zone->zone_time.getEQTimeOfDay( time(0), &eqTime);
|
zone->zone_time.GetCurrentEQTimeOfDay( time(0), &eqTime);
|
||||||
ExportVar(package_name.c_str(), "zonehour", eqTime.hour - 1);
|
ExportVar(package_name.c_str(), "zonehour", eqTime.hour - 1);
|
||||||
ExportVar(package_name.c_str(), "zonemin", eqTime.minute);
|
ExportVar(package_name.c_str(), "zonemin", eqTime.minute);
|
||||||
ExportVar(package_name.c_str(), "zonetime", (eqTime.hour - 1) * 100 + eqTime.minute);
|
ExportVar(package_name.c_str(), "zonetime", (eqTime.hour - 1) * 100 + eqTime.minute);
|
||||||
@ -1277,6 +1277,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
|||||||
|
|
||||||
case EVENT_PLAYER_PICKUP:{
|
case EVENT_PLAYER_PICKUP:{
|
||||||
ExportVar(package_name.c_str(), "picked_up_id", data);
|
ExportVar(package_name.c_str(), "picked_up_id", data);
|
||||||
|
ExportVar(package_name.c_str(), "picked_up_entity_id", extradata);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1320,6 +1321,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
|||||||
ExportVar(package_name.c_str(), "itemid", objid);
|
ExportVar(package_name.c_str(), "itemid", objid);
|
||||||
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
|
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
|
||||||
ExportVar(package_name.c_str(), "slotid", extradata);
|
ExportVar(package_name.c_str(), "slotid", extradata);
|
||||||
|
ExportVar(package_name.c_str(), "spell_id", iteminst->GetItem()->Click.Effect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1367,6 +1369,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
|||||||
|
|
||||||
case EVENT_CLICK_OBJECT: {
|
case EVENT_CLICK_OBJECT: {
|
||||||
ExportVar(package_name.c_str(), "objectid", data);
|
ExportVar(package_name.c_str(), "objectid", data);
|
||||||
|
ExportVar(package_name.c_str(), "clicker_id", extradata);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1397,6 +1400,14 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
|||||||
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
|
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case EVENT_DROP_ITEM: {
|
||||||
|
ExportVar(package_name.c_str(), "quantity", iteminst->IsStackable() ? iteminst->GetCharges() : 1);
|
||||||
|
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
|
||||||
|
ExportVar(package_name.c_str(), "itemid", iteminst->GetItem()->ID);
|
||||||
|
ExportVar(package_name.c_str(), "spell_id", iteminst->GetItem()->Click.Effect);
|
||||||
|
ExportVar(package_name.c_str(), "slotid", extradata);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1182,13 +1182,26 @@ XS(XS__settime);
|
|||||||
XS(XS__settime)
|
XS(XS__settime)
|
||||||
{
|
{
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
if (items != 2)
|
if (items < 2)
|
||||||
Perl_croak(aTHX_ "Usage: settime(new_hour, new_min)");
|
Perl_croak(aTHX_ "Usage: settime(new_hour, new_min, [update_world = true])");
|
||||||
|
|
||||||
int new_hour = (int)SvIV(ST(0));
|
if (items == 2){
|
||||||
int new_min = (int)SvIV(ST(1));
|
int new_hour = (int)SvIV(ST(0));
|
||||||
|
int new_min = (int)SvIV(ST(1));
|
||||||
|
quest_manager.settime(new_hour, new_min, true);
|
||||||
|
}
|
||||||
|
else if (items == 3){
|
||||||
|
int new_hour = (int)SvIV(ST(0));
|
||||||
|
int new_min = (int)SvIV(ST(1));
|
||||||
|
|
||||||
quest_manager.settime(new_hour, new_min);
|
int update_world = (int)SvIV(ST(2));
|
||||||
|
if (update_world == 1){
|
||||||
|
quest_manager.settime(new_hour, new_min, true);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
quest_manager.settime(new_hour, new_min, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
@ -1917,6 +1930,52 @@ XS(XS__repopzone)
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS__ConnectNodeToNode);
|
||||||
|
XS(XS__ConnectNodeToNode)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 4)
|
||||||
|
Perl_croak(aTHX_ "Usage: ConnectNodeToNode(node1, node2, teleport, doorid)");
|
||||||
|
|
||||||
|
int node1 = (int)SvIV(ST(0));
|
||||||
|
int node2 = (int)SvIV(ST(1));
|
||||||
|
int teleport = (int)SvIV(ST(2));
|
||||||
|
int doorid = (int)SvIV(ST(3));
|
||||||
|
|
||||||
|
quest_manager.ConnectNodeToNode(node1, node2, teleport, doorid);
|
||||||
|
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS__AddNode);
|
||||||
|
XS(XS__AddNode)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
//void QuestManager::AddNode(float x, float y, float z, float best_z, int32 requested_id);
|
||||||
|
if (items < 3 || items > 5)
|
||||||
|
Perl_croak(aTHX_ "Usage: AddNode(x, y, z, [best_z], [requested_id])");
|
||||||
|
|
||||||
|
int x = (int)SvIV(ST(0));
|
||||||
|
int y = (int)SvIV(ST(1));
|
||||||
|
int z = (int)SvIV(ST(2));
|
||||||
|
int best_z = 0;
|
||||||
|
int requested_id = 0;
|
||||||
|
|
||||||
|
if (items == 4)
|
||||||
|
{
|
||||||
|
best_z = (int)SvIV(ST(3));
|
||||||
|
}
|
||||||
|
else if (items == 5)
|
||||||
|
{
|
||||||
|
best_z = (int)SvIV(ST(3));
|
||||||
|
requested_id = (int)SvIV(ST(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
quest_manager.AddNode(x, y, z, best_z, requested_id);
|
||||||
|
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS__npcrace);
|
XS(XS__npcrace);
|
||||||
XS(XS__npcrace)
|
XS(XS__npcrace)
|
||||||
{
|
{
|
||||||
@ -3699,6 +3758,8 @@ EXTERN_C XS(boot_quest)
|
|||||||
newXS(strcpy(buf, "reloadzonestaticdata"), XS__reloadzonestaticdata, file);
|
newXS(strcpy(buf, "reloadzonestaticdata"), XS__reloadzonestaticdata, file);
|
||||||
newXS(strcpy(buf, "removetitle"), XS__removetitle, file);
|
newXS(strcpy(buf, "removetitle"), XS__removetitle, file);
|
||||||
newXS(strcpy(buf, "repopzone"), XS__repopzone, file);
|
newXS(strcpy(buf, "repopzone"), XS__repopzone, file);
|
||||||
|
newXS(strcpy(buf, "ConnectNodeToNode"), XS__ConnectNodeToNode, file);
|
||||||
|
newXS(strcpy(buf, "AddNode"), XS__AddNode, file);
|
||||||
newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file);
|
newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file);
|
||||||
newXS(strcpy(buf, "respawn"), XS__respawn, file);
|
newXS(strcpy(buf, "respawn"), XS__respawn, file);
|
||||||
newXS(strcpy(buf, "resume"), XS__resume, file);
|
newXS(strcpy(buf, "resume"), XS__resume, file);
|
||||||
|
|||||||
53
zone/encounter.cpp
Normal file
53
zone/encounter.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/* EQEMu: Everquest Server Emulator
|
||||||
|
Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net)
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
are required to give you total support for your newly bought product;
|
||||||
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _WINDOWS
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#define vsnprintf _vsnprintf
|
||||||
|
#define strncasecmp _strnicmp
|
||||||
|
#define strcasecmp _stricmp
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../common/races.h"
|
||||||
|
#include "encounter.h"
|
||||||
|
#include "entity.h"
|
||||||
|
#include "mob.h"
|
||||||
|
|
||||||
|
class Zone;
|
||||||
|
|
||||||
|
Encounter::Encounter(const char* enc_name)
|
||||||
|
:Mob
|
||||||
|
(
|
||||||
|
nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, glm::vec4(0,0,0,0), 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
encounter_name[0] = 0;
|
||||||
|
strn0cpy(encounter_name, enc_name, 64);
|
||||||
|
remove_me = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Encounter::~Encounter()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Encounter::Process() {
|
||||||
|
if (remove_me) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
62
zone/encounter.h
Normal file
62
zone/encounter.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/* EQEMu: Everquest Server Emulator
|
||||||
|
Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net)
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
are required to give you total support for your newly bought product;
|
||||||
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ENCOUNTER_H
|
||||||
|
#define ENCOUNTER_H
|
||||||
|
|
||||||
|
#include "mob.h"
|
||||||
|
#include "../common/types.h"
|
||||||
|
#include "../common/timer.h"
|
||||||
|
|
||||||
|
class Group;
|
||||||
|
class Raid;
|
||||||
|
struct ExtraAttackOptions;
|
||||||
|
|
||||||
|
class Encounter : public Mob
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Encounter(const char* enc_name);
|
||||||
|
~Encounter();
|
||||||
|
|
||||||
|
//abstract virtual function implementations required by base abstract class
|
||||||
|
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; }
|
||||||
|
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; }
|
||||||
|
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||||
|
ExtraAttackOptions *opts = nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual bool HasRaid() { return false; }
|
||||||
|
virtual bool HasGroup() { return false; }
|
||||||
|
virtual Raid* GetRaid() { return 0; }
|
||||||
|
virtual Group* GetGroup() { return 0; }
|
||||||
|
|
||||||
|
bool IsEncounter() const { return true; }
|
||||||
|
const char* GetEncounterName() const { return encounter_name; }
|
||||||
|
|
||||||
|
bool Process();
|
||||||
|
virtual void Depop(bool not_used = true) { remove_me = true; }
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool remove_me;
|
||||||
|
char encounter_name[64];
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -173,6 +173,11 @@ Beacon *Entity::CastToBeacon()
|
|||||||
return static_cast<Beacon *>(this);
|
return static_cast<Beacon *>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Encounter *Entity::CastToEncounter()
|
||||||
|
{
|
||||||
|
return static_cast<Encounter *>(this);
|
||||||
|
}
|
||||||
|
|
||||||
const Client *Entity::CastToClient() const
|
const Client *Entity::CastToClient() const
|
||||||
{
|
{
|
||||||
if (this == 0x00) {
|
if (this == 0x00) {
|
||||||
@ -263,6 +268,11 @@ const Beacon* Entity::CastToBeacon() const
|
|||||||
return static_cast<const Beacon *>(this);
|
return static_cast<const Beacon *>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Encounter* Entity::CastToEncounter() const
|
||||||
|
{
|
||||||
|
return static_cast<const Encounter *>(this);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
Bot *Entity::CastToBot()
|
Bot *Entity::CastToBot()
|
||||||
{
|
{
|
||||||
@ -533,6 +543,21 @@ void EntityList::BeaconProcess()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityList::EncounterProcess()
|
||||||
|
{
|
||||||
|
auto it = encounter_list.begin();
|
||||||
|
while (it != encounter_list.end()) {
|
||||||
|
if (!it->second->Process()) {
|
||||||
|
safe_delete(it->second);
|
||||||
|
free_ids.push(it->first);
|
||||||
|
it = encounter_list.erase(it);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EntityList::AddGroup(Group *group)
|
void EntityList::AddGroup(Group *group)
|
||||||
{
|
{
|
||||||
if (group == nullptr) //this seems to be happening somehow...
|
if (group == nullptr) //this seems to be happening somehow...
|
||||||
@ -618,6 +643,8 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
|
|||||||
EQApplicationPacket *app = new EQApplicationPacket;
|
EQApplicationPacket *app = new EQApplicationPacket;
|
||||||
npc->CreateSpawnPacket(app, npc);
|
npc->CreateSpawnPacket(app, npc);
|
||||||
QueueClients(npc, app);
|
QueueClients(npc, app);
|
||||||
|
npc->SendArmorAppearance();
|
||||||
|
npc->SetAppearance(npc->GetGuardPointAnim(),false);
|
||||||
safe_delete(app);
|
safe_delete(app);
|
||||||
} else {
|
} else {
|
||||||
NewSpawn_Struct *ns = new NewSpawn_Struct;
|
NewSpawn_Struct *ns = new NewSpawn_Struct;
|
||||||
@ -706,6 +733,12 @@ void EntityList::AddBeacon(Beacon *beacon)
|
|||||||
beacon_list.insert(std::pair<uint16, Beacon *>(beacon->GetID(), beacon));
|
beacon_list.insert(std::pair<uint16, Beacon *>(beacon->GetID(), beacon));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityList::AddEncounter(Encounter *encounter)
|
||||||
|
{
|
||||||
|
encounter->SetID(GetFreeID());
|
||||||
|
encounter_list.insert(std::pair<uint16, Encounter *>(encounter->GetID(), encounter));
|
||||||
|
}
|
||||||
|
|
||||||
void EntityList::AddToSpawnQueue(uint16 entityid, NewSpawn_Struct **ns)
|
void EntityList::AddToSpawnQueue(uint16 entityid, NewSpawn_Struct **ns)
|
||||||
{
|
{
|
||||||
uint32 count;
|
uint32 count;
|
||||||
@ -726,10 +759,23 @@ void EntityList::CheckSpawnQueue()
|
|||||||
EQApplicationPacket *outapp = 0;
|
EQApplicationPacket *outapp = 0;
|
||||||
|
|
||||||
iterator.Reset();
|
iterator.Reset();
|
||||||
|
NewSpawn_Struct *ns;
|
||||||
|
|
||||||
while(iterator.MoreElements()) {
|
while(iterator.MoreElements()) {
|
||||||
outapp = new EQApplicationPacket;
|
outapp = new EQApplicationPacket;
|
||||||
Mob::CreateSpawnPacket(outapp, iterator.GetData());
|
ns = iterator.GetData();
|
||||||
|
Mob::CreateSpawnPacket(outapp, ns);
|
||||||
QueueClients(0, outapp);
|
QueueClients(0, outapp);
|
||||||
|
auto it = npc_list.find(ns->spawn.spawnId);
|
||||||
|
if (it == npc_list.end()) {
|
||||||
|
// We must of despawned, hope that's the reason!
|
||||||
|
Log.Out(Logs::General, Logs::Error, "Error in EntityList::CheckSpawnQueue: Unable to find NPC for spawnId '%u'", ns->spawn.spawnId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NPC *pnpc = it->second;
|
||||||
|
pnpc->SendArmorAppearance();
|
||||||
|
pnpc->SetAppearance(pnpc->GetGuardPointAnim(), false);
|
||||||
|
}
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
iterator.RemoveCurrent();
|
iterator.RemoveCurrent();
|
||||||
}
|
}
|
||||||
@ -920,6 +966,11 @@ Entity *EntityList::GetEntityBeacon(uint16 id)
|
|||||||
return beacon_list.count(id) ? beacon_list.at(id) : nullptr;
|
return beacon_list.count(id) ? beacon_list.at(id) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Entity *EntityList::GetEntityEncounter(uint16 id)
|
||||||
|
{
|
||||||
|
return encounter_list.count(id) ? encounter_list.at(id) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Entity *EntityList::GetID(uint16 get_id)
|
Entity *EntityList::GetID(uint16 get_id)
|
||||||
{
|
{
|
||||||
Entity *ent = 0;
|
Entity *ent = 0;
|
||||||
@ -935,6 +986,8 @@ Entity *EntityList::GetID(uint16 get_id)
|
|||||||
return ent;
|
return ent;
|
||||||
else if ((ent=entity_list.GetEntityBeacon(get_id)) != 0)
|
else if ((ent=entity_list.GetEntityBeacon(get_id)) != 0)
|
||||||
return ent;
|
return ent;
|
||||||
|
else if ((ent = entity_list.GetEntityEncounter(get_id)) != 0)
|
||||||
|
return ent;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1149,19 +1202,39 @@ void EntityList::SendZoneSpawnsBulk(Client *client)
|
|||||||
NewSpawn_Struct ns;
|
NewSpawn_Struct ns;
|
||||||
Mob *spawn;
|
Mob *spawn;
|
||||||
uint32 maxspawns = 100;
|
uint32 maxspawns = 100;
|
||||||
|
EQApplicationPacket *app;
|
||||||
|
|
||||||
if (maxspawns > mob_list.size())
|
if (maxspawns > mob_list.size())
|
||||||
maxspawns = mob_list.size();
|
maxspawns = mob_list.size();
|
||||||
BulkZoneSpawnPacket *bzsp = new BulkZoneSpawnPacket(client, maxspawns);
|
BulkZoneSpawnPacket *bzsp = new BulkZoneSpawnPacket(client, maxspawns);
|
||||||
|
|
||||||
|
int32 race=-1;
|
||||||
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
|
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
|
||||||
spawn = it->second;
|
spawn = it->second;
|
||||||
if (spawn && spawn->InZone()) {
|
if (spawn && spawn->InZone()) {
|
||||||
if (spawn->IsClient() && (spawn->CastToClient()->GMHideMe(client) ||
|
if (spawn->IsClient() && (spawn->CastToClient()->GMHideMe(client) ||
|
||||||
spawn->CastToClient()->IsHoveringForRespawn()))
|
spawn->CastToClient()->IsHoveringForRespawn()))
|
||||||
continue;
|
continue;
|
||||||
memset(&ns, 0, sizeof(NewSpawn_Struct));
|
|
||||||
spawn->FillSpawnStruct(&ns, client);
|
race = spawn->GetRace();
|
||||||
bzsp->AddSpawn(&ns);
|
|
||||||
|
// Illusion races on PCs don't work as a mass spawn
|
||||||
|
// But they will work as an add_spawn AFTER CLIENT_CONNECTED.
|
||||||
|
if (spawn->IsClient() && (race == MINOR_ILL_OBJ || race == TREE)) {
|
||||||
|
app = new EQApplicationPacket;
|
||||||
|
spawn->CreateSpawnPacket(app);
|
||||||
|
client->QueuePacket(app, true, Client::CLIENT_CONNECTED);
|
||||||
|
safe_delete(app);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memset(&ns, 0, sizeof(NewSpawn_Struct));
|
||||||
|
spawn->FillSpawnStruct(&ns, client);
|
||||||
|
bzsp->AddSpawn(&ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Despite being sent in the OP_ZoneSpawns packet, the client
|
||||||
|
// does not display worn armor correctly so display it.
|
||||||
|
spawn->SendArmorAppearance(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
safe_delete(bzsp);
|
safe_delete(bzsp);
|
||||||
@ -1355,7 +1428,9 @@ void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *ap
|
|||||||
if (c != sender) {
|
if (c != sender) {
|
||||||
if (Target == sender) {
|
if (Target == sender) {
|
||||||
if (inspect_buffs) { // if inspect_buffs is true we're sending a mob's buffs to those with the LAA
|
if (inspect_buffs) { // if inspect_buffs is true we're sending a mob's buffs to those with the LAA
|
||||||
if (c->IsRaidGrouped()) {
|
if (c->GetGM() || RuleB(Spells, AlwaysSendTargetsBuffs)) {
|
||||||
|
Send = true;
|
||||||
|
} else if (c->IsRaidGrouped()) {
|
||||||
Raid *raid = c->GetRaid();
|
Raid *raid = c->GetRaid();
|
||||||
if (!raid)
|
if (!raid)
|
||||||
continue;
|
continue;
|
||||||
@ -3389,6 +3464,15 @@ bool EntityList::IsMobInZone(Mob *who)
|
|||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto enc_it = encounter_list.begin();
|
||||||
|
while (enc_it != encounter_list.end()) {
|
||||||
|
if (enc_it->second == who) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
++enc_it;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "zonedump.h"
|
#include "zonedump.h"
|
||||||
|
|
||||||
|
class Encounter;
|
||||||
class Beacon;
|
class Beacon;
|
||||||
class Client;
|
class Client;
|
||||||
class Corpse;
|
class Corpse;
|
||||||
@ -77,6 +78,7 @@ public:
|
|||||||
virtual bool IsDoor() const { return false; }
|
virtual bool IsDoor() const { return false; }
|
||||||
virtual bool IsTrap() const { return false; }
|
virtual bool IsTrap() const { return false; }
|
||||||
virtual bool IsBeacon() const { return false; }
|
virtual bool IsBeacon() const { return false; }
|
||||||
|
virtual bool IsEncounter() const { return false; }
|
||||||
|
|
||||||
virtual bool Process() { return false; }
|
virtual bool Process() { return false; }
|
||||||
virtual bool Save() { return true; }
|
virtual bool Save() { return true; }
|
||||||
@ -91,6 +93,7 @@ public:
|
|||||||
Doors *CastToDoors();
|
Doors *CastToDoors();
|
||||||
Trap *CastToTrap();
|
Trap *CastToTrap();
|
||||||
Beacon *CastToBeacon();
|
Beacon *CastToBeacon();
|
||||||
|
Encounter *CastToEncounter();
|
||||||
|
|
||||||
const Client *CastToClient() const;
|
const Client *CastToClient() const;
|
||||||
const NPC *CastToNPC() const;
|
const NPC *CastToNPC() const;
|
||||||
@ -101,6 +104,7 @@ public:
|
|||||||
const Doors *CastToDoors() const;
|
const Doors *CastToDoors() const;
|
||||||
const Trap *CastToTrap() const;
|
const Trap *CastToTrap() const;
|
||||||
const Beacon *CastToBeacon() const;
|
const Beacon *CastToBeacon() const;
|
||||||
|
const Encounter *CastToEncounter() const;
|
||||||
|
|
||||||
inline const uint16& GetID() const { return id; }
|
inline const uint16& GetID() const { return id; }
|
||||||
inline const time_t& GetSpawnTimeStamp() const { return spawn_timestamp; }
|
inline const time_t& GetSpawnTimeStamp() const { return spawn_timestamp; }
|
||||||
@ -203,6 +207,7 @@ public:
|
|||||||
void MobProcess();
|
void MobProcess();
|
||||||
void TrapProcess();
|
void TrapProcess();
|
||||||
void BeaconProcess();
|
void BeaconProcess();
|
||||||
|
void EncounterProcess();
|
||||||
void ProcessMove(Client *c, const glm::vec3& location);
|
void ProcessMove(Client *c, const glm::vec3& location);
|
||||||
void ProcessMove(NPC *n, float x, float y, float z);
|
void ProcessMove(NPC *n, float x, float y, float z);
|
||||||
void AddArea(int id, int type, float min_x, float max_x, float min_y, float max_y, float min_z, float max_z);
|
void AddArea(int id, int type, float min_x, float max_x, float min_y, float max_y, float min_z, float max_z);
|
||||||
@ -228,6 +233,7 @@ public:
|
|||||||
void AddDoor(Doors* door);
|
void AddDoor(Doors* door);
|
||||||
void AddTrap(Trap* trap);
|
void AddTrap(Trap* trap);
|
||||||
void AddBeacon(Beacon *beacon);
|
void AddBeacon(Beacon *beacon);
|
||||||
|
void AddEncounter(Encounter *encounter);
|
||||||
void AddProximity(NPC *proximity_for);
|
void AddProximity(NPC *proximity_for);
|
||||||
void Clear();
|
void Clear();
|
||||||
bool RemoveMob(uint16 delete_id);
|
bool RemoveMob(uint16 delete_id);
|
||||||
@ -266,6 +272,7 @@ public:
|
|||||||
Entity *GetEntityCorpse(uint16 id);
|
Entity *GetEntityCorpse(uint16 id);
|
||||||
Entity *GetEntityTrap(uint16 id);
|
Entity *GetEntityTrap(uint16 id);
|
||||||
Entity *GetEntityBeacon(uint16 id);
|
Entity *GetEntityBeacon(uint16 id);
|
||||||
|
Entity *GetEntityEncounter(uint16 id);
|
||||||
Entity *GetEntityMob(const char *name);
|
Entity *GetEntityMob(const char *name);
|
||||||
Entity *GetEntityCorpse(const char *name);
|
Entity *GetEntityCorpse(const char *name);
|
||||||
|
|
||||||
@ -448,6 +455,7 @@ private:
|
|||||||
std::unordered_map<uint16, Doors *> door_list;
|
std::unordered_map<uint16, Doors *> door_list;
|
||||||
std::unordered_map<uint16, Trap *> trap_list;
|
std::unordered_map<uint16, Trap *> trap_list;
|
||||||
std::unordered_map<uint16, Beacon *> beacon_list;
|
std::unordered_map<uint16, Beacon *> beacon_list;
|
||||||
|
std::unordered_map<uint16, Encounter *> encounter_list;
|
||||||
std::list<NPC *> proximity_list;
|
std::list<NPC *> proximity_list;
|
||||||
std::list<Group *> group_list;
|
std::list<Group *> group_list;
|
||||||
std::list<Raid *> raid_list;
|
std::list<Raid *> raid_list;
|
||||||
|
|||||||
137
zone/exp.cpp
137
zone/exp.cpp
@ -59,6 +59,97 @@ static uint32 MaxBankedRaidLeadershipPoints(int Level)
|
|||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 Client::CalcEXP(uint8 conlevel) {
|
||||||
|
|
||||||
|
uint32 in_add_exp = EXP_FORMULA;
|
||||||
|
|
||||||
|
|
||||||
|
if((XPRate != 0))
|
||||||
|
in_add_exp = static_cast<uint32>(in_add_exp * (static_cast<float>(XPRate) / 100.0f));
|
||||||
|
|
||||||
|
float totalmod = 1.0;
|
||||||
|
float zemmod = 1.0;
|
||||||
|
//get modifiers
|
||||||
|
if(RuleR(Character, ExpMultiplier) >= 0){
|
||||||
|
totalmod *= RuleR(Character, ExpMultiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(zone->newzone_data.zone_exp_multiplier >= 0){
|
||||||
|
zemmod *= zone->newzone_data.zone_exp_multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(RuleB(Character,UseRaceClassExpBonuses))
|
||||||
|
{
|
||||||
|
if(GetBaseRace() == HALFLING){
|
||||||
|
totalmod *= 1.05;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetClass() == ROGUE || GetClass() == WARRIOR){
|
||||||
|
totalmod *= 1.05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(zone->IsHotzone())
|
||||||
|
{
|
||||||
|
totalmod += RuleR(Zone, HotZoneBonus);
|
||||||
|
}
|
||||||
|
|
||||||
|
in_add_exp = uint32(float(in_add_exp) * totalmod * zemmod);
|
||||||
|
|
||||||
|
if(RuleB(Character,UseXPConScaling))
|
||||||
|
{
|
||||||
|
if (conlevel != 0xFF) {
|
||||||
|
switch (conlevel)
|
||||||
|
{
|
||||||
|
case CON_GREEN:
|
||||||
|
in_add_exp = 0;
|
||||||
|
return 0;
|
||||||
|
case CON_LIGHTBLUE:
|
||||||
|
in_add_exp = in_add_exp * RuleI(Character, LightBlueModifier)/100;
|
||||||
|
break;
|
||||||
|
case CON_BLUE:
|
||||||
|
in_add_exp = in_add_exp * RuleI(Character, BlueModifier)/100;
|
||||||
|
break;
|
||||||
|
case CON_WHITE:
|
||||||
|
in_add_exp = in_add_exp * RuleI(Character, WhiteModifier)/100;
|
||||||
|
break;
|
||||||
|
case CON_YELLOW:
|
||||||
|
in_add_exp = in_add_exp * RuleI(Character, YellowModifier)/100;
|
||||||
|
break;
|
||||||
|
case CON_RED:
|
||||||
|
in_add_exp = in_add_exp * RuleI(Character, RedModifier)/100;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float aatotalmod = 1.0;
|
||||||
|
if(zone->newzone_data.zone_exp_multiplier >= 0){
|
||||||
|
aatotalmod *= zone->newzone_data.zone_exp_multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(RuleB(Character,UseRaceClassExpBonuses))
|
||||||
|
{
|
||||||
|
if(GetBaseRace() == HALFLING){
|
||||||
|
aatotalmod *= 1.05;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetClass() == ROGUE || GetClass() == WARRIOR){
|
||||||
|
aatotalmod *= 1.05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(RuleB(Zone, LevelBasedEXPMods)){
|
||||||
|
if(zone->level_exp_mod[GetLevel()].ExpMod){
|
||||||
|
in_add_exp *= zone->level_exp_mod[GetLevel()].ExpMod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return in_add_exp;
|
||||||
|
}
|
||||||
|
|
||||||
void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||||
|
|
||||||
ItemScriptStopReturn();
|
ItemScriptStopReturn();
|
||||||
@ -78,7 +169,7 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
|||||||
|
|
||||||
//figure out how much of this goes to AAs
|
//figure out how much of this goes to AAs
|
||||||
add_aaxp = add_exp * m_epp.perAA / 100;
|
add_aaxp = add_exp * m_epp.perAA / 100;
|
||||||
//take that ammount away from regular exp
|
//take that amount away from regular exp
|
||||||
add_exp -= add_aaxp;
|
add_exp -= add_aaxp;
|
||||||
|
|
||||||
float totalmod = 1.0;
|
float totalmod = 1.0;
|
||||||
@ -247,12 +338,22 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
Message(13, "Error in Client::SetEXP. EXP not set.");
|
Message(13, "Error in Client::SetEXP. EXP not set.");
|
||||||
return; // Must be invalid class/race
|
return; // Must be invalid class/race
|
||||||
}
|
}
|
||||||
|
uint32 i = 0;
|
||||||
|
uint32 membercount = 0;
|
||||||
|
if(GetGroup())
|
||||||
|
{
|
||||||
|
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||||
|
if (GetGroup()->members[i] != nullptr) {
|
||||||
|
membercount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((set_exp + set_aaxp) > (m_pp.exp+m_pp.expAA)) {
|
if ((set_exp + set_aaxp) > (m_pp.exp+m_pp.expAA)) {
|
||||||
if (isrezzexp)
|
if (isrezzexp)
|
||||||
this->Message_StringID(MT_Experience, REZ_REGAIN);
|
this->Message_StringID(MT_Experience, REZ_REGAIN);
|
||||||
else{
|
else{
|
||||||
if(this->IsGrouped())
|
if(membercount > 1)
|
||||||
this->Message_StringID(MT_Experience, GAIN_GROUPXP);
|
this->Message_StringID(MT_Experience, GAIN_GROUPXP);
|
||||||
else if(IsRaidGrouped())
|
else if(IsRaidGrouped())
|
||||||
Message_StringID(MT_Experience, GAIN_RAIDEXP);
|
Message_StringID(MT_Experience, GAIN_RAIDEXP);
|
||||||
@ -268,12 +369,17 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
//this ammount of exp (once these loops complete)
|
//this ammount of exp (once these loops complete)
|
||||||
uint16 check_level = GetLevel()+1;
|
uint16 check_level = GetLevel()+1;
|
||||||
//see if we gained any levels
|
//see if we gained any levels
|
||||||
|
bool level_increase = true;
|
||||||
|
int8 level_count = 0;
|
||||||
|
|
||||||
while (set_exp >= GetEXPForLevel(check_level)) {
|
while (set_exp >= GetEXPForLevel(check_level)) {
|
||||||
check_level++;
|
check_level++;
|
||||||
if (check_level > 127) { //hard level cap
|
if (check_level > 127) { //hard level cap
|
||||||
check_level = 127;
|
check_level = 127;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
level_count++;
|
||||||
|
|
||||||
if(GetMercID())
|
if(GetMercID())
|
||||||
UpdateMercLevel();
|
UpdateMercLevel();
|
||||||
}
|
}
|
||||||
@ -284,6 +390,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
check_level = 2;
|
check_level = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
level_increase = false;
|
||||||
if(GetMercID())
|
if(GetMercID())
|
||||||
UpdateMercLevel();
|
UpdateMercLevel();
|
||||||
}
|
}
|
||||||
@ -364,17 +471,21 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
|
|
||||||
if ((GetLevel() != check_level) && !(check_level >= maxlevel)) {
|
if ((GetLevel() != check_level) && !(check_level >= maxlevel)) {
|
||||||
char val1[20]={0};
|
char val1[20]={0};
|
||||||
if (GetLevel() == check_level-1){
|
if (level_increase)
|
||||||
Message_StringID(MT_Experience, GAIN_LEVEL,ConvertArray(check_level,val1));
|
{
|
||||||
SendLevelAppearance();
|
if (level_count == 1)
|
||||||
/* Message(15, "You have gained a level! Welcome to level %i!", check_level); */
|
Message_StringID(MT_Experience, GAIN_LEVEL, ConvertArray(check_level, val1));
|
||||||
}
|
else
|
||||||
if (GetLevel() == check_level){
|
Message(15, "Welcome to level %i!", check_level);
|
||||||
Message_StringID(MT_Experience, LOSE_LEVEL,ConvertArray(check_level,val1));
|
|
||||||
/* Message(15, "You lost a level! You are now level %i!", check_level); */
|
if (check_level == RuleI(Character, DeathItemLossLevel))
|
||||||
|
Message_StringID(15, CORPSE_ITEM_LOST);
|
||||||
|
|
||||||
|
if (check_level == RuleI(Character, DeathExpLossLevel))
|
||||||
|
Message_StringID(15, CORPSE_EXP_LOST);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Message(15, "Welcome to level %i!", check_level);
|
Message_StringID(MT_Experience, LOSE_LEVEL, ConvertArray(check_level, val1));
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
uint8 myoldlevel = GetLevel();
|
uint8 myoldlevel = GetLevel();
|
||||||
@ -594,8 +705,8 @@ void Group::SplitExp(uint32 exp, Mob* other) {
|
|||||||
groupmod = 2.16;
|
groupmod = 2.16;
|
||||||
else
|
else
|
||||||
groupmod = 1.0;
|
groupmod = 1.0;
|
||||||
|
if(membercount > 1 && membercount <= 6)
|
||||||
groupexp += (uint32)((float)exp * groupmod * (RuleR(Character, GroupExpMultiplier)));
|
groupexp += (uint32)((float)exp * groupmod * (RuleR(Character, GroupExpMultiplier)));
|
||||||
|
|
||||||
int conlevel = Mob::GetLevelCon(maxlevel, other->GetLevel());
|
int conlevel = Mob::GetLevelCon(maxlevel, other->GetLevel());
|
||||||
if(conlevel == CON_GREEN)
|
if(conlevel == CON_GREEN)
|
||||||
|
|||||||
@ -123,29 +123,6 @@ void Mob::ProcessFlee()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float Mob::GetFearSpeed()
|
|
||||||
{
|
|
||||||
if (flee_mode) {
|
|
||||||
//we know ratio < FLEE_HP_RATIO
|
|
||||||
float speed = GetBaseRunspeed();
|
|
||||||
float ratio = GetHPRatio();
|
|
||||||
float multiplier = RuleR(Combat, FleeMultiplier);
|
|
||||||
|
|
||||||
if (GetSnaredAmount() > 40)
|
|
||||||
multiplier = multiplier / 6.0f;
|
|
||||||
|
|
||||||
speed = speed * ratio * multiplier / 100;
|
|
||||||
|
|
||||||
//NPC will eventually stop. Snares speeds this up.
|
|
||||||
if (speed < 0.09)
|
|
||||||
speed = 0.0001f;
|
|
||||||
|
|
||||||
return speed;
|
|
||||||
}
|
|
||||||
// fear and blind use their normal run speed
|
|
||||||
return GetRunspeed();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mob::CalculateNewFearpoint()
|
void Mob::CalculateNewFearpoint()
|
||||||
{
|
{
|
||||||
if(RuleB(Pathing, Fear) && zone->pathing)
|
if(RuleB(Pathing, Fear) && zone->pathing)
|
||||||
|
|||||||
@ -185,26 +185,35 @@ bool Client::CanFish() {
|
|||||||
|
|
||||||
rodPosition.x = m_Position.x + RodLength * sin(HeadingDegrees * M_PI/180.0f);
|
rodPosition.x = m_Position.x + RodLength * sin(HeadingDegrees * M_PI/180.0f);
|
||||||
rodPosition.y = m_Position.y + RodLength * cos(HeadingDegrees * M_PI/180.0f);
|
rodPosition.y = m_Position.y + RodLength * cos(HeadingDegrees * M_PI/180.0f);
|
||||||
|
rodPosition.z = m_Position.z;
|
||||||
|
|
||||||
// Do BestZ to find where the line hanging from the rod intersects the water (if it is water).
|
float bestz = zone->zonemap->FindBestZ(rodPosition, nullptr);
|
||||||
// and go 1 unit into the water.
|
float len = m_Position.z - bestz;
|
||||||
glm::vec3 dest;
|
if(len > LineLength || len < 0.0f) {
|
||||||
dest.x = rodPosition.x;
|
Message_StringID(MT_Skills, FISHING_LAND);
|
||||||
dest.y = rodPosition.y;
|
|
||||||
dest.z = m_Position.z+10;
|
|
||||||
|
|
||||||
rodPosition.z = zone->zonemap->FindBestZ(dest, nullptr) + 4;
|
|
||||||
bool in_lava = zone->watermap->InLava(rodPosition);
|
|
||||||
bool in_water = zone->watermap->InWater(rodPosition) || zone->watermap->InVWater(rodPosition);
|
|
||||||
//Message(0, "Rod is at %4.3f, %4.3f, %4.3f, InWater says %d, InLava says %d", RodX, RodY, RodZ, in_water, in_lava);
|
|
||||||
if (in_lava) {
|
|
||||||
Message_StringID(MT_Skills, FISHING_LAVA); //Trying to catch a fire elemental or something?
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if((!in_water) || (m_Position.z-rodPosition.z)>LineLength) { //Didn't hit the water OR the water is too far below us
|
|
||||||
Message_StringID(MT_Skills, FISHING_LAND); //Trying to catch land sharks perhaps?
|
float step_size = RuleR(Watermap, FishingLineStepSize);
|
||||||
return false;
|
|
||||||
|
for(float i = 0.0f; i < len; i += step_size) {
|
||||||
|
glm::vec3 dest(rodPosition.x, rodPosition.y, m_Position.z - i);
|
||||||
|
|
||||||
|
bool in_lava = zone->watermap->InLava(dest);
|
||||||
|
bool in_water = zone->watermap->InWater(dest) || zone->watermap->InVWater(dest);
|
||||||
|
|
||||||
|
if (in_lava) {
|
||||||
|
Message_StringID(MT_Skills, FISHING_LAVA); //Trying to catch a fire elemental or something?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(in_water) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message_StringID(MT_Skills, FISHING_LAND);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -606,7 +606,7 @@ void Client::DropItem(int16 slot_id)
|
|||||||
// Take control of item in client inventory
|
// Take control of item in client inventory
|
||||||
ItemInst *inst = m_inv.PopItem(slot_id);
|
ItemInst *inst = m_inv.PopItem(slot_id);
|
||||||
if(inst) {
|
if(inst) {
|
||||||
int i = parse->EventItem(EVENT_DROP_ITEM, this, inst, nullptr, "", 0);
|
int i = parse->EventItem(EVENT_DROP_ITEM, this, inst, nullptr, "", slot_id);
|
||||||
if(i != 0) {
|
if(i != 0) {
|
||||||
safe_delete(inst);
|
safe_delete(inst);
|
||||||
}
|
}
|
||||||
@ -2199,6 +2199,187 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool IsSummonedBagID(uint32 item_id)
|
||||||
|
{
|
||||||
|
switch (item_id) {
|
||||||
|
case 17147: // "Spiritual Prismatic Pack"
|
||||||
|
case 17303: // "Spirit Pouch"
|
||||||
|
case 17304: // "Dimensional Pocket"
|
||||||
|
case 17305: // "Dimensional Hole"
|
||||||
|
case 17306: // "Glowing Backpack"
|
||||||
|
case 17307: // "Quiver of Marr"
|
||||||
|
case 17308: // "Bandoleer of Luclin"
|
||||||
|
case 17309: // "Pouch of Quellious"
|
||||||
|
case 17310: // "Phantom Satchel"
|
||||||
|
case 17510: // "Glowing Chest"
|
||||||
|
case 17900: // "Grandmaster's Satchel"
|
||||||
|
case 57260: // "Glowing Backpack"
|
||||||
|
case 57261: // "Pouch of Quellious"
|
||||||
|
case 57262: // "Phantom Satchel"
|
||||||
|
case 60224: // "Faded-Glyph Tablet"
|
||||||
|
case 95199: // "Beginner Artisan Satchel"
|
||||||
|
case 95200: // "Apprentice Artisan Satchel"
|
||||||
|
case 95201: // "Freshman Artisan Satchel"
|
||||||
|
case 95202: // "Journeyman Artisan Satchel"
|
||||||
|
case 95203: // "Expert Artisan Satchel"
|
||||||
|
case 95204: // "Master Artisan Satchel"
|
||||||
|
//case 96960: // "Artisan Satchel" - no 12-slot disenchanted bags
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 GetDisenchantedBagID(uint8 bag_slots)
|
||||||
|
{
|
||||||
|
switch (bag_slots) {
|
||||||
|
case 4:
|
||||||
|
return 77772; // "Small Disenchanted Backpack"
|
||||||
|
case 6:
|
||||||
|
return 77774; // "Disenchanted Backpack"
|
||||||
|
case 8:
|
||||||
|
return 77776; // "Large Disenchanted Backpack"
|
||||||
|
case 10:
|
||||||
|
return 77778; // "Huge Disenchanted Backpack"
|
||||||
|
default:
|
||||||
|
return 0; // no suitable conversions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CopyBagContents(ItemInst* new_bag, const ItemInst* old_bag)
|
||||||
|
{
|
||||||
|
if (!new_bag || !old_bag) { return false; }
|
||||||
|
if (new_bag->GetItem()->BagSlots < old_bag->GetItem()->BagSlots) { return false; }
|
||||||
|
|
||||||
|
// pre-check for size comparisons
|
||||||
|
for (auto bag_slot = 0; bag_slot < old_bag->GetItem()->BagSlots; ++bag_slot) {
|
||||||
|
if (!old_bag->GetItem(bag_slot)) { continue; }
|
||||||
|
if (old_bag->GetItem(bag_slot)->GetItem()->Size > new_bag->GetItem()->BagSize) {
|
||||||
|
Log.Out(Logs::General, Logs::Inventory, "Copy Bag Contents: Failure due to %s is larger than size capacity of %s (%i > %i)",
|
||||||
|
old_bag->GetItem(bag_slot)->GetItem()->Name, new_bag->GetItem()->Name, old_bag->GetItem(bag_slot)->GetItem()->Size, new_bag->GetItem()->BagSize);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto bag_slot = 0; bag_slot < old_bag->GetItem()->BagSlots; ++bag_slot) {
|
||||||
|
if (!old_bag->GetItem(bag_slot)) { continue; }
|
||||||
|
new_bag->PutItem(bag_slot, *(old_bag->GetItem(bag_slot)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::DisenchantSummonedBags(bool client_update)
|
||||||
|
{
|
||||||
|
for (auto slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; ++slot_id) {
|
||||||
|
auto inst = m_inv[slot_id];
|
||||||
|
if (!inst) { continue; }
|
||||||
|
if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; }
|
||||||
|
if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; }
|
||||||
|
if (inst->GetTotalItemCount() == 1) { continue; }
|
||||||
|
|
||||||
|
auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots);
|
||||||
|
if (!new_id) { continue; }
|
||||||
|
auto new_item = database.GetItem(new_id);
|
||||||
|
if (!new_item) { continue; }
|
||||||
|
auto new_inst = database.CreateBaseItem(new_item);
|
||||||
|
if (!new_inst) { continue; }
|
||||||
|
|
||||||
|
if (CopyBagContents(new_inst, inst)) {
|
||||||
|
Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id);
|
||||||
|
PutItemInInventory(slot_id, *new_inst, client_update);
|
||||||
|
}
|
||||||
|
safe_delete(new_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; ++slot_id) {
|
||||||
|
auto inst = m_inv[slot_id];
|
||||||
|
if (!inst) { continue; }
|
||||||
|
if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; }
|
||||||
|
if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; }
|
||||||
|
if (inst->GetTotalItemCount() == 1) { continue; }
|
||||||
|
|
||||||
|
auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots);
|
||||||
|
if (!new_id) { continue; }
|
||||||
|
auto new_item = database.GetItem(new_id);
|
||||||
|
if (!new_item) { continue; }
|
||||||
|
auto new_inst = database.CreateBaseItem(new_item);
|
||||||
|
if (!new_inst) { continue; }
|
||||||
|
|
||||||
|
if (CopyBagContents(new_inst, inst)) {
|
||||||
|
Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id);
|
||||||
|
PutItemInInventory(slot_id, *new_inst, client_update);
|
||||||
|
}
|
||||||
|
safe_delete(new_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_END; ++slot_id) {
|
||||||
|
auto inst = m_inv[slot_id];
|
||||||
|
if (!inst) { continue; }
|
||||||
|
if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; }
|
||||||
|
if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; }
|
||||||
|
if (inst->GetTotalItemCount() == 1) { continue; }
|
||||||
|
|
||||||
|
auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots);
|
||||||
|
if (!new_id) { continue; }
|
||||||
|
auto new_item = database.GetItem(new_id);
|
||||||
|
if (!new_item) { continue; }
|
||||||
|
auto new_inst = database.CreateBaseItem(new_item);
|
||||||
|
if (!new_inst) { continue; }
|
||||||
|
|
||||||
|
if (CopyBagContents(new_inst, inst)) {
|
||||||
|
Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id);
|
||||||
|
PutItemInInventory(slot_id, *new_inst, client_update);
|
||||||
|
}
|
||||||
|
safe_delete(new_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!m_inv.CursorEmpty()) {
|
||||||
|
auto inst = m_inv[MainCursor];
|
||||||
|
if (!inst) { break; }
|
||||||
|
if (!IsSummonedBagID(inst->GetItem()->ID)) { break; }
|
||||||
|
if (inst->GetItem()->ItemClass != ItemClassContainer) { break; }
|
||||||
|
if (inst->GetTotalItemCount() == 1) { break; }
|
||||||
|
|
||||||
|
auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots);
|
||||||
|
if (!new_id) { break; }
|
||||||
|
auto new_item = database.GetItem(new_id);
|
||||||
|
if (!new_item) { break; }
|
||||||
|
auto new_inst = database.CreateBaseItem(new_item);
|
||||||
|
if (!new_inst) { break; }
|
||||||
|
|
||||||
|
if (CopyBagContents(new_inst, inst)) {
|
||||||
|
Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, MainCursor);
|
||||||
|
std::list<ItemInst*> local;
|
||||||
|
local.push_front(new_inst);
|
||||||
|
m_inv.PopItem(MainCursor);
|
||||||
|
safe_delete(inst);
|
||||||
|
|
||||||
|
while (!m_inv.CursorEmpty()) {
|
||||||
|
auto limbo_inst = m_inv.PopItem(MainCursor);
|
||||||
|
if (limbo_inst == nullptr) { continue; }
|
||||||
|
local.push_back(limbo_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto iter = local.begin(); iter != local.end(); ++iter) {
|
||||||
|
auto cur_inst = *iter;
|
||||||
|
if (cur_inst == nullptr) { continue; }
|
||||||
|
m_inv.PushCursor(*cur_inst);
|
||||||
|
safe_delete(cur_inst);
|
||||||
|
}
|
||||||
|
local.clear();
|
||||||
|
|
||||||
|
auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend();
|
||||||
|
database.SaveCursor(this->CharacterID(), s, e);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
safe_delete(new_inst); // deletes disenchanted bag if not used
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Client::RemoveNoRent(bool client_update)
|
void Client::RemoveNoRent(bool client_update)
|
||||||
{
|
{
|
||||||
for (auto slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; ++slot_id) {
|
for (auto slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; ++slot_id) {
|
||||||
|
|||||||
@ -332,6 +332,8 @@ void NPC::AddLootDrop(const ItemData *item2, ItemList* itemlist, int16 charges,
|
|||||||
CastToMob()->AddProcToWeapon(item2->Proc.Effect, true);
|
CastToMob()->AddProcToWeapon(item2->Proc.Effect, true);
|
||||||
|
|
||||||
eslot = MaterialPrimary;
|
eslot = MaterialPrimary;
|
||||||
|
if (item2->Damage > 0)
|
||||||
|
SendAddPlayerState(PlayerState::PrimaryWeaponEquipped);
|
||||||
}
|
}
|
||||||
else if (foundslot == MainSecondary
|
else if (foundslot == MainSecondary
|
||||||
&& (GetOwner() != nullptr || (GetLevel() >= 13 && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) &&
|
&& (GetOwner() != nullptr || (GetLevel() >= 13 && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) &&
|
||||||
@ -342,6 +344,8 @@ void NPC::AddLootDrop(const ItemData *item2, ItemList* itemlist, int16 charges,
|
|||||||
CastToMob()->AddProcToWeapon(item2->Proc.Effect, true);
|
CastToMob()->AddProcToWeapon(item2->Proc.Effect, true);
|
||||||
|
|
||||||
eslot = MaterialSecondary;
|
eslot = MaterialSecondary;
|
||||||
|
if (item2->Damage > 0)
|
||||||
|
SendAddPlayerState(PlayerState::SecondaryWeaponEquipped);
|
||||||
}
|
}
|
||||||
else if (foundslot == MainHead) {
|
else if (foundslot == MainHead) {
|
||||||
eslot = MaterialHead;
|
eslot = MaterialHead;
|
||||||
|
|||||||
@ -1255,6 +1255,46 @@ void Lua_Client::PlayMP3(std::string file)
|
|||||||
self->PlayMP3(file.c_str());
|
self->PlayMP3(file.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Lua_Client::QuestReward(Lua_Mob target) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->QuestReward(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->QuestReward(target, copper);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->QuestReward(target, copper, silver);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->QuestReward(target, copper, silver, gold);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->QuestReward(target, copper, silver, gold, platinum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->QuestReward(target, copper, silver, gold, platinum, itemid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid, uint32 exp) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->QuestReward(target, copper, silver, gold, platinum, itemid, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid, uint32 exp, bool faction) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->QuestReward(target, copper, silver, gold, platinum, itemid, exp, faction);
|
||||||
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_client() {
|
luabind::scope lua_register_client() {
|
||||||
return luabind::class_<Lua_Client, Lua_Mob>("Client")
|
return luabind::class_<Lua_Client, Lua_Mob>("Client")
|
||||||
.def(luabind::constructor<>())
|
.def(luabind::constructor<>())
|
||||||
@ -1504,7 +1544,15 @@ luabind::scope lua_register_client() {
|
|||||||
.def("SetConsumption", (void(Lua_Client::*)(int, int))&Lua_Client::SetConsumption)
|
.def("SetConsumption", (void(Lua_Client::*)(int, int))&Lua_Client::SetConsumption)
|
||||||
.def("SendMarqueeMessage", (void(Lua_Client::*)(uint32, uint32, uint32, uint32, uint32, std::string))&Lua_Client::SendMarqueeMessage)
|
.def("SendMarqueeMessage", (void(Lua_Client::*)(uint32, uint32, uint32, uint32, uint32, std::string))&Lua_Client::SendMarqueeMessage)
|
||||||
.def("SendColoredText", (void(Lua_Client::*)(uint32, std::string))&Lua_Client::SendColoredText)
|
.def("SendColoredText", (void(Lua_Client::*)(uint32, std::string))&Lua_Client::SendColoredText)
|
||||||
.def("PlayMP3", (void(Lua_Client::*)(std::string))&Lua_Client::PlayMP3);
|
.def("PlayMP3", (void(Lua_Client::*)(std::string))&Lua_Client::PlayMP3)
|
||||||
|
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob))&Lua_Client::QuestReward)
|
||||||
|
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32))&Lua_Client::QuestReward)
|
||||||
|
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32))&Lua_Client::QuestReward)
|
||||||
|
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32))&Lua_Client::QuestReward)
|
||||||
|
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32, uint32))&Lua_Client::QuestReward)
|
||||||
|
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32, uint32, uint32))&Lua_Client::QuestReward)
|
||||||
|
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32, uint32, uint32, uint32))&Lua_Client::QuestReward)
|
||||||
|
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32, uint32, uint32, uint32, bool))&Lua_Client::QuestReward);
|
||||||
}
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_inventory_where() {
|
luabind::scope lua_register_inventory_where() {
|
||||||
|
|||||||
@ -278,6 +278,14 @@ public:
|
|||||||
void SendMarqueeMessage(uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, std::string msg);
|
void SendMarqueeMessage(uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, std::string msg);
|
||||||
void SendColoredText(uint32 type, std::string msg);
|
void SendColoredText(uint32 type, std::string msg);
|
||||||
void PlayMP3(std::string file);
|
void PlayMP3(std::string file);
|
||||||
|
void QuestReward(Lua_Mob target);
|
||||||
|
void QuestReward(Lua_Mob target, uint32 copper);
|
||||||
|
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver);
|
||||||
|
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold);
|
||||||
|
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum);
|
||||||
|
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid);
|
||||||
|
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid, uint32 exp);
|
||||||
|
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid, uint32 exp, bool faction);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
13
zone/lua_encounter.cpp
Normal file
13
zone/lua_encounter.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifdef LUA_EQEMU
|
||||||
|
|
||||||
|
#include "lua.hpp"
|
||||||
|
#include <luabind/luabind.hpp>
|
||||||
|
#include "lua_encounter.h"
|
||||||
|
#include "encounter.h"
|
||||||
|
|
||||||
|
|
||||||
|
luabind::scope lua_register_encounter() {
|
||||||
|
return luabind::class_<Lua_Encounter>("Encounter");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
30
zone/lua_encounter.h
Normal file
30
zone/lua_encounter.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef EQEMU_LUA_ENCOUNTER_H
|
||||||
|
#define EQEMU_LUA_ENCOUNTER_H
|
||||||
|
#ifdef LUA_EQEMU
|
||||||
|
|
||||||
|
#include "lua_ptr.h"
|
||||||
|
|
||||||
|
class Encounter;
|
||||||
|
|
||||||
|
namespace luabind {
|
||||||
|
struct scope;
|
||||||
|
class object;
|
||||||
|
}
|
||||||
|
|
||||||
|
luabind::scope lua_register_encounter();
|
||||||
|
|
||||||
|
class Lua_Encounter : public Lua_Ptr<Encounter>
|
||||||
|
{
|
||||||
|
typedef Encounter NativeType;
|
||||||
|
public:
|
||||||
|
Lua_Encounter() { SetLuaPtrData(nullptr); }
|
||||||
|
Lua_Encounter(Encounter *d) { SetLuaPtrData(reinterpret_cast<Encounter*>(d)); }
|
||||||
|
virtual ~Lua_Encounter() { }
|
||||||
|
|
||||||
|
operator Encounter*() {
|
||||||
|
return reinterpret_cast<Encounter*>(GetLuaPtrData());
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@ -18,6 +18,8 @@
|
|||||||
#include "qglobals.h"
|
#include "qglobals.h"
|
||||||
#include "../common/timer.h"
|
#include "../common/timer.h"
|
||||||
#include "../common/eqemu_logsys.h"
|
#include "../common/eqemu_logsys.h"
|
||||||
|
#include "encounter.h"
|
||||||
|
#include "lua_encounter.h"
|
||||||
|
|
||||||
struct Events { };
|
struct Events { };
|
||||||
struct Factions { };
|
struct Factions { };
|
||||||
@ -34,6 +36,8 @@ struct lua_registered_event {
|
|||||||
|
|
||||||
extern std::map<std::string, std::list<lua_registered_event>> lua_encounter_events_registered;
|
extern std::map<std::string, std::list<lua_registered_event>> lua_encounter_events_registered;
|
||||||
extern std::map<std::string, bool> lua_encounters_loaded;
|
extern std::map<std::string, bool> lua_encounters_loaded;
|
||||||
|
extern std::map<std::string, Encounter *> lua_encounters;
|
||||||
|
|
||||||
extern void MapOpcodes();
|
extern void MapOpcodes();
|
||||||
extern void ClearMappedOpcode(EmuOpcode op);
|
extern void ClearMappedOpcode(EmuOpcode op);
|
||||||
|
|
||||||
@ -42,19 +46,23 @@ void unregister_event(std::string package_name, std::string name, int evt);
|
|||||||
void load_encounter(std::string name) {
|
void load_encounter(std::string name) {
|
||||||
if(lua_encounters_loaded.count(name) > 0)
|
if(lua_encounters_loaded.count(name) > 0)
|
||||||
return;
|
return;
|
||||||
|
Encounter *enc = new Encounter(name.c_str());
|
||||||
|
entity_list.AddEncounter(enc);
|
||||||
|
lua_encounters[name] = enc;
|
||||||
lua_encounters_loaded[name] = true;
|
lua_encounters_loaded[name] = true;
|
||||||
parse->EventEncounter(EVENT_ENCOUNTER_LOAD, name, 0);
|
parse->EventEncounter(EVENT_ENCOUNTER_LOAD, name, "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_encounter_with_data(std::string name, std::string info_str) {
|
void load_encounter_with_data(std::string name, std::string info_str) {
|
||||||
if(lua_encounters_loaded.count(name) > 0)
|
if(lua_encounters_loaded.count(name) > 0)
|
||||||
return;
|
return;
|
||||||
|
Encounter *enc = new Encounter(name.c_str());
|
||||||
|
entity_list.AddEncounter(enc);
|
||||||
|
lua_encounters[name] = enc;
|
||||||
lua_encounters_loaded[name] = true;
|
lua_encounters_loaded[name] = true;
|
||||||
std::vector<EQEmu::Any> info_ptrs;
|
std::vector<EQEmu::Any> info_ptrs;
|
||||||
info_ptrs.push_back(&info_str);
|
info_ptrs.push_back(&info_str);
|
||||||
parse->EventEncounter(EVENT_ENCOUNTER_LOAD, name, 0, &info_ptrs);
|
parse->EventEncounter(EVENT_ENCOUNTER_LOAD, name, "", 0, &info_ptrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unload_encounter(std::string name) {
|
void unload_encounter(std::string name) {
|
||||||
@ -80,8 +88,10 @@ void unload_encounter(std::string name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lua_encounters[name]->Depop();
|
||||||
|
lua_encounters.erase(name);
|
||||||
lua_encounters_loaded.erase(name);
|
lua_encounters_loaded.erase(name);
|
||||||
parse->EventEncounter(EVENT_ENCOUNTER_UNLOAD, name, 0);
|
parse->EventEncounter(EVENT_ENCOUNTER_UNLOAD, name, "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unload_encounter_with_data(std::string name, std::string info_str) {
|
void unload_encounter_with_data(std::string name, std::string info_str) {
|
||||||
@ -109,10 +119,12 @@ void unload_encounter_with_data(std::string name, std::string info_str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lua_encounters[name]->Depop();
|
||||||
|
lua_encounters.erase(name);
|
||||||
lua_encounters_loaded.erase(name);
|
lua_encounters_loaded.erase(name);
|
||||||
std::vector<EQEmu::Any> info_ptrs;
|
std::vector<EQEmu::Any> info_ptrs;
|
||||||
info_ptrs.push_back(&info_str);
|
info_ptrs.push_back(&info_str);
|
||||||
parse->EventEncounter(EVENT_ENCOUNTER_UNLOAD, name, 0, &info_ptrs);
|
parse->EventEncounter(EVENT_ENCOUNTER_UNLOAD, name, "", 0, &info_ptrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_event(std::string package_name, std::string name, int evt, luabind::adl::object func) {
|
void register_event(std::string package_name, std::string name, int evt, luabind::adl::object func) {
|
||||||
@ -285,6 +297,10 @@ void lua_set_timer(const char *timer, int time_ms, Lua_Mob mob) {
|
|||||||
quest_manager.settimerMS(timer, time_ms, mob);
|
quest_manager.settimerMS(timer, time_ms, mob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_set_timer(const char *timer, int time_ms, Lua_Encounter enc) {
|
||||||
|
quest_manager.settimerMS(timer, time_ms, enc);
|
||||||
|
}
|
||||||
|
|
||||||
void lua_stop_timer(const char *timer) {
|
void lua_stop_timer(const char *timer) {
|
||||||
quest_manager.stoptimer(timer);
|
quest_manager.stoptimer(timer);
|
||||||
}
|
}
|
||||||
@ -297,6 +313,10 @@ void lua_stop_timer(const char *timer, Lua_Mob mob) {
|
|||||||
quest_manager.stoptimer(timer, mob);
|
quest_manager.stoptimer(timer, mob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_stop_timer(const char *timer, Lua_Encounter enc) {
|
||||||
|
quest_manager.stoptimer(timer, enc);
|
||||||
|
}
|
||||||
|
|
||||||
void lua_stop_all_timers() {
|
void lua_stop_all_timers() {
|
||||||
quest_manager.stopalltimers();
|
quest_manager.stopalltimers();
|
||||||
}
|
}
|
||||||
@ -309,6 +329,10 @@ void lua_stop_all_timers(Lua_Mob mob) {
|
|||||||
quest_manager.stopalltimers(mob);
|
quest_manager.stopalltimers(mob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_stop_all_timers(Lua_Encounter enc) {
|
||||||
|
quest_manager.stopalltimers(enc);
|
||||||
|
}
|
||||||
|
|
||||||
void lua_depop() {
|
void lua_depop() {
|
||||||
quest_manager.depop(0);
|
quest_manager.depop(0);
|
||||||
}
|
}
|
||||||
@ -386,7 +410,11 @@ void lua_create_guild(const char *name, const char *leader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void lua_set_time(int hour, int min) {
|
void lua_set_time(int hour, int min) {
|
||||||
quest_manager.settime(hour, min);
|
quest_manager.settime(hour, min, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lua_set_time(int hour, int min, bool update_world) {
|
||||||
|
quest_manager.settime(hour, min, update_world);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_signal(int npc_id, int signal_id) {
|
void lua_signal(int npc_id, int signal_id) {
|
||||||
@ -979,7 +1007,7 @@ int lua_get_zone_weather() {
|
|||||||
|
|
||||||
luabind::adl::object lua_get_zone_time(lua_State *L) {
|
luabind::adl::object lua_get_zone_time(lua_State *L) {
|
||||||
TimeOfDay_Struct eqTime;
|
TimeOfDay_Struct eqTime;
|
||||||
zone->zone_time.getEQTimeOfDay(time(0), &eqTime);
|
zone->zone_time.GetCurrentEQTimeOfDay(time(0), &eqTime);
|
||||||
|
|
||||||
luabind::adl::object ret = luabind::newtable(L);
|
luabind::adl::object ret = luabind::newtable(L);
|
||||||
ret["zone_hour"] = eqTime.hour - 1;
|
ret["zone_hour"] = eqTime.hour - 1;
|
||||||
@ -1442,12 +1470,15 @@ luabind::scope lua_register_general() {
|
|||||||
luabind::def("set_timer", (void(*)(const char*, int))&lua_set_timer),
|
luabind::def("set_timer", (void(*)(const char*, int))&lua_set_timer),
|
||||||
luabind::def("set_timer", (void(*)(const char*, int, Lua_ItemInst))&lua_set_timer),
|
luabind::def("set_timer", (void(*)(const char*, int, Lua_ItemInst))&lua_set_timer),
|
||||||
luabind::def("set_timer", (void(*)(const char*, int, Lua_Mob))&lua_set_timer),
|
luabind::def("set_timer", (void(*)(const char*, int, Lua_Mob))&lua_set_timer),
|
||||||
|
luabind::def("set_timer", (void(*)(const char*, int, Lua_Encounter))&lua_set_timer),
|
||||||
luabind::def("stop_timer", (void(*)(const char*))&lua_stop_timer),
|
luabind::def("stop_timer", (void(*)(const char*))&lua_stop_timer),
|
||||||
luabind::def("stop_timer", (void(*)(const char*, Lua_ItemInst))&lua_stop_timer),
|
luabind::def("stop_timer", (void(*)(const char*, Lua_ItemInst))&lua_stop_timer),
|
||||||
luabind::def("stop_timer", (void(*)(const char*, Lua_Mob))&lua_stop_timer),
|
luabind::def("stop_timer", (void(*)(const char*, Lua_Mob))&lua_stop_timer),
|
||||||
|
luabind::def("stop_timer", (void(*)(const char*, Lua_Encounter))&lua_stop_timer),
|
||||||
luabind::def("stop_all_timers", (void(*)(void))&lua_stop_all_timers),
|
luabind::def("stop_all_timers", (void(*)(void))&lua_stop_all_timers),
|
||||||
luabind::def("stop_all_timers", (void(*)(Lua_ItemInst))&lua_stop_all_timers),
|
luabind::def("stop_all_timers", (void(*)(Lua_ItemInst))&lua_stop_all_timers),
|
||||||
luabind::def("stop_all_timers", (void(*)(Lua_Mob))&lua_stop_all_timers),
|
luabind::def("stop_all_timers", (void(*)(Lua_Mob))&lua_stop_all_timers),
|
||||||
|
luabind::def("stop_all_timers", (void(*)(Lua_Encounter))&lua_stop_all_timers),
|
||||||
luabind::def("depop", (void(*)(void))&lua_depop),
|
luabind::def("depop", (void(*)(void))&lua_depop),
|
||||||
luabind::def("depop", (void(*)(int))&lua_depop),
|
luabind::def("depop", (void(*)(int))&lua_depop),
|
||||||
luabind::def("depop_with_timer", (void(*)(void))&lua_depop_with_timer),
|
luabind::def("depop_with_timer", (void(*)(void))&lua_depop_with_timer),
|
||||||
@ -1467,7 +1498,8 @@ luabind::scope lua_register_general() {
|
|||||||
luabind::def("set_sky", &lua_set_sky),
|
luabind::def("set_sky", &lua_set_sky),
|
||||||
luabind::def("set_guild", &lua_set_guild),
|
luabind::def("set_guild", &lua_set_guild),
|
||||||
luabind::def("create_guild", &lua_create_guild),
|
luabind::def("create_guild", &lua_create_guild),
|
||||||
luabind::def("set_time", &lua_set_time),
|
luabind::def("set_time", (void(*)(int, int))&lua_set_time),
|
||||||
|
luabind::def("set_time", (void(*)(int, int, bool))&lua_set_time),
|
||||||
luabind::def("signal", (void(*)(int,int))&lua_signal),
|
luabind::def("signal", (void(*)(int,int))&lua_signal),
|
||||||
luabind::def("signal", (void(*)(int,int,int))&lua_signal),
|
luabind::def("signal", (void(*)(int,int,int))&lua_signal),
|
||||||
luabind::def("set_global", &lua_set_global),
|
luabind::def("set_global", &lua_set_global),
|
||||||
|
|||||||
@ -1590,26 +1590,6 @@ void Lua_Mob::SendIllusionPacket(luabind::adl::object illusion) {
|
|||||||
beard, aa_title, drakkin_heritage, drakkin_tattoo, drakkin_details, size);
|
beard, aa_title, drakkin_heritage, drakkin_tattoo, drakkin_details, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lua_Mob::QuestReward(Lua_Client c) {
|
|
||||||
Lua_Safe_Call_Void();
|
|
||||||
self->QuestReward(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lua_Mob::QuestReward(Lua_Client c, uint32 silver) {
|
|
||||||
Lua_Safe_Call_Void();
|
|
||||||
self->QuestReward(c, silver);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lua_Mob::QuestReward(Lua_Client c, uint32 silver, uint32 gold) {
|
|
||||||
Lua_Safe_Call_Void();
|
|
||||||
self->QuestReward(c, silver, gold);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lua_Mob::QuestReward(Lua_Client c, uint32 silver, uint32 gold, uint32 platinum) {
|
|
||||||
Lua_Safe_Call_Void();
|
|
||||||
self->QuestReward(c, silver, gold, platinum);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lua_Mob::CameraEffect(uint32 duration, uint32 intensity) {
|
void Lua_Mob::CameraEffect(uint32 duration, uint32 intensity) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
self->CameraEffect(duration, intensity);
|
self->CameraEffect(duration, intensity);
|
||||||
@ -1651,6 +1631,11 @@ void Lua_Mob::TempName(const char *newname) {
|
|||||||
self->TempName(newname);
|
self->TempName(newname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Lua_Mob::GetGlobal(const char *varname) {
|
||||||
|
Lua_Safe_Call_String();
|
||||||
|
return self->GetGlobal(varname);
|
||||||
|
}
|
||||||
|
|
||||||
void Lua_Mob::SetGlobal(const char *varname, const char *newvalue, int options, const char *duration) {
|
void Lua_Mob::SetGlobal(const char *varname, const char *newvalue, int options, const char *duration) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
self->SetGlobal(varname, newvalue, options, duration);
|
self->SetGlobal(varname, newvalue, options, duration);
|
||||||
@ -1866,6 +1851,10 @@ int Lua_Mob::CanBuffStack(int spell_id, int caster_level, bool fail_if_overwrite
|
|||||||
return self->CanBuffStack(spell_id, caster_level, fail_if_overwrite);
|
return self->CanBuffStack(spell_id, caster_level, fail_if_overwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Lua_Mob::SetPseudoRoot(bool in) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetPseudoRoot(in);
|
||||||
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_mob() {
|
luabind::scope lua_register_mob() {
|
||||||
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
||||||
@ -2132,10 +2121,6 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("SetRace", (void(Lua_Mob::*)(int))&Lua_Mob::SetRace)
|
.def("SetRace", (void(Lua_Mob::*)(int))&Lua_Mob::SetRace)
|
||||||
.def("SetGender", (void(Lua_Mob::*)(int))&Lua_Mob::SetGender)
|
.def("SetGender", (void(Lua_Mob::*)(int))&Lua_Mob::SetGender)
|
||||||
.def("SendIllusionPacket", (void(Lua_Mob::*)(luabind::adl::object))&Lua_Mob::SendIllusionPacket)
|
.def("SendIllusionPacket", (void(Lua_Mob::*)(luabind::adl::object))&Lua_Mob::SendIllusionPacket)
|
||||||
.def("QuestReward", (void(Lua_Mob::*)(Lua_Client))&Lua_Mob::QuestReward)
|
|
||||||
.def("QuestReward", (void(Lua_Mob::*)(Lua_Client,uint32))&Lua_Mob::QuestReward)
|
|
||||||
.def("QuestReward", (void(Lua_Mob::*)(Lua_Client,uint32,uint32))&Lua_Mob::QuestReward)
|
|
||||||
.def("QuestReward", (void(Lua_Mob::*)(Lua_Client,uint32,uint32,uint32))&Lua_Mob::QuestReward)
|
|
||||||
.def("CameraEffect", (void(Lua_Mob::*)(uint32,uint32))&Lua_Mob::CameraEffect)
|
.def("CameraEffect", (void(Lua_Mob::*)(uint32,uint32))&Lua_Mob::CameraEffect)
|
||||||
.def("CameraEffect", (void(Lua_Mob::*)(uint32,uint32,Lua_Client))&Lua_Mob::CameraEffect)
|
.def("CameraEffect", (void(Lua_Mob::*)(uint32,uint32,Lua_Client))&Lua_Mob::CameraEffect)
|
||||||
.def("CameraEffect", (void(Lua_Mob::*)(uint32,uint32,Lua_Client,bool))&Lua_Mob::CameraEffect)
|
.def("CameraEffect", (void(Lua_Mob::*)(uint32,uint32,Lua_Client,bool))&Lua_Mob::CameraEffect)
|
||||||
@ -2144,6 +2129,7 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("SendSpellEffect", (void(Lua_Mob::*)(uint32,uint32,uint32,bool,uint32,bool,Lua_Client))&Lua_Mob::SendSpellEffect)
|
.def("SendSpellEffect", (void(Lua_Mob::*)(uint32,uint32,uint32,bool,uint32,bool,Lua_Client))&Lua_Mob::SendSpellEffect)
|
||||||
.def("TempName", (void(Lua_Mob::*)(void))&Lua_Mob::TempName)
|
.def("TempName", (void(Lua_Mob::*)(void))&Lua_Mob::TempName)
|
||||||
.def("TempName", (void(Lua_Mob::*)(const char*))&Lua_Mob::TempName)
|
.def("TempName", (void(Lua_Mob::*)(const char*))&Lua_Mob::TempName)
|
||||||
|
.def("GetGlobal", (std::string(Lua_Mob::*)(const char*))&Lua_Mob::GetGlobal)
|
||||||
.def("SetGlobal", (void(Lua_Mob::*)(const char*,const char*,int,const char*))&Lua_Mob::SetGlobal)
|
.def("SetGlobal", (void(Lua_Mob::*)(const char*,const char*,int,const char*))&Lua_Mob::SetGlobal)
|
||||||
.def("SetGlobal", (void(Lua_Mob::*)(const char*,const char*,int,const char*,Lua_Mob))&Lua_Mob::SetGlobal)
|
.def("SetGlobal", (void(Lua_Mob::*)(const char*,const char*,int,const char*,Lua_Mob))&Lua_Mob::SetGlobal)
|
||||||
.def("TarGlobal", (void(Lua_Mob::*)(const char*,const char*,const char*,int,int,int))&Lua_Mob::TarGlobal)
|
.def("TarGlobal", (void(Lua_Mob::*)(const char*,const char*,const char*,int,int,int))&Lua_Mob::TarGlobal)
|
||||||
@ -2186,7 +2172,8 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("BuffFadeBySlot", (void(Lua_Mob::*)(int))&Lua_Mob::BuffFadeBySlot)
|
.def("BuffFadeBySlot", (void(Lua_Mob::*)(int))&Lua_Mob::BuffFadeBySlot)
|
||||||
.def("BuffFadeBySlot", (void(Lua_Mob::*)(int,bool))&Lua_Mob::BuffFadeBySlot)
|
.def("BuffFadeBySlot", (void(Lua_Mob::*)(int,bool))&Lua_Mob::BuffFadeBySlot)
|
||||||
.def("CanBuffStack", (int(Lua_Mob::*)(int,int))&Lua_Mob::CanBuffStack)
|
.def("CanBuffStack", (int(Lua_Mob::*)(int,int))&Lua_Mob::CanBuffStack)
|
||||||
.def("CanBuffStack", (int(Lua_Mob::*)(int,int,bool))&Lua_Mob::CanBuffStack);
|
.def("CanBuffStack", (int(Lua_Mob::*)(int,int,bool))&Lua_Mob::CanBuffStack)
|
||||||
|
.def("SetPseudoRoot", (void(Lua_Mob::*)(bool))&Lua_Mob::SetPseudoRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_special_abilities() {
|
luabind::scope lua_register_special_abilities() {
|
||||||
|
|||||||
@ -296,10 +296,6 @@ public:
|
|||||||
void SetRace(int in);
|
void SetRace(int in);
|
||||||
void SetGender(int in);
|
void SetGender(int in);
|
||||||
void SendIllusionPacket(luabind::adl::object illusion);
|
void SendIllusionPacket(luabind::adl::object illusion);
|
||||||
void QuestReward(Lua_Client c);
|
|
||||||
void QuestReward(Lua_Client c, uint32 silver);
|
|
||||||
void QuestReward(Lua_Client c, uint32 silver, uint32 gold);
|
|
||||||
void QuestReward(Lua_Client c, uint32 silver, uint32 gold, uint32 platinum);
|
|
||||||
void CameraEffect(uint32 duration, uint32 intensity);
|
void CameraEffect(uint32 duration, uint32 intensity);
|
||||||
void CameraEffect(uint32 duration, uint32 intensity, Lua_Client c);
|
void CameraEffect(uint32 duration, uint32 intensity, Lua_Client c);
|
||||||
void CameraEffect(uint32 duration, uint32 intensity, Lua_Client c, bool global);
|
void CameraEffect(uint32 duration, uint32 intensity, Lua_Client c, bool global);
|
||||||
@ -311,6 +307,7 @@ public:
|
|||||||
uint32 unk020, bool perm_effect, Lua_Client c);
|
uint32 unk020, bool perm_effect, Lua_Client c);
|
||||||
void TempName();
|
void TempName();
|
||||||
void TempName(const char *newname);
|
void TempName(const char *newname);
|
||||||
|
std::string GetGlobal(const char *varname);
|
||||||
void SetGlobal(const char *varname, const char *newvalue, int options, const char *duration);
|
void SetGlobal(const char *varname, const char *newvalue, int options, const char *duration);
|
||||||
void SetGlobal(const char *varname, const char *newvalue, int options, const char *duration, Lua_Mob other);
|
void SetGlobal(const char *varname, const char *newvalue, int options, const char *duration, Lua_Mob other);
|
||||||
void TarGlobal(const char *varname, const char *value, const char *duration, int npc_id, int char_id, int zone_id);
|
void TarGlobal(const char *varname, const char *value, const char *duration, int npc_id, int char_id, int zone_id);
|
||||||
@ -355,6 +352,7 @@ public:
|
|||||||
void BuffFadeBySlot(int slot, bool recalc_bonuses);
|
void BuffFadeBySlot(int slot, bool recalc_bonuses);
|
||||||
int CanBuffStack(int spell_id, int caster_level);
|
int CanBuffStack(int spell_id, int caster_level);
|
||||||
int CanBuffStack(int spell_id, int caster_level, bool fail_if_overwrite);
|
int CanBuffStack(int spell_id, int caster_level, bool fail_if_overwrite);
|
||||||
|
void SetPseudoRoot(bool in);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -692,8 +692,8 @@ luabind::scope lua_register_packet_opcodes() {
|
|||||||
luabind::value("VetClaimRequest", static_cast<int>(OP_VetClaimRequest)),
|
luabind::value("VetClaimRequest", static_cast<int>(OP_VetClaimRequest)),
|
||||||
luabind::value("VetClaimReply", static_cast<int>(OP_VetClaimReply)),
|
luabind::value("VetClaimReply", static_cast<int>(OP_VetClaimReply)),
|
||||||
luabind::value("WeaponEquip1", static_cast<int>(OP_WeaponEquip1)),
|
luabind::value("WeaponEquip1", static_cast<int>(OP_WeaponEquip1)),
|
||||||
luabind::value("WeaponEquip2", static_cast<int>(OP_WeaponEquip2)),
|
luabind::value("PlayerStateAdd", static_cast<int>(OP_PlayerStateAdd)),
|
||||||
luabind::value("WeaponUnequip2", static_cast<int>(OP_WeaponUnequip2)),
|
luabind::value("PlayerStateRemove", static_cast<int>(OP_PlayerStateRemove)),
|
||||||
luabind::value("WorldLogout", static_cast<int>(OP_WorldLogout)),
|
luabind::value("WorldLogout", static_cast<int>(OP_WorldLogout)),
|
||||||
luabind::value("SessionReady", static_cast<int>(OP_SessionReady)),
|
luabind::value("SessionReady", static_cast<int>(OP_SessionReady)),
|
||||||
luabind::value("Login", static_cast<int>(OP_Login)),
|
luabind::value("Login", static_cast<int>(OP_Login)),
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
#include "questmgr.h"
|
#include "questmgr.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
#include "lua_parser.h"
|
#include "lua_parser.h"
|
||||||
|
#include "lua_encounter.h"
|
||||||
|
|
||||||
const char *LuaEvents[_LargestEventID] = {
|
const char *LuaEvents[_LargestEventID] = {
|
||||||
"event_say",
|
"event_say",
|
||||||
@ -128,6 +129,7 @@ struct lua_registered_event {
|
|||||||
|
|
||||||
std::map<std::string, std::list<lua_registered_event>> lua_encounter_events_registered;
|
std::map<std::string, std::list<lua_registered_event>> lua_encounter_events_registered;
|
||||||
std::map<std::string, bool> lua_encounters_loaded;
|
std::map<std::string, bool> lua_encounters_loaded;
|
||||||
|
std::map<std::string, Encounter *> lua_encounters;
|
||||||
|
|
||||||
LuaParser::LuaParser() {
|
LuaParser::LuaParser() {
|
||||||
for(int i = 0; i < _LargestEventID; ++i) {
|
for(int i = 0; i < _LargestEventID; ++i) {
|
||||||
@ -135,6 +137,7 @@ LuaParser::LuaParser() {
|
|||||||
PlayerArgumentDispatch[i] = handle_player_null;
|
PlayerArgumentDispatch[i] = handle_player_null;
|
||||||
ItemArgumentDispatch[i] = handle_item_null;
|
ItemArgumentDispatch[i] = handle_item_null;
|
||||||
SpellArgumentDispatch[i] = handle_spell_null;
|
SpellArgumentDispatch[i] = handle_spell_null;
|
||||||
|
EncounterArgumentDispatch[i] = handle_encounter_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
NPCArgumentDispatch[EVENT_SAY] = handle_npc_event_say;
|
NPCArgumentDispatch[EVENT_SAY] = handle_npc_event_say;
|
||||||
@ -213,6 +216,10 @@ LuaParser::LuaParser() {
|
|||||||
SpellArgumentDispatch[EVENT_SPELL_FADE] = handle_spell_fade;
|
SpellArgumentDispatch[EVENT_SPELL_FADE] = handle_spell_fade;
|
||||||
SpellArgumentDispatch[EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE] = handle_translocate_finish;
|
SpellArgumentDispatch[EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE] = handle_translocate_finish;
|
||||||
|
|
||||||
|
EncounterArgumentDispatch[EVENT_TIMER] = handle_encounter_timer;
|
||||||
|
EncounterArgumentDispatch[EVENT_ENCOUNTER_LOAD] = handle_encounter_load;
|
||||||
|
EncounterArgumentDispatch[EVENT_ENCOUNTER_UNLOAD] = handle_encounter_unload;
|
||||||
|
|
||||||
L = nullptr;
|
L = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,7 +582,7 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers) {
|
int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -587,10 +594,10 @@ int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _EventEncounter(package_name, evt, encounter_name, extra_data, extra_pointers);
|
return _EventEncounter(package_name, evt, encounter_name, data, extra_data, extra_pointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
||||||
std::vector<EQEmu::Any> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
const char *sub_name = LuaEvents[evt];
|
const char *sub_name = LuaEvents[evt];
|
||||||
|
|
||||||
@ -604,13 +611,12 @@ int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::
|
|||||||
lua_pushstring(L, encounter_name.c_str());
|
lua_pushstring(L, encounter_name.c_str());
|
||||||
lua_setfield(L, -2, "name");
|
lua_setfield(L, -2, "name");
|
||||||
|
|
||||||
if(extra_pointers) {
|
Encounter *enc = lua_encounters[encounter_name];
|
||||||
std::string *str = EQEmu::any_cast<std::string*>(extra_pointers->at(0));
|
|
||||||
lua_pushstring(L, str->c_str());
|
|
||||||
lua_setfield(L, -2, "data");
|
|
||||||
}
|
|
||||||
|
|
||||||
quest_manager.StartQuest(nullptr, nullptr, nullptr, encounter_name);
|
auto arg_function = EncounterArgumentDispatch[evt];
|
||||||
|
arg_function(this, L, enc, data, extra_data, extra_pointers);
|
||||||
|
|
||||||
|
quest_manager.StartQuest(enc, nullptr, nullptr, encounter_name);
|
||||||
if(lua_pcall(L, 1, 1, 0)) {
|
if(lua_pcall(L, 1, 1, 0)) {
|
||||||
std::string error = lua_tostring(L, -1);
|
std::string error = lua_tostring(L, -1);
|
||||||
AddError(error);
|
AddError(error);
|
||||||
@ -786,6 +792,11 @@ void LuaParser::ReloadQuests() {
|
|||||||
lua_encounter_events_registered.clear();
|
lua_encounter_events_registered.clear();
|
||||||
lua_encounters_loaded.clear();
|
lua_encounters_loaded.clear();
|
||||||
|
|
||||||
|
for (auto encounter : lua_encounters) {
|
||||||
|
encounter.second->Depop();
|
||||||
|
}
|
||||||
|
lua_encounters.clear();
|
||||||
|
|
||||||
if(L) {
|
if(L) {
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
}
|
}
|
||||||
@ -968,6 +979,7 @@ void LuaParser::MapFunctions(lua_State *L) {
|
|||||||
lua_register_client_version(),
|
lua_register_client_version(),
|
||||||
lua_register_appearance(),
|
lua_register_appearance(),
|
||||||
lua_register_entity(),
|
lua_register_entity(),
|
||||||
|
lua_register_encounter(),
|
||||||
lua_register_mob(),
|
lua_register_mob(),
|
||||||
lua_register_special_abilities(),
|
lua_register_special_abilities(),
|
||||||
lua_register_npc(),
|
lua_register_npc(),
|
||||||
|
|||||||
@ -39,7 +39,7 @@ public:
|
|||||||
std::vector<EQEmu::Any> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<EQEmu::Any> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
virtual int EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
||||||
std::vector<EQEmu::Any> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
virtual bool HasQuestSub(uint32 npc_id, QuestEventID evt);
|
virtual bool HasQuestSub(uint32 npc_id, QuestEventID evt);
|
||||||
@ -82,7 +82,7 @@ private:
|
|||||||
uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
||||||
int _EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
int _EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
||||||
int _EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
int _EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
||||||
std::vector<EQEmu::Any> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
void LoadScript(std::string filename, std::string package_name);
|
void LoadScript(std::string filename, std::string package_name);
|
||||||
@ -99,6 +99,8 @@ private:
|
|||||||
PlayerArgumentHandler PlayerArgumentDispatch[_LargestEventID];
|
PlayerArgumentHandler PlayerArgumentDispatch[_LargestEventID];
|
||||||
ItemArgumentHandler ItemArgumentDispatch[_LargestEventID];
|
ItemArgumentHandler ItemArgumentDispatch[_LargestEventID];
|
||||||
SpellArgumentHandler SpellArgumentDispatch[_LargestEventID];
|
SpellArgumentHandler SpellArgumentDispatch[_LargestEventID];
|
||||||
|
EncounterArgumentHandler EncounterArgumentDispatch[_LargestEventID];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "lua_door.h"
|
#include "lua_door.h"
|
||||||
#include "lua_object.h"
|
#include "lua_object.h"
|
||||||
#include "lua_packet.h"
|
#include "lua_packet.h"
|
||||||
|
#include "lua_encounter.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
#include "lua_parser_events.h"
|
#include "lua_parser_events.h"
|
||||||
|
|
||||||
@ -704,4 +705,39 @@ void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* cl
|
|||||||
std::vector<EQEmu::Any> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_encounter_timer(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||||
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
|
lua_pushstring(L, data.c_str());
|
||||||
|
lua_setfield(L, -2, "timer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_encounter_load(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||||
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
|
if (encounter) {
|
||||||
|
Lua_Encounter l_enc(encounter);
|
||||||
|
luabind::adl::object l_enc_o = luabind::adl::object(L, l_enc);
|
||||||
|
l_enc_o.push(L);
|
||||||
|
lua_setfield(L, -2, "encounter");
|
||||||
|
}
|
||||||
|
if (extra_pointers) {
|
||||||
|
std::string *str = EQEmu::any_cast<std::string*>(extra_pointers->at(0));
|
||||||
|
lua_pushstring(L, str->c_str());
|
||||||
|
lua_setfield(L, -2, "data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_encounter_unload(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||||
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
|
if (extra_pointers) {
|
||||||
|
std::string *str = EQEmu::any_cast<std::string*>(extra_pointers->at(0));
|
||||||
|
lua_pushstring(L, str->c_str());
|
||||||
|
lua_setfield(L, -2, "data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_encounter_null(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||||
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -6,6 +6,7 @@ typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::
|
|||||||
typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector<EQEmu::Any>*);
|
typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector<EQEmu::Any>*);
|
||||||
typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, Mob*, std::string, uint32, std::vector<EQEmu::Any>*);
|
typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, Mob*, std::string, uint32, std::vector<EQEmu::Any>*);
|
||||||
typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, uint32, std::vector<EQEmu::Any>*);
|
typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, uint32, std::vector<EQEmu::Any>*);
|
||||||
|
typedef void(*EncounterArgumentHandler)(QuestInterface*, lua_State*, Encounter* encounter, std::string, uint32, std::vector<EQEmu::Any>*);
|
||||||
|
|
||||||
//NPC
|
//NPC
|
||||||
void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
@ -127,5 +128,16 @@ void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Cl
|
|||||||
void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<EQEmu::Any> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
|
|
||||||
|
//Encounter
|
||||||
|
void handle_encounter_timer(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||||
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
void handle_encounter_load(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||||
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
void handle_encounter_unload(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||||
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
void handle_encounter_null(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||||
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
37
zone/map.cpp
37
zone/map.cpp
@ -64,7 +64,7 @@ Map::~Map() {
|
|||||||
|
|
||||||
float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const {
|
float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const {
|
||||||
if (!imp)
|
if (!imp)
|
||||||
return false;
|
return BEST_Z_INVALID;
|
||||||
|
|
||||||
glm::vec3 tmp;
|
glm::vec3 tmp;
|
||||||
if(!result)
|
if(!result)
|
||||||
@ -93,6 +93,41 @@ float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const {
|
|||||||
return BEST_Z_INVALID;
|
return BEST_Z_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Map::FindClosestZ(glm::vec3 &start, glm::vec3 *result) const {
|
||||||
|
// Unlike FindBestZ, this method finds the closest Z value above or below the specified point.
|
||||||
|
//
|
||||||
|
if (!imp)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
float ClosestZ = BEST_Z_INVALID;
|
||||||
|
|
||||||
|
glm::vec3 tmp;
|
||||||
|
if (!result)
|
||||||
|
result = &tmp;
|
||||||
|
|
||||||
|
glm::vec3 from(start.x, start.y, start.z);
|
||||||
|
glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
|
||||||
|
float hit_distance;
|
||||||
|
bool hit = false;
|
||||||
|
|
||||||
|
// first check is below us
|
||||||
|
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
|
||||||
|
if (hit) {
|
||||||
|
ClosestZ = result->z;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find nearest Z above us
|
||||||
|
to.z = -BEST_Z_INVALID;
|
||||||
|
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
|
||||||
|
if (hit) {
|
||||||
|
if (abs(from.z - result->z) < abs(ClosestZ - from.z))
|
||||||
|
return result->z;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ClosestZ;
|
||||||
|
}
|
||||||
|
|
||||||
bool Map::LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const {
|
bool Map::LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const {
|
||||||
if(!imp)
|
if(!imp)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -34,6 +34,7 @@ public:
|
|||||||
~Map();
|
~Map();
|
||||||
|
|
||||||
float FindBestZ(glm::vec3 &start, glm::vec3 *result) const;
|
float FindBestZ(glm::vec3 &start, glm::vec3 *result) const;
|
||||||
|
float FindClosestZ(glm::vec3 &start, glm::vec3 *result) const;
|
||||||
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
|
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
|
||||||
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
|
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
|
||||||
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
|
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
|
||||||
|
|||||||
@ -1236,10 +1236,7 @@ void Merc::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
|||||||
bool Merc::Process()
|
bool Merc::Process()
|
||||||
{
|
{
|
||||||
if(IsStunned() && stunned_timer.Check())
|
if(IsStunned() && stunned_timer.Check())
|
||||||
{
|
Mob::UnStun();
|
||||||
this->stunned = false;
|
|
||||||
this->stunned_timer.Disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetDepop())
|
if (GetDepop())
|
||||||
{
|
{
|
||||||
@ -1463,14 +1460,16 @@ void Merc::AI_Process() {
|
|||||||
|
|
||||||
if(moved) {
|
if(moved) {
|
||||||
moved = false;
|
moved = false;
|
||||||
SendPosition();
|
SetCurrentSpeed(0);
|
||||||
SetMoving(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(m_PlayerState & static_cast<uint32>(PlayerState::Aggressive)))
|
||||||
|
SendAddPlayerState(PlayerState::Aggressive);
|
||||||
|
|
||||||
bool atCombatRange = false;
|
bool atCombatRange = false;
|
||||||
|
|
||||||
float meleeDistance = GetMaxMeleeRangeToTarget(GetTarget());
|
float meleeDistance = GetMaxMeleeRangeToTarget(GetTarget());
|
||||||
@ -1497,9 +1496,7 @@ void Merc::AI_Process() {
|
|||||||
SetRunAnimSpeed(0);
|
SetRunAnimSpeed(0);
|
||||||
|
|
||||||
if(moved) {
|
if(moved) {
|
||||||
moved = false;
|
SetCurrentSpeed(0);
|
||||||
SendPosition();
|
|
||||||
SetMoving(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1684,6 +1681,9 @@ void Merc::AI_Process() {
|
|||||||
confidence_timer.Disable();
|
confidence_timer.Disable();
|
||||||
_check_confidence = false;
|
_check_confidence = false;
|
||||||
|
|
||||||
|
if (m_PlayerState & static_cast<uint32>(PlayerState::Aggressive))
|
||||||
|
SendRemovePlayerState(PlayerState::Aggressive);
|
||||||
|
|
||||||
if(!check_target_timer.Enabled())
|
if(!check_target_timer.Enabled())
|
||||||
check_target_timer.Start(2000, false);
|
check_target_timer.Start(2000, false);
|
||||||
|
|
||||||
@ -1707,7 +1707,7 @@ void Merc::AI_Process() {
|
|||||||
if(follow)
|
if(follow)
|
||||||
{
|
{
|
||||||
float dist = DistanceSquared(m_Position, follow->GetPosition());
|
float dist = DistanceSquared(m_Position, follow->GetPosition());
|
||||||
float speed = GetRunspeed();
|
int speed = GetRunspeed();
|
||||||
|
|
||||||
if(dist < GetFollowDistance() + 1000)
|
if(dist < GetFollowDistance() + 1000)
|
||||||
speed = GetWalkspeed();
|
speed = GetWalkspeed();
|
||||||
@ -1724,9 +1724,8 @@ void Merc::AI_Process() {
|
|||||||
{
|
{
|
||||||
if(moved)
|
if(moved)
|
||||||
{
|
{
|
||||||
moved=false;
|
SetCurrentSpeed(0);
|
||||||
SendPosition();
|
moved = false;
|
||||||
SetMoving(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
441
zone/mob.cpp
441
zone/mob.cpp
@ -26,6 +26,7 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#include "bot.h"
|
#include "bot.h"
|
||||||
@ -149,6 +150,29 @@ Mob::Mob(const char* in_name,
|
|||||||
size = in_size;
|
size = in_size;
|
||||||
base_size = size;
|
base_size = size;
|
||||||
runspeed = in_runspeed;
|
runspeed = in_runspeed;
|
||||||
|
// neotokyo: sanity check
|
||||||
|
if (runspeed < 0 || runspeed > 20)
|
||||||
|
runspeed = 1.25f;
|
||||||
|
base_runspeed = (int)((float)runspeed * 40.0f);
|
||||||
|
// clients
|
||||||
|
if (runspeed == 0.7f) {
|
||||||
|
base_runspeed = 28;
|
||||||
|
walkspeed = 0.3f;
|
||||||
|
base_walkspeed = 12;
|
||||||
|
fearspeed = 0.625f;
|
||||||
|
base_fearspeed = 25;
|
||||||
|
// npcs
|
||||||
|
} else {
|
||||||
|
base_walkspeed = base_runspeed * 100 / 265;
|
||||||
|
walkspeed = ((float)base_walkspeed) * 0.025f;
|
||||||
|
base_fearspeed = base_runspeed * 100 / 127;
|
||||||
|
fearspeed = ((float)base_fearspeed) * 0.025f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
current_speed = base_runspeed;
|
||||||
|
|
||||||
|
m_PlayerState = 0;
|
||||||
|
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
@ -240,15 +264,19 @@ Mob::Mob(const char* in_name,
|
|||||||
PermaProcs[j].spellID = SPELL_UNKNOWN;
|
PermaProcs[j].spellID = SPELL_UNKNOWN;
|
||||||
PermaProcs[j].chance = 0;
|
PermaProcs[j].chance = 0;
|
||||||
PermaProcs[j].base_spellID = SPELL_UNKNOWN;
|
PermaProcs[j].base_spellID = SPELL_UNKNOWN;
|
||||||
|
PermaProcs[j].level_override = -1;
|
||||||
SpellProcs[j].spellID = SPELL_UNKNOWN;
|
SpellProcs[j].spellID = SPELL_UNKNOWN;
|
||||||
SpellProcs[j].chance = 0;
|
SpellProcs[j].chance = 0;
|
||||||
SpellProcs[j].base_spellID = SPELL_UNKNOWN;
|
SpellProcs[j].base_spellID = SPELL_UNKNOWN;
|
||||||
|
SpellProcs[j].level_override = -1;
|
||||||
DefensiveProcs[j].spellID = SPELL_UNKNOWN;
|
DefensiveProcs[j].spellID = SPELL_UNKNOWN;
|
||||||
DefensiveProcs[j].chance = 0;
|
DefensiveProcs[j].chance = 0;
|
||||||
DefensiveProcs[j].base_spellID = SPELL_UNKNOWN;
|
DefensiveProcs[j].base_spellID = SPELL_UNKNOWN;
|
||||||
|
DefensiveProcs[j].level_override = -1;
|
||||||
RangedProcs[j].spellID = SPELL_UNKNOWN;
|
RangedProcs[j].spellID = SPELL_UNKNOWN;
|
||||||
RangedProcs[j].chance = 0;
|
RangedProcs[j].chance = 0;
|
||||||
RangedProcs[j].base_spellID = SPELL_UNKNOWN;
|
RangedProcs[j].base_spellID = SPELL_UNKNOWN;
|
||||||
|
RangedProcs[j].level_override = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < _MaterialCount; i++)
|
for (i = 0; i < _MaterialCount; i++)
|
||||||
@ -311,7 +339,7 @@ Mob::Mob(const char* in_name,
|
|||||||
pLastChange = 0;
|
pLastChange = 0;
|
||||||
SetPetID(0);
|
SetPetID(0);
|
||||||
SetOwnerID(0);
|
SetOwnerID(0);
|
||||||
typeofpet = petCharmed; //default to charmed...
|
typeofpet = petNone; // default to not a pet
|
||||||
petpower = 0;
|
petpower = 0;
|
||||||
held = false;
|
held = false;
|
||||||
nocast = false;
|
nocast = false;
|
||||||
@ -531,48 +559,32 @@ bool Mob::IsInvisible(Mob* other) const
|
|||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Mob::_GetMovementSpeed(int mod) const
|
int Mob::_GetWalkSpeed() const {
|
||||||
{
|
|
||||||
// List of movement speed modifiers, including AAs & spells:
|
if (IsRooted() || IsStunned() || IsMezzed())
|
||||||
// http://everquest.allakhazam.com/db/item.html?item=1721;page=1;howmany=50#m10822246245352
|
return 0;
|
||||||
if (IsRooted())
|
|
||||||
return 0.0f;
|
|
||||||
else if (IsPseudoRooted())
|
else if (IsPseudoRooted())
|
||||||
return 0.00001f;
|
return 0;
|
||||||
|
|
||||||
float speed_mod = runspeed;
|
int aa_mod = 0;
|
||||||
|
int speed_mod = base_walkspeed;
|
||||||
|
int base_run = base_runspeed;
|
||||||
|
bool has_horse = false;
|
||||||
|
int runspeedcap = RuleI(Character,BaseRunSpeedCap);
|
||||||
|
runspeedcap += itembonuses.IncreaseRunSpeedCap + spellbonuses.IncreaseRunSpeedCap + aabonuses.IncreaseRunSpeedCap;
|
||||||
|
aa_mod += aabonuses.BaseMovementSpeed;
|
||||||
|
|
||||||
// These two cases ignore the cap, be wise in the DB for horses.
|
|
||||||
if (IsClient()) {
|
if (IsClient()) {
|
||||||
if (CastToClient()->GetGMSpeed()) {
|
Mob *horse = entity_list.GetMob(CastToClient()->GetHorseId());
|
||||||
speed_mod = 3.125f;
|
if (horse) {
|
||||||
if (mod != 0)
|
speed_mod = horse->GetBaseRunspeed();
|
||||||
speed_mod += speed_mod * static_cast<float>(mod) / 100.0f;
|
|
||||||
return speed_mod;
|
return speed_mod;
|
||||||
} else {
|
|
||||||
Mob *horse = entity_list.GetMob(CastToClient()->GetHorseId());
|
|
||||||
if (horse) {
|
|
||||||
speed_mod = horse->GetBaseRunspeed();
|
|
||||||
if (mod != 0)
|
|
||||||
speed_mod += speed_mod * static_cast<float>(mod) / 100.0f;
|
|
||||||
return speed_mod;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int aa_mod = 0;
|
int spell_mod = spellbonuses.movementspeed + itembonuses.movementspeed;
|
||||||
int spell_mod = 0;
|
|
||||||
int runspeedcap = RuleI(Character,BaseRunSpeedCap);
|
|
||||||
int movemod = 0;
|
int movemod = 0;
|
||||||
float frunspeedcap = 0.0f;
|
|
||||||
|
|
||||||
runspeedcap += itembonuses.IncreaseRunSpeedCap + spellbonuses.IncreaseRunSpeedCap + aabonuses.IncreaseRunSpeedCap;
|
|
||||||
aa_mod += itembonuses.BaseMovementSpeed + spellbonuses.BaseMovementSpeed + aabonuses.BaseMovementSpeed;
|
|
||||||
spell_mod += spellbonuses.movementspeed + itembonuses.movementspeed;
|
|
||||||
|
|
||||||
// hard cap
|
|
||||||
if (runspeedcap > 225)
|
|
||||||
runspeedcap = 225;
|
|
||||||
|
|
||||||
if (spell_mod < 0)
|
if (spell_mod < 0)
|
||||||
movemod += spell_mod;
|
movemod += spell_mod;
|
||||||
@ -581,27 +593,189 @@ float Mob::_GetMovementSpeed(int mod) const
|
|||||||
else
|
else
|
||||||
movemod = aa_mod;
|
movemod = aa_mod;
|
||||||
|
|
||||||
// cap negative movemods from snares mostly
|
// hard cap
|
||||||
if (movemod < -85)
|
if (runspeedcap > 225)
|
||||||
|
runspeedcap = 225;
|
||||||
|
|
||||||
|
if(movemod < -85) //cap it at moving very very slow
|
||||||
movemod = -85;
|
movemod = -85;
|
||||||
|
|
||||||
if (movemod != 0)
|
if (!has_horse && movemod != 0)
|
||||||
speed_mod += speed_mod * static_cast<float>(movemod) / 100.0f;
|
speed_mod += (base_run * movemod / 100);
|
||||||
|
|
||||||
// runspeed caps
|
if(speed_mod < 1)
|
||||||
frunspeedcap = static_cast<float>(runspeedcap) / 100.0f;
|
return(0);
|
||||||
if (IsClient() && speed_mod > frunspeedcap)
|
|
||||||
speed_mod = frunspeedcap;
|
|
||||||
|
|
||||||
// apply final mod such as the -47 for walking
|
//runspeed cap.
|
||||||
// use runspeed since it should stack with snares
|
if(IsClient())
|
||||||
// and if we get here, we know runspeed was the initial
|
{
|
||||||
// value before we applied movemod.
|
if(speed_mod > runspeedcap)
|
||||||
if (mod != 0)
|
speed_mod = runspeedcap;
|
||||||
speed_mod += runspeed * static_cast<float>(mod) / 100.0f;
|
}
|
||||||
|
return speed_mod;
|
||||||
|
}
|
||||||
|
|
||||||
if (speed_mod <= 0.0f)
|
int Mob::_GetRunSpeed() const {
|
||||||
speed_mod = IsClient() ? 0.0001f : 0.0f;
|
if (IsRooted() || IsStunned() || IsMezzed() || IsPseudoRooted())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int aa_mod = 0;
|
||||||
|
int speed_mod = base_runspeed;
|
||||||
|
int base_walk = base_walkspeed;
|
||||||
|
bool has_horse = false;
|
||||||
|
if (IsClient())
|
||||||
|
{
|
||||||
|
if(CastToClient()->GetGMSpeed())
|
||||||
|
{
|
||||||
|
speed_mod = 325;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Mob* horse = entity_list.GetMob(CastToClient()->GetHorseId());
|
||||||
|
if(horse)
|
||||||
|
{
|
||||||
|
speed_mod = horse->GetBaseRunspeed();
|
||||||
|
base_walk = horse->GetBaseWalkspeed();
|
||||||
|
has_horse = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int runspeedcap = RuleI(Character,BaseRunSpeedCap);
|
||||||
|
runspeedcap += itembonuses.IncreaseRunSpeedCap + spellbonuses.IncreaseRunSpeedCap + aabonuses.IncreaseRunSpeedCap;
|
||||||
|
|
||||||
|
aa_mod = itembonuses.IncreaseRunSpeedCap + spellbonuses.IncreaseRunSpeedCap + aabonuses.IncreaseRunSpeedCap;
|
||||||
|
int spell_mod = spellbonuses.movementspeed + itembonuses.movementspeed;
|
||||||
|
int movemod = 0;
|
||||||
|
|
||||||
|
if(spell_mod < 0)
|
||||||
|
{
|
||||||
|
movemod += spell_mod;
|
||||||
|
}
|
||||||
|
else if(spell_mod > aa_mod)
|
||||||
|
{
|
||||||
|
movemod = spell_mod;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
movemod = aa_mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(movemod < -85) //cap it at moving very very slow
|
||||||
|
movemod = -85;
|
||||||
|
|
||||||
|
if (!has_horse && movemod != 0)
|
||||||
|
{
|
||||||
|
if (IsClient())
|
||||||
|
{
|
||||||
|
speed_mod += (speed_mod * movemod / 100);
|
||||||
|
} else {
|
||||||
|
if (movemod < 0) {
|
||||||
|
speed_mod += (50 * movemod / 100);
|
||||||
|
// basically stoped
|
||||||
|
if(speed_mod < 1)
|
||||||
|
{
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
// moving slowly
|
||||||
|
if (speed_mod < 8)
|
||||||
|
return(8);
|
||||||
|
} else {
|
||||||
|
speed_mod += GetBaseWalkspeed();
|
||||||
|
if (movemod > 50)
|
||||||
|
speed_mod += 4;
|
||||||
|
if (movemod > 40)
|
||||||
|
speed_mod += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(speed_mod < 1)
|
||||||
|
{
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
//runspeed cap.
|
||||||
|
if(IsClient())
|
||||||
|
{
|
||||||
|
if(speed_mod > runspeedcap)
|
||||||
|
speed_mod = runspeedcap;
|
||||||
|
}
|
||||||
|
return speed_mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Mob::_GetFearSpeed() const {
|
||||||
|
|
||||||
|
if (IsRooted() || IsStunned() || IsMezzed())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
//float speed_mod = fearspeed;
|
||||||
|
int speed_mod = GetBaseFearSpeed();
|
||||||
|
|
||||||
|
// use a max of 1.75f in calcs.
|
||||||
|
int base_run = std::min(GetBaseRunspeed(), 70);
|
||||||
|
|
||||||
|
int spell_mod = spellbonuses.movementspeed + itembonuses.movementspeed;
|
||||||
|
int movemod = 0;
|
||||||
|
|
||||||
|
if(spell_mod < 0)
|
||||||
|
{
|
||||||
|
movemod += spell_mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(movemod < -85) //cap it at moving very very slow
|
||||||
|
movemod = -85;
|
||||||
|
|
||||||
|
if (IsClient()) {
|
||||||
|
if (CastToClient()->IsRunning())
|
||||||
|
speed_mod = GetBaseRunspeed();
|
||||||
|
else
|
||||||
|
speed_mod = GetBaseWalkspeed();
|
||||||
|
if (movemod < 0)
|
||||||
|
return GetBaseWalkspeed();
|
||||||
|
speed_mod += (base_run * movemod / 100);
|
||||||
|
return speed_mod;
|
||||||
|
} else {
|
||||||
|
int hp_ratio = GetIntHPRatio();
|
||||||
|
// very large snares 50% or higher
|
||||||
|
if (movemod < -49)
|
||||||
|
{
|
||||||
|
if (hp_ratio < 25)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (hp_ratio < 50)
|
||||||
|
return (8);
|
||||||
|
else
|
||||||
|
return (12);
|
||||||
|
}
|
||||||
|
if (hp_ratio < 5) {
|
||||||
|
speed_mod = base_walkspeed / 3;
|
||||||
|
} else if (hp_ratio < 15) {
|
||||||
|
speed_mod = base_walkspeed / 2;
|
||||||
|
} else if (hp_ratio < 25) {
|
||||||
|
speed_mod = base_walkspeed + 1; // add the +1 so they do the run animation
|
||||||
|
} else if (hp_ratio < 50) {
|
||||||
|
speed_mod *= 82;
|
||||||
|
speed_mod /= 100;
|
||||||
|
}
|
||||||
|
if (movemod > 0) {
|
||||||
|
speed_mod += GetBaseWalkspeed();
|
||||||
|
if (movemod > 50)
|
||||||
|
speed_mod += 4;
|
||||||
|
if (movemod > 40)
|
||||||
|
speed_mod += 3;
|
||||||
|
return speed_mod;
|
||||||
|
}
|
||||||
|
else if (movemod < 0) {
|
||||||
|
speed_mod += (base_run * movemod / 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (speed_mod < 1)
|
||||||
|
return (0);
|
||||||
|
if (speed_mod < 9)
|
||||||
|
return (8);
|
||||||
|
if (speed_mod < 13)
|
||||||
|
return (12);
|
||||||
|
|
||||||
return speed_mod;
|
return speed_mod;
|
||||||
}
|
}
|
||||||
@ -916,6 +1090,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
|||||||
ns->spawn.class_ = class_;
|
ns->spawn.class_ = class_;
|
||||||
ns->spawn.gender = gender;
|
ns->spawn.gender = gender;
|
||||||
ns->spawn.level = level;
|
ns->spawn.level = level;
|
||||||
|
ns->spawn.PlayerState = m_PlayerState;
|
||||||
ns->spawn.deity = deity;
|
ns->spawn.deity = deity;
|
||||||
ns->spawn.animation = 0;
|
ns->spawn.animation = 0;
|
||||||
ns->spawn.findable = findable?1:0;
|
ns->spawn.findable = findable?1:0;
|
||||||
@ -1092,7 +1267,7 @@ void Mob::CreateHPPacket(EQApplicationPacket* app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sends hp update of this mob to people who might care
|
// sends hp update of this mob to people who might care
|
||||||
void Mob::SendHPUpdate()
|
void Mob::SendHPUpdate(bool skip_self)
|
||||||
{
|
{
|
||||||
EQApplicationPacket hp_app;
|
EQApplicationPacket hp_app;
|
||||||
Group *group;
|
Group *group;
|
||||||
@ -1181,8 +1356,7 @@ void Mob::SendHPUpdate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send to self - we need the actual hps here
|
// send to self - we need the actual hps here
|
||||||
if(IsClient())
|
if(IsClient() && !skip_self) {
|
||||||
{
|
|
||||||
EQApplicationPacket* hp_app2 = new EQApplicationPacket(OP_HPUpdate,sizeof(SpawnHPUpdate_Struct));
|
EQApplicationPacket* hp_app2 = new EQApplicationPacket(OP_HPUpdate,sizeof(SpawnHPUpdate_Struct));
|
||||||
SpawnHPUpdate_Struct* ds = (SpawnHPUpdate_Struct*)hp_app2->pBuffer;
|
SpawnHPUpdate_Struct* ds = (SpawnHPUpdate_Struct*)hp_app2->pBuffer;
|
||||||
ds->cur_hp = CastToClient()->GetHP() - itembonuses.HP;
|
ds->cur_hp = CastToClient()->GetHP() - itembonuses.HP;
|
||||||
@ -1191,6 +1365,7 @@ void Mob::SendHPUpdate()
|
|||||||
CastToClient()->QueuePacket(hp_app2);
|
CastToClient()->QueuePacket(hp_app2);
|
||||||
safe_delete(hp_app2);
|
safe_delete(hp_app2);
|
||||||
}
|
}
|
||||||
|
ResetHPUpdateTimer(); // delay the timer
|
||||||
}
|
}
|
||||||
|
|
||||||
// this one just warps the mob to the current location
|
// this one just warps the mob to the current location
|
||||||
@ -1301,7 +1476,7 @@ void Mob::ShowStats(Client* client)
|
|||||||
if(n->respawn2 != 0)
|
if(n->respawn2 != 0)
|
||||||
spawngroupid = n->respawn2->SpawnGroupID();
|
spawngroupid = n->respawn2->SpawnGroupID();
|
||||||
client->Message(0, " NPCID: %u SpawnGroupID: %u Grid: %i LootTable: %u FactionID: %i SpellsID: %u ", GetNPCTypeID(),spawngroupid, n->GetGrid(), n->GetLoottableID(), n->GetNPCFactionID(), n->GetNPCSpellsID());
|
client->Message(0, " NPCID: %u SpawnGroupID: %u Grid: %i LootTable: %u FactionID: %i SpellsID: %u ", GetNPCTypeID(),spawngroupid, n->GetGrid(), n->GetLoottableID(), n->GetNPCFactionID(), n->GetNPCSpellsID());
|
||||||
client->Message(0, " Accuracy: %i MerchantID: %i EmoteID: %i Runspeed: %f Walkspeed: %f", n->GetAccuracyRating(), n->MerchantType, n->GetEmoteID(), n->GetRunspeed(), n->GetWalkspeed());
|
client->Message(0, " Accuracy: %i MerchantID: %i EmoteID: %i Runspeed: %u Walkspeed: %u", n->GetAccuracyRating(), n->MerchantType, n->GetEmoteID(), n->GetRunspeed(), n->GetWalkspeed());
|
||||||
n->QueryLoot(client);
|
n->QueryLoot(client);
|
||||||
}
|
}
|
||||||
if (IsAIControlled()) {
|
if (IsAIControlled()) {
|
||||||
@ -1788,7 +1963,7 @@ bool Mob::IsPlayerRace(uint16 in_race) {
|
|||||||
|
|
||||||
|
|
||||||
uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) {
|
uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) {
|
||||||
if (Mob::IsPlayerRace(in_race) || in_race == 15 || in_race == 50 || in_race == 57 || in_race == 70 || in_race == 98 || in_race == 118) {
|
if (Mob::IsPlayerRace(in_race) || in_race == 15 || in_race == 50 || in_race == 57 || in_race == 70 || in_race == 98 || in_race == 118 || in_race == 23) {
|
||||||
if (in_gender >= 2) {
|
if (in_gender >= 2) {
|
||||||
// Male default for PC Races
|
// Male default for PC Races
|
||||||
return 0;
|
return 0;
|
||||||
@ -1909,22 +2084,6 @@ void Mob::SendTargetable(bool on, Client *specific_target) {
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::QuestReward(Client *c, uint32 silver, uint32 gold, uint32 platinum) {
|
|
||||||
|
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Sound, sizeof(QuestReward_Struct));
|
|
||||||
QuestReward_Struct* qr = (QuestReward_Struct*) outapp->pBuffer;
|
|
||||||
|
|
||||||
qr->from_mob = GetID(); // Entity ID for the from mob name
|
|
||||||
qr->silver = silver;
|
|
||||||
qr->gold = gold;
|
|
||||||
qr->platinum = platinum;
|
|
||||||
|
|
||||||
if(c)
|
|
||||||
c->QueuePacket(outapp, false, Client::CLIENT_CONNECTED);
|
|
||||||
|
|
||||||
safe_delete(outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mob::CameraEffect(uint32 duration, uint32 intensity, Client *c, bool global) {
|
void Mob::CameraEffect(uint32 duration, uint32 intensity, Client *c, bool global) {
|
||||||
|
|
||||||
|
|
||||||
@ -2041,12 +2200,12 @@ const int32& Mob::SetMana(int32 amount)
|
|||||||
|
|
||||||
|
|
||||||
void Mob::SetAppearance(EmuAppearance app, bool iIgnoreSelf) {
|
void Mob::SetAppearance(EmuAppearance app, bool iIgnoreSelf) {
|
||||||
if (_appearance != app) {
|
if (_appearance == app)
|
||||||
_appearance = app;
|
return;
|
||||||
SendAppearancePacket(AT_Anim, GetAppearanceValue(app), true, iIgnoreSelf);
|
_appearance = app;
|
||||||
if (this->IsClient() && this->IsAIControlled())
|
SendAppearancePacket(AT_Anim, GetAppearanceValue(app), true, iIgnoreSelf);
|
||||||
SendAppearancePacket(AT_Anim, ANIM_FREEZE, false, false);
|
if (this->IsClient() && this->IsAIControlled())
|
||||||
}
|
SendAppearancePacket(AT_Anim, ANIM_FREEZE, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::UpdateActiveLight()
|
bool Mob::UpdateActiveLight()
|
||||||
@ -2138,8 +2297,10 @@ void Mob::SetOwnerID(uint16 NewOwnerID) {
|
|||||||
if (NewOwnerID == GetID() && NewOwnerID != 0) // ok, no charming yourself now =p
|
if (NewOwnerID == GetID() && NewOwnerID != 0) // ok, no charming yourself now =p
|
||||||
return;
|
return;
|
||||||
ownerid = NewOwnerID;
|
ownerid = NewOwnerID;
|
||||||
if (ownerid == 0 && this->IsNPC() && this->GetPetType() != petCharmed)
|
// if we're setting the owner ID to 0 and they're not either charmed or not-a-pet then
|
||||||
this->Depop();
|
// they're a normal pet and should be despawned
|
||||||
|
if (ownerid == 0 && IsNPC() && GetPetType() != petCharmed && GetPetType() != petNone)
|
||||||
|
Depop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// used in checking for behind (backstab) and checking in front (melee LoS)
|
// used in checking for behind (backstab) and checking in front (melee LoS)
|
||||||
@ -2553,7 +2714,35 @@ uint32 NPC::GetEquipment(uint8 material_slot) const
|
|||||||
return equipment[invslot];
|
return equipment[invslot];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::SendWearChange(uint8 material_slot)
|
void Mob::SendArmorAppearance(Client *one_client)
|
||||||
|
{
|
||||||
|
// one_client of 0 means sent to all clients
|
||||||
|
//
|
||||||
|
// Despite the fact that OP_NewSpawn and OP_ZoneSpawns include the
|
||||||
|
// armor being worn and its mats, the client doesn't update the display
|
||||||
|
// on arrival of these packets reliably.
|
||||||
|
//
|
||||||
|
// Send Wear changes if mob is a PC race and item is an armor slot.
|
||||||
|
// The other packets work for primary/secondary.
|
||||||
|
|
||||||
|
if (IsPlayerRace(race))
|
||||||
|
{
|
||||||
|
if (!IsClient())
|
||||||
|
{
|
||||||
|
const Item_Struct *item;
|
||||||
|
for (int i=0; i< 7 ; ++i)
|
||||||
|
{
|
||||||
|
item=database.GetItem(GetEquipment(i));
|
||||||
|
if (item != 0)
|
||||||
|
{
|
||||||
|
SendWearChange(i,one_client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mob::SendWearChange(uint8 material_slot, Client *one_client)
|
||||||
{
|
{
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct));
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct));
|
||||||
WearChange_Struct* wc = (WearChange_Struct*)outapp->pBuffer;
|
WearChange_Struct* wc = (WearChange_Struct*)outapp->pBuffer;
|
||||||
@ -2565,7 +2754,15 @@ void Mob::SendWearChange(uint8 material_slot)
|
|||||||
wc->color.Color = GetEquipmentColor(material_slot);
|
wc->color.Color = GetEquipmentColor(material_slot);
|
||||||
wc->wear_slot_id = material_slot;
|
wc->wear_slot_id = material_slot;
|
||||||
|
|
||||||
entity_list.QueueClients(this, outapp);
|
if (!one_client)
|
||||||
|
{
|
||||||
|
entity_list.QueueClients(this, outapp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
one_client->QueuePacket(outapp, false, Client::CLIENT_CONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2970,7 +3167,7 @@ int32 Mob::GetActSpellCasttime(uint16 spell_id, int32 casttime) {
|
|||||||
return casttime;
|
return casttime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on) {
|
void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on, int level_override) {
|
||||||
// Changed proc targets to look up based on the spells goodEffect flag.
|
// Changed proc targets to look up based on the spells goodEffect flag.
|
||||||
// This should work for the majority of weapons.
|
// This should work for the majority of weapons.
|
||||||
if(spell_id == SPELL_UNKNOWN || on->GetSpecialAbility(NO_HARM_FROM_CLIENT)) {
|
if(spell_id == SPELL_UNKNOWN || on->GetSpecialAbility(NO_HARM_FROM_CLIENT)) {
|
||||||
@ -3009,14 +3206,14 @@ void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on) {
|
|||||||
twinproc = true;
|
twinproc = true;
|
||||||
|
|
||||||
if (IsBeneficialSpell(spell_id)) {
|
if (IsBeneficialSpell(spell_id)) {
|
||||||
SpellFinished(spell_id, this, 10, 0, -1, spells[spell_id].ResistDiff, true);
|
SpellFinished(spell_id, this, 10, 0, -1, spells[spell_id].ResistDiff, true, level_override);
|
||||||
if(twinproc)
|
if(twinproc)
|
||||||
SpellOnTarget(spell_id, this, false, false, 0, true);
|
SpellOnTarget(spell_id, this, false, false, 0, true, level_override);
|
||||||
}
|
}
|
||||||
else if(!(on->IsClient() && on->CastToClient()->dead)) { //dont proc on dead clients
|
else if(!(on->IsClient() && on->CastToClient()->dead)) { //dont proc on dead clients
|
||||||
SpellFinished(spell_id, on, 10, 0, -1, spells[spell_id].ResistDiff, true);
|
SpellFinished(spell_id, on, 10, 0, -1, spells[spell_id].ResistDiff, true, level_override);
|
||||||
if(twinproc)
|
if(twinproc)
|
||||||
SpellOnTarget(spell_id, on, false, false, 0, true);
|
SpellOnTarget(spell_id, on, false, false, 0, true, level_override);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4006,6 +4203,39 @@ int32 Mob::GetItemStat(uint32 itemid, const char *identifier)
|
|||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Mob::GetGlobal(const char *varname) {
|
||||||
|
int qgCharid = 0;
|
||||||
|
int qgNpcid = 0;
|
||||||
|
|
||||||
|
if (this->IsNPC())
|
||||||
|
qgNpcid = this->GetNPCTypeID();
|
||||||
|
|
||||||
|
if (this->IsClient())
|
||||||
|
qgCharid = this->CastToClient()->CharacterID();
|
||||||
|
|
||||||
|
QGlobalCache *qglobals = nullptr;
|
||||||
|
std::list<QGlobal> globalMap;
|
||||||
|
|
||||||
|
if (this->IsClient())
|
||||||
|
qglobals = this->CastToClient()->GetQGlobals();
|
||||||
|
|
||||||
|
if (this->IsNPC())
|
||||||
|
qglobals = this->CastToNPC()->GetQGlobals();
|
||||||
|
|
||||||
|
if(qglobals)
|
||||||
|
QGlobalCache::Combine(globalMap, qglobals->GetBucket(), qgNpcid, qgCharid, zone->GetZoneID());
|
||||||
|
|
||||||
|
std::list<QGlobal>::iterator iter = globalMap.begin();
|
||||||
|
while(iter != globalMap.end()) {
|
||||||
|
if ((*iter).name.compare(varname) == 0)
|
||||||
|
return (*iter).value;
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Undefined";
|
||||||
|
}
|
||||||
|
|
||||||
void Mob::SetGlobal(const char *varname, const char *newvalue, int options, const char *duration, Mob *other) {
|
void Mob::SetGlobal(const char *varname, const char *newvalue, int options, const char *duration, Mob *other) {
|
||||||
|
|
||||||
int qgZoneid = zone->GetZoneID();
|
int qgZoneid = zone->GetZoneID();
|
||||||
@ -5388,3 +5618,42 @@ bool Mob::CanClassEquipItem(uint32 item_id)
|
|||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mob::SendAddPlayerState(PlayerState new_state)
|
||||||
|
{
|
||||||
|
auto app = new EQApplicationPacket(OP_PlayerStateAdd, sizeof(PlayerState_Struct));
|
||||||
|
auto ps = (PlayerState_Struct *)app->pBuffer;
|
||||||
|
|
||||||
|
ps->spawn_id = GetID();
|
||||||
|
ps->state = static_cast<uint32>(new_state);
|
||||||
|
|
||||||
|
AddPlayerState(ps->state);
|
||||||
|
entity_list.QueueClients(nullptr, app);
|
||||||
|
safe_delete(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mob::SendRemovePlayerState(PlayerState old_state)
|
||||||
|
{
|
||||||
|
auto app = new EQApplicationPacket(OP_PlayerStateRemove, sizeof(PlayerState_Struct));
|
||||||
|
auto ps = (PlayerState_Struct *)app->pBuffer;
|
||||||
|
|
||||||
|
ps->spawn_id = GetID();
|
||||||
|
ps->state = static_cast<uint32>(old_state);
|
||||||
|
|
||||||
|
RemovePlayerState(ps->state);
|
||||||
|
entity_list.QueueClients(nullptr, app);
|
||||||
|
safe_delete(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mob::SetCurrentSpeed(int in){
|
||||||
|
if (current_speed != in)
|
||||||
|
{
|
||||||
|
current_speed = in;
|
||||||
|
tar_ndx = 20;
|
||||||
|
if (in == 0) {
|
||||||
|
SetRunAnimSpeed(0);
|
||||||
|
SetMoving(false);
|
||||||
|
SendPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
67
zone/mob.h
67
zone/mob.h
@ -172,7 +172,8 @@ public:
|
|||||||
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5,
|
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5,
|
||||||
Client *specific_target=nullptr);
|
Client *specific_target=nullptr);
|
||||||
void SendTargetable(bool on, Client *specific_target = nullptr);
|
void SendTargetable(bool on, Client *specific_target = nullptr);
|
||||||
virtual void SendWearChange(uint8 material_slot);
|
virtual void SendArmorAppearance(Client *one_client = nullptr);
|
||||||
|
virtual void SendWearChange(uint8 material_slot, Client *one_client = nullptr);
|
||||||
virtual void SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model = 0, uint32 elite_material = 0,
|
virtual void SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model = 0, uint32 elite_material = 0,
|
||||||
uint32 unknown06 = 0, uint32 unknown18 = 0);
|
uint32 unknown06 = 0, uint32 unknown18 = 0);
|
||||||
virtual void SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint);
|
virtual void SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint);
|
||||||
@ -200,7 +201,7 @@ public:
|
|||||||
bool IsBeneficialAllowed(Mob *target);
|
bool IsBeneficialAllowed(Mob *target);
|
||||||
virtual int GetCasterLevel(uint16 spell_id);
|
virtual int GetCasterLevel(uint16 spell_id);
|
||||||
void ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* newbon, uint16 casterID = 0,
|
void ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* newbon, uint16 casterID = 0,
|
||||||
uint8 WornType = 0, uint32 ticsremaining = 0, int buffslot = -1,
|
uint8 WornType = 0, int32 ticsremaining = 0, int buffslot = -1, int instrument_mod = 10,
|
||||||
bool IsAISpellEffect = false, uint16 effect_id = 0, int32 se_base = 0, int32 se_limit = 0, int32 se_max = 0);
|
bool IsAISpellEffect = false, uint16 effect_id = 0, int32 se_base = 0, int32 se_limit = 0, int32 se_max = 0);
|
||||||
void NegateSpellsBonuses(uint16 spell_id);
|
void NegateSpellsBonuses(uint16 spell_id);
|
||||||
virtual float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false);
|
virtual float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false);
|
||||||
@ -211,7 +212,8 @@ public:
|
|||||||
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration);
|
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration);
|
||||||
virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime);
|
virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime);
|
||||||
float ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use_resist_override = false,
|
float ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use_resist_override = false,
|
||||||
int resist_override = 0, bool CharismaCheck = false, bool CharmTick = false, bool IsRoot = false);
|
int resist_override = 0, bool CharismaCheck = false, bool CharmTick = false, bool IsRoot = false,
|
||||||
|
int level_override = -1);
|
||||||
int ResistPhysical(int level_diff, uint8 caster_level);
|
int ResistPhysical(int level_diff, uint8 caster_level);
|
||||||
uint16 GetSpecializeSkillValue(uint16 spell_id) const;
|
uint16 GetSpecializeSkillValue(uint16 spell_id) const;
|
||||||
void SendSpellBarDisable();
|
void SendSpellBarDisable();
|
||||||
@ -227,10 +229,10 @@ public:
|
|||||||
void CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, uint16 mana_used,
|
void CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, uint16 mana_used,
|
||||||
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0);
|
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0);
|
||||||
bool SpellFinished(uint16 spell_id, Mob *target, uint16 slot = 10, uint16 mana_used = 0,
|
bool SpellFinished(uint16 spell_id, Mob *target, uint16 slot = 10, uint16 mana_used = 0,
|
||||||
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false);
|
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false, int level_override = -1);
|
||||||
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect = false,
|
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect = false,
|
||||||
bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false);
|
bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false, int level_override = -1);
|
||||||
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100);
|
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100, int level_override = -1);
|
||||||
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center,
|
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center,
|
||||||
CastAction_type &CastAction);
|
CastAction_type &CastAction);
|
||||||
virtual bool CheckFizzle(uint16 spell_id);
|
virtual bool CheckFizzle(uint16 spell_id);
|
||||||
@ -253,7 +255,7 @@ public:
|
|||||||
|
|
||||||
//Buff
|
//Buff
|
||||||
void BuffProcess();
|
void BuffProcess();
|
||||||
virtual void DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caster_level, Mob* caster = 0);
|
virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr);
|
||||||
void BuffFadeBySpellID(uint16 spell_id);
|
void BuffFadeBySpellID(uint16 spell_id);
|
||||||
void BuffFadeByEffect(int effectid, int skipslot = -1);
|
void BuffFadeByEffect(int effectid, int skipslot = -1);
|
||||||
void BuffFadeAll();
|
void BuffFadeAll();
|
||||||
@ -364,6 +366,7 @@ public:
|
|||||||
inline Mob* GetTarget() const { return target; }
|
inline Mob* GetTarget() const { return target; }
|
||||||
virtual void SetTarget(Mob* mob);
|
virtual void SetTarget(Mob* mob);
|
||||||
virtual inline float GetHPRatio() const { return max_hp == 0 ? 0 : ((float)cur_hp/max_hp*100); }
|
virtual inline float GetHPRatio() const { return max_hp == 0 ? 0 : ((float)cur_hp/max_hp*100); }
|
||||||
|
virtual inline float GetIntHPRatio() const { return max_hp == 0 ? 0 : (cur_hp/max_hp*100); }
|
||||||
inline virtual int32 GetAC() const { return AC + itembonuses.AC + spellbonuses.AC; }
|
inline virtual int32 GetAC() const { return AC + itembonuses.AC + spellbonuses.AC; }
|
||||||
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK; }
|
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK; }
|
||||||
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
||||||
@ -441,9 +444,12 @@ public:
|
|||||||
virtual void SetMoving(bool move) { moving = move; m_Delta = glm::vec4(); }
|
virtual void SetMoving(bool move) { moving = move; m_Delta = glm::vec4(); }
|
||||||
virtual void GoToBind(uint8 bindnum = 0) { }
|
virtual void GoToBind(uint8 bindnum = 0) { }
|
||||||
virtual void Gate();
|
virtual void Gate();
|
||||||
float GetWalkspeed() const { return(_GetMovementSpeed(-47)); }
|
int GetWalkspeed() const { return(_GetWalkSpeed()); }
|
||||||
float GetRunspeed() const { return(_GetMovementSpeed(0)); }
|
int GetRunspeed() const { return(_GetRunSpeed()); }
|
||||||
float GetBaseRunspeed() const { return runspeed; }
|
void SetCurrentSpeed(int in);
|
||||||
|
int GetBaseRunspeed() const { return base_runspeed; }
|
||||||
|
int GetBaseWalkspeed() const { return base_walkspeed; }
|
||||||
|
int GetBaseFearSpeed() const { return base_fearspeed; }
|
||||||
float GetMovespeed() const { return IsRunning() ? GetRunspeed() : GetWalkspeed(); }
|
float GetMovespeed() const { return IsRunning() ? GetRunspeed() : GetWalkspeed(); }
|
||||||
bool IsRunning() const { return m_is_running; }
|
bool IsRunning() const { return m_is_running; }
|
||||||
void SetRunning(bool val) { m_is_running = val; }
|
void SetRunning(bool val) { m_is_running = val; }
|
||||||
@ -493,7 +499,6 @@ public:
|
|||||||
inline bool CheckLastLosState() const { return last_los_check; }
|
inline bool CheckLastLosState() const { return last_los_check; }
|
||||||
|
|
||||||
//Quest
|
//Quest
|
||||||
void QuestReward(Client *c = nullptr, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0);
|
|
||||||
void CameraEffect(uint32 duration, uint32 intensity, Client *c = nullptr, bool global = false);
|
void CameraEffect(uint32 duration, uint32 intensity, Client *c = nullptr, bool global = false);
|
||||||
inline bool GetQglobal() const { return qglobal; }
|
inline bool GetQglobal() const { return qglobal; }
|
||||||
|
|
||||||
@ -504,7 +509,8 @@ public:
|
|||||||
static void CreateSpawnPacket(EQApplicationPacket* app, NewSpawn_Struct* ns);
|
static void CreateSpawnPacket(EQApplicationPacket* app, NewSpawn_Struct* ns);
|
||||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||||
void CreateHPPacket(EQApplicationPacket* app);
|
void CreateHPPacket(EQApplicationPacket* app);
|
||||||
void SendHPUpdate();
|
void SendHPUpdate(bool skip_self = false);
|
||||||
|
virtual void ResetHPUpdateTimer() {}; // does nothing
|
||||||
|
|
||||||
//Util
|
//Util
|
||||||
static uint32 RandomTimer(int min, int max);
|
static uint32 RandomTimer(int min, int max);
|
||||||
@ -533,7 +539,7 @@ public:
|
|||||||
bool HasDefensiveProcs() const;
|
bool HasDefensiveProcs() const;
|
||||||
bool HasSkillProcs() const;
|
bool HasSkillProcs() const;
|
||||||
bool HasSkillProcSuccess() const;
|
bool HasSkillProcSuccess() const;
|
||||||
bool AddProcToWeapon(uint16 spell_id, bool bPerma = false, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN);
|
bool AddProcToWeapon(uint16 spell_id, bool bPerma = false, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN, int level_override = -1);
|
||||||
bool RemoveProcFromWeapon(uint16 spell_id, bool bAll = false);
|
bool RemoveProcFromWeapon(uint16 spell_id, bool bAll = false);
|
||||||
bool HasProcs() const;
|
bool HasProcs() const;
|
||||||
bool IsCombatProc(uint16 spell_id);
|
bool IsCombatProc(uint16 spell_id);
|
||||||
@ -802,9 +808,8 @@ public:
|
|||||||
|
|
||||||
//old fear function
|
//old fear function
|
||||||
//void SetFeared(Mob *caster, uint32 duration, bool flee = false);
|
//void SetFeared(Mob *caster, uint32 duration, bool flee = false);
|
||||||
float GetFearSpeed();
|
int GetFearSpeed() { return _GetFearSpeed(); }
|
||||||
bool IsFeared() { return curfp; } // This returns true if the mob is feared or fleeing due to low HP
|
bool IsFeared() { return (spellbonuses.IsFeared || flee_mode); } // This returns true if the mob is feared or fleeing due to low HP
|
||||||
//old fear: inline void StartFleeing() { SetFeared(GetHateTop(), FLEE_RUN_DURATION, true); }
|
|
||||||
inline void StartFleeing() { flee_mode = true; CalculateNewFearpoint(); }
|
inline void StartFleeing() { flee_mode = true; CalculateNewFearpoint(); }
|
||||||
void ProcessFlee();
|
void ProcessFlee();
|
||||||
void CheckFlee();
|
void CheckFlee();
|
||||||
@ -812,8 +817,8 @@ public:
|
|||||||
|
|
||||||
inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);}
|
inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);}
|
||||||
float CalculateHeadingToTarget(float in_x, float in_y);
|
float CalculateHeadingToTarget(float in_x, float in_y);
|
||||||
bool CalculateNewPosition(float x, float y, float z, float speed, bool checkZ = false);
|
bool CalculateNewPosition(float x, float y, float z, int speed, bool checkZ = false, bool calcheading = true);
|
||||||
virtual bool CalculateNewPosition2(float x, float y, float z, float speed, bool checkZ = true);
|
virtual bool CalculateNewPosition2(float x, float y, float z, int speed, bool checkZ = true, bool calcheading = true);
|
||||||
float CalculateDistance(float x, float y, float z);
|
float CalculateDistance(float x, float y, float z);
|
||||||
float GetGroundZ(float new_x, float new_y, float z_offset=0.0);
|
float GetGroundZ(float new_x, float new_y, float z_offset=0.0);
|
||||||
void SendTo(float new_x, float new_y, float new_z);
|
void SendTo(float new_x, float new_y, float new_z);
|
||||||
@ -859,7 +864,7 @@ public:
|
|||||||
virtual uint32 GetAA(uint32 aa_id) const { return(0); }
|
virtual uint32 GetAA(uint32 aa_id) const { return(0); }
|
||||||
|
|
||||||
uint32 GetInstrumentMod(uint16 spell_id) const;
|
uint32 GetInstrumentMod(uint16 spell_id) const;
|
||||||
int CalcSpellEffectValue(uint16 spell_id, int effect_id, int caster_level = 1, Mob *caster = nullptr, int ticsremaining = 0);
|
int CalcSpellEffectValue(uint16 spell_id, int effect_id, int caster_level = 1, uint32 instrument_mod = 10, Mob *caster = nullptr, int ticsremaining = 0);
|
||||||
int CalcSpellEffectValue_formula(int formula, int base, int max, int caster_level, uint16 spell_id, int ticsremaining = 0);
|
int CalcSpellEffectValue_formula(int formula, int base, int max, int caster_level, uint16 spell_id, int ticsremaining = 0);
|
||||||
virtual int CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, int caster_level2, Mob* caster1 = nullptr, Mob* caster2 = nullptr, int buffslot = -1);
|
virtual int CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, int caster_level2, Mob* caster1 = nullptr, Mob* caster2 = nullptr, int buffslot = -1);
|
||||||
uint32 GetCastedSpellInvSlot() const { return casting_spell_inventory_slot; }
|
uint32 GetCastedSpellInvSlot() const { return casting_spell_inventory_slot; }
|
||||||
@ -884,6 +889,8 @@ public:
|
|||||||
Timer *GetSpecialAbilityTimer(int ability);
|
Timer *GetSpecialAbilityTimer(int ability);
|
||||||
void ClearSpecialAbilities();
|
void ClearSpecialAbilities();
|
||||||
void ProcessSpecialAbilities(const std::string &str);
|
void ProcessSpecialAbilities(const std::string &str);
|
||||||
|
bool IsMoved() { return moved; }
|
||||||
|
void SetMoved(bool moveflag) { moved = moveflag; }
|
||||||
|
|
||||||
Shielders_Struct shielder[MAX_SHIELDERS];
|
Shielders_Struct shielder[MAX_SHIELDERS];
|
||||||
Trade* trade;
|
Trade* trade;
|
||||||
@ -906,6 +913,7 @@ public:
|
|||||||
inline virtual bool IsBlockedBuff(int16 SpellID) { return false; }
|
inline virtual bool IsBlockedBuff(int16 SpellID) { return false; }
|
||||||
inline virtual bool IsBlockedPetBuff(int16 SpellID) { return false; }
|
inline virtual bool IsBlockedPetBuff(int16 SpellID) { return false; }
|
||||||
|
|
||||||
|
std::string GetGlobal(const char *varname);
|
||||||
void SetGlobal(const char *varname, const char *newvalue, int options, const char *duration, Mob *other = nullptr);
|
void SetGlobal(const char *varname, const char *newvalue, int options, const char *duration, Mob *other = nullptr);
|
||||||
void TarGlobal(const char *varname, const char *value, const char *duration, int npcid, int charid, int zoneid);
|
void TarGlobal(const char *varname, const char *value, const char *duration, int npcid, int charid, int zoneid);
|
||||||
void DelGlobal(const char *varname);
|
void DelGlobal(const char *varname);
|
||||||
@ -956,7 +964,10 @@ protected:
|
|||||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
||||||
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||||
float _GetMovementSpeed(int mod) const;
|
float _GetMovementSpeed(int mod) const;
|
||||||
virtual bool MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, bool checkZ);
|
int _GetWalkSpeed() const;
|
||||||
|
int _GetRunSpeed() const;
|
||||||
|
int _GetFearSpeed() const;
|
||||||
|
virtual bool MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, bool checkZ);
|
||||||
|
|
||||||
virtual bool AI_EngagedCastCheck() { return(false); }
|
virtual bool AI_EngagedCastCheck() { return(false); }
|
||||||
virtual bool AI_PursueCastCheck() { return(false); }
|
virtual bool AI_PursueCastCheck() { return(false); }
|
||||||
@ -1030,6 +1041,13 @@ protected:
|
|||||||
uint32 follow_dist;
|
uint32 follow_dist;
|
||||||
bool no_target_hotkey;
|
bool no_target_hotkey;
|
||||||
|
|
||||||
|
uint32 m_PlayerState;
|
||||||
|
uint32 GetPlayerState() { return m_PlayerState; }
|
||||||
|
void AddPlayerState(uint32 new_state) { m_PlayerState |= new_state; }
|
||||||
|
void RemovePlayerState(uint32 old_state) { m_PlayerState &= ~old_state; }
|
||||||
|
void SendAddPlayerState(PlayerState new_state);
|
||||||
|
void SendRemovePlayerState(PlayerState old_state);
|
||||||
|
|
||||||
uint8 gender;
|
uint8 gender;
|
||||||
uint16 race;
|
uint16 race;
|
||||||
uint8 base_gender;
|
uint8 base_gender;
|
||||||
@ -1046,6 +1064,13 @@ protected:
|
|||||||
float base_size;
|
float base_size;
|
||||||
float size;
|
float size;
|
||||||
float runspeed;
|
float runspeed;
|
||||||
|
float walkspeed;
|
||||||
|
float fearspeed;
|
||||||
|
int base_runspeed;
|
||||||
|
int base_walkspeed;
|
||||||
|
int base_fearspeed;
|
||||||
|
int current_speed;
|
||||||
|
|
||||||
uint32 pLastChange;
|
uint32 pLastChange;
|
||||||
bool held;
|
bool held;
|
||||||
bool nocast;
|
bool nocast;
|
||||||
@ -1059,7 +1084,7 @@ protected:
|
|||||||
void TryWeaponProc(const ItemInst* inst, const ItemData* weapon, Mob *on, uint16 hand = MainPrimary);
|
void TryWeaponProc(const ItemInst* inst, const ItemData* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||||
void TrySpellProc(const ItemInst* inst, const ItemData* weapon, Mob *on, uint16 hand = MainPrimary);
|
void TrySpellProc(const ItemInst* inst, const ItemData* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||||
void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);
|
void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||||
void ExecWeaponProc(const ItemInst* weapon, uint16 spell_id, Mob *on);
|
void ExecWeaponProc(const ItemInst* weapon, uint16 spell_id, Mob *on, int level_override = -1);
|
||||||
virtual float GetProcChances(float ProcBonus, uint16 hand = MainPrimary);
|
virtual float GetProcChances(float ProcBonus, uint16 hand = MainPrimary);
|
||||||
virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 hand = MainPrimary, Mob *on = nullptr);
|
virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 hand = MainPrimary, Mob *on = nullptr);
|
||||||
virtual float GetSpecialProcChances(uint16 hand);
|
virtual float GetSpecialProcChances(uint16 hand);
|
||||||
|
|||||||
307
zone/mob_ai.cpp
307
zone/mob_ai.cpp
@ -339,9 +339,7 @@ bool NPC::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain
|
|||||||
|
|
||||||
//stop moving if were casting a spell and were not a bard...
|
//stop moving if were casting a spell and were not a bard...
|
||||||
if(!IsBardSong(AIspells[i].spellid)) {
|
if(!IsBardSong(AIspells[i].spellid)) {
|
||||||
SetRunAnimSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
SendPosition();
|
|
||||||
SetMoving(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return CastSpell(AIspells[i].spellid, tar->GetID(), 1, AIspells[i].manacost == -2 ? 0 : -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, 0, &(AIspells[i].resist_adjust));
|
return CastSpell(AIspells[i].spellid, tar->GetID(), 1, AIspells[i].manacost == -2 ? 0 : -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, 0, &(AIspells[i].resist_adjust));
|
||||||
@ -698,9 +696,7 @@ void Client::AI_SpellCast()
|
|||||||
{
|
{
|
||||||
if(!IsBardSong(spell_to_cast))
|
if(!IsBardSong(spell_to_cast))
|
||||||
{
|
{
|
||||||
SetRunAnimSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
SendPosition();
|
|
||||||
SetMoving(false);
|
|
||||||
}
|
}
|
||||||
CastSpell(spell_to_cast, tar->GetID(), slot_to_use);
|
CastSpell(spell_to_cast, tar->GetID(), slot_to_use);
|
||||||
return;
|
return;
|
||||||
@ -714,9 +710,7 @@ void Client::AI_SpellCast()
|
|||||||
{
|
{
|
||||||
if(!IsBardSong(spell_to_cast))
|
if(!IsBardSong(spell_to_cast))
|
||||||
{
|
{
|
||||||
SetRunAnimSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
SendPosition();
|
|
||||||
SetMoving(false);
|
|
||||||
}
|
}
|
||||||
CastSpell(spell_to_cast, tar->GetID(), slot_to_use);
|
CastSpell(spell_to_cast, tar->GetID(), slot_to_use);
|
||||||
return;
|
return;
|
||||||
@ -772,16 +766,13 @@ void Client::AI_Process()
|
|||||||
{
|
{
|
||||||
if(GetTarget())
|
if(GetTarget())
|
||||||
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
||||||
SetRunAnimSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
SendPosition();
|
|
||||||
SetMoving(false);
|
|
||||||
moved=false;
|
|
||||||
}
|
}
|
||||||
//continue on to attack code, ensuring that we execute the engaged code
|
//continue on to attack code, ensuring that we execute the engaged code
|
||||||
engaged = true;
|
engaged = true;
|
||||||
} else {
|
} else {
|
||||||
if(AImovement_timer->Check()) {
|
if(AImovement_timer->Check()) {
|
||||||
animation = GetRunspeed() * 21;
|
//animation = GetFearSpeed() * 21;
|
||||||
// Check if we have reached the last fear point
|
// Check if we have reached the last fear point
|
||||||
if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) &&
|
if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) &&
|
||||||
(std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) {
|
(std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) {
|
||||||
@ -839,16 +830,13 @@ void Client::AI_Process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (AImovement_timer->Check()) {
|
if (AImovement_timer->Check()) {
|
||||||
SetRunAnimSpeed(0);
|
if(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w)
|
||||||
|
{
|
||||||
|
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
||||||
|
SendPosition();
|
||||||
|
}
|
||||||
|
SetCurrentSpeed(0);
|
||||||
}
|
}
|
||||||
if(IsMoving()) {
|
|
||||||
SetMoving(false);
|
|
||||||
moved=false;
|
|
||||||
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
|
||||||
SendPosition();
|
|
||||||
tar_ndx =0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(GetTarget() && !IsStunned() && !IsMezzed() && !GetFeigned()) {
|
if(GetTarget() && !IsStunned() && !IsMezzed() && !GetFeigned()) {
|
||||||
if(attack_timer.Check()) {
|
if(attack_timer.Check()) {
|
||||||
Attack(GetTarget(), MainPrimary);
|
Attack(GetTarget(), MainPrimary);
|
||||||
@ -944,28 +932,27 @@ void Client::AI_Process()
|
|||||||
{
|
{
|
||||||
if(!IsRooted())
|
if(!IsRooted())
|
||||||
{
|
{
|
||||||
animation = 21 * GetRunspeed();
|
if(AImovement_timer->Check())
|
||||||
if(!RuleB(Pathing, Aggro) || !zone->pathing)
|
|
||||||
CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed());
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
bool WaypointChanged, NodeReached;
|
if(!RuleB(Pathing, Aggro) || !zone->pathing)
|
||||||
glm::vec3 Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(),
|
CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed());
|
||||||
GetRunspeed(), WaypointChanged, NodeReached);
|
else
|
||||||
|
{
|
||||||
|
bool WaypointChanged, NodeReached;
|
||||||
|
glm::vec3 Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(),
|
||||||
|
GetRunspeed(), WaypointChanged, NodeReached);
|
||||||
|
|
||||||
if(WaypointChanged)
|
if(WaypointChanged)
|
||||||
tar_ndx = 20;
|
tar_ndx = 20;
|
||||||
|
|
||||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetRunspeed());
|
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetRunspeed());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(IsMoving())
|
else if(IsMoving())
|
||||||
{
|
{
|
||||||
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
||||||
SetRunAnimSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
SendPosition();
|
|
||||||
SetMoving(false);
|
|
||||||
moved=false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AI_SpellCast();
|
AI_SpellCast();
|
||||||
@ -998,21 +985,23 @@ void Client::AI_Process()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
float dist = DistanceSquared(m_Position, owner->GetPosition());
|
float dist = DistanceSquared(m_Position, owner->GetPosition());
|
||||||
if (dist >= 100)
|
if (dist >= 400)
|
||||||
{
|
{
|
||||||
float speed = dist >= 225 ? GetRunspeed() : GetWalkspeed();
|
if(AImovement_timer->Check())
|
||||||
animation = 21 * speed;
|
{
|
||||||
CalculateNewPosition2(owner->GetX(), owner->GetY(), owner->GetZ(), speed);
|
int speed = GetWalkspeed();
|
||||||
|
if (dist >= 5625)
|
||||||
|
speed = GetRunspeed();
|
||||||
|
|
||||||
|
CalculateNewPosition2(owner->GetX(), owner->GetY(), owner->GetZ(), speed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetHeading(owner->GetHeading());
|
|
||||||
if(moved)
|
if(moved)
|
||||||
{
|
{
|
||||||
moved=false;
|
SetCurrentSpeed(0);
|
||||||
SetMoving(false);
|
moved = false;
|
||||||
SendPosition();
|
|
||||||
SetRunAnimSpeed(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1042,9 +1031,7 @@ void Mob::AI_Process() {
|
|||||||
{
|
{
|
||||||
if(target)
|
if(target)
|
||||||
SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY()));
|
SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY()));
|
||||||
SetRunAnimSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
SendPosition();
|
|
||||||
SetMoving(false);
|
|
||||||
moved=false;
|
moved=false;
|
||||||
}
|
}
|
||||||
//continue on to attack code, ensuring that we execute the engaged code
|
//continue on to attack code, ensuring that we execute the engaged code
|
||||||
@ -1058,7 +1045,9 @@ void Mob::AI_Process() {
|
|||||||
CalculateNewFearpoint();
|
CalculateNewFearpoint();
|
||||||
}
|
}
|
||||||
if(!RuleB(Pathing, Fear) || !zone->pathing)
|
if(!RuleB(Pathing, Fear) || !zone->pathing)
|
||||||
|
{
|
||||||
CalculateNewPosition2(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, GetFearSpeed(), true);
|
CalculateNewPosition2(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, GetFearSpeed(), true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool WaypointChanged, NodeReached;
|
bool WaypointChanged, NodeReached;
|
||||||
@ -1084,6 +1073,8 @@ void Mob::AI_Process() {
|
|||||||
|
|
||||||
if (engaged)
|
if (engaged)
|
||||||
{
|
{
|
||||||
|
if (!(m_PlayerState & static_cast<uint32>(PlayerState::Aggressive)))
|
||||||
|
SendAddPlayerState(PlayerState::Aggressive);
|
||||||
// we are prevented from getting here if we are blind and don't have a target in range
|
// we are prevented from getting here if we are blind and don't have a target in range
|
||||||
// from above, so no extra blind checks needed
|
// from above, so no extra blind checks needed
|
||||||
if ((IsRooted() && !GetSpecialAbility(IGNORE_ROOT_AGGRO_RULES)) || IsBlind())
|
if ((IsRooted() && !GetSpecialAbility(IGNORE_ROOT_AGGRO_RULES)) || IsBlind())
|
||||||
@ -1114,7 +1105,7 @@ void Mob::AI_Process() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
if (IsPet() && GetOwner()->IsBot() && target == GetOwner())
|
if (IsPet() && GetOwner() && GetOwner()->IsBot() && target == GetOwner())
|
||||||
{
|
{
|
||||||
// this blocks all pet attacks against owner..bot pet test (copied above check)
|
// this blocks all pet attacks against owner..bot pet test (copied above check)
|
||||||
RemoveFromHateList(this);
|
RemoveFromHateList(this);
|
||||||
@ -1154,15 +1145,21 @@ void Mob::AI_Process() {
|
|||||||
{
|
{
|
||||||
if (AImovement_timer->Check())
|
if (AImovement_timer->Check())
|
||||||
{
|
{
|
||||||
SetRunAnimSpeed(0);
|
if(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w)
|
||||||
|
{
|
||||||
|
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
||||||
|
SendPosition();
|
||||||
|
}
|
||||||
|
SetCurrentSpeed(0);
|
||||||
}
|
}
|
||||||
if(IsMoving())
|
if(IsMoving())
|
||||||
{
|
{
|
||||||
SetMoving(false);
|
if(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w)
|
||||||
moved=false;
|
{
|
||||||
SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY()));
|
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
||||||
SendPosition();
|
SendPosition();
|
||||||
tar_ndx =0;
|
}
|
||||||
|
SetCurrentSpeed(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//casting checked above...
|
//casting checked above...
|
||||||
@ -1367,7 +1364,7 @@ void Mob::AI_Process() {
|
|||||||
CastToNPC()->DoClassAttacks(target);
|
CastToNPC()->DoClassAttacks(target);
|
||||||
}
|
}
|
||||||
AI_EngagedCastCheck();
|
AI_EngagedCastCheck();
|
||||||
} //end is within combat range
|
} //end is within combat rangepet
|
||||||
else {
|
else {
|
||||||
//we cannot reach our target...
|
//we cannot reach our target...
|
||||||
//underwater stuff only works with water maps in the zone!
|
//underwater stuff only works with water maps in the zone!
|
||||||
@ -1423,10 +1420,7 @@ void Mob::AI_Process() {
|
|||||||
}
|
}
|
||||||
else if(IsMoving()) {
|
else if(IsMoving()) {
|
||||||
SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY()));
|
SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY()));
|
||||||
SetRunAnimSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
SendPosition();
|
|
||||||
SetMoving(false);
|
|
||||||
moved=false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1435,6 +1429,8 @@ void Mob::AI_Process() {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (m_PlayerState & static_cast<uint32>(PlayerState::Aggressive))
|
||||||
|
SendRemovePlayerState(PlayerState::Aggressive);
|
||||||
if(AIfeignremember_timer->Check()) {
|
if(AIfeignremember_timer->Check()) {
|
||||||
// 6/14/06
|
// 6/14/06
|
||||||
// Improved Feign Death Memory
|
// Improved Feign Death Memory
|
||||||
@ -1477,7 +1473,6 @@ void Mob::AI_Process() {
|
|||||||
}
|
}
|
||||||
else if (AImovement_timer->Check() && !IsRooted())
|
else if (AImovement_timer->Check() && !IsRooted())
|
||||||
{
|
{
|
||||||
SetRunAnimSpeed(0);
|
|
||||||
if (IsPet())
|
if (IsPet())
|
||||||
{
|
{
|
||||||
// we're a pet, do as we're told
|
// we're a pet, do as we're told
|
||||||
@ -1496,18 +1491,18 @@ void Mob::AI_Process() {
|
|||||||
float dist = DistanceSquared(m_Position, owner->GetPosition());
|
float dist = DistanceSquared(m_Position, owner->GetPosition());
|
||||||
if (dist >= 400)
|
if (dist >= 400)
|
||||||
{
|
{
|
||||||
float speed = GetWalkspeed();
|
int speed = GetWalkspeed();
|
||||||
if (dist >= 5625)
|
if (dist >= 5625)
|
||||||
speed = GetRunspeed();
|
speed = GetRunspeed();
|
||||||
|
|
||||||
CalculateNewPosition2(owner->GetX(), owner->GetY(), owner->GetZ(), speed);
|
CalculateNewPosition2(owner->GetX(), owner->GetY(), owner->GetZ(), speed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(moved)
|
if(moved)
|
||||||
{
|
{
|
||||||
moved=false;
|
SetCurrentSpeed(0);
|
||||||
SetMoving(false);
|
moved = false;
|
||||||
SendPosition();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1553,19 +1548,15 @@ void Mob::AI_Process() {
|
|||||||
|
|
||||||
if (dist2 >= followdist) // Default follow distance is 100
|
if (dist2 >= followdist) // Default follow distance is 100
|
||||||
{
|
{
|
||||||
float speed = GetWalkspeed();
|
int speed = GetWalkspeed();
|
||||||
if (dist2 >= followdist + 150)
|
if (dist2 >= followdist + 150)
|
||||||
speed = GetRunspeed();
|
speed = GetRunspeed();
|
||||||
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), speed);
|
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), speed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(moved)
|
moved = false;
|
||||||
{
|
SetCurrentSpeed(0);
|
||||||
SendPosition();
|
|
||||||
moved=false;
|
|
||||||
SetMoving(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1662,92 +1653,39 @@ void NPC::AI_DoMovement() {
|
|||||||
|
|
||||||
if (gridno > 0 || cur_wp==-2) {
|
if (gridno > 0 || cur_wp==-2) {
|
||||||
if (movetimercompleted==true) { // time to pause at wp is over
|
if (movetimercompleted==true) { // time to pause at wp is over
|
||||||
|
AI_SetupNextWaypoint();
|
||||||
int32 spawn_id = this->GetSpawnPointID();
|
|
||||||
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
|
|
||||||
iterator.Reset();
|
|
||||||
Spawn2 *found_spawn = nullptr;
|
|
||||||
|
|
||||||
while(iterator.MoreElements())
|
|
||||||
{
|
|
||||||
Spawn2* cur = iterator.GetData();
|
|
||||||
iterator.Advance();
|
|
||||||
if(cur->GetID() == spawn_id)
|
|
||||||
{
|
|
||||||
found_spawn = cur;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wandertype == 4 && cur_wp == CastToNPC()->GetMaxWp()) {
|
|
||||||
CastToNPC()->Depop(true); //depop and resart spawn timer
|
|
||||||
if(found_spawn)
|
|
||||||
found_spawn->SetNPCPointerNull();
|
|
||||||
}
|
|
||||||
else if (wandertype == 6 && cur_wp == CastToNPC()->GetMaxWp()) {
|
|
||||||
CastToNPC()->Depop(false);//depop without spawn timer
|
|
||||||
if(found_spawn)
|
|
||||||
found_spawn->SetNPCPointerNull();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
movetimercompleted=false;
|
|
||||||
|
|
||||||
Log.Out(Logs::Detail, Logs::Pathing, "We are departing waypoint %d.", cur_wp);
|
|
||||||
|
|
||||||
//if we were under quest control (with no grid), we are done now..
|
|
||||||
if(cur_wp == -2) {
|
|
||||||
Log.Out(Logs::Detail, Logs::Pathing, "Non-grid quest mob has reached its quest ordered waypoint. Leaving pathing mode.");
|
|
||||||
roamer = false;
|
|
||||||
cur_wp = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(GetAppearance() != eaStanding)
|
|
||||||
SetAppearance(eaStanding, false);
|
|
||||||
|
|
||||||
entity_list.OpenDoorsNear(CastToNPC());
|
|
||||||
|
|
||||||
if(!DistractedFromGrid) {
|
|
||||||
//kick off event_waypoint depart
|
|
||||||
char temp[16];
|
|
||||||
sprintf(temp, "%d", cur_wp);
|
|
||||||
parse->EventNPC(EVENT_WAYPOINT_DEPART, CastToNPC(), nullptr, temp, 0);
|
|
||||||
|
|
||||||
//setup our next waypoint, if we are still on our normal grid
|
|
||||||
//remember that the quest event above could have done anything it wanted with our grid
|
|
||||||
if(gridno > 0) {
|
|
||||||
CastToNPC()->CalculateNewWaypoint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DistractedFromGrid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // endif (movetimercompleted==true)
|
} // endif (movetimercompleted==true)
|
||||||
else if (!(AIwalking_timer->Enabled()))
|
else if (!(AIwalking_timer->Enabled()))
|
||||||
{ // currently moving
|
{ // currently moving
|
||||||
|
bool doMove = true;
|
||||||
if (m_CurrentWayPoint.x == GetX() && m_CurrentWayPoint.y == GetY())
|
if (m_CurrentWayPoint.x == GetX() && m_CurrentWayPoint.y == GetY())
|
||||||
{ // are we there yet? then stop
|
{ // are we there yet? then stop
|
||||||
Log.Out(Logs::Detail, Logs::AI, "We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d", cur_wp, GetX(), GetY(), GetZ(), GetGrid());
|
Log.Out(Logs::Detail, Logs::AI, "We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d", cur_wp, GetX(), GetY(), GetZ(), GetGrid());
|
||||||
SetWaypointPause();
|
if (cur_wp_pause != 0) {
|
||||||
if(GetAppearance() != eaStanding)
|
SetWaypointPause();
|
||||||
SetAppearance(eaStanding, false);
|
SetAppearance(eaStanding, false);
|
||||||
SetMoving(false);
|
SetMoving(false);
|
||||||
if (m_CurrentWayPoint.w >= 0.0) {
|
if (m_CurrentWayPoint.w >= 0.0) {
|
||||||
SetHeading(m_CurrentWayPoint.w);
|
SetHeading(m_CurrentWayPoint.w);
|
||||||
|
}
|
||||||
|
SendPosition();
|
||||||
}
|
}
|
||||||
SendPosition();
|
|
||||||
|
|
||||||
//kick off event_waypoint arrive
|
//kick off event_waypoint arrive
|
||||||
char temp[16];
|
char temp[16];
|
||||||
sprintf(temp, "%d", cur_wp);
|
sprintf(temp, "%d", cur_wp);
|
||||||
parse->EventNPC(EVENT_WAYPOINT_ARRIVE, CastToNPC(), nullptr, temp, 0);
|
parse->EventNPC(EVENT_WAYPOINT_ARRIVE, CastToNPC(), nullptr, temp, 0);
|
||||||
|
// start moving directly to next waypoint if we're at a 0 pause waypoint and we didn't get quest halted.
|
||||||
|
if (!AIwalking_timer->Enabled())
|
||||||
|
AI_SetupNextWaypoint();
|
||||||
|
else
|
||||||
|
doMove = false;
|
||||||
// wipe feign memory since we reached our first waypoint
|
// wipe feign memory since we reached our first waypoint
|
||||||
if(cur_wp == 1)
|
if(cur_wp == 1)
|
||||||
ClearFeignMemory();
|
ClearFeignMemory();
|
||||||
}
|
}
|
||||||
else
|
if (doMove)
|
||||||
{ // not at waypoint yet, so keep moving
|
{ // not at waypoint yet or at 0 pause WP, so keep moving
|
||||||
if(!RuleB(Pathing, AggroReturnToGrid) || !zone->pathing || (DistractedFromGrid == 0))
|
if(!RuleB(Pathing, AggroReturnToGrid) || !zone->pathing || (DistractedFromGrid == 0))
|
||||||
CalculateNewPosition2(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, true);
|
CalculateNewPosition2(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, true);
|
||||||
else
|
else
|
||||||
@ -1775,8 +1713,7 @@ void NPC::AI_DoMovement() {
|
|||||||
SetGrid( 0 - GetGrid()); // revert to AI control
|
SetGrid( 0 - GetGrid()); // revert to AI control
|
||||||
Log.Out(Logs::Detail, Logs::Pathing, "Quest pathing is finished. Resuming on grid %d", GetGrid());
|
Log.Out(Logs::Detail, Logs::Pathing, "Quest pathing is finished. Resuming on grid %d", GetGrid());
|
||||||
|
|
||||||
if(GetAppearance() != eaStanding)
|
SetAppearance(eaStanding, false);
|
||||||
SetAppearance(eaStanding, false);
|
|
||||||
|
|
||||||
CalculateNewWaypoint();
|
CalculateNewWaypoint();
|
||||||
}
|
}
|
||||||
@ -1812,29 +1749,86 @@ void NPC::AI_DoMovement() {
|
|||||||
Log.Out(Logs::Detail, Logs::AI, "Reached guard point (%.3f,%.3f,%.3f)", m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z);
|
Log.Out(Logs::Detail, Logs::AI, "Reached guard point (%.3f,%.3f,%.3f)", m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z);
|
||||||
ClearFeignMemory();
|
ClearFeignMemory();
|
||||||
moved=false;
|
moved=false;
|
||||||
SetMoving(false);
|
|
||||||
if (GetTarget() == nullptr || DistanceSquared(m_Position, GetTarget()->GetPosition()) >= 5*5 )
|
if (GetTarget() == nullptr || DistanceSquared(m_Position, GetTarget()->GetPosition()) >= 5*5 )
|
||||||
{
|
{
|
||||||
SetHeading(m_GuardPoint.w);
|
SetHeading(m_GuardPoint.w);
|
||||||
} else {
|
} else {
|
||||||
FaceTarget(GetTarget());
|
FaceTarget(GetTarget());
|
||||||
}
|
}
|
||||||
SendPosition();
|
SetCurrentSpeed(0);
|
||||||
SetAppearance(GetGuardPointAnim());
|
SetAppearance(GetGuardPointAnim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NPC::AI_SetupNextWaypoint() {
|
||||||
|
int32 spawn_id = this->GetSpawnPointID();
|
||||||
|
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
|
||||||
|
iterator.Reset();
|
||||||
|
Spawn2 *found_spawn = nullptr;
|
||||||
|
|
||||||
|
while (iterator.MoreElements())
|
||||||
|
{
|
||||||
|
Spawn2* cur = iterator.GetData();
|
||||||
|
iterator.Advance();
|
||||||
|
if (cur->GetID() == spawn_id)
|
||||||
|
{
|
||||||
|
found_spawn = cur;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wandertype == 4 && cur_wp == CastToNPC()->GetMaxWp()) {
|
||||||
|
CastToNPC()->Depop(true); //depop and restart spawn timer
|
||||||
|
if (found_spawn)
|
||||||
|
found_spawn->SetNPCPointerNull();
|
||||||
|
}
|
||||||
|
else if (wandertype == 6 && cur_wp == CastToNPC()->GetMaxWp()) {
|
||||||
|
CastToNPC()->Depop(false);//depop without spawn timer
|
||||||
|
if (found_spawn)
|
||||||
|
found_spawn->SetNPCPointerNull();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
movetimercompleted = false;
|
||||||
|
|
||||||
|
Log.Out(Logs::Detail, Logs::Pathing, "We are departing waypoint %d.", cur_wp);
|
||||||
|
|
||||||
|
//if we were under quest control (with no grid), we are done now..
|
||||||
|
if (cur_wp == -2) {
|
||||||
|
Log.Out(Logs::Detail, Logs::Pathing, "Non-grid quest mob has reached its quest ordered waypoint. Leaving pathing mode.");
|
||||||
|
roamer = false;
|
||||||
|
cur_wp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetAppearance(eaStanding, false);
|
||||||
|
|
||||||
|
entity_list.OpenDoorsNear(CastToNPC());
|
||||||
|
|
||||||
|
if (!DistractedFromGrid) {
|
||||||
|
//kick off event_waypoint depart
|
||||||
|
char temp[16];
|
||||||
|
sprintf(temp, "%d", cur_wp);
|
||||||
|
parse->EventNPC(EVENT_WAYPOINT_DEPART, CastToNPC(), nullptr, temp, 0);
|
||||||
|
|
||||||
|
//setup our next waypoint, if we are still on our normal grid
|
||||||
|
//remember that the quest event above could have done anything it wanted with our grid
|
||||||
|
if (GetGrid() > 0) {
|
||||||
|
CastToNPC()->CalculateNewWaypoint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DistractedFromGrid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Note: Mob that caused this may not get added to the hate list until after this function call completes
|
// Note: Mob that caused this may not get added to the hate list until after this function call completes
|
||||||
void Mob::AI_Event_Engaged(Mob* attacker, bool iYellForHelp) {
|
void Mob::AI_Event_Engaged(Mob* attacker, bool iYellForHelp) {
|
||||||
if (!IsAIControlled())
|
if (!IsAIControlled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(GetAppearance() != eaStanding)
|
SetAppearance(eaStanding);
|
||||||
{
|
|
||||||
SetAppearance(eaStanding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iYellForHelp) {
|
if (iYellForHelp) {
|
||||||
if(IsPet()) {
|
if(IsPet()) {
|
||||||
@ -1881,9 +1875,10 @@ void Mob::AI_Event_NoLongerEngaged() {
|
|||||||
pLastFightingDelayMoving += zone->random.Int(minLastFightingDelayMoving, maxLastFightingDelayMoving);
|
pLastFightingDelayMoving += zone->random.Int(minLastFightingDelayMoving, maxLastFightingDelayMoving);
|
||||||
// So mobs don't keep running as a ghost until AIwalking_timer fires
|
// So mobs don't keep running as a ghost until AIwalking_timer fires
|
||||||
// if they were moving prior to losing all hate
|
// if they were moving prior to losing all hate
|
||||||
if(IsMoving()){
|
// except if we're a pet, then we might run into some issues with pets backing off when they should immediately be moving
|
||||||
|
if(!IsPet())
|
||||||
|
{
|
||||||
SetRunAnimSpeed(0);
|
SetRunAnimSpeed(0);
|
||||||
SetMoving(false);
|
|
||||||
SendPosition();
|
SendPosition();
|
||||||
}
|
}
|
||||||
ClearRampage();
|
ClearRampage();
|
||||||
@ -2557,11 +2552,9 @@ void NPC::ApplyAISpellEffects(StatBonuses* newbon)
|
|||||||
if (!AI_HasSpellsEffects())
|
if (!AI_HasSpellsEffects())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(int i=0; i < AIspellsEffects.size(); i++)
|
for (int i = 0; i < AIspellsEffects.size(); i++)
|
||||||
{
|
ApplySpellsBonuses(0, 0, newbon, 0, 0, 0, -1, 10, true, AIspellsEffects[i].spelleffectid,
|
||||||
ApplySpellsBonuses(0, 0, newbon, 0, 0, 0,-1,
|
AIspellsEffects[i].base, AIspellsEffects[i].limit, AIspellsEffects[i].max);
|
||||||
true, AIspellsEffects[i].spelleffectid, AIspellsEffects[i].base, AIspellsEffects[i].limit,AIspellsEffects[i].max);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -423,6 +423,7 @@ int main(int argc, char** argv) {
|
|||||||
entity_list.Process();
|
entity_list.Process();
|
||||||
entity_list.MobProcess();
|
entity_list.MobProcess();
|
||||||
entity_list.BeaconProcess();
|
entity_list.BeaconProcess();
|
||||||
|
entity_list.EncounterProcess();
|
||||||
|
|
||||||
if (zone) {
|
if (zone) {
|
||||||
if(!zone->Process()) {
|
if(!zone->Process()) {
|
||||||
|
|||||||
@ -115,7 +115,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
|
|||||||
knightattack_timer(1000),
|
knightattack_timer(1000),
|
||||||
assist_timer(AIassistcheck_delay),
|
assist_timer(AIassistcheck_delay),
|
||||||
qglobal_purge_timer(30000),
|
qglobal_purge_timer(30000),
|
||||||
sendhpupdate_timer(1000),
|
sendhpupdate_timer(2000),
|
||||||
enraged_timer(1000),
|
enraged_timer(1000),
|
||||||
taunt_timer(TauntReuseTime * 1000),
|
taunt_timer(TauntReuseTime * 1000),
|
||||||
m_SpawnPoint(position),
|
m_SpawnPoint(position),
|
||||||
@ -569,8 +569,7 @@ bool NPC::Process()
|
|||||||
{
|
{
|
||||||
if (IsStunned() && stunned_timer.Check())
|
if (IsStunned() && stunned_timer.Check())
|
||||||
{
|
{
|
||||||
this->stunned = false;
|
Mob::UnStun();
|
||||||
this->stunned_timer.Disable();
|
|
||||||
this->spun_timer.Disable();
|
this->spun_timer.Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,7 +650,8 @@ bool NPC::Process()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sendhpupdate_timer.Check() && (IsTargeted() || (IsPet() && GetOwner() && GetOwner()->IsClient()))) {
|
// we might actually want to reset in this check ... won't until issues arise at least :P
|
||||||
|
if (sendhpupdate_timer.Check(false) && (IsTargeted() || (IsPet() && GetOwner() && GetOwner()->IsClient()))) {
|
||||||
if(!IsFullHP || cur_hp<max_hp){
|
if(!IsFullHP || cur_hp<max_hp){
|
||||||
SendHPUpdate();
|
SendHPUpdate();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -119,6 +119,7 @@ public:
|
|||||||
virtual void AI_Start(uint32 iMoveDelay = 0);
|
virtual void AI_Start(uint32 iMoveDelay = 0);
|
||||||
virtual void AI_Stop();
|
virtual void AI_Stop();
|
||||||
void AI_DoMovement();
|
void AI_DoMovement();
|
||||||
|
void AI_SetupNextWaypoint();
|
||||||
bool AI_AddNPCSpells(uint32 iDBSpellsID);
|
bool AI_AddNPCSpells(uint32 iDBSpellsID);
|
||||||
bool AI_AddNPCSpellsEffects(uint32 iDBSpellsEffectsID);
|
bool AI_AddNPCSpellsEffects(uint32 iDBSpellsEffectsID);
|
||||||
virtual bool AI_EngagedCastCheck();
|
virtual bool AI_EngagedCastCheck();
|
||||||
@ -406,6 +407,7 @@ public:
|
|||||||
void SetHeroForgeModel(uint32 model) { herosforgemodel = model; }
|
void SetHeroForgeModel(uint32 model) { herosforgemodel = model; }
|
||||||
|
|
||||||
bool IsRaidTarget() const { return raid_target; };
|
bool IsRaidTarget() const { return raid_target; };
|
||||||
|
void ResetHPUpdateTimer() { sendhpupdate_timer.Start(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user