示例#1
0
 public void Start(MabiNPC target)
 {
     this.Target = target;
 }
示例#2
0
        /// <summary>
        /// Loads the script file at the given path and adds the NPC to the world.
        /// </summary>
        /// <param name="path"></param>
        private void LoadScript(string scriptPath, bool virtualLoadFile = false)
        {
            try
            {
                var fileName = Path.GetFileName(scriptPath);
                if (fileName.StartsWith("_"))
                    virtualLoadFile = true;

                var cleanScriptPath = scriptPath.Trim('.', '/').Replace("\\", "/");

                // Load assembly and loop through the defined classes.
                var scriptAsm = this.GetScript(scriptPath);
                if (scriptAsm == null)
                    return;

                var types = scriptAsm.GetTypes().Where(t => t.IsSubclassOf(typeof(BaseScript)));
                foreach (var type in types)
                {
                    if (type.IsAbstract)
                        continue;

                    var sType = type.ToString();

                    // Skip stuff generated by the compiler.
                    if (sType.Contains("+") || sType.Contains("<"))
                        continue;

                    var virtualLoadType = false;
                    if (sType.StartsWith("_"))
                        virtualLoadType = true;

                    // Create object from loaded assembly.
                    //var scriptObj = scriptAsm.CreateObject(sType);
                    var scriptObj = Activator.CreateInstance(type);

                    // Check if the object is derived from NPCScript. Needed to
                    // allow simpler scripts that only derive from BaseScript.
                    if (scriptObj is NPCScript)
                    {
                        var script = scriptObj as NPCScript;
                        script.ScriptPath = scriptPath;
                        script.ScriptName = fileName;
                        if (!virtualLoadFile && !virtualLoadType)
                        {
                            // New NPC with some defaults, so we don't crash if
                            // somebody forgot something.
                            var npc = new MabiNPC();
                            npc.Name = "_undefined";
                            npc.Race = 190140;

                            npc.Script = script;
                            npc.ScriptPath = cleanScriptPath;
                            script.ScriptName = Path.GetFileName(scriptPath);
                            script.NPC = npc;
                            script.LoadType = NPCLoadType.Real;
                            script.OnLoad();
                            script.OnLoadDone();

                            // Only load defaults if race is set.
                            if (npc.Race != 0 && npc.Race != uint.MaxValue)
                                npc.LoadDefault();

                            WorldManager.Instance.AddCreature(npc);
                        }
                        //else
                        //{
                        //    script.LoadType = NPCLoadType.Virtual;
                        //}
                    }
                    else if (scriptObj is QuestScript)
                    {
                        var script = scriptObj as QuestScript;
                        script.ScriptPath = cleanScriptPath;
                        script.ScriptName = Path.GetFileName(scriptPath);
                        script.OnLoad();
                        script.OnLoadDone();

                        if (MabiData.QuestDb.Entries.ContainsKey(script.Info.Id))
                            Logger.Warning("Double quest id '{0}', overwriting from '{1}'.", script.Info.Id, cleanScriptPath);

                        MabiData.QuestDb.Entries[script.Id] = script.Info;
                        _questScripts[script.Id] = script;
                    }
                    else if (scriptObj is BaseScript)
                    {
                        // Script that doesn't use an NPC or anything, like prop scripts and stuff.

                        var script = scriptObj as BaseScript;
                        script.ScriptPath = cleanScriptPath;
                        script.ScriptName = Path.GetFileName(scriptPath);

                        script.OnLoad();
                        script.OnLoadDone();
                    }
                    else
                    {
                        // Type doesn't derive from NPCScript or BaseScript,
                        // probably a custom class. Ignore.
                        //Logger.Warning("Unknown script class: " + sType);
                    }
                }

                Interlocked.Increment(ref _loadedScripts);
            }
            catch (Exception ex)
            {
                try
                {
                    File.Delete(this.GetCompiledPath(scriptPath));
                }
                catch { }
                try
                {
                    // "Touch" the file, to mark it for recompilation
                    // (due to type load errors with inherited scripts)
                    new FileInfo(scriptPath).LastWriteTime = DateTime.Now;
                }
                catch { }

                scriptPath = scriptPath.Replace(WorldConf.ScriptPath, "").Replace('\\', '/').TrimStart('/');

                Logger.Error("While loading '{0}': {1}\n{2}", scriptPath, ex.Message, ex.StackTrace);
            }
        }
示例#3
0
 public void Clear()
 {
     this.Target = null;
     this.State = null;
     this.Response = null;
 }
示例#4
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="info"></param>
        /// <param name="amount">SpawnInfo.Amount used if 0. Needed for respawning.</param>
        /// <param name="effect"></param>
        /// <returns>Amount of creatures spawned</returns>
        public int Spawn(SpawnInfo info, uint amount = 0, bool effect = false)
        {
            var result = 0;

            var rand = RandomProvider.Get();

            var raceInfo = MabiData.RaceDb.Find(info.RaceId);
            if (raceInfo == null)
            {
                Logger.Warning("Race not found: " + info.RaceId.ToString());
                return 0;
            }

            string aiFilePath = null;
            if (!string.IsNullOrEmpty(raceInfo.AI))
            {
                aiFilePath = Path.Combine(WorldConf.ScriptPath, "ai", raceInfo.AI + ".cs");
                if (!File.Exists(aiFilePath))
                {
                    Logger.Warning("AI script '" + raceInfo.AI + ".cs' couldn't be found.");
                    aiFilePath = null;
                }
            }

            if (amount == 0)
                amount = info.Amount;

            for (int i = 0; i < amount; ++i)
            {
                var monster = new MabiNPC();
                monster.SpawnId = info.Id;
                monster.Name = raceInfo.Name;
                var loc = info.GetRandomSpawnPoint(rand);
                monster.SetLocation(info.Region, loc.X, loc.Y);
                monster.AnchorPoint = new MabiVertex(loc.X, loc.Y);
                monster.Color1 = raceInfo.ColorA;
                monster.Color2 = raceInfo.ColorB;
                monster.Color3 = raceInfo.ColorC;
                monster.Height = raceInfo.Size;
                monster.LifeMaxBase = raceInfo.Life;
                monster.Life = raceInfo.Life;
                monster.Race = raceInfo.Id;
                monster.BattleExp = raceInfo.Exp;
                monster.Direction = (byte)rand.Next(256);
                monster.State &= ~CreatureStates.GoodNpc; // Use race default?
                monster.GoldMin = raceInfo.GoldMin;
                monster.GoldMax = raceInfo.GoldMax;
                monster.Drops = raceInfo.Drops;

                foreach (var skill in raceInfo.Skills)
                {
                    monster.Skills.Add(new MabiSkill(skill.SkillId, skill.Rank, monster.Race));
                }

                monster.LoadDefault();

                // Missing stat data?
                if (monster.Life < 1)
                    monster.Life = monster.LifeMaxBase = 10;

                try
                {
                    if (aiFilePath != null)
                    {
                        var aiscriptAsm = this.GetScript(aiFilePath);
                        if (aiscriptAsm != null)
                        {
                            var types = aiscriptAsm.GetTypes().Where(t => t.IsSubclassOf(typeof(AIScript)));
                            monster.AIScript = Activator.CreateInstance(types.First()) as AIScript;
                            monster.AIScript.Creature = monster;
                            monster.AIScript.OnLoad();
                            monster.AIScript.Activate(0); // AI is intially active
                        }
                        else
                        {
                            raceInfo.AI = null; // Suppress future attempts to load this AI
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.Exception(ex);
                }

                monster.AncientEligible = true;
                monster.AncientTime = DateTime.Now.AddMinutes(WorldConf.TimeBeforeAncient);

                WorldManager.Instance.AddCreature(monster);

                if (effect)
                    WorldManager.Instance.Broadcast(PacketCreator.SpawnEffect(monster, SpawnEffect.Monster), SendTargets.Range, monster);

                result++;
            }

            return result;
        }