// Copyright (c) CypherCore All rights reserved. // Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information. using Framework.Constants; using Game.AI; using Game.BattleFields; using Game.BattleGrounds; using Game.Chat; using Game.Conditions; using Game.DataStorage; using Game.Entities; using Game.Groups; using Game.Guilds; using Game.Maps; using Game.PvP; using Game.Spells; using System; using System.Collections.Generic; namespace Game.Scripting { public class ScriptObject { public ScriptObject(string name) { _name = name; } public string GetName() { return _name; } // Do not override this in scripts; it should be overridden by the various script type classes. It indicates // whether or not this script type must be assigned in the database. public virtual bool IsDatabaseBound() { return false; } public static T GetInstanceAI(WorldObject obj) where T : class { InstanceMap instance = obj.GetMap().ToInstanceMap(); if (instance != null && instance.GetInstanceScript() != null) return (T)Activator.CreateInstance(typeof(T), new object[] { obj }); return null; } public static void ClearGossipMenuFor(Player player) { player.PlayerTalkClass.ClearMenus(); } // Using provided text, not from DB public static void AddGossipItemFor(Player player, GossipOptionNpc optionNpc, string text, uint sender, uint action) { player.PlayerTalkClass.GetGossipMenu().AddMenuItem(0, -1, optionNpc, text, 0, GossipOptionFlags.None, null, 0, 0, false, 0, "", null, null, sender, action); } // Using provided texts, not from DB public static void AddGossipItemFor(Player player, GossipOptionNpc optionNpc, string text, uint sender, uint action, string popupText, ulong popupMoney, bool coded) { player.PlayerTalkClass.GetGossipMenu().AddMenuItem(0, -1, optionNpc, text, 0, GossipOptionFlags.None, null, 0, 0, coded, popupMoney, popupText, null, null, sender, action); } // Uses gossip item info from DB public static void AddGossipItemFor(Player player, uint gossipMenuID, uint gossipMenuItemID, uint sender, uint action) { player.PlayerTalkClass.GetGossipMenu().AddMenuItem(gossipMenuID, gossipMenuItemID, sender, action); } public static void SendGossipMenuFor(Player player, uint npcTextID, ObjectGuid guid) { player.PlayerTalkClass.SendGossipMenu(npcTextID, guid); } public static void SendGossipMenuFor(Player player, uint npcTextID, Creature creature) { if (creature != null) SendGossipMenuFor(player, npcTextID, creature.GetGUID()); } public static void CloseGossipMenuFor(Player player) { player.PlayerTalkClass.SendCloseGossip(); } string _name; } class GenericSpellScriptLoader : SpellScriptLoader where S : SpellScript { public GenericSpellScriptLoader(string name, object[] args) : base(name) { _args = args; } public override SpellScript GetSpellScript() { return (S)Activator.CreateInstance(typeof(S), _args); } object[] _args; } class GenericAuraScriptLoader : AuraScriptLoader where A : AuraScript { public GenericAuraScriptLoader(string name, object[] args) : base(name) { _args = args; } public override AuraScript GetAuraScript() { return (A)Activator.CreateInstance(typeof(A), _args); } object[] _args; } public class SpellScriptLoader : ScriptObject { public SpellScriptLoader(string name) : base(name) { Global.ScriptMgr.AddScript(this); } public override bool IsDatabaseBound() { return true; } // Should return a fully valid SpellScript. public virtual SpellScript GetSpellScript() { return null; } } public class AuraScriptLoader : ScriptObject { public AuraScriptLoader(string name) : base(name) { Global.ScriptMgr.AddScript(this); } public override bool IsDatabaseBound() { return true; } // Should return a fully valid AuraScript. public virtual AuraScript GetAuraScript() { return null; } } public class WorldScript : ScriptObject { protected WorldScript(string name) : base(name) { Global.ScriptMgr.AddScript(this); } // Called when the open/closed state of the world changes. public virtual void OnOpenStateChange(bool open) { } // Called after the world configuration is (re)loaded. public virtual void OnConfigLoad(bool reload) { } // Called before the message of the day is changed. public virtual void OnMotdChange(string newMotd) { } // Called when a world shutdown is initiated. public virtual void OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) { } // Called when a world shutdown is cancelled. public virtual void OnShutdownCancel() { } // Called on every world tick (don't execute too heavy code here). public virtual void OnUpdate(uint diff) { } // Called when the world is started. public virtual void OnStartup() { } // Called when the world is actually shut down. public virtual void OnShutdown() { } } public class FormulaScript : ScriptObject { public FormulaScript(string name) : base(name) { } // Called after calculating honor. public virtual void OnHonorCalculation(float honor, uint level, float multiplier) { } // Called after gray level calculation. public virtual void OnGrayLevelCalculation(uint grayLevel, uint playerLevel) { } // Called after calculating experience color. public virtual void OnColorCodeCalculation(XPColorChar color, uint playerLevel, uint mobLevel) { } // Called after calculating zero difference. public virtual void OnZeroDifferenceCalculation(uint diff, uint playerLevel) { } // Called after calculating base experience gain. public virtual void OnBaseGainCalculation(uint gain, uint playerLevel, uint mobLevel) { } // Called after calculating experience gain. public virtual void OnGainCalculation(uint gain, Player player, Unit unit) { } // Called when calculating the experience rate for group experience. public virtual void OnGroupRateCalculation(float rate, uint count, bool isRaid) { } } public class MapScript : ScriptObject where T : Map { public MapScript(string name, uint mapId) : base(name) { _mapEntry = CliDB.MapStorage.LookupByKey(mapId); if (_mapEntry == null) Log.outError(LogFilter.Scripts, "Invalid MapScript for {0}; no such map ID.", mapId); } // Gets the MapEntry structure associated with this script. Can return NULL. public MapRecord GetEntry() { return _mapEntry; } // Called when the map is created. public virtual void OnCreate(T map) { } // Called just before the map is destroyed. public virtual void OnDestroy(T map) { } // Called when a player enters the map. public virtual void OnPlayerEnter(T map, Player player) { } // Called when a player leaves the map. public virtual void OnPlayerLeave(T map, Player player) { } public virtual void OnUpdate(T obj, uint diff) { } MapRecord _mapEntry; } public class WorldMapScript : MapScript { public WorldMapScript(string name, uint mapId) : base(name, mapId) { if (GetEntry() != null && !GetEntry().IsWorldMap()) Log.outError(LogFilter.Scripts, "WorldMapScript for map {0} is invalid.", mapId); Global.ScriptMgr.AddScript(this); } } public class InstanceMapScript : MapScript { public InstanceMapScript(string name, uint mapId) : base(name, mapId) { if (GetEntry() != null && !GetEntry().IsDungeon()) Log.outError(LogFilter.Scripts, "InstanceMapScript for map {0} is invalid.", mapId); Global.ScriptMgr.AddScript(this); } public override bool IsDatabaseBound() { return true; } // Gets an InstanceScript object for this instance. public virtual InstanceScript GetInstanceScript(InstanceMap map) { return null; } } public class BattlegroundMapScript : MapScript { public BattlegroundMapScript(string name, uint mapId) : base(name, mapId) { if (GetEntry() != null && GetEntry().IsBattleground()) Log.outError(LogFilter.Scripts, "BattlegroundMapScript for map {0} is invalid.", mapId); Global.ScriptMgr.AddScript(this); } // Gets an BattlegroundScript object for this battleground. public virtual BattlegroundScript GetBattlegroundScript(BattlegroundMap map) { return null; } } public class GenericConversationScript