mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-30 15:01:29 +00:00
Merge remote-tracking branch 'origin/master' into feature/eqemu-api-data-service-netstats-ws
This commit is contained in:
commit
e277e55718
@ -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;
|
||||
|
||||
@ -307,6 +307,12 @@ namespace EQEmu
|
||||
|
||||
} // namespace bug
|
||||
|
||||
enum WaypointStatus : int {
|
||||
RoamBoxPauseInProgress = -3,
|
||||
QuestControlNoGrid = -2,
|
||||
QuestControlGrid = -1
|
||||
};
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||
|
||||
@ -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
|
||||
|
||||
@ -735,6 +735,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, 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, -500)
|
||||
RULE_INT(Faction, ThreateninglyFactionMinimum, -750)
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
#undef RULE_CATEGORY
|
||||
#undef RULE_INT
|
||||
#undef RULE_REAL
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -257,11 +257,13 @@ 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;
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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|
|
||||
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
|
||||
|
||||
@ -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)
|
||||
;
|
||||
1
utils/sql/git/required/2019_03_25_optional_npc_model.sql
Normal file
1
utils/sql/git/required/2019_03_25_optional_npc_model.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE `npc_types` ADD COLUMN `model` SMALLINT(5) NOT NULL DEFAULT '0' AFTER `stuck_behavior`;
|
||||
@ -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)
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -119,6 +119,7 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
),
|
||||
hpupdate_timer(2000),
|
||||
@ -2603,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;
|
||||
}
|
||||
|
||||
@ -5608,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);
|
||||
|
||||
@ -7809,9 +7819,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
|
||||
@ -7852,9 +7862,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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)),
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -267,6 +267,11 @@ void Lua_Mob::ChangeSize(double in_size, bool no_restriction) {
|
||||
self->ChangeSize(static_cast<float>(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<float>(x), static_cast<float>(y), static_cast<float>(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)
|
||||
|
||||
@ -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);
|
||||
|
||||
245
zone/mob.cpp
245
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<uint8>(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,74 @@ 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 == 0xFFFFFFFF) ? GetDrakkinHeritage() : in_drakkin_heritage;
|
||||
new_drakkin_tattoo =
|
||||
(in_drakkin_tattoo == 0xFFFFFFFF) ? GetDrakkinTattoo() : in_drakkin_tattoo;
|
||||
new_drakkin_details =
|
||||
(in_drakkin_details == 0xFFFFFFFF) ? 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 +1798,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 +1823,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);
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -1091,7 +1092,7 @@ public:
|
||||
inline glm::vec4 GetCurrentWayPoint() const { return m_CurrentWayPoint; }
|
||||
inline float GetCWPP() const { return(static_cast<float>(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; }
|
||||
@ -1280,6 +1281,7 @@ protected:
|
||||
|
||||
uint8 gender;
|
||||
uint16 race;
|
||||
uint16 use_model;
|
||||
uint8 base_gender;
|
||||
uint16 base_race;
|
||||
uint8 class_;
|
||||
|
||||
@ -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;
|
||||
@ -1574,7 +1574,18 @@ void NPC::AI_DoMovement() {
|
||||
*/
|
||||
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() == EQEmu::WaypointStatus::RoamBoxPauseInProgress && !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<float>(zone->random.Real(-roambox_distance, roambox_distance));
|
||||
auto move_y = static_cast<float>(zone->random.Real(-roambox_distance, roambox_distance));
|
||||
|
||||
@ -1625,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,
|
||||
@ -1642,12 +1654,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(EQEmu::WaypointStatus::RoamBoxPauseInProgress);
|
||||
NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -1660,7 +1670,7 @@ void NPC::AI_DoMovement() {
|
||||
|
||||
int32 gridno = CastToNPC()->GetGrid();
|
||||
|
||||
if (gridno > 0 || cur_wp == -2) {
|
||||
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)
|
||||
@ -1692,7 +1702,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 == EQEmu::WaypointStatus::QuestControlNoGrid) {
|
||||
AI_SetupNextWaypoint();
|
||||
}
|
||||
|
||||
@ -1790,9 +1800,8 @@ 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 == -2) {
|
||||
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;
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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, "$;$");
|
||||
|
||||
@ -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;
|
||||
@ -4205,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);
|
||||
@ -4223,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;
|
||||
}
|
||||
@ -4233,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);
|
||||
@ -4249,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);
|
||||
@ -4260,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)
|
||||
@ -4279,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;
|
||||
}
|
||||
}
|
||||
@ -4289,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);
|
||||
@ -4302,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;
|
||||
}
|
||||
|
||||
@ -4315,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<Paste>
|
||||
AddToHateList(caster, 1,0,true,false,false,spell_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -4330,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);
|
||||
@ -4346,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;
|
||||
}
|
||||
}
|
||||
@ -4356,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;
|
||||
}
|
||||
}
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -110,7 +110,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::WaypointStatus::QuestControlGrid)
|
||||
{ // got here by a MoveTo()
|
||||
cur_wp = save_wp;
|
||||
UpdateWaypoint(cur_wp); // have him head to last destination from here
|
||||
@ -166,28 +166,32 @@ void NPC::PauseWandering(int pausetime)
|
||||
return;
|
||||
}
|
||||
|
||||
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());
|
||||
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 = -1; // flag this move as quest controlled
|
||||
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<glm::vec3>(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<glm::vec3>(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 = -2; // flag as quest controlled w/no grid
|
||||
cur_wp = EQEmu::WaypointStatus::QuestControlNoGrid;
|
||||
Log(Logs::Detail, Logs::AI, "MoveTo %s without a grid.", to_string(static_cast<glm::vec3>(position)).c_str());
|
||||
}
|
||||
|
||||
@ -196,23 +200,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<glm::vec3>(m_GuardPoint)).c_str());
|
||||
Log(Logs::Detail,
|
||||
Logs::AI,
|
||||
"Setting guard position to %s",
|
||||
to_string(static_cast<glm::vec3>(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)
|
||||
|
||||
@ -2498,7 +2498,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()
|
||||
);
|
||||
@ -2688,6 +2689,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.
|
||||
|
||||
@ -144,6 +144,7 @@ struct NPCType
|
||||
bool skip_global_loot;
|
||||
bool rare_spawn;
|
||||
int8 stuck_behavior;
|
||||
uint16 use_model;
|
||||
};
|
||||
|
||||
namespace player_lootitem {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user