Add quest add and remove commands and make questcomplete try satisfy the requirements and act like quest complete command. Merge SetLevel and GiveLevel for player methods.

This commit is contained in:
Rochet2
2015-05-02 02:06:53 +03:00
parent adccf1ef36
commit 564cf2b15b
4 changed files with 274 additions and 38 deletions

View File

@@ -634,7 +634,6 @@ namespace LuaCreature
* Returns a target from the [Creature]'s threat list based on the
* supplied arguments.
*
* <pre>
* enum SelectAggroTarget
* {
* SELECT_TARGET_RANDOM = 0, //Just selects a random target
@@ -643,7 +642,6 @@ namespace LuaCreature
* SELECT_TARGET_NEAREST,
* SELECT_TARGET_FARTHEST
* };
* </pre>
*
* For example, if you wanted to select the third-farthest [Player]
* within 50 yards that has the [Aura] "Corrupted Blood" (ID 24328),
@@ -651,12 +649,12 @@ namespace LuaCreature
*
* target = creature:GetAITarget(4, true, 3, 50, 24328)
*
* @param SelectAggroTarget targetType : how the threat list should be sorted
* @param [SelectAggroTarget] targetType : how the threat list should be sorted
* @param bool playerOnly = false : if `true`, skips targets that aren't [Player]s
* @param uint32 position = 0 : used as an offset into the threat list. If `targetType` is random, used as the number of players from top of aggro to choose from
* @param float distance = 0.0 : if positive, the maximum distance for the target. If negative, the minimum distance
* @param int32 aura = 0 : if positive, the target must have this [Aura]. If negative, the the target must not have this Aura
* @return Unit target : the target, or `nil`
* @return [Unit] target : the target, or `nil`
*/
int GetAITarget(Eluna* /*E*/, lua_State* L, Creature* creature)
{

View File

@@ -576,6 +576,7 @@ ElunaRegister<Player> PlayerMethods[] =
#ifndef CLASSIC
{ "IsInArenaTeam", &LuaPlayer::IsInArenaTeam }, // :IsInArenaTeam(type) - type : 0 = 2v2, 1 = 3v3, 2 = 5v5
#endif
{ "CanCompleteQuest", &LuaPlayer::CanCompleteQuest },
{ "CanEquipItem", &LuaPlayer::CanEquipItem }, // :CanEquipItem(entry/item, slot) - Returns true if the player can equip given item/item entry
{ "IsFalling", &LuaPlayer::IsFalling }, // :IsFalling() - Returns true if the unit is falling
{ "ToggleAFK", &LuaPlayer::ToggleAFK }, // :ToggleAFK() - Toggles AFK state for player
@@ -661,7 +662,6 @@ ElunaRegister<Player> PlayerMethods[] =
{ "ResetSpellCooldown", &LuaPlayer::ResetSpellCooldown }, // :ResetSpellCooldown(spellId, update(bool~optional)) - Resets cooldown of the specified spellId. If update is true, it will send WorldPacket SMSG_CLEAR_COOLDOWN to the player, else it will just clear the spellId from m_spellCooldowns. This is true by default
{ "ResetTypeCooldowns", &LuaPlayer::ResetTypeCooldowns }, // :ResetTypeCooldowns(category, update(bool~optional)) - Resets all cooldowns for the spell category(type). If update is true, it will send WorldPacket SMSG_CLEAR_COOLDOWN to the player, else it will just clear the spellId from m_spellCooldowns. This is true by default
{ "ResetAllCooldowns", &LuaPlayer::ResetAllCooldowns }, // :ResetAllCooldowns() - Resets all spell cooldowns
{ "GiveLevel", &LuaPlayer::GiveLevel }, // :GiveLevel(level) - Gives levels to the player
{ "GiveXP", &LuaPlayer::GiveXP }, // :GiveXP(xp[, victim, pureXP, triggerHook]) - Gives XP to the player. If pure is false, bonuses are count in. If triggerHook is false, GiveXp hook is not triggered.
// {"RemovePet", &LuaPlayer::RemovePet}, // :RemovePet([mode, returnreagent]) - Removes the player's pet. Mode determines if the pet is saved and how
// {"SummonPet", &LuaPlayer::SummonPet}, // :SummonPet(entry, x, y, z, o, petType, despwtime) - Summons a pet for the player
@@ -672,6 +672,8 @@ ElunaRegister<Player> PlayerMethods[] =
{ "CompleteQuest", &LuaPlayer::CompleteQuest }, // :CompleteQuest(entry) - Completes a quest by entry
{ "IncompleteQuest", &LuaPlayer::IncompleteQuest }, // :IncompleteQuest(entry) - Uncompletes the quest by entry for the player
{ "FailQuest", &LuaPlayer::FailQuest }, // :FailQuest(entry) - Player fails the quest entry
{ "AddQuest", &LuaPlayer::AddQuest },
{ "RemoveQuest", &LuaPlayer::RemoveQuest },
// {"RemoveActiveQuest", &LuaPlayer::RemoveActiveQuest}, // :RemoveActiveQuest(entry) - Removes an active quest
// {"RemoveRewardedQuest", &LuaPlayer::RemoveRewardedQuest}, // :RemoveRewardedQuest(entry) - Removes a rewarded quest
{ "AreaExploredOrEventHappens", &LuaPlayer::AreaExploredOrEventHappens }, // :AreaExploredOrEventHappens(questId) - Satisfies an area or event requrement for the questId
@@ -721,7 +723,7 @@ ElunaRegister<Player> PlayerMethods[] =
{ "SendTabardVendorActivate", &LuaPlayer::SendTabardVendorActivate }, // :SendTabardVendorActivate(WorldObject) - Sends tabard vendor window from object to player
{ "SendSpiritResurrect", &LuaPlayer::SendSpiritResurrect }, // :SendSpiritResurrect() - Sends resurrect window to player
{ "SendTaxiMenu", &LuaPlayer::SendTaxiMenu }, // :SendTaxiMenu(creature) - Sends flight window to player from creature
{ "RewardQuest", &LuaPlayer::RewardQuest }, // :RewardQuest(entry) - Gives quest rewards for the player
{ "RewardQuest", &LuaPlayer::RewardQuest },
{ "SendAuctionMenu", &LuaPlayer::SendAuctionMenu }, // :SendAuctionMenu(unit) - Sends auction window to player. Auction house is sent by object.
{ "SendShowMailBox", &LuaPlayer::SendShowMailBox }, // :SendShowMailBox([mailboxguid]) - Sends the mail window to player from the mailbox gameobject. The guid is required on patches below wotlk.
{ "StartTaxi", &LuaPlayer::StartTaxi }, // :StartTaxi(pathId) - player starts the given flight path

View File

@@ -395,6 +395,20 @@ namespace LuaPlayer
}
#endif
/**
* Returns 'true' if the [Player] satisfies all requirements to complete the quest entry.
*
* @param uint32 entry
* @return bool canComplete
*/
int CanCompleteQuest(Eluna* /*E*/, lua_State* L, Player* player)
{
uint32 entry = Eluna::CHECKVAL<uint32>(L, 2);
Eluna::Push(L, player->CanCompleteQuest(entry));
return 1;
}
/**
* Returns 'true' if the [Player] is a part of the Horde faction, 'false' otherwise.
*
@@ -1193,19 +1207,6 @@ namespace LuaPlayer
return 1;
}
/**
* Give the amount of levels specified to the [Player]
*
* @param uint8 levelAmt
*/
int GiveLevel(Eluna* /*E*/, lua_State* L, Player* player)
{
uint8 level = Eluna::CHECKVAL<uint8>(L, 2);
player->GiveLevel(level);
return 0;
}
int GetChatTag(Eluna* /*E*/, lua_State* L, Player* player)
{
Eluna::Push(L, player->GetChatTag());
@@ -2088,12 +2089,21 @@ namespace LuaPlayer
return 0;
}
/**
* Rewards the given quest entry for the [Player] if he has completed it.
*
* @param uint32 entry : quest entry
*/
int RewardQuest(Eluna* /*E*/, lua_State* L, Player* player)
{
uint32 entry = Eluna::CHECKVAL<uint32>(L, 2);
Quest const* quest = eObjectMgr->GetQuestTemplate(entry);
if (quest)
// If player doesn't have the quest
if (!quest || player->GetQuestStatus(entry) != QUEST_STATUS_COMPLETE)
return 0;
player->RewardQuest(quest, 0, player);
return 0;
}
@@ -2511,9 +2521,9 @@ namespace LuaPlayer
}
/**
* Forces a [Player]s [Quest] by entry ID to fail
* Sets the given quest entry failed for the [Player].
*
* @param uint32 entryId
* @param uint32 entry : quest entry
*/
int FailQuest(Eluna* /*E*/, lua_State* L, Player* player)
{
@@ -2524,9 +2534,9 @@ namespace LuaPlayer
}
/**
* Flags a [Player]s [Quest] by entry ID as incomplete
* Sets the given quest entry incomplete for the [Player].
*
* @param uint32 entryId
* @param uint32 entry : quest entry
*/
int IncompleteQuest(Eluna* /*E*/, lua_State* L, Player* player)
{
@@ -2537,18 +2547,229 @@ namespace LuaPlayer
}
/**
* Completes a [Player]s [Quest] by entry ID
* Completes the given quest entry for the [Player] and tries to satisfy all quest requirements.
*
* @param uint32 entryId
* The player should have the quest to complete it.
*
* @param uint32 entry : quest entry
*/
int CompleteQuest(Eluna* /*E*/, lua_State* L, Player* player)
{
uint32 entry = Eluna::CHECKVAL<uint32>(L, 2);
Quest const* quest = eObjectMgr->GetQuestTemplate(entry);
// If player doesn't have the quest
if (!quest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE)
return 0;
// Add quest items for quests that require items
for (uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x)
{
#ifdef TRINITY
uint32 id = quest->RequiredItemId[x];
uint32 count = quest->RequiredItemCount[x];
#else
uint32 id = quest->ReqItemId[x];
uint32 count = quest->ReqItemCount[x];
#endif
if (!id || !count)
continue;
uint32 curItemCount = player->GetItemCount(id, true);
ItemPosCountVec dest;
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, id, count - curItemCount);
if (msg == EQUIP_ERR_OK)
{
Item* item = player->StoreNewItem(dest, id, true);
player->SendNewItem(item, count - curItemCount, true, false);
}
}
// All creature/GO slain/cast (not required, but otherwise it will display "Creature slain 0/10")
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
#ifdef TRINITY
int32 creature = quest->RequiredNpcOrGo[i];
uint32 creatureCount = quest->RequiredNpcOrGoCount[i];
if (creature > 0)
{
if (CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature))
for (uint16 z = 0; z < creatureCount; ++z)
player->KilledMonster(creatureInfo, ObjectGuid::Empty);
}
else if (creature < 0)
for (uint16 z = 0; z < creatureCount; ++z)
player->KillCreditGO(creature);
#else
int32 creature = quest->ReqCreatureOrGOId[i];
uint32 creaturecount = quest->ReqCreatureOrGOCount[i];
if (uint32 spell_id = quest->ReqSpell[i])
{
for (uint16 z = 0; z < creaturecount; ++z)
player->CastedCreatureOrGO(creature, ObjectGuid(), spell_id);
}
else if (creature > 0)
{
if (CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(creature))
for (uint16 z = 0; z < creaturecount; ++z)
player->KilledMonster(cInfo, ObjectGuid());
}
else if (creature < 0)
{
for (uint16 z = 0; z < creaturecount; ++z)
player->CastedCreatureOrGO(-creature, ObjectGuid(), 0);
}
#endif
}
// If the quest requires reputation to complete
if (uint32 repFaction = quest->GetRepObjectiveFaction())
{
uint32 repValue = quest->GetRepObjectiveValue();
uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
if (curRep < repValue)
if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction))
player->GetReputationMgr().SetReputation(factionEntry, repValue);
}
#ifdef TRINITY
// If the quest requires a SECOND reputation to complete
if (uint32 repFaction = quest->GetRepObjectiveFaction2())
{
uint32 repValue2 = quest->GetRepObjectiveValue2();
uint32 curRep = player->GetReputationMgr().GetReputation(repFaction);
if (curRep < repValue2)
if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction))
player->GetReputationMgr().SetReputation(factionEntry, repValue2);
}
#endif
// If the quest requires money
int32 ReqOrRewMoney = quest->GetRewOrReqMoney();
if (ReqOrRewMoney < 0)
player->ModifyMoney(-ReqOrRewMoney);
#ifdef TRINITY
if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled
{
// prepare Quest Tracker datas
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_GM_COMPLETE);
stmt->setUInt32(0, quest->GetQuestId());
stmt->setUInt32(1, player->GetGUIDLow());
// add to Quest Tracker
CharacterDatabase.Execute(stmt);
}
#endif
player->CompleteQuest(entry);
return 0;
}
/**
* Tries to add the given quest entry for the [Player].
*
* @param uint32 entry : quest entry
*/
int AddQuest(Eluna* /*E*/, lua_State* L, Player* player)
{
uint32 entry = Eluna::CHECKVAL<uint32>(L, 2);
Quest const* quest = eObjectMgr->GetQuestTemplate(entry);
if (!quest)
return 0;
#ifdef TRINITY
// check item starting quest (it can work incorrectly if added without item in inventory)
ItemTemplateContainer const* itc = sObjectMgr->GetItemTemplateStore();
ItemTemplateContainer::const_iterator result = find_if(itc->begin(), itc->end(), Finder<uint32, ItemTemplate>(entry, &ItemTemplate::StartQuest));
if (result != itc->end())
return 0;
// ok, normal (creature/GO starting) quest
if (player->CanAddQuest(quest, true))
player->AddQuestAndCheckCompletion(quest, NULL);
#else
// check item starting quest (it can work incorrectly if added without item in inventory)
for (uint32 id = 0; id < sItemStorage.GetMaxEntry(); ++id)
{
ItemPrototype const* pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
if (!pProto)
continue;
if (pProto->StartQuest == entry)
return 0;
}
// ok, normal (creature/GO starting) quest
if (player->CanAddQuest(quest, true))
{
player->AddQuest(quest, NULL);
if (player->CanCompleteQuest(entry))
player->CompleteQuest(entry);
}
#endif
return 0;
}
/**
* Tries to add the given quest entry for the [Player].
*
* @param uint32 entry : quest entry
*/
int RemoveQuest(Eluna* /*E*/, lua_State* L, Player* player)
{
uint32 entry = Eluna::CHECKVAL<uint32>(L, 2);
Quest const* quest = eObjectMgr->GetQuestTemplate(entry);
if (!quest)
return 0;
// remove all quest entries for 'entry' from quest log
for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
{
uint32 logQuest = player->GetQuestSlotQuestId(slot);
if (logQuest == entry)
{
player->SetQuestSlot(slot, 0);
// we ignore unequippable quest items in this case, its' still be equipped
player->TakeQuestSourceItem(logQuest, false);
#ifdef TRINITY
if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
{
player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
player->UpdatePvPState();
}
#endif
}
}
#ifdef TRINITY
player->RemoveActiveQuest(entry, false);
player->RemoveRewardedQuest(entry);
#else
// set quest status to not started (will updated in DB at next save)
player->SetQuestStatus(entry, QUEST_STATUS_NONE);
// reset rewarded for restart repeatable quest
player->getQuestStatusMap()[entry].m_rewarded = false;
#endif
return 0;
}
int Whisper(Eluna* /*E*/, lua_State* L, Player* player)
{
std::string text = Eluna::CHECKVAL<std::string>(L, 2);

View File

@@ -1431,8 +1431,23 @@ namespace LuaUnit
*/
int SetLevel(Eluna* /*E*/, lua_State* L, Unit* unit)
{
uint8 newLevel = Eluna::CHECKVAL<uint8>(L, 2);
unit->SetLevel(newLevel);
uint8 newlevel = Eluna::CHECKVAL<uint8>(L, 2);
if (newlevel < 1)
return 0;
if (newlevel > STRONG_MAX_LEVEL)
newlevel = STRONG_MAX_LEVEL;
if (Player* player = unit->ToPlayer())
{
player->GiveLevel(newlevel);
player->InitTalentForLevel();
player->SetUInt32Value(PLAYER_XP, 0);
}
else
unit->SetLevel(newlevel);
return 0;
}