From 6715977a1f815288190f3290f2036abe2c44f478 Mon Sep 17 00:00:00 2001 From: Noudess Date: Mon, 11 Mar 2019 13:15:55 -0400 Subject: [PATCH 01/31] Change the system call to an exec. Fix the misnamed argument. --- utils/scripts/eqemu_server.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index 5bf7391c3..de46a8bb0 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -637,7 +637,7 @@ sub do_self_update_check_routine { if ($OS eq "Linux") { system("chmod 755 eqemu_server.pl"); } - system("perl eqemu_server.pl start_from_world"); + exec("perl eqemu_server.pl ran_from_world"); } } print "[Install] Done\n"; From 75d3329d37a3a9d35448390b95317a6385ee13f3 Mon Sep 17 00:00:00 2001 From: Noudess Date: Mon, 11 Mar 2019 18:24:02 -0400 Subject: [PATCH 02/31] Fix Spin() to use old mechanism so the npc actually spins again. --- zone/spells.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/zone/spells.cpp b/zone/spells.cpp index 296097376..c4ba88520 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -100,6 +100,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org) #include "bot.h" #endif +#include "mob_movement_manager.h" extern Zone* zone; @@ -4818,7 +4819,22 @@ void Mob::Spin() { safe_delete(outapp); } else { - GMMove(GetX(), GetY(), GetZ(), GetHeading()+5); + float x,y,z,h; + + x=GetX(); + y=GetY(); + z=GetZ(); + h=GetHeading()+5; + + if (IsCorpse() || (IsClient() && !IsAIControlled())) { + m_Position.x = x; + m_Position.y = y; + m_Position.z = z; + mMovementManager->SendCommandToClients(this, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny); + } + else { + Teleport(glm::vec4(x, y, z, h)); + } } } From 9c42f28b0dcc30f1d3c433350c434bff2279452f Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Tue, 12 Mar 2019 14:31:23 -0400 Subject: [PATCH 03/31] Make Database::CheckStatus() 2038 safe --- common/database.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 0af9169e5..2c234aa64 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -171,30 +171,27 @@ void Database::LoginIP(uint32 AccountID, const char* LoginIP) { QueryDatabase(query); } -int16 Database::CheckStatus(uint32 account_id) { - std::string query = StringFormat("SELECT `status`, UNIX_TIMESTAMP(`suspendeduntil`) as `suspendeduntil`, UNIX_TIMESTAMP() as `current`" - " FROM `account` WHERE `id` = %i", account_id); +int16 Database::CheckStatus(uint32 account_id) +{ + std::string query = StringFormat( + "SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `account` WHERE `id` = %i", + account_id); - auto results = QueryDatabase(query); - if (!results.Success()) { + auto results = QueryDatabase(query); + if (!results.Success()) return 0; - } if (results.RowCount() != 1) return 0; - - auto row = results.begin(); - int16 status = atoi(row[0]); - int32 suspendeduntil = 0; - // MariaDB initalizes with NULL if unix_timestamp() is out of range - if (row[1] != nullptr) { - suspendeduntil = atoi(row[1]); - } + auto row = results.begin(); + int16 status = atoi(row[0]); + int32 date_diff = 0; - int32 current = atoi(row[2]); + if (row[1] != nullptr) + date_diff = atoi(row[1]); - if(suspendeduntil > current) + if (date_diff > 0) return -1; return status; From a4c171cb1d601325d31ab728f44caf2287197bcb Mon Sep 17 00:00:00 2001 From: Noudess Date: Fri, 15 Mar 2019 10:28:23 -0400 Subject: [PATCH 04/31] Fix issue with roambox wait time after switch to navmesh. --- zone/mob_ai.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 5a31cc12b..907a47e3c 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -38,6 +38,8 @@ #include #include +#define ROAMBOX_MOVE_IN_PROGESS (666) + extern EntityList entity_list; extern FastMath g_Math; @@ -1572,9 +1574,21 @@ void NPC::AI_DoMovement() { /** * Roambox logic sets precedence */ + if (roambox_distance > 0) { - if (!IsMoving()) { + // Check if we're already moving to a WP + // If so, if we're not moving we have arrived and need to set delay + + if (GetCWP() == ROAMBOX_MOVE_IN_PROGESS && !IsMoving()) { + // We have arrived + time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay); + SetCurrentWP(0); + return; + } + + // Set a new destination + if (!IsMoving() && time_until_can_move < Timer::GetCurrentTime()) { auto move_x = static_cast(zone->random.Real(-roambox_distance, roambox_distance)); auto move_y = static_cast(zone->random.Real(-roambox_distance, roambox_distance)); @@ -1642,12 +1656,10 @@ void NPC::AI_DoMovement() { roambox_min_y, roambox_max_y, roambox_destination_y); - } + Log(Logs::Detail, Logs::NPCRoamBox, "Dest Z is (%f)", roambox_destination_z); - NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z); - - if (m_Position.x == roambox_destination_x && m_Position.y == roambox_destination_y) { - time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay); + SetCurrentWP(ROAMBOX_MOVE_IN_PROGESS); + NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z); } return; From 3d1dda888d1ba5e32906e868484f1021da118e2c Mon Sep 17 00:00:00 2001 From: Noudess Date: Mon, 25 Mar 2019 14:58:26 -0400 Subject: [PATCH 05/31] Use constants for waypoint values that are not actual waypoints --- zone/mob_ai.cpp | 15 ++++++++------- zone/waypoints.cpp | 9 ++++++--- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 907a47e3c..0ed475384 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -38,8 +38,6 @@ #include #include -#define ROAMBOX_MOVE_IN_PROGESS (666) - extern EntityList entity_list; extern FastMath g_Math; @@ -1574,13 +1572,14 @@ void NPC::AI_DoMovement() { /** * Roambox logic sets precedence */ + using EQEmu::waypoints::WaypointStatus; if (roambox_distance > 0) { // Check if we're already moving to a WP // If so, if we're not moving we have arrived and need to set delay - if (GetCWP() == ROAMBOX_MOVE_IN_PROGESS && !IsMoving()) { + if (GetCWP() == WaypointStatus::wpsRoamBoxPauseInProgress && !IsMoving()) { // We have arrived time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay); SetCurrentWP(0); @@ -1658,7 +1657,7 @@ void NPC::AI_DoMovement() { roambox_destination_y); Log(Logs::Detail, Logs::NPCRoamBox, "Dest Z is (%f)", roambox_destination_z); - SetCurrentWP(ROAMBOX_MOVE_IN_PROGESS); + SetCurrentWP(WaypointStatus::wpsRoamBoxPauseInProgress); NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z); } @@ -1672,7 +1671,7 @@ void NPC::AI_DoMovement() { int32 gridno = CastToNPC()->GetGrid(); - if (gridno > 0 || cur_wp == -2) { + if (gridno > 0 || cur_wp == WaypointStatus::wpsQuestControlNoGrid) { if (pause_timer_complete == true) { // time to pause at wp is over AI_SetupNextWaypoint(); } // endif (pause_timer_complete==true) @@ -1704,7 +1703,7 @@ void NPC::AI_DoMovement() { // as that is where roamer is unset and we don't want // the next trip through to move again based on grid stuff. doMove = false; - if (cur_wp == -2) { + if (cur_wp == WaypointStatus::wpsQuestControlNoGrid) { AI_SetupNextWaypoint(); } @@ -1803,8 +1802,10 @@ void NPC::AI_SetupNextWaypoint() { pause_timer_complete = false; Log(Logs::Detail, Logs::Pathing, "We are departing waypoint %d.", cur_wp); + using EQEmu::waypoints::WaypointStatus; + //if we were under quest control (with no grid), we are done now.. - if (cur_wp == -2) { + if (cur_wp == WaypointStatus::wpsQuestControlNoGrid) { Log(Logs::Detail, Logs::Pathing, "Non-grid quest mob has reached its quest ordered waypoint. Leaving pathing mode."); roamer = false; cur_wp = 0; diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index cf79aae08..7a7ab917e 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -108,7 +108,7 @@ void NPC::ResumeWandering() { // we were paused by a quest AI_walking_timer->Disable(); SetGrid(0 - GetGrid()); - if (cur_wp == -1) + if (cur_wp == EQEmu::waypoints::WaypointStatus::wpsQuestControlGrid) { // got here by a MoveTo() cur_wp = save_wp; UpdateWaypoint(cur_wp); // have him head to last destination from here @@ -166,6 +166,9 @@ void NPC::PauseWandering(int pausetime) void NPC::MoveTo(const glm::vec4& position, bool saveguardspot) { // makes mob walk to specified location + + using EQEmu::waypoints::WaypointStatus; + if (IsNPC() && GetGrid() != 0) { // he is on a grid if (GetGrid() < 0) @@ -177,7 +180,7 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot) if (cur_wp >= 0) { // we've not already done a MoveTo() save_wp = cur_wp; // save the current waypoint - cur_wp = -1; // flag this move as quest controlled + cur_wp = WaypointStatus::wpsQuestControlGrid; } Log(Logs::Detail, Logs::AI, "MoveTo %s, pausing regular grid wandering. Grid %d, save_wp %d", to_string(static_cast(position)).c_str(), -GetGrid(), save_wp); } @@ -185,7 +188,7 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot) { // not on a grid roamer = true; save_wp = 0; - cur_wp = -2; // flag as quest controlled w/no grid + cur_wp = WaypointStatus::wpsQuestControlNoGrid; Log(Logs::Detail, Logs::AI, "MoveTo %s without a grid.", to_string(static_cast(position)).c_str()); } From 0852468b8827ebce67e3808e0bfee2f024f5cc1e Mon Sep 17 00:00:00 2001 From: Noudess Date: Mon, 25 Mar 2019 17:54:17 -0400 Subject: [PATCH 06/31] Add constants for waypoints --- common/emu_constants.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/emu_constants.h b/common/emu_constants.h index ee8fdfcee..72ddfa11b 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -307,6 +307,14 @@ namespace EQEmu } // namespace bug + namespace waypoints { + enum WaypointStatus : int { + wpsRoamBoxPauseInProgress = -3, + wpsQuestControlNoGrid = -2, + wpsQuestControlGrid = -1 + }; + } // waypoint_status behavior + } /*EQEmu*/ #endif /*COMMON_EMU_CONSTANTS_H*/ From 60d5c11c43539944cb1f45a1e50af001bb3a7a46 Mon Sep 17 00:00:00 2001 From: Noudess Date: Mon, 25 Mar 2019 19:21:33 -0400 Subject: [PATCH 07/31] Added a use_model field to npc_types to override race-graphics, maintain race. --- zone/beacon.cpp | 2 +- zone/client.cpp | 1 + zone/corpse.cpp | 5 +- zone/encounter.cpp | 2 +- zone/mob.cpp | 248 ++++++++++++++++----------------------------- zone/mob.h | 4 +- zone/npc.cpp | 3 +- zone/zonedb.cpp | 4 +- zone/zonedump.h | 1 + 9 files changed, 104 insertions(+), 166 deletions(-) diff --git a/zone/beacon.cpp b/zone/beacon.cpp index 36075dca5..81b964290 100644 --- a/zone/beacon.cpp +++ b/zone/beacon.cpp @@ -56,7 +56,7 @@ Beacon::Beacon(Mob *at_mob, int lifetime) :Mob ( nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, at_mob->GetPosition(), 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQEmu::TintProfile(), 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, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ), remove_timer(lifetime), spell_timer(0) diff --git a/zone/client.cpp b/zone/client.cpp index 7eea9e845..f56aa1d31 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -119,6 +119,7 @@ Client::Client(EQStreamInterface* ieqs) 0, 0, 0, + 0, 0 ), hpupdate_timer(2000), diff --git a/zone/corpse.cpp b/zone/corpse.cpp index fbb319cb5..1465064f3 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -152,7 +152,8 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0, in_npc->GetPosition(), in_npc->GetInnateLightType(), in_npc->GetTexture(),in_npc->GetHelmTexture(), 0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,EQEmu::TintProfile(),0xff,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + 0,0,0,0,0,0,0,0,0,0,EQEmu::TintProfile(),0xff,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + (*in_npctypedata)->use_model), corpse_decay_timer(in_decaytime), corpse_rez_timer(0), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), @@ -258,6 +259,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( 0, // uint8 in_bracertexture, 0, // uint8 in_handtexture, 0, // uint8 in_legtexture, + 0, 0 // uint8 in_feettexture, ), corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), @@ -484,6 +486,7 @@ EQEmu::TintProfile(), 0, 0, 0, +0, 0), corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), corpse_rez_timer(RuleI(Character, CorpseResTimeMS)), diff --git a/zone/encounter.cpp b/zone/encounter.cpp index 1eff0ca59..e0ec83d90 100644 --- a/zone/encounter.cpp +++ b/zone/encounter.cpp @@ -36,7 +36,7 @@ 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, EQEmu::TintProfile(), 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, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) { encounter_name[0] = 0; diff --git a/zone/mob.cpp b/zone/mob.cpp index aec319ba7..facb6dc77 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -92,7 +92,8 @@ Mob::Mob( uint8 in_bracertexture, uint8 in_handtexture, uint8 in_legtexture, - uint8 in_feettexture + uint8 in_feettexture, + uint16 in_usemodel ) : attack_timer(2000), attack_dw_timer(2000), @@ -147,6 +148,7 @@ Mob::Mob( race = in_race; base_gender = in_gender; base_race = in_race; + use_model = in_usemodel; class_ = in_class; bodytype = in_bodytype; orig_bodytype = in_bodytype; @@ -1112,7 +1114,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) ns->spawn.spawnId = GetID(); ns->spawn.curHp = static_cast(GetHPRatio()); ns->spawn.max_hp = 100; //this field needs a better name - ns->spawn.race = race; + ns->spawn.race = (use_model) ? use_model : race; ns->spawn.runspeed = runspeed; ns->spawn.walkspeed = walkspeed; ns->spawn.class_ = class_; @@ -1692,151 +1694,77 @@ void Mob::SendIllusionPacket( float in_size ) { + uint8 new_texture = in_texture; + uint8 new_helmtexture = in_helmtexture; + uint8 new_haircolor; + uint8 new_beardcolor; + uint8 new_eyecolor1; + uint8 new_eyecolor2; + uint8 new_hairstyle; + uint8 new_luclinface; + uint8 new_beard; + uint8 new_aa_title; + uint32 new_drakkin_heritage; + uint32 new_drakkin_tattoo; + uint32 new_drakkin_details; - uint16 BaseRace = GetBaseRace(); + race = (in_race) ? in_race : GetBaseRace(); - if (in_race == 0) { - race = BaseRace; - if (in_gender == 0xFF) { - gender = GetBaseGender(); + if (in_gender != 0xFF) + { + gender = in_gender; } - else { - gender = in_gender; + else + { + gender = (in_race) ? GetDefaultGender(race, gender) : GetBaseGender(); } - } - else { - race = in_race; - if (in_gender == 0xFF) { - gender = GetDefaultGender(race, gender); + + if (in_texture == 0xFF && !IsPlayerRace(in_race)) + { + new_texture = GetTexture(); } - else { - gender = in_gender; + + if (in_helmtexture == 0xFF && !IsPlayerRace(in_race)) + { + new_helmtexture = GetHelmTexture(); } - } - if (in_texture == 0xFF) { - if (IsPlayerRace(in_race)) { - texture = 0xFF; - } - else { - texture = GetTexture(); - } - } - else { - texture = in_texture; - } - - if (in_helmtexture == 0xFF) { - if (IsPlayerRace(in_race)) { - helmtexture = 0xFF; - } - else if (in_texture != 0xFF) { - helmtexture = in_texture; - } - else { - helmtexture = GetHelmTexture(); - } - } - else { - helmtexture = in_helmtexture; - } - - if (in_haircolor == 0xFF) { - haircolor = GetHairColor(); - } - else { - haircolor = in_haircolor; - } - - if (in_beardcolor == 0xFF) { - beardcolor = GetBeardColor(); - } - else { - beardcolor = in_beardcolor; - } - - if (in_eyecolor1 == 0xFF) { - eyecolor1 = GetEyeColor1(); - } - else { - eyecolor1 = in_eyecolor1; - } - - if (in_eyecolor2 == 0xFF) { - eyecolor2 = GetEyeColor2(); - } - else { - eyecolor2 = in_eyecolor2; - } - - if (in_hairstyle == 0xFF) { - hairstyle = GetHairStyle(); - } - else { - hairstyle = in_hairstyle; - } - - if (in_luclinface == 0xFF) { - luclinface = GetLuclinFace(); - } - else { - luclinface = in_luclinface; - } - - if (in_beard == 0xFF) { - beard = GetBeard(); - } - else { - beard = in_beard; - } - - aa_title = in_aa_title; - - if (in_drakkin_heritage == 0xFFFFFFFF) { - drakkin_heritage = GetDrakkinHeritage(); - } - else { - drakkin_heritage = in_drakkin_heritage; - } - - if (in_drakkin_tattoo == 0xFFFFFFFF) { - drakkin_tattoo = GetDrakkinTattoo(); - } - else { - drakkin_tattoo = in_drakkin_tattoo; - } - - if (in_drakkin_details == 0xFFFFFFFF) { - drakkin_details = GetDrakkinDetails(); - } - else { - drakkin_details = in_drakkin_details; - } - - if (in_size <= 0.0f) { - size = GetSize(); - } - else { - size = in_size; - } + new_haircolor = (in_haircolor == 0xFF) ? GetHairColor() : in_haircolor; + new_beardcolor = (in_beardcolor == 0xFF) ? GetBeardColor() : in_beardcolor; + new_eyecolor1 = (in_eyecolor1 == 0xFF) ? GetEyeColor1() : in_eyecolor1; + new_eyecolor2 = (in_eyecolor2 == 0xFF) ? GetEyeColor2() : in_eyecolor2; + new_hairstyle = (in_hairstyle == 0xFF) ? GetHairStyle() : in_hairstyle; + new_luclinface = (in_luclinface == 0xFF) ? GetLuclinFace() : in_luclinface; + new_beard = (in_beard == 0xFF) ? GetBeard() : in_beard; + new_drakkin_heritage = + (in_drakkin_heritage == 0xFF) ? GetDrakkinHeritage() : in_drakkin_heritage; + new_drakkin_tattoo = + (in_drakkin_tattoo == 0xFF) ? GetDrakkinTattoo() : in_drakkin_tattoo; + new_drakkin_details = + (in_drakkin_details == 0xFF) ? GetDrakkinDetails() : in_drakkin_details; + new_aa_title = in_aa_title; + size = (in_size <= 0.0f) ? GetSize() : in_size; // Reset features to Base from the Player Profile if (IsClient() && in_race == 0) { - race = CastToClient()->GetBaseRace(); - gender = CastToClient()->GetBaseGender(); - texture = 0xFF; - helmtexture = 0xFF; - haircolor = CastToClient()->GetBaseHairColor(); - beardcolor = CastToClient()->GetBaseBeardColor(); - eyecolor1 = CastToClient()->GetBaseEyeColor(); - eyecolor2 = CastToClient()->GetBaseEyeColor(); - hairstyle = CastToClient()->GetBaseHairStyle(); - luclinface = CastToClient()->GetBaseFace(); - beard = CastToClient()->GetBaseBeard(); - aa_title = 0xFF; - drakkin_heritage = CastToClient()->GetBaseHeritage(); - drakkin_tattoo = CastToClient()->GetBaseTattoo(); - drakkin_details = CastToClient()->GetBaseDetails(); + race = CastToClient()->GetBaseRace(); + gender = CastToClient()->GetBaseGender(); + new_texture = texture = 0xFF; + new_helmtexture = helmtexture = 0xFF; + new_haircolor = haircolor = CastToClient()->GetBaseHairColor(); + new_beardcolor = beardcolor = CastToClient()->GetBaseBeardColor(); + new_eyecolor1 = eyecolor1 = CastToClient()->GetBaseEyeColor(); + new_eyecolor2 = eyecolor2 = CastToClient()->GetBaseEyeColor(); + new_hairstyle = hairstyle = CastToClient()->GetBaseHairStyle(); + new_luclinface = luclinface = CastToClient()->GetBaseFace(); + new_beard = beard = CastToClient()->GetBaseBeard(); + new_aa_title = aa_title = 0xFF; + new_drakkin_heritage = drakkin_heritage + = CastToClient()->GetBaseHeritage(); + new_drakkin_tattoo = drakkin_tattoo + = CastToClient()->GetBaseTattoo(); + new_drakkin_details = drakkin_details + = CastToClient()->GetBaseDetails(); switch (race) { case OGRE: size = 9; @@ -1873,18 +1801,18 @@ void Mob::SendIllusionPacket( strcpy(is->charname, GetCleanName()); is->race = race; is->gender = gender; - is->texture = texture; - is->helmtexture = helmtexture; - is->haircolor = haircolor; - is->beardcolor = beardcolor; - is->beard = beard; - is->eyecolor1 = eyecolor1; - is->eyecolor2 = eyecolor2; - is->hairstyle = hairstyle; - is->face = luclinface; - is->drakkin_heritage = drakkin_heritage; - is->drakkin_tattoo = drakkin_tattoo; - is->drakkin_details = drakkin_details; + is->texture = new_texture; + is->helmtexture = new_helmtexture; + is->haircolor = new_haircolor; + is->beardcolor = new_beardcolor; + is->beard = new_beard; + is->eyecolor1 = new_eyecolor1; + is->eyecolor2 = new_eyecolor2; + is->hairstyle = new_hairstyle; + is->face = new_luclinface; + is->drakkin_heritage = new_drakkin_heritage; + is->drakkin_tattoo = new_drakkin_tattoo; + is->drakkin_details = new_drakkin_details; is->size = size; entity_list.QueueClients(this, outapp); @@ -1898,17 +1826,17 @@ void Mob::SendIllusionPacket( "Illusion: Race = %i, Gender = %i, Texture = %i, HelmTexture = %i, HairColor = %i, BeardColor = %i, EyeColor1 = %i, EyeColor2 = %i, HairStyle = %i, Face = %i, DrakkinHeritage = %i, DrakkinTattoo = %i, DrakkinDetails = %i, Size = %f", race, gender, - texture, - helmtexture, - haircolor, - beardcolor, - eyecolor1, - eyecolor2, - hairstyle, - luclinface, - drakkin_heritage, - drakkin_tattoo, - drakkin_details, + new_texture, + new_helmtexture, + new_haircolor, + new_beardcolor, + new_eyecolor1, + new_eyecolor2, + new_hairstyle, + new_luclinface, + new_drakkin_heritage, + new_drakkin_tattoo, + new_drakkin_details, size); } diff --git a/zone/mob.h b/zone/mob.h index c9f1de58c..080aaf268 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -159,7 +159,8 @@ public: uint8 in_bracertexture, uint8 in_handtexture, uint8 in_legtexture, - uint8 in_feettexture + uint8 in_feettexture, + uint16 in_usemodel ); virtual ~Mob(); @@ -1280,6 +1281,7 @@ protected: uint8 gender; uint16 race; + uint16 use_model; uint8 base_gender; uint16 base_race; uint8 class_; diff --git a/zone/npc.cpp b/zone/npc.cpp index 16a508d1f..ac8825774 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -112,7 +112,8 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi npc_type_data->bracertexture, npc_type_data->handtexture, npc_type_data->legtexture, - npc_type_data->feettexture + npc_type_data->feettexture, + npc_type_data->use_model ), attacked_timer(CombatEventTimer_expire), swarm_timer(100), diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 82bc5ae29..093e1e30c 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -2483,7 +2483,8 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load "npc_types.charm_atk, " "npc_types.skip_global_loot, " "npc_types.rare_spawn, " - "npc_types.stuck_behavior " + "npc_types.stuck_behavior, " + "npc_types.model " "FROM npc_types %s", where_condition.c_str() ); @@ -2673,6 +2674,7 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load temp_npctype_data->skip_global_loot = atoi(row[107]) != 0; temp_npctype_data->rare_spawn = atoi(row[108]) != 0; temp_npctype_data->stuck_behavior = atoi(row[109]); + temp_npctype_data->use_model = atoi(row[110]); // If NPC with duplicate NPC id already in table, // free item we attempted to add. diff --git a/zone/zonedump.h b/zone/zonedump.h index b75057a16..be978a1be 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -144,6 +144,7 @@ struct NPCType bool skip_global_loot; bool rare_spawn; int8 stuck_behavior; + uint16 use_model; }; namespace player_lootitem { From 850b32f2caca92f79e31713d82157f1b84c0560b Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 25 Mar 2019 18:24:16 -0500 Subject: [PATCH 08/31] Adjust constants --- common/emu_constants.h | 12 ++++---- zone/mob_ai.cpp | 14 ++++------ zone/waypoints.cpp | 63 +++++++++++++++++++++++------------------- 3 files changed, 44 insertions(+), 45 deletions(-) diff --git a/common/emu_constants.h b/common/emu_constants.h index 72ddfa11b..384aa3768 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -307,13 +307,11 @@ namespace EQEmu } // namespace bug - namespace waypoints { - enum WaypointStatus : int { - wpsRoamBoxPauseInProgress = -3, - wpsQuestControlNoGrid = -2, - wpsQuestControlGrid = -1 - }; - } // waypoint_status behavior + enum WaypointStatus : int { + RoamBoxPauseInProgress = -3, + QuestControlNoGrid = -2, + QuestControlGrid = -1 + }; } /*EQEmu*/ diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 0ed475384..fa4ccc3ab 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1572,14 +1572,12 @@ void NPC::AI_DoMovement() { /** * Roambox logic sets precedence */ - using EQEmu::waypoints::WaypointStatus; - if (roambox_distance > 0) { // Check if we're already moving to a WP // If so, if we're not moving we have arrived and need to set delay - if (GetCWP() == WaypointStatus::wpsRoamBoxPauseInProgress && !IsMoving()) { + if (GetCWP() == EQEmu::WaypointStatus::RoamBoxPauseInProgress && !IsMoving()) { // We have arrived time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay); SetCurrentWP(0); @@ -1657,7 +1655,7 @@ void NPC::AI_DoMovement() { roambox_destination_y); Log(Logs::Detail, Logs::NPCRoamBox, "Dest Z is (%f)", roambox_destination_z); - SetCurrentWP(WaypointStatus::wpsRoamBoxPauseInProgress); + SetCurrentWP(EQEmu::WaypointStatus::RoamBoxPauseInProgress); NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z); } @@ -1671,7 +1669,7 @@ void NPC::AI_DoMovement() { int32 gridno = CastToNPC()->GetGrid(); - if (gridno > 0 || cur_wp == WaypointStatus::wpsQuestControlNoGrid) { + if (gridno > 0 || cur_wp == EQEmu::WaypointStatus::QuestControlNoGrid) { if (pause_timer_complete == true) { // time to pause at wp is over AI_SetupNextWaypoint(); } // endif (pause_timer_complete==true) @@ -1703,7 +1701,7 @@ void NPC::AI_DoMovement() { // as that is where roamer is unset and we don't want // the next trip through to move again based on grid stuff. doMove = false; - if (cur_wp == WaypointStatus::wpsQuestControlNoGrid) { + if (cur_wp == EQEmu::WaypointStatus::QuestControlNoGrid) { AI_SetupNextWaypoint(); } @@ -1801,11 +1799,9 @@ void NPC::AI_SetupNextWaypoint() { else { pause_timer_complete = false; Log(Logs::Detail, Logs::Pathing, "We are departing waypoint %d.", cur_wp); - - using EQEmu::waypoints::WaypointStatus; //if we were under quest control (with no grid), we are done now.. - if (cur_wp == WaypointStatus::wpsQuestControlNoGrid) { + if (cur_wp == EQEmu::WaypointStatus::QuestControlNoGrid) { Log(Logs::Detail, Logs::Pathing, "Non-grid quest mob has reached its quest ordered waypoint. Leaving pathing mode."); roamer = false; cur_wp = 0; diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 7a7ab917e..22d1c9a60 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -108,7 +108,7 @@ void NPC::ResumeWandering() { // we were paused by a quest AI_walking_timer->Disable(); SetGrid(0 - GetGrid()); - if (cur_wp == EQEmu::waypoints::WaypointStatus::wpsQuestControlGrid) + if (cur_wp == EQEmu::WaypointStatus::QuestControlGrid) { // got here by a MoveTo() cur_wp = save_wp; UpdateWaypoint(cur_wp); // have him head to last destination from here @@ -164,31 +164,32 @@ void NPC::PauseWandering(int pausetime) return; } -void NPC::MoveTo(const glm::vec4& position, bool saveguardspot) -{ // makes mob walk to specified location - - using EQEmu::waypoints::WaypointStatus; - - if (IsNPC() && GetGrid() != 0) - { // he is on a grid - if (GetGrid() < 0) - { // currently stopped by a quest command - SetGrid(0 - GetGrid()); // get him moving again - Log(Logs::Detail, Logs::AI, "MoveTo during quest wandering. Canceling quest wandering and going back to grid %d when MoveTo is done.", GetGrid()); +void NPC::MoveTo(const glm::vec4 &position, bool saveguardspot) +{ // makes mob walk to specified location + if (IsNPC() && GetGrid() != 0) { // he is on a grid + if (GetGrid() < 0) { // currently stopped by a quest command + SetGrid(0 - GetGrid()); // get him moving again + Log(Logs::Detail, + Logs::AI, + "MoveTo during quest wandering. Canceling quest wandering and going back to grid %d when MoveTo is done.", + GetGrid()); } - AI_walking_timer->Disable(); // disable timer in case he is paused at a wp - if (cur_wp >= 0) - { // we've not already done a MoveTo() - save_wp = cur_wp; // save the current waypoint - cur_wp = WaypointStatus::wpsQuestControlGrid; + AI_walking_timer->Disable(); // disable timer in case he is paused at a wp + if (cur_wp >= 0) { // we've not already done a MoveTo() + save_wp = cur_wp; // save the current waypoint + cur_wp = EQEmu::WaypointStatus::QuestControlGrid; } - Log(Logs::Detail, Logs::AI, "MoveTo %s, pausing regular grid wandering. Grid %d, save_wp %d", to_string(static_cast(position)).c_str(), -GetGrid(), save_wp); + Log(Logs::Detail, + Logs::AI, + "MoveTo %s, pausing regular grid wandering. Grid %d, save_wp %d", + to_string(static_cast(position)).c_str(), + -GetGrid(), + save_wp); } - else - { // not on a grid - roamer = true; + else { // not on a grid + roamer = true; save_wp = 0; - cur_wp = WaypointStatus::wpsQuestControlNoGrid; + cur_wp = EQEmu::WaypointStatus::QuestControlNoGrid; Log(Logs::Detail, Logs::AI, "MoveTo %s without a grid.", to_string(static_cast(position)).c_str()); } @@ -197,23 +198,27 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot) m_CurrentWayPoint = position; m_CurrentWayPoint.z = GetFixedZ(dest); - if (saveguardspot) - { + if (saveguardspot) { m_GuardPoint = m_CurrentWayPoint; - if (m_GuardPoint.w == 0) - m_GuardPoint.w = 0.0001; //hack to make IsGuarding simpler + if (m_GuardPoint.w == 0) { + m_GuardPoint.w = 0.0001; + } //hack to make IsGuarding simpler if (m_GuardPoint.w == -1) m_GuardPoint.w = this->CalculateHeadingToTarget(position.x, position.y); - Log(Logs::Detail, Logs::AI, "Setting guard position to %s", to_string(static_cast(m_GuardPoint)).c_str()); + Log(Logs::Detail, + Logs::AI, + "Setting guard position to %s", + to_string(static_cast(m_GuardPoint)).c_str()); } - cur_wp_pause = 0; + cur_wp_pause = 0; time_until_can_move = 0; - if (AI_walking_timer->Enabled()) + if (AI_walking_timer->Enabled()) { AI_walking_timer->Start(100); + } } void NPC::UpdateWaypoint(int wp_index) From 63045fadd99b2c4f78fdee624df56f0e996379d5 Mon Sep 17 00:00:00 2001 From: Noudess Date: Mon, 25 Mar 2019 19:29:57 -0400 Subject: [PATCH 09/31] Manifest and sql to add model to npc_types to override race if presentwq --- utils/sql/db_update_manifest.txt | 1 + utils/sql/git/required/2019_03_25_optional_npc_model.sql | 1 + 2 files changed, 2 insertions(+) create mode 100644 utils/sql/git/required/2019_03_25_optional_npc_model.sql diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index fdb4c4d58..a4441cafa 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -392,6 +392,7 @@ 9136|2019_02_04_profanity_command.sql|SHOW TABLES LIKE 'profanity_list'|empty| 9137|2018_12_12_client_faction_tables.sql|SHOW TABLES LIKE 'faction_base_data'|empty| 9138|2018_12_12_convert_to_client_functions.sql|SELECT `id` FROM `faction_list` WHERE `id` > 4999|empty| +9138|2019_03_25_optional_npc_model.sql|SHOW COLUMNS FROM `npc_types` LIKE 'model'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2019_03_25_optional_npc_model.sql b/utils/sql/git/required/2019_03_25_optional_npc_model.sql new file mode 100644 index 000000000..0f82bd62e --- /dev/null +++ b/utils/sql/git/required/2019_03_25_optional_npc_model.sql @@ -0,0 +1 @@ +ALTER TABLE `npc_types` ADD COLUMN `model` SMALLINT(5) NOT NULL DEFAULT '0' AFTER `stuck_behavior`; From f75c5b6fc89417fc23c80490c4bf651d2466c73b Mon Sep 17 00:00:00 2001 From: Noudess Date: Mon, 25 Mar 2019 19:32:46 -0400 Subject: [PATCH 10/31] Fix db version. --- utils/sql/db_update_manifest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index a4441cafa..ac13b5953 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -392,7 +392,7 @@ 9136|2019_02_04_profanity_command.sql|SHOW TABLES LIKE 'profanity_list'|empty| 9137|2018_12_12_client_faction_tables.sql|SHOW TABLES LIKE 'faction_base_data'|empty| 9138|2018_12_12_convert_to_client_functions.sql|SELECT `id` FROM `faction_list` WHERE `id` > 4999|empty| -9138|2019_03_25_optional_npc_model.sql|SHOW COLUMNS FROM `npc_types` LIKE 'model'|empty| +9139|2019_03_25_optional_npc_model.sql|SHOW COLUMNS FROM `npc_types` LIKE 'model'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not From fa2052236cd445ec3c011935fd75107088fc4bb9 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Wed, 27 Mar 2019 18:20:39 -0400 Subject: [PATCH 11/31] Update some spell immune message colors Fixes #833 Should probably go and do some captures on live, but MQ2Cast's source is probably correct --- zone/spells.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/zone/spells.cpp b/zone/spells.cpp index c4ba88520..4bcb8b1c3 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -4206,7 +4206,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) { if(GetSpecialAbility(UNMEZABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Mez spells."); - caster->Message_StringID(MT_Shout, CANNOT_MEZ); + caster->Message_StringID(MT_SpellFailure, CANNOT_MEZ); int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4224,7 +4224,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) (!caster->IsNPC() || (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity)))) { Log(Logs::Detail, Logs::Spells, "Our level (%d) is higher than the limit of this Mez spell (%d)", GetLevel(), spells[spell_id].max[effect_index]); - caster->Message_StringID(MT_Shout, CANNOT_MEZ_WITH_SPELL); + caster->Message_StringID(MT_SpellFailure, CANNOT_MEZ_WITH_SPELL); AddToHateList(caster, 1,0,true,false,false,spell_id); return true; } @@ -4234,7 +4234,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(GetSpecialAbility(UNSLOWABLE) && IsEffectInSpell(spell_id, SE_AttackSpeed)) { Log(Logs::Detail, Logs::Spells, "We are immune to Slow spells."); - caster->Message_StringID(MT_Shout, IMMUNE_ATKSPEED); + caster->Message_StringID(CC_Red, IMMUNE_ATKSPEED); int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4250,7 +4250,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) effect_index = GetSpellEffectIndex(spell_id, SE_Fear); if(GetSpecialAbility(UNFEARABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Fear spells."); - caster->Message_StringID(MT_Shout, IMMUNE_FEAR); + caster->Message_StringID(CC_Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4261,7 +4261,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) } else if(IsClient() && caster->IsClient() && (caster->CastToClient()->GetGM() == false)) { Log(Logs::Detail, Logs::Spells, "Clients cannot fear eachother!"); - caster->Message_StringID(MT_Shout, IMMUNE_FEAR); + caster->Message_StringID(CC_Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up return true; } else if(GetLevel() > spells[spell_id].max[effect_index] && spells[spell_id].max[effect_index] != 0) @@ -4280,7 +4280,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) { Message(13, "Your are immune to fear."); Log(Logs::Detail, Logs::Spells, "Clients has WarCry effect, immune to fear!"); - caster->Message_StringID(MT_Shout, IMMUNE_FEAR); + caster->Message_StringID(CC_Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up return true; } } @@ -4290,7 +4290,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(GetSpecialAbility(UNCHARMABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Charm spells."); - caster->Message_StringID(MT_Shout, CANNOT_CHARM); + caster->Message_StringID(CC_Red, CANNOT_CHARM); // need to verify message type, not in MQ2Cast for easy look up int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4303,7 +4303,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(this == caster) { Log(Logs::Detail, Logs::Spells, "You are immune to your own charms."); - caster->Message(MT_Shout, "You cannot charm yourself."); + caster->Message(CC_Red, "You cannot charm yourself."); // need to look up message? return true; } @@ -4316,8 +4316,8 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(GetLevel() > spells[spell_id].max[effect_index] && spells[spell_id].max[effect_index] != 0) { Log(Logs::Detail, Logs::Spells, "Our level (%d) is higher than the limit of this Charm spell (%d)", GetLevel(), spells[spell_id].max[effect_index]); - caster->Message_StringID(MT_Shout, CANNOT_CHARM_YET); - AddToHateList(caster, 1,0,true,false,false,spell_id); + caster->Message_StringID(CC_Red, CANNOT_CHARM_YET); // need to verify message type, not in MQ2Cast for easy look up + AddToHateList(caster, 1,0,true,false,false,spell_id); return true; } } @@ -4331,7 +4331,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) { if(GetSpecialAbility(UNSNAREABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Snare spells."); - caster->Message_StringID(MT_Shout, IMMUNE_MOVEMENT); + caster->Message_StringID(CC_Red, IMMUNE_MOVEMENT); int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4347,7 +4347,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(this == caster) { Log(Logs::Detail, Logs::Spells, "You cannot lifetap yourself."); - caster->Message_StringID(MT_Shout, CANT_DRAIN_SELF); + caster->Message_StringID(MT_SpellFailure, CANT_DRAIN_SELF); return true; } } @@ -4357,7 +4357,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(this == caster) { Log(Logs::Detail, Logs::Spells, "You cannot sacrifice yourself."); - caster->Message_StringID(MT_Shout, CANNOT_SAC_SELF); + caster->Message_StringID(MT_SpellFailure, CANNOT_SAC_SELF); return true; } } From 5e008a5a97268965e5cd1394bc14a94c48e55218 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Wed, 3 Apr 2019 15:56:12 -0400 Subject: [PATCH 12/31] Fix SetCurrentWP to allow negatives Needed to make new roambox constants (that were used instead of 666) actually work. --- zone/mob.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/mob.h b/zone/mob.h index c9f1de58c..18cdfeceb 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -1091,7 +1091,7 @@ public: inline glm::vec4 GetCurrentWayPoint() const { return m_CurrentWayPoint; } inline float GetCWPP() const { return(static_cast(cur_wp_pause)); } inline int GetCWP() const { return(cur_wp); } - void SetCurrentWP(uint16 waypoint) { cur_wp = waypoint; } + void SetCurrentWP(int waypoint) { cur_wp = waypoint; } virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther) { return FACTION_INDIFFERENT; } virtual const bool IsUnderwaterOnly() const { return false; } From 762de03be766ebf942ebd40e27df1fae272677f1 Mon Sep 17 00:00:00 2001 From: Noudess Date: Fri, 12 Apr 2019 10:50:11 -0400 Subject: [PATCH 13/31] Merge --- zone/mob_ai.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index fa4ccc3ab..1f79fa5c1 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -447,7 +447,7 @@ void Mob::AI_Init() maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax); pDontHealMeBefore = 0; - pDontBuffMeBefore = 0; + pDontBuffMeBefore = Timer::GetCurrentTime() + 400; pDontDotMeBefore = 0; pDontRootMeBefore = 0; pDontSnareMeBefore = 0; @@ -1636,11 +1636,12 @@ void NPC::AI_DoMovement() { } } - glm::vec3 destination; - destination.x = roambox_destination_x; - destination.y = roambox_destination_y; - destination.z = m_Position.z; - roambox_destination_z = zone->zonemap ? zone->zonemap->FindClosestZ(destination, nullptr) + this->GetZOffset() : 0; + roambox_destination_z = 0; + /* + if (zone->zonemap) { + roambox_destination_z = FindGroundZ(roambox_destination_x, roambox_destination_y, this->GetZOffset()); + } + */ Log(Logs::Detail, Logs::NPCRoamBox, @@ -1799,7 +1800,6 @@ void NPC::AI_SetupNextWaypoint() { else { pause_timer_complete = false; Log(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 == EQEmu::WaypointStatus::QuestControlNoGrid) { Log(Logs::Detail, Logs::Pathing, "Non-grid quest mob has reached its quest ordered waypoint. Leaving pathing mode."); From 2bb305305a11a268ecf6318066f401d99f2caf5e Mon Sep 17 00:00:00 2001 From: Brian Kinney Date: Fri, 12 Apr 2019 15:25:32 -0400 Subject: [PATCH 14/31] Use rules to configure faction thresholds Default to legacy values. Updated "accurate" values are available in optional database script --- common/faction.cpp | 22 +++++++++---------- common/ruletypes.h | 11 ++++++++++ .../2019_04_12_update_faction_thresholds.sql | 10 +++++++++ 3 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql diff --git a/common/faction.cpp b/common/faction.cpp index c1d4fe398..3dd8584e1 100644 --- a/common/faction.cpp +++ b/common/faction.cpp @@ -18,6 +18,7 @@ #include "faction.h" #include "races.h" +#include "rulesys.h" const char *FactionValueToString(FACTION_VALUE fv) { @@ -59,34 +60,31 @@ FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value) if (fm) { character_value += fm->base + fm->class_mod + fm->race_mod + fm->deity_mod; } - if (character_value >= 1100) { + if (character_value >= RuleI(Faction, AllyFactionMinimum)) { return FACTION_ALLY; } - if (character_value >= 750 && character_value <= 1099) { + if (character_value >= RuleI(Faction, WarmlyFactionMinimum)) { return FACTION_WARMLY; } - if (character_value >= 500 && character_value <= 749) { + if (character_value >= RuleI(Faction, KindlyFactionMinimum)) { return FACTION_KINDLY; } - if (character_value >= 100 && character_value <= 499) { + if (character_value >= RuleI(Faction, AmiablyFactionMinimum)) { return FACTION_AMIABLE; } - if (character_value >= 0 && character_value <= 99) { + if (character_value >= RuleI(Faction, IndifferentlyFactionMinimum)) { return FACTION_INDIFFERENT; } - if (character_value >= -100 && character_value <= -1) { + if (character_value >= RuleI(Faction, ApprehensivelyFactionMinimum)) { return FACTION_APPREHENSIVE; } - if (character_value >= -500 && character_value <= -101) { + if (character_value >= RuleI(Faction, DubiouslyFactionMinimum)) { return FACTION_DUBIOUS; } - if (character_value >= -750 && character_value <= -501) { + if (character_value >= RuleI(Faction, ThreateninglyFactionMinimum)) { return FACTION_THREATENLY; } - if (character_value <= -751) { - return FACTION_SCOWLS; - } - return FACTION_INDIFFERENT; + return FACTION_SCOWLS; } // this function should check if some races have more than one race define diff --git a/common/ruletypes.h b/common/ruletypes.h index 71a57145b..e33272162 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -758,6 +758,17 @@ RULE_BOOL(Bugs, UseOldReportingMethod, true) // Forces the use of the old bug re RULE_BOOL(Bugs, DumpTargetEntity, false) // Dumps the target entity, if one is provided RULE_CATEGORY_END() +RULE_CATEGORY(Faction) +RULE_INT(Faction, AllyFactionMinimum, 1101) +RULE_INT(Faction, WarmlyFactionMinimum, 701) +RULE_INT(Faction, KindlyFactionMinimum, 401) +RULE_INT(Faction, AmiablyFactionMinimum, 101) +RULE_INT(Faction, IndifferentlyFactionMinimum, 0) +RULE_INT(Faction, ApprehensivelyFactionMinimum, -100) +RULE_INT(Faction, DubiouslyFactionMinimum, -700) +RULE_INT(Faction, ThreateninglyFactionMinimum, -999) +RULE_CATEGORY_END() + #undef RULE_CATEGORY #undef RULE_INT #undef RULE_REAL diff --git a/utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql b/utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql new file mode 100644 index 000000000..1261a5dab --- /dev/null +++ b/utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql @@ -0,0 +1,10 @@ +INSERT INTO rule_values VALUES + (0, "Faction:AllyFactionMinimum", 1100), + (0, "Spells:WarmlyFactionMinimum", 750), + (0, "Spells:KindlyFactionMinimu", 500), + (0, "Spells:AmiablyFactionMinimum", 100), + (0, "Spells:IndifferentlyFactionMinimum", 0) + (0, "Spells:ApprehensivelyFactionMinimum", -100) + (0, "Spells:DubiouslyFactionMinimum", -500) + (0, "Spells:ThreateninglyFactionMinimum", -750) +; From 8aaf39d2d938874b74ff051ba0ca9be2822d7281 Mon Sep 17 00:00:00 2001 From: Brian Kinney Date: Fri, 12 Apr 2019 15:29:05 -0400 Subject: [PATCH 15/31] Fix incorrect rule categories in SQL --- .../2019_04_12_update_faction_thresholds.sql | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql b/utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql index 1261a5dab..b54edc981 100644 --- a/utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql +++ b/utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql @@ -1,10 +1,10 @@ INSERT INTO rule_values VALUES (0, "Faction:AllyFactionMinimum", 1100), - (0, "Spells:WarmlyFactionMinimum", 750), - (0, "Spells:KindlyFactionMinimu", 500), - (0, "Spells:AmiablyFactionMinimum", 100), - (0, "Spells:IndifferentlyFactionMinimum", 0) - (0, "Spells:ApprehensivelyFactionMinimum", -100) - (0, "Spells:DubiouslyFactionMinimum", -500) - (0, "Spells:ThreateninglyFactionMinimum", -750) + (0, "Faction:WarmlyFactionMinimum", 750), + (0, "Faction:KindlyFactionMinimu", 500), + (0, "Faction:AmiablyFactionMinimum", 100), + (0, "Faction:IndifferentlyFactionMinimum", 0) + (0, "Faction:ApprehensivelyFactionMinimum", -100) + (0, "Faction:DubiouslyFactionMinimum", -500) + (0, "Faction:ThreateninglyFactionMinimum", -750) ; From d59170f84f37413f513c3eb175510b84b42389da Mon Sep 17 00:00:00 2001 From: Noudess Date: Fri, 12 Apr 2019 19:09:47 -0400 Subject: [PATCH 16/31] Fix some formatting and fix some incorrect constants. --- zone/mob.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/zone/mob.cpp b/zone/mob.cpp index facb6dc77..b068905a9 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1737,11 +1737,11 @@ void Mob::SendIllusionPacket( new_luclinface = (in_luclinface == 0xFF) ? GetLuclinFace() : in_luclinface; new_beard = (in_beard == 0xFF) ? GetBeard() : in_beard; new_drakkin_heritage = - (in_drakkin_heritage == 0xFF) ? GetDrakkinHeritage() : in_drakkin_heritage; + (in_drakkin_heritage == 0xFFFFFFFF) ? GetDrakkinHeritage() : in_drakkin_heritage; new_drakkin_tattoo = - (in_drakkin_tattoo == 0xFF) ? GetDrakkinTattoo() : in_drakkin_tattoo; + (in_drakkin_tattoo == 0xFFFFFFFF) ? GetDrakkinTattoo() : in_drakkin_tattoo; new_drakkin_details = - (in_drakkin_details == 0xFF) ? GetDrakkinDetails() : in_drakkin_details; + (in_drakkin_details == 0xFFFFFFFF) ? GetDrakkinDetails() : in_drakkin_details; new_aa_title = in_aa_title; size = (in_size <= 0.0f) ? GetSize() : in_size; @@ -1759,12 +1759,9 @@ void Mob::SendIllusionPacket( new_luclinface = luclinface = CastToClient()->GetBaseFace(); new_beard = beard = CastToClient()->GetBaseBeard(); new_aa_title = aa_title = 0xFF; - new_drakkin_heritage = drakkin_heritage - = CastToClient()->GetBaseHeritage(); - new_drakkin_tattoo = drakkin_tattoo - = CastToClient()->GetBaseTattoo(); - new_drakkin_details = drakkin_details - = CastToClient()->GetBaseDetails(); + new_drakkin_heritage = drakkin_heritage = CastToClient()->GetBaseHeritage(); + new_drakkin_tattoo = drakkin_tattoo = CastToClient()->GetBaseTattoo(); + new_drakkin_details = drakkin_details = CastToClient()->GetBaseDetails(); switch (race) { case OGRE: size = 9; From 5b374927f2f0c5401a1a488a153869aea90de562 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Fri, 12 Apr 2019 19:16:00 -0400 Subject: [PATCH 17/31] Update mob.cpp --- zone/mob.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/zone/mob.cpp b/zone/mob.cpp index facb6dc77..e6e11fc26 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -74,7 +74,7 @@ Mob::Mob( uint8 in_hairstyle, uint8 in_luclinface, uint8 in_beard, - uint32 in_drakkin_heritage, + uint32 in__heritage, uint32 in_drakkin_tattoo, uint32 in_drakkin_details, EQEmu::TintProfile in_armor_tint, @@ -1737,11 +1737,11 @@ void Mob::SendIllusionPacket( new_luclinface = (in_luclinface == 0xFF) ? GetLuclinFace() : in_luclinface; new_beard = (in_beard == 0xFF) ? GetBeard() : in_beard; new_drakkin_heritage = - (in_drakkin_heritage == 0xFF) ? GetDrakkinHeritage() : in_drakkin_heritage; + (in_drakkin_heritage == 0xFFFFFFFF) ? GetDrakkinHeritage() : in_drakkin_heritage; new_drakkin_tattoo = - (in_drakkin_tattoo == 0xFF) ? GetDrakkinTattoo() : in_drakkin_tattoo; + (in_drakkin_tattoo == 0xFFFFFFFF) ? GetDrakkinTattoo() : in_drakkin_tattoo; new_drakkin_details = - (in_drakkin_details == 0xFF) ? GetDrakkinDetails() : in_drakkin_details; + (in_drakkin_details == 0xFFFFFFFF) ? GetDrakkinDetails() : in_drakkin_details; new_aa_title = in_aa_title; size = (in_size <= 0.0f) ? GetSize() : in_size; @@ -1759,12 +1759,9 @@ void Mob::SendIllusionPacket( new_luclinface = luclinface = CastToClient()->GetBaseFace(); new_beard = beard = CastToClient()->GetBaseBeard(); new_aa_title = aa_title = 0xFF; - new_drakkin_heritage = drakkin_heritage - = CastToClient()->GetBaseHeritage(); - new_drakkin_tattoo = drakkin_tattoo - = CastToClient()->GetBaseTattoo(); - new_drakkin_details = drakkin_details - = CastToClient()->GetBaseDetails(); + new_drakkin_heritage = drakkin_heritage = CastToClient()->GetBaseHeritage(); + new_drakkin_tattoo = drakkin_tattoo = CastToClient()->GetBaseTattoo(); + new_drakkin_details = drakkin_details = CastToClient()->GetBaseDetails(); switch (race) { case OGRE: size = 9; From 0426a15fecddf1fb5af09ea6445b219e115648e8 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Fri, 12 Apr 2019 19:34:28 -0400 Subject: [PATCH 18/31] Update mob.cpp --- zone/mob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/mob.cpp b/zone/mob.cpp index e6e11fc26..b068905a9 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -74,7 +74,7 @@ Mob::Mob( uint8 in_hairstyle, uint8 in_luclinface, uint8 in_beard, - uint32 in__heritage, + uint32 in_drakkin_heritage, uint32 in_drakkin_tattoo, uint32 in_drakkin_details, EQEmu::TintProfile in_armor_tint, From e1e3d99a79d12cf38976fa66b9d7af63bd7d024c Mon Sep 17 00:00:00 2001 From: Noudess Date: Fri, 12 Apr 2019 20:13:30 -0400 Subject: [PATCH 19/31] Change range of values to accomodate large roamboxes --- zone/pathfinder_nav_mesh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/pathfinder_nav_mesh.cpp b/zone/pathfinder_nav_mesh.cpp index d4879f6f7..8ab50d508 100644 --- a/zone/pathfinder_nav_mesh.cpp +++ b/zone/pathfinder_nav_mesh.cpp @@ -163,7 +163,7 @@ IPathfinder::IPath PathfinderNavmesh::FindPath(const glm::vec3 &start, const glm static const int max_polys = 256; dtPolyRef start_ref; dtPolyRef end_ref; - glm::vec3 ext(5.0f, 100.0f, 5.0f); + glm::vec3 ext(10.0f, 200.0f, 10.0f); m_impl->query->findNearestPoly(¤t_location[0], &ext[0], &filter, &start_ref, 0); m_impl->query->findNearestPoly(&dest_location[0], &ext[0], &filter, &end_ref, 0); From c06774ca61e82dd44c27ffc815444b7c8df919c7 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Sat, 13 Apr 2019 07:22:16 -0400 Subject: [PATCH 20/31] Fix version to match committed manifest --- common/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/version.h b/common/version.h index 1fa07c028..2d3df779d 100644 --- a/common/version.h +++ b/common/version.h @@ -31,7 +31,7 @@ */ -#define CURRENT_BINARY_DATABASE_VERSION 9138 +#define CURRENT_BINARY_DATABASE_VERSION 9139 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9022 From 3105577c1bc6a0c05a2f8ad385b7b5b27238d8cc Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Sat, 13 Apr 2019 12:39:45 -0400 Subject: [PATCH 21/31] Fix the auto-correct mechanism on illegal faction Auto correct was not using the new client_base_data for min/max. --- zone/client.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index f56aa1d31..e713ce6e4 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7810,9 +7810,9 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui // // Adjust these values for cases where starting faction is below // min or above max by not allowing any earn in those directions. - this_faction_min = MIN_PERSONAL_FACTION - fm.base; + this_faction_min = fm.min - fm.base; this_faction_min = std::min(0, this_faction_min); - this_faction_max = MAX_PERSONAL_FACTION - fm.base; + this_faction_max = fm.max - fm.base; this_faction_max = std::max(0, this_faction_max); // Get the characters current value with that faction @@ -7853,9 +7853,9 @@ void Client::SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class // min or above max by not allowing any earn/loss in those directions. // At least one faction starts out way below min, so we don't want // to allow loses in those cases, just massive gains. - this_faction_min = MIN_PERSONAL_FACTION - fm.base; + this_faction_min = fm.min - fm.base; this_faction_min = std::min(0, this_faction_min); - this_faction_max = MAX_PERSONAL_FACTION - fm.base; + this_faction_max = fm.max - fm.base; this_faction_max = std::max(0, this_faction_max); //Get the faction modifiers From 3e8ef681a3cdc6b1e01f8490446059c3956ade7b Mon Sep 17 00:00:00 2001 From: Brian Kinney Date: Sat, 13 Apr 2019 15:04:43 -0400 Subject: [PATCH 22/31] Change defaults to the values intended by recent update --- common/ruletypes.h | 12 ++++++------ .../2019_04_12_update_faction_thresholds.sql | 10 ---------- .../2019_04_13_restore_legacy_faction_thresholds.sql | 11 +++++++++++ 3 files changed, 17 insertions(+), 16 deletions(-) delete mode 100644 utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql create mode 100644 utils/sql/git/optional/2019_04_13_restore_legacy_faction_thresholds.sql diff --git a/common/ruletypes.h b/common/ruletypes.h index e33272162..18360280a 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -759,14 +759,14 @@ RULE_BOOL(Bugs, DumpTargetEntity, false) // Dumps the target entity, if one is p RULE_CATEGORY_END() RULE_CATEGORY(Faction) -RULE_INT(Faction, AllyFactionMinimum, 1101) -RULE_INT(Faction, WarmlyFactionMinimum, 701) -RULE_INT(Faction, KindlyFactionMinimum, 401) -RULE_INT(Faction, AmiablyFactionMinimum, 101) +RULE_INT(Faction, AllyFactionMinimum, 1100) +RULE_INT(Faction, WarmlyFactionMinimum, 750) +RULE_INT(Faction, KindlyFactionMinimum, 500) +RULE_INT(Faction, AmiablyFactionMinimum, 100) RULE_INT(Faction, IndifferentlyFactionMinimum, 0) RULE_INT(Faction, ApprehensivelyFactionMinimum, -100) -RULE_INT(Faction, DubiouslyFactionMinimum, -700) -RULE_INT(Faction, ThreateninglyFactionMinimum, -999) +RULE_INT(Faction, DubiouslyFactionMinimum, -500) +RULE_INT(Faction, ThreateninglyFactionMinimum, -750) RULE_CATEGORY_END() #undef RULE_CATEGORY diff --git a/utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql b/utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql deleted file mode 100644 index b54edc981..000000000 --- a/utils/sql/git/optional/2019_04_12_update_faction_thresholds.sql +++ /dev/null @@ -1,10 +0,0 @@ -INSERT INTO rule_values VALUES - (0, "Faction:AllyFactionMinimum", 1100), - (0, "Faction:WarmlyFactionMinimum", 750), - (0, "Faction:KindlyFactionMinimu", 500), - (0, "Faction:AmiablyFactionMinimum", 100), - (0, "Faction:IndifferentlyFactionMinimum", 0) - (0, "Faction:ApprehensivelyFactionMinimum", -100) - (0, "Faction:DubiouslyFactionMinimum", -500) - (0, "Faction:ThreateninglyFactionMinimum", -750) -; diff --git a/utils/sql/git/optional/2019_04_13_restore_legacy_faction_thresholds.sql b/utils/sql/git/optional/2019_04_13_restore_legacy_faction_thresholds.sql new file mode 100644 index 000000000..531b90ebc --- /dev/null +++ b/utils/sql/git/optional/2019_04_13_restore_legacy_faction_thresholds.sql @@ -0,0 +1,11 @@ +-- Supplied for convenient configuration of faction thresholds to the values that were in place prior to 2019-03-01 update +INSERT INTO rule_values VALUES + (0, "Faction:AllyFactionMinimum", 1101), + (0, "Faction:WarmlyFactionMinimum", 701), + (0, "Faction:KindlyFactionMinimu", 401), + (0, "Faction:AmiablyFactionMinimum", 101), + (0, "Faction:IndifferentlyFactionMinimum", 0) + (0, "Faction:ApprehensivelyFactionMinimum", -100) + (0, "Faction:DubiouslyFactionMinimum", -700) + (0, "Faction:ThreateninglyFactionMinimum", -999) +; From 54da27424f1130658ebbdab347298576a1a12306 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sun, 14 Apr 2019 00:18:23 -0400 Subject: [PATCH 23/31] Implement Foraging AA Currently this SPA is only checked for AA bonuses since a non-permanent bonus doesn't make sense. Plus I'm not sure the client is aware of it in spells/gear --- common/spdat.h | 2 +- zone/bonuses.cpp | 13 +++++++++++-- zone/client.cpp | 5 ++++- zone/common.h | 1 + 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/common/spdat.h b/common/spdat.h index 877d37823..2616ba717 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -590,7 +590,7 @@ typedef enum { #define SE_CorruptionCounter 369 // implemented #define SE_ResistCorruption 370 // implemented #define SE_AttackSpeed4 371 // implemented - stackable slow effect 'Inhibit Melee' -#define SE_ForageSkill 372 // *not implemented[AA] Will increase the skill cap for those that have the Forage skill and grant the skill and raise the cap to those that do not. +#define SE_ForageSkill 372 // implemented[AA] Will increase the skill cap for those that have the Forage skill and grant the skill and raise the cap to those that do not. #define SE_CastOnFadeEffectAlways 373 // implemented - Triggers if fades after natural duration OR from rune/numhits fades. #define SE_ApplyEffect 374 // implemented #define SE_DotCritDmgIncrease 375 // implemented - Increase damage of DoT critical amount diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index c7d5cf2a8..9b7354190 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -1472,6 +1472,17 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon) newbon->trap_slots += base1; break; + case SE_ForageSkill: + newbon->GrantForage += base1; + // we need to grant a skill point here + // I'd rather not do this here, but whatever, probably fine + if (IsClient()) { + auto client = CastToClient(); + if (client->GetRawSkill(EQEmu::skills::SkillType::SkillForage) == 0) + client->SetSkill(EQEmu::skills::SkillType::SkillForage, 1); + } + break; + // to do case SE_PetDiscipline: break; @@ -1479,8 +1490,6 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon) break; case SE_BandolierSlots: break; - case SE_ForageSkill: - break; case SE_SecondaryForte: break; case SE_ExtendedShielding: diff --git a/zone/client.cpp b/zone/client.cpp index e713ce6e4..86b402f44 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2604,9 +2604,12 @@ uint16 Client::GetMaxSkillAfterSpecializationRules(EQEmu::skills::SkillType skil } } - + Result += spellbonuses.RaiseSkillCap[skillid] + itembonuses.RaiseSkillCap[skillid] + aabonuses.RaiseSkillCap[skillid]; + if (skillid == EQEmu::skills::SkillType::SkillForage) + Result += aabonuses.GrantForage; + return Result; } diff --git a/zone/common.h b/zone/common.h index 6d78dc46f..62f1d9771 100644 --- a/zone/common.h +++ b/zone/common.h @@ -558,6 +558,7 @@ struct StatBonuses { int16 FeignedCastOnChance; // Percent Value bool PetCommands[PET_MAXCOMMANDS]; // SPA 267 int FeignedMinionChance; // SPA 281 base1 = chance, just like normal FD + int GrantForage; // affects max skill of forage as well as granting non-forage classes forage int aura_slots; int trap_slots; bool hunger; // Song of Sustenance -- min caps to 3500 From 7dc1e10956e51869a9445f2f42b952a871cedb5c Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Wed, 24 Apr 2019 10:10:48 -0400 Subject: [PATCH 24/31] Update perl_mob.cpp --- zone/perl_mob.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 334aeaf0b..20172f996 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -1135,6 +1135,29 @@ XS(XS_Mob_ChangeSize) { XSRETURN_EMPTY; } ++XS(XS_Mob_RandomizeFeatures); /* prototype to pass -Wmissing-prototypes */ ++XS(XS_Mob_RandomizeFeatures) { ++ dXSARGS; ++ if (items < 2 || items > 3) ++ Perl_croak(aTHX_ "Usage: Mob::RandomizeFeatures(THIS, bool send_illusion, set_variables)"); ++ { ++ Mob *THIS; ++ bool send_illusion = (bool) SvNV(ST(1)); ++ bool set_variables = (bool) SvNV(ST(2)); ++ ++ if (sv_derived_from(ST(0), "Mob")) { ++ IV tmp = SvIV((SV *) SvRV(ST(0))); ++ THIS = INT2PTR(Mob *, tmp); ++ } else ++ Perl_croak(aTHX_ "THIS is not of type Mob"); ++ if (THIS == nullptr) ++ Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); ++ ++ THIS->RandomizeFeatures(send_illusion, set_variables); ++ } ++ XSRETURN_EMPTY; ++} + XS(XS_Mob_GMMove); /* prototype to pass -Wmissing-prototypes */ XS(XS_Mob_GMMove) { dXSARGS; @@ -6760,7 +6783,7 @@ XS(XS_Mob_SendIllusion) { dXSARGS; if (items < 2 || items > 14) Perl_croak(aTHX_ - "Usage: Mob::SendIllusion(THIS, uint16 race, [uint8 gender = 0xFF], [uint8 texture = 0xFF], [unit8 helmtexture = 0xFF], [unit8 face = 0xFF], [unit8 hairstyle = 0xFF], [uint8 hair_color = 0xFF], [uint8 beard = 0xFF], [uint8 beard_color = 0xFF], [uint32 drakkin_heritage = 0xFFFFFFFF], [uint32 drakkin_tattoo = 0xFFFFFFFF], [uint32 drakkin_details = 0xFFFFFFFF], [float size = -1])"); + "Usage: Mob::SendIllusion(THIS, uint16 race, [uint8 gender = 0xFF], [uint8 texture face = 0xFF], [uint8 hairstyle = 0xFF], [uint8 hair_color = 0xFF], [uint8 beard = 0xFF], [uint8 beard_color =FF], [uint32 drakkin_tattoo = 0xFFFFFFFF], [uint32 drakkin_details = 0xFFFFFFFF], [float size = -1])"); { Mob *THIS; uint16 race = (uint16) SvIV(ST(1)); @@ -8552,6 +8575,7 @@ XS(boot_Mob) { newXSproto(strcpy(buf, "SetHP"), XS_Mob_SetHP, file, "$$"); newXSproto(strcpy(buf, "DoAnim"), XS_Mob_DoAnim, file, "$$;$"); newXSproto(strcpy(buf, "ChangeSize"), XS_Mob_ChangeSize, file, "$$;$"); + newXSproto(strcpy(buf, "RandomizeFeatures"), XS_Mob_RandomizeFeatures, file, "$$;$"); newXSproto(strcpy(buf, "GMMove"), XS_Mob_GMMove, file, "$$$$;$"); newXSproto(strcpy(buf, "HasProcs"), XS_Mob_HasProcs, file, "$"); newXSproto(strcpy(buf, "IsInvisible"), XS_Mob_IsInvisible, file, "$;$"); From c24bfaf35f91700a495106fb09d0006b616faa28 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Wed, 24 Apr 2019 10:30:24 -0400 Subject: [PATCH 25/31] Update lua_mob.h --- zone/lua_mob.h | 1 + 1 file changed, 1 insertion(+) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index fc58af6d5..b132acbf6 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -71,6 +71,7 @@ public: void DoAnim(int anim_num, int type, bool ackreq, int filter); void ChangeSize(double in_size); void ChangeSize(double in_size, bool no_restriction); + void RandomizeFeatures(bool send_illusion, bool save_variables); void GMMove(double x, double y, double z); void GMMove(double x, double y, double z, double heading); void GMMove(double x, double y, double z, double heading, bool send_update); From dfe4bb5b7819ef5efdf456d03cdeefe56bdca6ac Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Wed, 24 Apr 2019 10:32:09 -0400 Subject: [PATCH 26/31] Update lua_mob.cpp --- zone/lua_mob.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 59d50508e..471ff6d00 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -267,6 +267,11 @@ void Lua_Mob::ChangeSize(double in_size, bool no_restriction) { self->ChangeSize(static_cast(in_size), no_restriction); } +void Lua_Mob::RandomizeFeatures(bool send_illusion, bool save_variables) { + Lua_Safe_Call_Void(); + self->RandomizeFeatures(send_illusion, save_variables); +} + void Lua_Mob::GMMove(double x, double y, double z) { Lua_Safe_Call_Void(); self->GMMove(static_cast(x), static_cast(y), static_cast(z)); @@ -2202,6 +2207,7 @@ luabind::scope lua_register_mob() { .def("DoAnim", (void(Lua_Mob::*)(int,int,bool,int))&Lua_Mob::DoAnim) .def("ChangeSize", (void(Lua_Mob::*)(double))&Lua_Mob::ChangeSize) .def("ChangeSize", (void(Lua_Mob::*)(double,bool))&Lua_Mob::ChangeSize) + .def("RandomizeFeatures", (void(Lua_Mob::*)(bool,bool))&Lua_Mob::RandomizeFeatures) .def("GMMove", (void(Lua_Mob::*)(double,double,double))&Lua_Mob::GMMove) .def("GMMove", (void(Lua_Mob::*)(double,double,double,double))&Lua_Mob::GMMove) .def("GMMove", (void(Lua_Mob::*)(double,double,double,double,bool))&Lua_Mob::GMMove) From a402f015146ebce824d775ee64c500f8555ce392 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Wed, 24 Apr 2019 17:26:17 -0400 Subject: [PATCH 27/31] Update perl_mob.cpp --- zone/perl_mob.cpp | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 20172f996..f7cbfcfea 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -1135,28 +1135,28 @@ XS(XS_Mob_ChangeSize) { XSRETURN_EMPTY; } -+XS(XS_Mob_RandomizeFeatures); /* prototype to pass -Wmissing-prototypes */ -+XS(XS_Mob_RandomizeFeatures) { -+ dXSARGS; -+ if (items < 2 || items > 3) -+ Perl_croak(aTHX_ "Usage: Mob::RandomizeFeatures(THIS, bool send_illusion, set_variables)"); -+ { -+ Mob *THIS; -+ bool send_illusion = (bool) SvNV(ST(1)); -+ bool set_variables = (bool) SvNV(ST(2)); -+ -+ if (sv_derived_from(ST(0), "Mob")) { -+ IV tmp = SvIV((SV *) SvRV(ST(0))); -+ THIS = INT2PTR(Mob *, tmp); -+ } else -+ Perl_croak(aTHX_ "THIS is not of type Mob"); -+ if (THIS == nullptr) -+ Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); -+ -+ THIS->RandomizeFeatures(send_illusion, set_variables); -+ } -+ XSRETURN_EMPTY; -+} +XS(XS_Mob_RandomizeFeatures); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Mob_RandomizeFeatures) { + dXSARGS; + if (items < 2 || items > 3) + Perl_croak(aTHX_ "Usage: Mob::RandomizeFeatures(THIS, bool send_illusion, set_variables)"); + { + Mob *THIS; + bool send_illusion = (bool) SvNV(ST(1)); + bool set_variables = (bool) SvNV(ST(2)); + + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Mob"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + THIS->RandomizeFeatures(send_illusion, set_variables); + } + XSRETURN_EMPTY; +} XS(XS_Mob_GMMove); /* prototype to pass -Wmissing-prototypes */ XS(XS_Mob_GMMove) { From 72e0320509cb69227cea7d5ba4a583cc38454e57 Mon Sep 17 00:00:00 2001 From: Uleat Date: Thu, 25 Apr 2019 01:11:56 -0400 Subject: [PATCH 28/31] Fix for loginserver crashes --- loginserver/server_manager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 550dba806..b4db9b1ec 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -256,13 +256,15 @@ void ServerManager::DestroyServerByName(std::string l_name, std::string s_name, while (iter != world_servers.end()) { if ((*iter).get() == ignore) { ++iter; + continue; } if ((*iter)->GetLongName().compare(l_name) == 0 && (*iter)->GetShortName().compare(s_name) == 0) { (*iter)->GetConnection()->Handle()->Disconnect(); iter = world_servers.erase(iter); + continue; } ++iter; } -} \ No newline at end of file +} From cd3125ced0f6a8fee8e6c430973dce17409de67a Mon Sep 17 00:00:00 2001 From: Uleat Date: Sun, 28 Apr 2019 21:20:52 -0400 Subject: [PATCH 29/31] Added safety to SuspendMinion spell index dereference --- zone/client.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/zone/client.cpp b/zone/client.cpp index 86b402f44..2d126598f 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -5612,6 +5612,12 @@ void Client::SuspendMinion() { if(m_suspendedminion.SpellID > 0) { + if (m_suspendedminion.SpellID >= SPDAT_RECORDS) { + Message(13, "Invalid suspended minion spell id (%u).", m_suspendedminion.SpellID); + memset(&m_suspendedminion, 0, sizeof(PetInfo)); + return; + } + MakePoweredPet(m_suspendedminion.SpellID, spells[m_suspendedminion.SpellID].teleport_zone, m_suspendedminion.petpower, m_suspendedminion.Name, m_suspendedminion.size); From 6739eea78bbc0f293c8faacbb07c38a2b9b73f75 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 1 May 2019 15:26:16 -0500 Subject: [PATCH 30/31] Change NPC scaling classification order check --- zone/npc_scale_manager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zone/npc_scale_manager.cpp b/zone/npc_scale_manager.cpp index 9e20935e8..dd1b9734d 100644 --- a/zone/npc_scale_manager.cpp +++ b/zone/npc_scale_manager.cpp @@ -416,14 +416,14 @@ int8 NpcScaleManager::GetNPCScalingType(NPC *&npc) { std::string npc_name = npc->GetName(); - if (npc->IsRareSpawn() || npc_name.find('#') != std::string::npos || isupper(npc_name[0])) { - return 1; - } - if (npc->IsRaidTarget()) { return 2; } + if (npc->IsRareSpawn() || npc_name.find('#') != std::string::npos || isupper(npc_name[0])) { + return 1; + } + return 0; } From d7abf3f26c12e2aaa7c30266e77121f344f60a18 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 1 May 2019 16:23:24 -0500 Subject: [PATCH 31/31] Change compression level in deflate --- common/net/daybreak_connection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/net/daybreak_connection.cpp b/common/net/daybreak_connection.cpp index f54260e43..962d3c7e3 100644 --- a/common/net/daybreak_connection.cpp +++ b/common/net/daybreak_connection.cpp @@ -942,7 +942,7 @@ uint32_t Deflate(const uint8_t* in, uint32_t in_len, uint8_t* out, uint32_t out_ zstream.avail_in = in_len; zstream.opaque = Z_NULL; - deflateInit(&zstream, Z_FINISH); + deflateInit(&zstream, Z_BEST_SPEED); zstream.next_out = out; zstream.avail_out = out_len;