From e0192deaf634dc0caade841afef39e67a85505df Mon Sep 17 00:00:00 2001 From: NeatElves Date: Fri, 31 May 2013 10:25:13 +0100 Subject: [PATCH] [c12582] Add support for XP-Gain disabling --- doc/script_commands.txt | 58 ++++++++++++++++++++++++----------- src/game/ObjectMgr.cpp | 22 ++++++++++++++ src/game/ObjectMgr.h | 66 +++++++++++++++++++++------------------- src/game/Player.cpp | 3 ++ src/game/ScriptMgr.cpp | 14 +++++++++ src/game/ScriptMgr.h | 8 +++++ src/shared/revision_nr.h | 2 +- 7 files changed, 122 insertions(+), 51 deletions(-) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index a621ec8ce..75617d420 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -8,14 +8,15 @@ This file is part of the CMaNGOS Project. See AUTHORS file for Copyright informa ## id -- -------------------------- -creature_movement_scripts DB project self defined id -event_scripts Event id. Several sources: spell effect 61, taxi/transport nodes, gameobject_template data -gameobject_scripts Gameobject guid -gameobject_template_scripts Gameobject entry -gossip_scripts DB project self defined id -quest_end_scripts DB project self defined id (generally quest entry) -quest_start_scripts DB project self defined id (generally quest entry) -spell_scripts Spell id +dbscripts_on_creature_death Creature entry +dbscripts_on_creature_movement DB project self defined id +dbscripts_on_event Event id. Several sources: spell effect 61, taxi/transport nodes, gameobject_template data +dbscripts_on_go_use Gameobject guid +dbscripts_on_go_template_use Gameobject entry +dbscripts_on_gossip DB project self defined id +dbscripts_on_quest_end DB project self defined id (generally quest entry) +dbscripts_on_quest_start DB project self defined id (generally quest entry) +dbscripts_on_spell Spell id -- -------------------------- ## delay @@ -66,7 +67,8 @@ Detailed meaning described below! -- -------------------------- 4 multipurpose fields, store raw data as signed values -Note: currently used only for text ids +Note: currently used only for text ids SCRIPT_COMMAND_TALK (0), + and in relation with SCRIPT_COMMAND_TERMINATE_SCRIPT (31) -- -------------------------- ## x y z o @@ -78,10 +80,13 @@ Map coordinates for commands that need it. ## origin of script and source/target in scripts -- -------------------------- -creature_movement_scripts +dbscripts_on_creature_death + Creature death + Source: creature. Target: Unit (player/creature) +dbscripts_on_creature_movement `creature_movement` `creature_movement_template` Source: creature. Target: creature -event_scripts +dbscripts_on_event Flight path Source: player. Target: player Transport path @@ -90,21 +95,21 @@ event_scripts Source: User (player/creature). Target: GO Spell (effect 61) Source: caster. Target: Target -gameobject_scripts -gameobject_template_scripts +dbscripts_on_go_use +dbscripts_on_go_template_use Gameobject use Source: user: Target: GO -gossip_scripts - `gossip_menu_option` +dbscripts_on_gossip + `gossip_menu_option`, `gossip_menu` Source: creature. Target: player (in case of NPC-Gossip) Source: player. Target: GO (in case of GO-Gossip) -quest_end_scripts +dbscripts_on_quest_end `quest_template` Source: quest taker (creature/GO). Target: player -quest_start_scripts +dbscripts_on_quest_start `quest_template` Source: quest giver (creature/GO). Target: player -spell_scripts +dbscripts_on_spell Spell (effect 77 - SCRIPT_EFFECT) Spell (effect 3 - DUMMY) Spell (effect 64 - TRIGGER_SPELL, with non-existing triggered spell) @@ -234,6 +239,10 @@ Where "A -> B" means that the command is executed from A with B as target. TEMPFACTION_RESTORE_RESPAWN = 0x01, // Default faction will be restored at respawn TEMPFACTION_RESTORE_COMBAT_STOP = 0x02, // ... at CombatStop() (happens at creature death, at evade or custom scripte among others) TEMPFACTION_RESTORE_REACH_HOME = 0x04, // ... at reaching home in home movement (evade), if not already done at CombatStop() + // The next three allow to remove unit_flags combined with a faction change (also these flags will be reapplied when the faction is changed back) + TEMPFACTION_TOGGLE_NON_ATTACKABLE = 0x08, // Remove UNIT_FLAG_NON_ATTACKABLE(0x02) when faction is changed (reapply when temp-faction is removed) + TEMPFACTION_TOGGLE_OOC_NOT_ATTACK = 0x10, // Remove UNIT_FLAG_OOC_NOT_ATTACKABLE(0x100) when faction is changed (reapply when temp-faction is removed) + TEMPFACTION_TOGGLE_PASSIVE = 0x20, // Remove UNIT_FLAG_PASSIVE(0x200) 23 SCRIPT_COMMAND_MORPH_TO_ENTRY_OR_MODEL resultingSource = Creature * datalong=creature entry/modelid (depend on data_flags) OR 0 to demorph @@ -258,5 +267,18 @@ Where "A -> B" means that the command is executed from A with B as target. 29 SCRIPT_COMMAND_MODIFY_NPC_FLAGS resultingSource = Creature * datalong=NPCFlags * datalong2= 0x00=toggle, 0x01=add, 0x02=remove + 30 SCRIPT_COMMAND_SEND_TAXI_PATH resultingTarget or Source must be Player * datalong = taxi path id + +31 SCRIPT_COMMAND_TERMINATE_SCRIPT * datalong = search for npc entry if provided + * datalong2= search distance + * !(data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL): if npc not alive found, terminate script + data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL: if npc alive found, terminate script + * dataint = change of waittime (MILLIESECONDS) of a current waypoint movement type (negative values will decrease time) + +32 SCRIPT_COMMAND_PAUSE_WAYPOINTS resultingSource must be Creature + * datalong: 0/1 unpause/pause waypoint movement + +33 SCRIPT_COMMAND_XP_USER source or target with Player + * datalong=bool 0=off, 1=on diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index efea81411..1982c9f64 100755 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -8087,6 +8087,15 @@ bool PlayerCondition::Meets(Player const* player, Map const* map, WorldObject co } return false; } + case CONDITION_XP_USER: + { + switch (m_value1) + { + case 0: return player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_XP_USER_DISABLED); + case 1: return !player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_XP_USER_DISABLED); + } + return false; + } default: return false; } @@ -8486,6 +8495,19 @@ bool PlayerCondition::IsValid(uint16 entry, ConditionType condition, uint32 valu } break; } + case CONDITION_XP_USER: + { + if (value1 > 1) + { + sLog.outErrorDb("XP user condition (entry %u, type %u) has invalid argument %u (must be 0..1), skipped", entry, condition, value1); + return false; + } + + if (value2) + sLog.outErrorDb("XP user condition (entry %u, type %u) has useless data in value2 (%u)!", entry, condition, value2); + + break; + } case CONDITION_NONE: break; default: diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 73858f190..b4735a63f 100755 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -90,14 +90,17 @@ struct AreaTrigger float target_Orientation; // Operators - bool IsMinimal() const { return requiredLevel == 0 && requiredItem == 0 && requiredItem2 == 0 && heroicKey == 0 && - heroicKey2 == 0 && requiredQuest == 0 && requiredQuestHeroic == 0; } + bool IsMinimal() const + { + return requiredLevel == 0 && requiredItem == 0 && requiredItem2 == 0 && heroicKey == 0 && + heroicKey2 == 0 && requiredQuest == 0 && requiredQuestHeroic == 0; + } bool IsLessOrEqualThan(AreaTrigger const* l) const // Expected to have same map { MANGOS_ASSERT(target_mapId == l->target_mapId); return requiredLevel <= l->requiredLevel && requiredItem <= l->requiredItem && requiredItem2 <= l->requiredItem2 - && heroicKey <= l->heroicKey&& heroicKey2 <= l->heroicKey2 && requiredQuest <= l->requiredQuest && requiredQuestHeroic <= l->requiredQuestHeroic; + && heroicKey <= l->heroicKey && heroicKey2 <= l->heroicKey2 && requiredQuest <= l->requiredQuest && requiredQuestHeroic <= l->requiredQuestHeroic; } }; @@ -119,6 +122,8 @@ typedef UNORDERED_MAP < uint32/*(mapid,spawnMode) pair*/, CellObjectGuidsMap > M #define MIN_CREATURE_AI_TEXT_STRING_ID (-1) // 'creature_ai_texts' #define MAX_CREATURE_AI_TEXT_STRING_ID (-1000000) +static_assert(MAX_DB_SCRIPT_STRING_ID < ACE_INT32_MAX, "Must scope with int32 range"); + struct MangosStringLocale { std::vector Content; // 0 -> default, i -> i-1 locale index @@ -264,9 +269,6 @@ struct GossipMenuItems bool box_coded; uint32 box_money; std::string box_text; - uint16 cond_1; - uint16 cond_2; - uint16 cond_3; uint16 conditionId; }; @@ -275,8 +277,6 @@ struct GossipMenus uint32 entry; uint32 text_id; uint32 script_id; - uint16 cond_1; - uint16 cond_2; uint16 conditionId; }; @@ -359,7 +359,7 @@ typedef std::pair Gr enum ConditionType { - // value1 value2 for the Condition enumed + // // value1 value2 for the Condition enumed CONDITION_NOT = -3, // cond-id-1 0 returns !cond-id-1 CONDITION_OR = -2, // cond-id-1 cond-id-2 returns cond-id-1 OR cond-id-2 CONDITION_AND = -1, // cond-id-1 cond-id-2 returns cond-id-1 AND cond-id-2 @@ -381,7 +381,7 @@ enum ConditionType CONDITION_LEVEL = 15, // player_level 0, 1 or 2 (0: equal to, 1: equal or higher than, 2: equal or less than) CONDITION_NOITEM = 16, // item_id count check not present req. amount items in inventory 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_INSTANCE_SCRIPT = 18, // instance_condition_id (instance script specific enum) 0 CONDITION_QUESTAVAILABLE = 19, // quest_id 0 for case when loot/gossip possible only if player can start quest CONDITION_ACHIEVEMENT = 20, // ach_id 0, 1 (0: has achievement, 1: hasn't achievement) for player CONDITION_ACHIEVEMENT_REALM = 21, // ach_id 0, 1 (0: has achievement, 1: hasn't achievement) for server @@ -400,6 +400,21 @@ enum ConditionType // If skill_value == 1, then true if player has not skill skill_id CONDITION_REPUTATION_RANK_MAX = 30, // faction_id max_rank CONDITION_COMPLETED_ENCOUNTER = 31, // encounter_id encounter_id2 encounter_id[2] = DungeonEncounter(dbc).id (if value2 provided it will return value1 OR value2) + CONDITION_SOURCE_AURA = 32, // spell_id effindex (returns true if the source of the condition check has aura of spell_id, effIndex) + CONDITION_LAST_WAYPOINT = 33, // waypointId 0 = exact, 1: wp <= waypointId, 2: wp > waypointId Use to check what waypoint was last reached + CONDITION_XP_USER = 34, // 0, 1 (0: XP off, 1: XP on) for player 0 + +}; + +enum ConditionSource // From where was the condition called? +{ + CONDITION_FROM_LOOT = 0, // Used to check a *_loot_template entry + CONDITION_FROM_REFERING_LOOT = 1, // Used to check a entry refering to a reference_loot_template entry + CONDITION_FROM_GOSSIP_MENU = 2, // Used to check a gossip menu menu-text + CONDITION_FROM_GOSSIP_OPTION = 3, // Used to check a gossip menu option-item + CONDITION_FROM_EVENTAI = 4, // Used to check EventAI Event "On Receive Emote" + CONDITION_FROM_HARDCODED = 5, // Used to check a hardcoded event - not actually a condition + CONDITION_FROM_VENDOR = 6, // Used to check a condition from a vendor }; class PlayerCondition @@ -415,15 +430,13 @@ class PlayerCondition bool IsValid() const { return IsValid(m_entry, m_condition, m_value1, m_value2); } static bool IsValid(uint16 entry, ConditionType condition, uint32 value1, uint32 value2); - bool Meets(Player const* pPlayer) const; // Checks if the player meets the condition + static bool CanBeUsedWithoutPlayer(uint16 entry); - // TODO: old system, remove soon! - bool operator == (PlayerCondition const& lc) const - { - return (lc.m_condition == m_condition && lc.m_value1 == m_value1 && lc.m_value2 == m_value2); - } + // Checks if the player meets the condition + bool Meets(Player const* pPlayer, Map const* map, WorldObject const* source, ConditionSource conditionSourceType) const; private: + bool CheckParamRequirements(Player const* pPlayer, Map const* map, WorldObject const* source, ConditionSource conditionSourceType) const; uint16 m_entry; // entry of the condition ConditionType m_condition; // additional condition type uint32 m_value1; // data for the condition - see ConditionType definition @@ -731,6 +744,7 @@ class ObjectMgr void LoadNPCSpellClickSpells(); void LoadSpellTemplate(); + void LoadCreatureTemplateSpells(); void LoadWeatherZoneChances(); void LoadGameTele(); @@ -744,6 +758,8 @@ class ObjectMgr void LoadTrainerTemplates(); void LoadTrainers() { LoadTrainers("npc_trainer", false); } + void LoadVehicleAccessory(); + std::string GeneratePetName(uint32 entry); uint32 GetBaseXP(uint32 level) const; uint32 GetXPForLevel(uint32 level) const; @@ -958,18 +974,8 @@ class ObjectMgr int GetIndexForLocale(LocaleConstant loc); LocaleConstant GetLocaleForIndex(int i); - // TODO: Outdated version, rename NEW and remove soon - uint16 GetConditionId(ConditionType condition, uint32 value1, uint32 value2); - bool IsPlayerMeetToCondition(Player const* player, uint16 condition_id) const - { - if (condition_id >= mConditions.size()) - return false; - - return mConditions[condition_id].Meets(player); - } - // Check if a player meets condition conditionId - bool IsPlayerMeetToNEWCondition(Player const* pPlayer, uint16 conditionId) const; + bool IsPlayerMeetToCondition(uint16 conditionId, Player const* pPlayer, Map const* map, WorldObject const* source, ConditionSource conditionSourceType) const; GameTele const* GetGameTele(uint32 id) const { @@ -1030,7 +1036,7 @@ class ObjectMgr void AddVendorItem(uint32 entry, uint32 item, uint8 type, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost); bool RemoveVendorItem(uint32 entry, uint32 item, uint8 type); - bool IsVendorItemValid(bool isTemplate, char const* tableName, uint32 vendor_entry, uint32 item, uint8 type, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set* skip_vendors = NULL) const; + bool IsVendorItemValid(bool isTemplate, char const* tableName, uint32 vendor_entry, uint32 item, uint8 type, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, uint16 conditionId, Player* pl = NULL, std::set* skip_vendors = NULL) const; int GetOrNewIndexForLocale(LocaleConstant loc); @@ -1232,10 +1238,6 @@ class ObjectMgr PointOfInterestLocaleMap mPointOfInterestLocaleMap; DungeonEncounterMap m_DungeonEncounters; - // Storage for Conditions. First element (index 0) is reserved for zero-condition (nothing required) - typedef std::vector ConditionStore; - ConditionStore mConditions; - CreatureModelRaceMap m_mCreatureModelRaceMap; CacheNpcTextIdMap m_mCacheNpcTextIdMap; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 98da4f32d..f8cddaf04 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2544,6 +2544,9 @@ void Player::GiveXP(uint32 xp, Unit* victim) if (!isAlive()) return; + if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_XP_USER_DISABLED)) + return; + uint32 level = getLevel(); // XP to money conversion processed in Player::RewardQuest diff --git a/src/game/ScriptMgr.cpp b/src/game/ScriptMgr.cpp index 05201c06a..0f3969ae2 100644 --- a/src/game/ScriptMgr.cpp +++ b/src/game/ScriptMgr.cpp @@ -643,6 +643,8 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename) } case SCRIPT_COMMAND_PAUSE_WAYPOINTS: // 32 break; + case SCRIPT_COMMAND_XP_USER: // 33 + break; default: { sLog.outErrorDb("Table `%s` unknown command %u, skipping.", tablename, tmp.command); @@ -1690,6 +1692,18 @@ bool ScriptAction::HandleScriptStep() ((Creature*)pSource)->clearUnitState(UNIT_STAT_WAYPOINT_PAUSED); break; } + case SCRIPT_COMMAND_XP_USER: // 33 + { + Player* pPlayer = GetPlayerTargetOrSourceAndLog(pSource, pTarget); + if (!pPlayer) + break; + + if (m_script->xpDisabled.flags) + pPlayer->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_XP_USER_DISABLED); + else + pPlayer->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_XP_USER_DISABLED); + break; + } default: sLog.outError(" DB-SCRIPTS: Process table `%s` id %u, command %u unknown command used.", m_table, m_script->id, m_script->command); break; diff --git a/src/game/ScriptMgr.h b/src/game/ScriptMgr.h index f50d80c30..1ff9dc2a7 100644 --- a/src/game/ScriptMgr.h +++ b/src/game/ScriptMgr.h @@ -98,6 +98,8 @@ enum ScriptCommand // resSource, resTar // dataint=diff to change a waittime of current Waypoint Movement SCRIPT_COMMAND_PAUSE_WAYPOINTS = 32, // resSource = Creature // datalong = 0: unpause waypoint 1: pause waypoint + SCRIPT_COMMAND_XP_USER = 33, // source or target with Player, datalong = bool (0=off, 1=on) + }; #define MAX_TEXT_ID 4 // used for SCRIPT_COMMAND_TALK @@ -313,6 +315,12 @@ struct ScriptInfo uint32 empty; } pauseWaypoint; + struct // SCRIPT_COMMAND_XP_USER (33) + { + uint32 flags; // datalong + uint32 empty; // datalong2 + } xpDisabled; + struct { uint32 data[2]; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9671ac32e..e43e977d3 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "12581" + #define REVISION_NR "12582" #endif // __REVISION_NR_H__