public void Start(MabiNPC target) { this.Target = target; }
/// <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); } }
public void Clear() { this.Target = null; this.State = null; this.Response = null; }
/// <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; }