Merge branch 'master' into feature/eqemu-api-data-service-netstats-ws

This commit is contained in:
Akkadius
2019-06-23 22:51:21 +00:00
35 changed files with 431 additions and 99 deletions
+11 -2
View File
@@ -251,9 +251,17 @@ bool Mob::CheckWillAggro(Mob *mob) {
return false;
}
Mob *ownr = mob->GetOwner();
if(ownr && ownr->IsClient() && !ownr->CastToClient()->ClientFinishedLoading())
/**
* Pets shouldn't scan for aggro
*/
if (this->GetOwner()) {
return false;
}
Mob *pet_owner = mob->GetOwner();
if (pet_owner && pet_owner->IsClient()) {
return false;
}
float iAggroRange = GetAggroRange();
@@ -727,6 +735,7 @@ type', in which case, the answer is yes.
}
#ifdef BOTS
// this is HIGHLY inefficient
bool HasRuleDefined = false;
bool IsBotAttackAllowed = false;
IsBotAttackAllowed = Bot::IsBotAttackAllowed(mob1, mob2, HasRuleDefined);
+5 -1
View File
@@ -439,6 +439,7 @@ NPCType *Bot::FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::st
bot_npc_type->skip_global_loot = true;
//bot_npc_type->rare_spawn = false;
bot_npc_type->stuck_behavior = Ground;
bot_npc_type->skip_auto_scale = true;
return bot_npc_type;
}
@@ -3498,7 +3499,7 @@ void Bot::LevelBotWithClient(Client* client, uint8 level, bool sendlvlapp) {
Bot* bot = *biter;
if(bot && (bot->GetLevel() != client->GetLevel())) {
bot->SetPetChooser(false); // not sure what this does, but was in bot 'update' code
bot->CalcBotStats(false); // TODO: look at this and see if 'true' should be passed...
bot->CalcBotStats(client->GetBotOptionStatsUpdate());
if(sendlvlapp)
bot->SendLevelAppearance();
// modified from Client::SetLevel()
@@ -4175,6 +4176,9 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
size_t returned_count = client_return.size();
client->Message(CC_Lime, "Trade with '%s' resulted in %i accepted item%s, %i returned item%s.", GetCleanName(), accepted_count, ((accepted_count == 1) ? "" : "s"), returned_count, ((returned_count == 1) ? "" : "s"));
if (accepted_count)
CalcBotStats(client->GetBotOptionStatsUpdate());
}
bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) {
+23 -5
View File
@@ -3441,16 +3441,34 @@ void bot_command_movement_speed(Client *c, const Seperator *sep)
void bot_command_owner_option(Client *c, const Seperator *sep)
{
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(m_usage, "usage: %s [deathmarquee]", sep->arg[0]);
c->Message(m_usage, "usage: %s [deathmarquee | statsupdate] (argument: enable | disable | null (toggles))", sep->arg[0]);
return;
}
std::string owner_option = sep->arg[1];
std::string flag = sep->arg[2];
if (!owner_option.compare("deathmarquee")) {
c->SetBotOptionDeathMarquee(!c->GetBotOptionDeathMarquee());
c->Message(m_action, "Bot death marquee is now %s.", (c->GetBotOptionDeathMarquee() == true ? "enabled" : "disabled"));
if (!flag.compare("enable"))
c->SetBotOptionDeathMarquee(true);
else if (!flag.compare("disable"))
c->SetBotOptionDeathMarquee(false);
else
c->SetBotOptionDeathMarquee(!c->GetBotOptionDeathMarquee());
botdb.SaveOwnerOptionDeathMarquee(c->CharacterID(), c->GetBotOptionDeathMarquee());
c->Message(m_action, "Bot 'death marquee' is now %s.", (c->GetBotOptionDeathMarquee() == true ? "enabled" : "disabled"));
}
else if (!owner_option.compare("statsupdate")) {
if (!flag.compare("enable"))
c->SetBotOptionStatsUpdate(true);
else if (!flag.compare("disable"))
c->SetBotOptionStatsUpdate(false);
else
c->SetBotOptionStatsUpdate(!c->GetBotOptionStatsUpdate());
botdb.SaveOwnerOptionStatsUpdate(c->CharacterID(), c->GetBotOptionStatsUpdate());
c->Message(m_action, "Bot 'stats update' is now %s.", (c->GetBotOptionStatsUpdate() == true ? "enabled" : "disabled"));
}
else {
c->Message(m_fail, "Owner option '%s' is not recognized.", owner_option.c_str());
@@ -5532,7 +5550,7 @@ void bot_subcommand_bot_update(Client *c, const Seperator *sep)
continue;
bot_iter->SetPetChooser(false);
bot_iter->CalcBotStats((sbl.size() == 1));
bot_iter->CalcBotStats(c->GetBotOptionStatsUpdate());
bot_iter->SendAppearancePacket(AT_WhoLevel, bot_iter->GetLevel(), true, true);
++bot_count;
}
@@ -7321,7 +7339,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
}
my_bot->BotRemoveEquipItem(slotId);
my_bot->CalcBotStats();
my_bot->CalcBotStats(c->GetBotOptionStatsUpdate());
}
switch (slotId) {
+21 -1
View File
@@ -2188,7 +2188,7 @@ bool BotDatabase::LoadOwnerOptions(Client *owner)
return false;
query = StringFormat(
"SELECT `death_marquee` FROM `bot_owner_options`"
"SELECT `death_marquee`, `stats_update` FROM `bot_owner_options`"
" WHERE `owner_id` = '%u'",
owner->CharacterID()
);
@@ -2204,6 +2204,7 @@ bool BotDatabase::LoadOwnerOptions(Client *owner)
auto row = results.begin();
owner->SetBotOptionDeathMarquee((atoi(row[0]) != 0));
owner->SetBotOptionStatsUpdate((atoi(row[1]) != 0));
return true;
}
@@ -2227,6 +2228,25 @@ bool BotDatabase::SaveOwnerOptionDeathMarquee(const uint32 owner_id, const bool
return true;
}
bool BotDatabase::SaveOwnerOptionStatsUpdate(const uint32 owner_id, const bool flag)
{
if (!owner_id)
return false;
query = StringFormat(
"UPDATE `bot_owner_options`"
" SET `stats_update` = '%u'"
" WHERE `owner_id` = '%u'",
(flag == true ? 1 : 0),
owner_id
);
auto results = QueryDatabase(query);
if (!results.Success())
return false;
return true;
}
/* Bot bot-group functions */
bool BotDatabase::QueryBotGroupExistence(const std::string& group_name, bool& extant_flag)
+1
View File
@@ -148,6 +148,7 @@ public:
bool LoadOwnerOptions(Client *owner);
bool SaveOwnerOptionDeathMarquee(const uint32 owner_id, const bool flag);
bool SaveOwnerOptionStatsUpdate(const uint32 owner_id, const bool flag);
/* Bot bot-group functions */
bool QueryBotGroupExistence(const std::string& botgroup_name, bool& extant_flag);
+7 -1
View File
@@ -781,6 +781,8 @@ public:
void UnmemSpell(int slot, bool update_client = true);
void UnmemSpellBySpellID(int32 spell_id);
void UnmemSpellAll(bool update_client = true);
uint16 FindMemmedSpellBySlot(int slot);
int MemmedCount();
void ScribeSpell(uint16 spell_id, int slot, bool update_client = true);
void UnscribeSpell(int slot, bool update_client = true);
void UnscribeSpellAll(bool update_client = true);
@@ -1640,18 +1642,22 @@ private:
#ifdef BOTS
struct BotOwnerOptions {
bool death_marquee;
bool stats_update;
};
BotOwnerOptions bot_owner_options;
const BotOwnerOptions DefaultBotOwnerOptions = {
false // death_marquee
false, // death_marquee
false // stats_update
};
public:
void SetBotOptionDeathMarquee(bool flag) { bot_owner_options.death_marquee = flag; }
void SetBotOptionStatsUpdate(bool flag) { bot_owner_options.stats_update = flag; }
bool GetBotOptionDeathMarquee() const { return bot_owner_options.death_marquee; }
bool GetBotOptionStatsUpdate() const { return bot_owner_options.stats_update; }
private:
#endif
+16 -5
View File
@@ -286,6 +286,17 @@ Bot *Entity::CastToBot()
#endif
return static_cast<Bot *>(this);
}
const Bot *Entity::CastToBot() const
{
#ifdef _EQDEBUG
if (!IsBot()) {
std::cout << "CastToBot error" << std::endl;
return 0;
}
#endif
return static_cast<const Bot *>(this);
}
#endif
EntityList::EntityList()
@@ -509,16 +520,16 @@ void EntityList::MobProcess()
}
if(mob_dead) {
if(mob->IsNPC()) {
entity_list.RemoveNPC(id);
}
else if(mob->IsMerc()) {
if(mob->IsMerc()) {
entity_list.RemoveMerc(id);
#ifdef BOTS
}
#ifdef BOTS
else if(mob->IsBot()) {
entity_list.RemoveBot(id);
}
#endif
else if(mob->IsNPC()) {
entity_list.RemoveNPC(id);
}
else {
#ifdef _WINDOWS
+1
View File
@@ -116,6 +116,7 @@ public:
#ifdef BOTS
Bot* CastToBot();
const Bot* CastToBot() const;
#endif
protected:
+1 -1
View File
@@ -180,7 +180,7 @@ bool Client::CanFish() {
const float LineLength = RuleR(Watermap, FishingLineLength);
int HeadingDegrees;
HeadingDegrees = (int) ((GetHeading()*360)/256);
HeadingDegrees = (int) ((GetHeading()*360)/512);
HeadingDegrees = HeadingDegrees % 360;
rodPosition.x = m_Position.x + RodLength * sin(HeadingDegrees * M_PI/180.0f);
+3 -3
View File
@@ -98,7 +98,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
x++;
}
DeleteItemInInventory(i, 0, ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((i - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) == 0));
DeleteItemInInventory(i, 0, ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((i - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) != 0));
}
}
}
@@ -972,8 +972,8 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd
safe_delete(outapp);
}
else {
outapp = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct));
DeleteItem_Struct* delitem = (DeleteItem_Struct*)outapp->pBuffer;
outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
MoveItem_Struct* delitem = (MoveItem_Struct*)outapp->pBuffer;
delitem->from_slot = slot_id;
delitem->to_slot = 0xFFFFFFFF;
delitem->number_in_stack = 0xFFFFFFFF;
+12
View File
@@ -550,6 +550,16 @@ void Lua_Client::UnmemSpellAll(bool update_client) {
self->UnmemSpellAll(update_client);
}
uint16 Lua_Client::FindMemmedSpellBySlot(int slot) {
Lua_Safe_Call_Int();
return self->FindMemmedSpellBySlot(slot);
}
int Lua_Client::MemmedCount() {
Lua_Safe_Call_Int();
return self->MemmedCount();
}
void Lua_Client::ScribeSpell(int spell_id, int slot) {
Lua_Safe_Call_Void();
self->ScribeSpell(spell_id, slot);
@@ -1618,6 +1628,8 @@ luabind::scope lua_register_client() {
.def("UnmemSpellBySpellID", (void(Lua_Client::*)(int32))&Lua_Client::UnmemSpellBySpellID)
.def("UnmemSpellAll", (void(Lua_Client::*)(void))&Lua_Client::UnmemSpellAll)
.def("UnmemSpellAll", (void(Lua_Client::*)(bool))&Lua_Client::UnmemSpellAll)
.def("FindMemmedSpellBySlot", (uint16(Lua_Client::*)(int))&Lua_Client::FindMemmedSpellBySlot)
.def("MemmedCount", (int(Lua_Client::*)(void))&Lua_Client::MemmedCount)
.def("ScribeSpell", (void(Lua_Client::*)(int,int))&Lua_Client::ScribeSpell)
.def("ScribeSpell", (void(Lua_Client::*)(int,int,bool))&Lua_Client::ScribeSpell)
.def("UnscribeSpell", (void(Lua_Client::*)(int))&Lua_Client::UnscribeSpell)
+2
View File
@@ -135,6 +135,8 @@ public:
void UnmemSpellBySpellID(int32 spell_id);
void UnmemSpellAll();
void UnmemSpellAll(bool update_client);
uint16 FindMemmedSpellBySlot(int slot);
int MemmedCount();
void ScribeSpell(int spell_id, int slot);
void ScribeSpell(int spell_id, int slot, bool update_client);
void UnscribeSpell(int slot);
+18
View File
@@ -322,6 +322,16 @@ bool Lua_Mob::FindBuff(int spell_id) {
return self->FindBuff(spell_id);
}
uint16 Lua_Mob::FindBuffBySlot(int slot) {
Lua_Safe_Call_Int();
return self->FindBuffBySlot(slot);
}
uint32 Lua_Mob::BuffCount() {
Lua_Safe_Call_Int();
return self->BuffCount();
}
bool Lua_Mob::FindType(int type) {
Lua_Safe_Call_Bool();
return self->FindType(type);
@@ -2091,6 +2101,11 @@ int Lua_Mob::GetWeaponDamageBonus(Lua_Item weapon, bool offhand) {
return self->GetWeaponDamageBonus(weapon, offhand);
}
int Lua_Mob::GetItemStat(uint32 itemid, const char* identifier) {
Lua_Safe_Call_Int();
return self->GetItemStat(itemid, identifier);
}
Lua_StatBonuses Lua_Mob::GetItemBonuses()
{
Lua_Safe_Call_Class(Lua_StatBonuses);
@@ -2218,6 +2233,8 @@ luabind::scope lua_register_mob() {
.def("IsInvisible", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsInvisible)
.def("SetInvisible", &Lua_Mob::SetInvisible)
.def("FindBuff", &Lua_Mob::FindBuff)
.def("FindBuffBySlot", (uint16(Lua_Mob::*)(int))&Lua_Mob::FindBuffBySlot)
.def("BuffCount", &Lua_Mob::BuffCount)
.def("FindType", (bool(Lua_Mob::*)(int))&Lua_Mob::FindType)
.def("FindType", (bool(Lua_Mob::*)(int,bool))&Lua_Mob::FindType)
.def("FindType", (bool(Lua_Mob::*)(int,bool,int))&Lua_Mob::FindType)
@@ -2248,6 +2265,7 @@ luabind::scope lua_register_mob() {
.def("IsWarriorClass", &Lua_Mob::IsWarriorClass)
.def("GetHP", &Lua_Mob::GetHP)
.def("GetMaxHP", &Lua_Mob::GetMaxHP)
.def("GetItemStat", (int(Lua_Mob::*)(uint32,const char*))&Lua_Mob::GetItemStat)
.def("GetItemHPBonuses", &Lua_Mob::GetItemHPBonuses)
.def("GetSpellHPBonuses", &Lua_Mob::GetSpellHPBonuses)
.def("GetWalkspeed", &Lua_Mob::GetWalkspeed)
+3
View File
@@ -82,6 +82,8 @@ public:
bool IsInvisible(Lua_Mob other);
void SetInvisible(int state);
bool FindBuff(int spell_id);
uint16 FindBuffBySlot(int slot);
uint32 BuffCount();
bool FindType(int type);
bool FindType(int type, bool offensive);
bool FindType(int type, bool offensive, int threshold);
@@ -402,6 +404,7 @@ public:
bool IsAmnesiad();
int32 GetMeleeMitigation();
int GetWeaponDamageBonus(Lua_Item weapon, bool offhand);
int GetItemStat(uint32 itemid, const char* identifier);
Lua_StatBonuses GetItemBonuses();
Lua_StatBonuses GetSpellBonuses();
Lua_StatBonuses GetAABonuses();
+2
View File
@@ -385,6 +385,8 @@ public:
void DamageShield(Mob* other, bool spell_ds = false);
int32 RuneAbsorb(int32 damage, uint16 type);
bool FindBuff(uint16 spellid);
uint16 FindBuffBySlot(int slot);
uint32 BuffCount();
bool FindType(uint16 type, bool bOffensive = false, uint16 threshold = 100);
int16 GetBuffSlotFromType(uint16 type);
uint16 GetSpellIDFromSlot(uint8 slot);
+17 -1
View File
@@ -2436,7 +2436,7 @@ bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) {
}
DBnpcspells_Struct* parentlist = database.GetNPCSpells(spell_list->parent_list);
#if MobAI_DEBUG_Spells >= 10
std::string debug_msg = StringFormat("Loading NPCSpells onto %s: dbspellsid=%u", this->GetName(), iDBSpellsID);
std::string debug_msg = StringFormat("Loading NPCSpells onto %s: dbspellsid=%u, level=%u", this->GetName(), iDBSpellsID, this->GetLevel());
if (spell_list) {
debug_msg.append(StringFormat(" (found, %u), parentlist=%u", spell_list->entries.size(), spell_list->parent_list));
if (spell_list->parent_list) {
@@ -2450,6 +2450,22 @@ bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) {
debug_msg.append(" (not found)");
}
Log(Logs::Detail, Logs::AI, "%s", debug_msg.c_str());
#ifdef MobAI_DEBUG_Spells >= 25
if (parentlist) {
for (const auto &iter : parentlist->entries) {
Log(Logs::Detail, Logs::AI, "(%i) %s", iter.spellid, spells[iter.spellid].name);
}
}
Log(Logs::Detail, Logs::AI, "fin (parent list)");
if (spell_list) {
for (const auto &iter : spell_list->entries) {
Log(Logs::Detail, Logs::AI, "(%i) %s", iter.spellid, spells[iter.spellid].name);
}
}
Log(Logs::Detail, Logs::AI, "fin (spell list)");
#endif
#endif
uint16 attack_proc_spell = -1;
int8 proc_chance = 3;
+2 -2
View File
@@ -189,11 +189,11 @@ inline std::string GetMobAttributeByString(Mob *mob, const std::string &attribut
}
if (attribute == "cor") {
return std::to_string(mob->GetCorrup());
return commify(std::to_string(mob->GetCorrup())) + scaling_modified;
}
if (attribute == "phy") {
return std::to_string(mob->GetPhR());
return commify(std::to_string(mob->GetPhR())) + scaling_modified;
}
if (attribute == "name") {
+3
View File
@@ -574,6 +574,9 @@ int main(int argc, char** argv) {
if (InterserverTimer.Check()) {
InterserverTimer.Start();
database.ping();
#ifdef BOTS
botdb.ping();
#endif
entity_list.UpdateWho();
}
};
+9
View File
@@ -239,6 +239,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
p_depop = false;
loottable_id = npc_type_data->loottable_id;
skip_global_loot = npc_type_data->skip_global_loot;
skip_auto_scale = npc_type_data->skip_auto_scale;
rare_spawn = npc_type_data->rare_spawn;
no_target_hotkey = npc_type_data->no_target_hotkey;
primary_faction = 0;
@@ -2214,6 +2215,14 @@ void NPC::ModifyNPCStat(const char *identifier, const char *new_value)
CR = atoi(val.c_str());
return;
}
else if (id == "cor") {
Corrup = atoi(val.c_str());
return;
}
else if (id == "phr") {
PhR = atoi(val.c_str());
return;
}
else if (id == "pr") {
PR = atoi(val.c_str());
return;
+2
View File
@@ -468,6 +468,7 @@ public:
virtual int GetStuckBehavior() const { return NPCTypedata_ours ? NPCTypedata_ours->stuck_behavior : NPCTypedata->stuck_behavior; }
inline bool IsSkipAutoScale() const { return skip_auto_scale; }
protected:
@@ -612,6 +613,7 @@ protected:
private:
uint32 loottable_id;
bool skip_global_loot;
bool skip_auto_scale;
bool p_depop;
};
+9 -6
View File
@@ -26,6 +26,9 @@
*/
void NpcScaleManager::ScaleNPC(NPC * npc)
{
if (npc->IsSkipAutoScale())
return;
int8 npc_type = GetNPCScalingType(npc);
int npc_level = npc->GetLevel();
bool is_auto_scaled = IsAutoScaled(npc);
@@ -42,7 +45,7 @@ void NpcScaleManager::ScaleNPC(NPC * npc)
return;
}
if (npc->GetAC() == 0) {
if (npc->GetAC() == 0 && is_auto_scaled) {
npc->ModifyNPCStat("ac", std::to_string(scale_data.ac).c_str());
}
if (npc->GetMaxHP() == 0) {
@@ -94,11 +97,11 @@ void NpcScaleManager::ScaleNPC(NPC * npc)
if (npc->GetDR() == 0) {
npc->ModifyNPCStat("dr", std::to_string(scale_data.disease_resist).c_str());
}
if (npc->GetCorrup() == 0) {
npc->ModifyNPCStat("cr", std::to_string(scale_data.corruption_resist).c_str());
if (npc->GetCorrup() == 0 && is_auto_scaled) {
npc->ModifyNPCStat("cor", std::to_string(scale_data.corruption_resist).c_str());
}
if (npc->GetPhR() == 0) {
npc->ModifyNPCStat("pr", std::to_string(scale_data.physical_resist).c_str());
if (npc->GetPhR() == 0 && is_auto_scaled) {
npc->ModifyNPCStat("phr", std::to_string(scale_data.physical_resist).c_str());
}
if (npc->GetMinDMG() == 0 && npc->GetMaxDMG() == 0) {
int min_dmg = scale_data.min_dmg;
@@ -621,4 +624,4 @@ bool NpcScaleManager::ApplyGlobalBaseScalingToNPCDynamically(NPC *&npc)
auto results = database.QueryDatabase(query);
return results.Success();
}
}
+69 -12
View File
@@ -1233,15 +1233,17 @@ XS(XS_Client_MovePC) {
if (THIS->IsMerc()) {
Log(Logs::Detail, Logs::None,
"[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Merc reference");
} else if (THIS->IsNPC()) {
}
#ifdef BOTS
else if (THIS->IsBot()) {
Log(Logs::Detail, Logs::None,
"[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Bot reference");
}
#endif
else if (THIS->IsNPC()) {
Log(Logs::Detail, Logs::None,
"[CLIENT] Perl(XS_Client_MovePC) attempted to process a type NPC reference");
}
#ifdef BOTS
else if (THIS->IsBot()) {
Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Bot reference");
}
#endif
else {
Log(Logs::Detail, Logs::None,
"[CLIENT] Perl(XS_Client_MovePC) attempted to process an Unknown type reference");
@@ -1283,15 +1285,17 @@ XS(XS_Client_MovePCInstance) {
if (THIS->IsMerc()) {
Log(Logs::Detail, Logs::None,
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Merc reference");
} else if (THIS->IsNPC()) {
}
#ifdef BOTS
else if (THIS->IsBot()) {
Log(Logs::Detail, Logs::None,
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Bot reference");
}
#endif
else if (THIS->IsNPC()) {
Log(Logs::Detail, Logs::None,
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type NPC reference");
}
#ifdef BOTS
else if (THIS->IsBot()) {
Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Bot reference");
}
#endif
else {
Log(Logs::Detail, Logs::None,
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference");
@@ -2404,6 +2408,57 @@ XS(XS_Client_UnmemSpellAll) {
XSRETURN_EMPTY;
}
XS(XS_Client_FindMemmedSpellBySlot); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_FindMemmedSpellBySlot) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::FindMemmedSpellBySlot(THIS, int slot)");
{
Client *THIS;
uint16 RETVAL;
dXSTARG;
int slot = SvIV(ST(1));
if (sv_derived_from(ST(0), "Client")) {
IV tmp = SvIV((SV *) SvRV(ST(0)));
THIS = INT2PTR(Client *, tmp);
} else
Perl_croak(aTHX_ "THIS is not of type Client");
if (THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->FindMemmedSpellBySlot(slot);
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
XS(XS_Client_MemmedCount); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_MemmedCount) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Client::MemmedCount(THIS)");
{
Client *THIS;
uint32 RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "Client")) {
IV tmp = SvIV((SV *) SvRV(ST(0)));
THIS = INT2PTR(Client *, tmp);
} else
Perl_croak(aTHX_ "THIS is not of type Client");
if (THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->MemmedCount();
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
XS(XS_Client_ScribeSpell); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_ScribeSpell) {
dXSARGS;
@@ -6478,6 +6533,8 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "UnmemSpell"), XS_Client_UnmemSpell, file, "$$;$");
newXSproto(strcpy(buf, "UnmemSpellAll"), XS_Client_UnmemSpellAll, file, "$;$");
newXSproto(strcpy(buf, "UnmemSpellBySpellID"), XS_Client_UnmemSpellBySpellID, file, "$$");
newXSproto(strcpy(buf, "FindMemmedSpellBySlot"), XS_Client_FindMemmedSpellBySlot, file, "$$");
newXSproto(strcpy(buf, "MemmedCount"), XS_Client_MemmedCount, file, "$");
newXSproto(strcpy(buf, "UnscribeSpell"), XS_Client_UnscribeSpell, file, "$$;$");
newXSproto(strcpy(buf, "UnscribeSpellAll"), XS_Client_UnscribeSpellAll, file, "$;$");
newXSproto(strcpy(buf, "UntrainDisc"), XS_Client_UntrainDisc, file, "$$;$");
+53
View File
@@ -1297,6 +1297,57 @@ XS(XS_Mob_FindBuff) {
XSRETURN(1);
}
XS(XS_Mob_FindBuffBySlot); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_FindBuffBySlot) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Mob::FindBuffBySlot(THIS, int slot)");
{
Mob *THIS;
uint16 RETVAL;
dXSTARG;
int slot = SvIV(ST(1));
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.");
RETVAL = THIS->FindBuffBySlot(slot);
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
XS(XS_Mob_BuffCount); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_BuffCount) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Mob::BuffCount(THIS)");
{
Mob *THIS;
uint32 RETVAL;
dXSTARG;
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.");
RETVAL = THIS->BuffCount();
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
XS(XS_Mob_FindType); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_FindType) {
dXSARGS;
@@ -8581,6 +8632,8 @@ XS(boot_Mob) {
newXSproto(strcpy(buf, "IsInvisible"), XS_Mob_IsInvisible, file, "$;$");
newXSproto(strcpy(buf, "SetInvisible"), XS_Mob_SetInvisible, file, "$$");
newXSproto(strcpy(buf, "FindBuff"), XS_Mob_FindBuff, file, "$$");
newXSproto(strcpy(buf, "FindBuffBySlot"), XS_Mob_FindBuffBySlot, file, "$$");
newXSproto(strcpy(buf, "BuffCount"), XS_Mob_BuffCount, file, "$");
newXSproto(strcpy(buf, "FindType"), XS_Mob_FindType, file, "$$;$$");
newXSproto(strcpy(buf, "GetBuffSlotFromType"), XS_Mob_GetBuffSlotFromType, file, "$$");
newXSproto(strcpy(buf, "MakePet"), XS_Mob_MakePet, file, "$$$;$");
+1
View File
@@ -1278,6 +1278,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
}
else if(dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
Message_StringID(15,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase.
return;
}
if(!IsAttackAllowed(other) ||
+35 -1
View File
@@ -455,7 +455,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
{
mana_cost = 0;
} else {
Log(Logs::Detail, Logs::Spells, "Spell Error not enough mana spell=%d mymana=%d cost=%d\n", GetName(), spell_id, my_curmana, mana_cost);
Log(Logs::Detail, Logs::Spells, "Spell Error not enough mana spell=%d mymana=%d cost=%d\n", spell_id, my_curmana, mana_cost);
if(IsClient()) {
//clients produce messages... npcs should not for this case
Message_StringID(13, INSUFFICIENT_MANA);
@@ -4032,6 +4032,23 @@ bool Mob::FindBuff(uint16 spellid)
return false;
}
uint16 Mob::FindBuffBySlot(int slot) {
if (buffs[slot].spellid != SPELL_UNKNOWN)
return buffs[slot].spellid;
return 0;
}
uint32 Mob::BuffCount() {
uint32 active_buff_count = 0;
int buff_count = GetMaxTotalSlots();
for (int i = 0; i < buff_count; i++)
if (buffs[i].spellid != SPELL_UNKNOWN)
active_buff_count++;
return active_buff_count;
}
// removes all buffs
void Mob::BuffFadeAll()
{
@@ -5039,6 +5056,23 @@ void Client::UnmemSpellAll(bool update_client)
UnmemSpell(i, update_client);
}
uint16 Client::FindMemmedSpellBySlot(int slot) {
if (m_pp.mem_spells[slot] != 0xFFFFFFFF)
return m_pp.mem_spells[slot];
return 0;
}
int Client::MemmedCount() {
int memmed_count = 0;
for (int i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; i++)
if (m_pp.mem_spells[i] != 0xFFFFFFFF)
memmed_count++;
return memmed_count;
}
void Client::ScribeSpell(uint16 spell_id, int slot, bool update_client)
{
if(slot >= EQEmu::spells::SPELLBOOK_SIZE || slot < 0)
+3
View File
@@ -2690,6 +2690,7 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
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]);
temp_npctype_data->skip_auto_scale = false; // hardcoded here for now
// If NPC with duplicate NPC id already in table,
// free item we attempted to add.
@@ -2892,6 +2893,8 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client
tmpNPCType->scalerate = atoi(row[43]);
tmpNPCType->spellscale = atoi(row[44]);
tmpNPCType->healscale = atoi(row[45]);
tmpNPCType->skip_global_loot = true;
tmpNPCType->skip_auto_scale = true;
// If Merc with duplicate NPC id already in table,
// free item we attempted to add.
+1
View File
@@ -143,6 +143,7 @@ struct NPCType
bool untargetable;
bool skip_global_loot;
bool rare_spawn;
bool skip_auto_scale; // just so it doesn't mess up bots or mercs, probably should add to DB too just in case
int8 stuck_behavior;
uint16 use_model;
};