[10042] Implement CONDITION_QUESTAVAILABLE.

Also do come constatification of quest status check functions
and fix one unsafe use std::map operator[].
Never never use std::map operator [] for _read_ access.
Good chance corrupt related structure state ;)
Not in found case but in general.
This commit is contained in:
VladimirMangos 2010-06-07 22:21:28 +04:00
parent 5ea6815ea1
commit 5eabf12111
6 changed files with 193 additions and 179 deletions

View file

@ -7455,6 +7455,13 @@ bool PlayerCondition::Meets(Player const * player) const
return data->CheckConditionCriteriaMeet(player, value1, value2);
return false;
}
case CONDITION_QUESTAVAILABLE:
{
if (Quest const* quest = sObjectMgr.GetQuestTemplate(value1))
return player->CanTakeQuest(quest, false);
else
false;
}
default:
return false;
}
@ -7563,6 +7570,7 @@ bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 val
}
case CONDITION_QUESTREWARDED:
case CONDITION_QUESTTAKEN:
case CONDITION_QUESTAVAILABLE:
{
Quest const *Quest = sObjectMgr.GetQuestTemplate(value1);
if (!Quest)

View file

@ -317,9 +317,10 @@ enum ConditionType
CONDITION_NOITEM = 16, // item_id count
CONDITION_SPELL = 17, // spell_id 0, 1 (0: has spell, 1: hasn't spell)
CONDITION_INSTANCE_SCRIPT = 18, // map_id instance_condition_id (instance script specific enum)
CONDITION_QUESTAVAILABLE = 19, // quest_id 0 for case when loot/gossip possible only if player can start quest
};
#define MAX_CONDITION 19 // maximum value in ConditionType enum
#define MAX_CONDITION 20 // maximum value in ConditionType enum
struct PlayerCondition
{

View file

@ -11922,7 +11922,7 @@ void Player::RemoveItemFromBuyBackSlot( uint32 slot, bool del )
}
}
void Player::SendEquipError( uint8 msg, Item* pItem, Item *pItem2, uint32 itemid /*= 0*/ )
void Player::SendEquipError( uint8 msg, Item* pItem, Item *pItem2, uint32 itemid /*= 0*/ ) const
{
DEBUG_LOG( "WORLD: Sent SMSG_INVENTORY_CHANGE_FAILURE (%u)", msg);
WorldPacket data(SMSG_INVENTORY_CHANGE_FAILURE, 1+8+8+1);
@ -13125,7 +13125,7 @@ Quest const * Player::GetNextQuest( uint64 guid, Quest const *pQuest )
return NULL;
}
bool Player::CanSeeStartQuest( Quest const *pQuest )
bool Player::CanSeeStartQuest( Quest const *pQuest ) const
{
if (SatisfyQuestRace( pQuest, false ) && SatisfyQuestSkillOrClass( pQuest, false ) &&
SatisfyQuestExclusiveGroup( pQuest, false ) && SatisfyQuestReputation( pQuest, false ) &&
@ -13138,7 +13138,7 @@ bool Player::CanSeeStartQuest( Quest const *pQuest )
return false;
}
bool Player::CanTakeQuest( Quest const *pQuest, bool msg )
bool Player::CanTakeQuest( Quest const *pQuest, bool msg ) const
{
return SatisfyQuestStatus( pQuest, msg ) && SatisfyQuestExclusiveGroup( pQuest, msg )
&& SatisfyQuestRace( pQuest, msg ) && SatisfyQuestLevel( pQuest, msg )
@ -13148,7 +13148,7 @@ bool Player::CanTakeQuest( Quest const *pQuest, bool msg )
&& SatisfyQuestDay( pQuest, msg ) && SatisfyQuestWeek( pQuest, msg );
}
bool Player::CanAddQuest( Quest const *pQuest, bool msg )
bool Player::CanAddQuest( Quest const *pQuest, bool msg ) const
{
if (!SatisfyQuestLog( msg ))
return false;
@ -13172,12 +13172,17 @@ bool Player::CanAddQuest( Quest const *pQuest, bool msg )
return true;
}
bool Player::CanCompleteQuest( uint32 quest_id )
bool Player::CanCompleteQuest( uint32 quest_id ) const
{
if( quest_id )
{
QuestStatusData& q_status = mQuestStatus[quest_id];
if( q_status.m_status == QUEST_STATUS_COMPLETE )
if (!quest_id)
return false;
QuestStatusMap::const_iterator q_itr = mQuestStatus.find(quest_id);
// some quests can be auto taken and auto completed in one step
QuestStatus status = q_itr != mQuestStatus.end() ? q_itr->second.m_status : QUEST_STATUS_NONE;
if (status == QUEST_STATUS_COMPLETE)
return false; // not allow re-complete quest
Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest_id);
@ -13189,8 +13194,11 @@ bool Player::CanCompleteQuest( uint32 quest_id )
if (qInfo->IsAutoComplete() && CanTakeQuest(qInfo, false))
return true;
if ( q_status.m_status == QUEST_STATUS_INCOMPLETE )
{
if (status != QUEST_STATUS_INCOMPLETE)
return false;
// incomplete quest have status data
QuestStatusData const& q_status = q_itr->second;
if (qInfo->HasFlag( QUEST_MANGOS_FLAGS_DELIVER ))
{
@ -13231,11 +13239,8 @@ bool Player::CanCompleteQuest( uint32 quest_id )
return true;
}
}
return false;
}
bool Player::CanCompleteRepeatableQuest( Quest const *pQuest )
bool Player::CanCompleteRepeatableQuest( Quest const *pQuest ) const
{
// Solve problem that player don't have the quest and try complete it.
// if repeatable she must be able to complete event if player don't have it.
@ -13254,7 +13259,7 @@ bool Player::CanCompleteRepeatableQuest( Quest const *pQuest )
return true;
}
bool Player::CanRewardQuest( Quest const *pQuest, bool msg )
bool Player::CanRewardQuest( Quest const *pQuest, bool msg ) const
{
// not auto complete quest and not completed quest (only cheating case, then ignore without message)
if (!pQuest->IsAutoComplete() && GetQuestStatus(pQuest->GetQuestId()) != QUEST_STATUS_COMPLETE)
@ -13290,7 +13295,7 @@ bool Player::CanRewardQuest( Quest const *pQuest, bool msg )
return true;
}
bool Player::CanRewardQuest( Quest const *pQuest, uint32 reward, bool msg )
bool Player::CanRewardQuest( Quest const *pQuest, uint32 reward, bool msg ) const
{
// prevent receive reward with quest items in bank or for not completed quest
if (!CanRewardQuest(pQuest,msg))
@ -13633,7 +13638,7 @@ void Player::FailQuest(uint32 questId)
}
}
bool Player::SatisfyQuestSkillOrClass( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestSkillOrClass( Quest const* qInfo, bool msg ) const
{
int32 zoneOrSort = qInfo->GetZoneOrSort();
int32 skillOrClass = qInfo->GetSkillOrClass();
@ -13679,7 +13684,7 @@ bool Player::SatisfyQuestSkillOrClass( Quest const* qInfo, bool msg )
return true;
}
bool Player::SatisfyQuestLevel( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestLevel( Quest const* qInfo, bool msg ) const
{
if (getLevel() < qInfo->GetMinLevel())
{
@ -13690,7 +13695,7 @@ bool Player::SatisfyQuestLevel( Quest const* qInfo, bool msg )
return true;
}
bool Player::SatisfyQuestLog( bool msg )
bool Player::SatisfyQuestLog( bool msg ) const
{
// exist free slot
if (FindQuestSlot(0) < MAX_QUEST_LOG_SIZE)
@ -13705,7 +13710,7 @@ bool Player::SatisfyQuestLog( bool msg )
return false;
}
bool Player::SatisfyQuestPreviousQuest( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestPreviousQuest( Quest const* qInfo, bool msg ) const
{
// No previous quest (might be first quest in a series)
if (qInfo->prevQuests.empty())
@ -13802,7 +13807,7 @@ bool Player::SatisfyQuestPreviousQuest( Quest const* qInfo, bool msg )
return false;
}
bool Player::SatisfyQuestRace( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestRace( Quest const* qInfo, bool msg ) const
{
uint32 reqraces = qInfo->GetRequiredRaces();
if (reqraces == 0)
@ -13816,7 +13821,7 @@ bool Player::SatisfyQuestRace( Quest const* qInfo, bool msg )
return true;
}
bool Player::SatisfyQuestReputation( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestReputation( Quest const* qInfo, bool msg ) const
{
uint32 fIdMin = qInfo->GetRequiredMinRepFaction(); //Min required rep
if (fIdMin && GetReputationMgr().GetReputation(fIdMin) < qInfo->GetRequiredMinRepValue())
@ -13837,7 +13842,7 @@ bool Player::SatisfyQuestReputation( Quest const* qInfo, bool msg )
return true;
}
bool Player::SatisfyQuestStatus( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestStatus( Quest const* qInfo, bool msg ) const
{
QuestStatusMap::const_iterator itr = mQuestStatus.find( qInfo->GetQuestId() );
if (itr != mQuestStatus.end() && itr->second.m_status != QUEST_STATUS_NONE)
@ -13849,7 +13854,7 @@ bool Player::SatisfyQuestStatus( Quest const* qInfo, bool msg )
return true;
}
bool Player::SatisfyQuestTimed(Quest const* qInfo, bool msg)
bool Player::SatisfyQuestTimed(Quest const* qInfo, bool msg) const
{
if (!m_timedquests.empty() && qInfo->HasFlag(QUEST_MANGOS_FLAGS_TIMED))
{
@ -13861,7 +13866,7 @@ bool Player::SatisfyQuestTimed(Quest const* qInfo, bool msg)
return true;
}
bool Player::SatisfyQuestExclusiveGroup( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestExclusiveGroup( Quest const* qInfo, bool msg ) const
{
// non positive exclusive group, if > 0 then can be start if any other quest in exclusive group already started/completed
if (qInfo->GetExclusiveGroup() <= 0)
@ -13889,7 +13894,7 @@ bool Player::SatisfyQuestExclusiveGroup( Quest const* qInfo, bool msg )
return false;
}
QuestStatusMap::iterator i_exstatus = mQuestStatus.find( exclude_Id );
QuestStatusMap::const_iterator i_exstatus = mQuestStatus.find( exclude_Id );
// alternative quest already started or completed
if (i_exstatus != mQuestStatus.end()
@ -13903,7 +13908,7 @@ bool Player::SatisfyQuestExclusiveGroup( Quest const* qInfo, bool msg )
return true;
}
bool Player::SatisfyQuestNextChain( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestNextChain( Quest const* qInfo, bool msg ) const
{
if (!qInfo->GetNextQuestInChain())
return true;
@ -13924,7 +13929,7 @@ bool Player::SatisfyQuestNextChain( Quest const* qInfo, bool msg )
return true;
}
bool Player::SatisfyQuestPrevChain( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestPrevChain( Quest const* qInfo, bool msg ) const
{
// No previous quest in chain
if (qInfo->prevChainQuests.empty())
@ -13958,7 +13963,7 @@ bool Player::SatisfyQuestPrevChain( Quest const* qInfo, bool msg )
return true;
}
bool Player::SatisfyQuestDay( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestDay( Quest const* qInfo, bool msg ) const
{
if (!qInfo->IsDaily())
return true;
@ -13984,7 +13989,7 @@ bool Player::SatisfyQuestDay( Quest const* qInfo, bool msg )
return true;
}
bool Player::SatisfyQuestWeek( Quest const* qInfo, bool msg )
bool Player::SatisfyQuestWeek( Quest const* qInfo, bool msg ) const
{
if (!qInfo->IsWeekly() || m_weeklyquests.empty())
return true;
@ -14636,7 +14641,7 @@ void Player::SendQuestTimerFailed( uint32 quest_id )
}
}
void Player::SendCanTakeQuestResponse( uint32 msg )
void Player::SendCanTakeQuestResponse( uint32 msg ) const
{
WorldPacket data( SMSG_QUESTGIVER_QUEST_INVALID, 4 );
data << uint32(msg);

View file

@ -1259,7 +1259,7 @@ class MANGOS_DLL_SPEC Player : public Unit
Item* GetItemFromBuyBackSlot( uint32 slot );
void RemoveItemFromBuyBackSlot( uint32 slot, bool del );
uint32 GetMaxKeyringSize() const { return KEYRING_SLOT_END-KEYRING_SLOT_START; }
void SendEquipError( uint8 msg, Item* pItem, Item *pItem2 = NULL, uint32 itemid = 0 );
void SendEquipError( uint8 msg, Item* pItem, Item *pItem2 = NULL, uint32 itemid = 0 ) const;
void SendBuyError( uint8 msg, Creature* pCreature, uint32 item, uint32 param );
void SendSellError( uint8 msg, Creature* pCreature, uint64 guid, uint32 param );
void AddWeaponProficiency(uint32 newflag) { m_WeaponProficiency |= newflag; }
@ -1326,32 +1326,32 @@ class MANGOS_DLL_SPEC Player : public Unit
void SendPreparedQuest( uint64 guid );
bool IsActiveQuest( uint32 quest_id ) const;
Quest const *GetNextQuest( uint64 guid, Quest const *pQuest );
bool CanSeeStartQuest( Quest const *pQuest );
bool CanTakeQuest( Quest const *pQuest, bool msg );
bool CanAddQuest( Quest const *pQuest, bool msg );
bool CanCompleteQuest( uint32 quest_id );
bool CanCompleteRepeatableQuest(Quest const *pQuest);
bool CanRewardQuest( Quest const *pQuest, bool msg );
bool CanRewardQuest( Quest const *pQuest, uint32 reward, bool msg );
bool CanSeeStartQuest( Quest const *pQuest ) const;
bool CanTakeQuest( Quest const *pQuest, bool msg ) const;
bool CanAddQuest( Quest const *pQuest, bool msg ) const;
bool CanCompleteQuest( uint32 quest_id ) const;
bool CanCompleteRepeatableQuest(Quest const *pQuest) const;
bool CanRewardQuest( Quest const *pQuest, bool msg ) const;
bool CanRewardQuest( Quest const *pQuest, uint32 reward, bool msg ) const;
void AddQuest( Quest const *pQuest, Object *questGiver );
void CompleteQuest( uint32 quest_id );
void IncompleteQuest( uint32 quest_id );
void RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver, bool announce = true );
void FailQuest( uint32 quest_id );
bool SatisfyQuestSkillOrClass( Quest const* qInfo, bool msg );
bool SatisfyQuestLevel( Quest const* qInfo, bool msg );
bool SatisfyQuestLog( bool msg );
bool SatisfyQuestPreviousQuest( Quest const* qInfo, bool msg );
bool SatisfyQuestRace( Quest const* qInfo, bool msg );
bool SatisfyQuestReputation( Quest const* qInfo, bool msg );
bool SatisfyQuestStatus( Quest const* qInfo, bool msg );
bool SatisfyQuestTimed( Quest const* qInfo, bool msg );
bool SatisfyQuestExclusiveGroup( Quest const* qInfo, bool msg );
bool SatisfyQuestNextChain( Quest const* qInfo, bool msg );
bool SatisfyQuestPrevChain( Quest const* qInfo, bool msg );
bool SatisfyQuestDay( Quest const* qInfo, bool msg );
bool SatisfyQuestWeek( Quest const* qInfo, bool msg );
bool SatisfyQuestSkillOrClass( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestLevel( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestLog( bool msg ) const;
bool SatisfyQuestPreviousQuest( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestRace( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestReputation( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestStatus( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestTimed( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestExclusiveGroup( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestNextChain( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestPrevChain( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestDay( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestWeek( Quest const* qInfo, bool msg ) const;
bool GiveQuestSourceItem( Quest const *pQuest );
bool TakeQuestSourceItem( uint32 quest_id, bool msg );
bool GetQuestRewardStatus( uint32 quest_id ) const;
@ -1417,7 +1417,7 @@ class MANGOS_DLL_SPEC Player : public Unit
void SendQuestReward( Quest const *pQuest, uint32 XP, Object* questGiver );
void SendQuestFailed( uint32 quest_id );
void SendQuestTimerFailed( uint32 quest_id );
void SendCanTakeQuestResponse( uint32 msg );
void SendCanTakeQuestResponse( uint32 msg ) const;
void SendQuestConfirmAccept(Quest const* pQuest, Player* pReceiver);
void SendPushToPartyResponse( Player *pPlayer, uint32 msg );
void SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count );
@ -1474,7 +1474,7 @@ class MANGOS_DLL_SPEC Player : public Unit
void setRegenTimer(uint32 time) {m_regenTimer = time;}
void setWeaponChangeTimer(uint32 time) {m_weaponChangeTimer = time;}
uint32 GetMoney() { return GetUInt32Value (PLAYER_FIELD_COINAGE); }
uint32 GetMoney() const { return GetUInt32Value (PLAYER_FIELD_COINAGE); }
void ModifyMoney( int32 d )
{
if(d < 0)

View file

@ -98,7 +98,7 @@ enum QuestStatus
QUEST_STATUS_COMPLETE = 1,
QUEST_STATUS_UNAVAILABLE = 2,
QUEST_STATUS_INCOMPLETE = 3,
QUEST_STATUS_AVAILABLE = 4,
QUEST_STATUS_AVAILABLE = 4, // unused in fact
QUEST_STATUS_FAILED = 5,
MAX_QUEST_STATUS
};

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10041"
#define REVISION_NR "10042"
#endif // __REVISION_NR_H__