From d939820918c775964628a8618c1d14574261d213 Mon Sep 17 00:00:00 2001 From: Uleat Date: Mon, 31 Mar 2014 03:21:22 -0400 Subject: [PATCH] Fix for unconscious ability skillups. Fix for zone crash related to item==nullptr in Client::SummonItem(). --- changelog.txt | 6 ++++++ common/ruletypes.h | 1 + zone/client.cpp | 6 ++++++ zone/client.h | 1 + zone/inventory.cpp | 27 ++++++++++++++++++--------- zone/spells.cpp | 18 ++++++++++++++++++ 6 files changed, 50 insertions(+), 9 deletions(-) diff --git a/changelog.txt b/changelog.txt index 767db2ea0..0d8f82041 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,11 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== xx/xx/2014 == +Uleat: Fix for unconscious skillups. +Uleat: Fix for crash issue with nullptr reference in recent Client::SummonItem() work. +Uleat: Added rule for GM Status check code in Client::SummonItem(). +Note: Rule default is set to 250..but, implementation is on hold until load item code handles the database 'minstatus' field. + == 03/27/2014 == Kayen: SE_Gate will now use have a fail chance as defined by its base value in the spell data. Kayen: SE_Succor will now have a baseline fail chance of (2%). Rule added to adjust this as needed. diff --git a/common/ruletypes.h b/common/ruletypes.h index e800a14e8..d275595fe 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -138,6 +138,7 @@ RULE_BOOL( Pets, UnTargetableSwarmPet, false ) RULE_CATEGORY_END() RULE_CATEGORY( GM ) +RULE_INT ( GM, MinStatusToSummonItem, 250) RULE_INT ( GM, MinStatusToZoneAnywhere, 250 ) RULE_CATEGORY_END() diff --git a/zone/client.cpp b/zone/client.cpp index ebf5d806c..827a3f3f8 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2306,6 +2306,8 @@ uint64 Client::GetAllMoney() { } bool Client::CheckIncreaseSkill(SkillUseTypes skillid, Mob *against_who, int chancemodi) { + if (IsDead() || IsUnconscious()) + return false; if (IsAIControlled()) // no skillups while chamred =p return false; if (skillid > HIGHEST_SKILL) @@ -2349,6 +2351,10 @@ bool Client::CheckIncreaseSkill(SkillUseTypes skillid, Mob *against_who, int cha } void Client::CheckLanguageSkillIncrease(uint8 langid, uint8 TeacherSkill) { + if (IsDead() || IsUnconscious()) + return; + if (IsAIControlled()) + return; if (langid >= MAX_PP_LANGUAGE) return; // do nothing if langid is an invalid language diff --git a/zone/client.h b/zone/client.h index 97ee1b32f..76b2c6774 100644 --- a/zone/client.h +++ b/zone/client.h @@ -305,6 +305,7 @@ public: void SetHideMe(bool hm); inline uint16 GetPort() const { return port; } bool IsDead() const { return(dead); } + bool IsUnconscious() const { return ((cur_hp <= 0) ? true : false); } inline bool IsLFP() { return LFP; } void UpdateLFP(); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index b18514056..5292dd1c0 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -209,7 +209,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, if(item == nullptr) { Message(13, "Item %u does not exist.", item_id); mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create an item with an invalid id.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n", - GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5); + GetName(), account_name, item_id, aug1, aug2, aug3, aug4, aug5); return false; } @@ -228,14 +228,20 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, return false; } + + // This code is ready to implement once the item load code is changed to process the 'minstatus' field. + // Checking #iteminfo in-game verfies that item->MinStatus is set to '0' regardless of field value. + // An optional sql script will also need to be added, once this goes live, to allow changing of the min status. + // check to make sure we are a GM if the item is GM-only /* - else if(item->gm && (this->Admin() < 100)) - Message(13, "You are not a GM and can not summon this item."); - mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create a GM-only item with a status of %i.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n", - GetName(), account_name, this->Admin(), item->ID, aug1, aug2, aug3, aug4, aug5); + else if(item->MinStatus && ((this->Admin() < item->MinStatus) || (this->Admin() < RuleI(GM, MinStatusToSummonItem)))) { + Message(13, "You are not a GM or do not have the status to summon this item."); + mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create a GM-only item with a status of %i.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, MinStatus: %u)\n", + GetName(), account_name, this->Admin(), item->ID, aug1, aug2, aug3, aug4, aug5, item->MinStatus); return false; + } */ uint32 augments[MAX_AUGMENT_SLOTS] = { aug1, aug2, aug3, aug4, aug5 }; @@ -276,12 +282,15 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, return false; } + + // Same as GM check above + // check to make sure we are a GM if the augment is GM-only /* - else if(augtest->gm && (this->Admin() < 100)) { - Message(13, "You are not a GM and can not summon this augment."); - mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create a GM-only augment (Aug%i) with a status of %i.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n", - GetName(), account_name, (iter + 1), this->Admin(), item->ID, aug1, aug2, aug3, aug4, aug5); + else if(augtest->MinStatus && ((this->Admin() < augtest->MinStatus) || (this->Admin() < RuleI(GM, MinStatusToSummonItem)))) { + Message(13, "You are not a GM or do not have the status to summon this augment."); + mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create a GM-only augment (Aug%i) with a status of %i.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, MinStatus: %u)\n", + GetName(), account_name, (iter + 1), this->Admin(), item->ID, aug1, aug2, aug3, aug4, aug5, item->MinStatus); return false; } diff --git a/zone/spells.cpp b/zone/spells.cpp index 2963172c5..c8903c537 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -557,6 +557,15 @@ uint16 Mob::GetSpecializeSkillValue(uint16 spell_id) const { } void Client::CheckSpecializeIncrease(uint16 spell_id) { + // These are not active because CheckIncreaseSkill() already does so. + // It's such a rare occurance that adding them here is wasted..(ref only) + /* + if (IsDead() || IsUnconscious()) + return; + if (IsAIControlled()) + return; + */ + switch(spells[spell_id].skill) { case SkillAbjuration: CheckIncreaseSkill(SkillSpecializeAbjure, nullptr); @@ -580,6 +589,15 @@ void Client::CheckSpecializeIncrease(uint16 spell_id) { } void Client::CheckSongSkillIncrease(uint16 spell_id){ + // These are not active because CheckIncreaseSkill() already does so. + // It's such a rare occurance that adding them here is wasted..(ref only) + /* + if (IsDead() || IsUnconscious()) + return; + if (IsAIControlled()) + return; + */ + switch(spells[spell_id].skill) { case SkillSinging: