/// <summary> /// Starts a new session and calls Gift. /// </summary> /// <param name="target"></param> /// <param name="creature"></param> /// <param name="gift"></param> public void StartGift(NPC target, Creature creature, Item gift) { if (!this.Start(target, creature)) return; this.Script.GiftAsync(gift); }
/// <summary> /// Starts a new session and calls Talk. /// </summary> /// <param name="target"></param> /// <param name="creature"></param> public void StartTalk(NPC target, Creature creature) { if (!this.Start(target, creature)) return; this.Script.TalkAsync(); }
/// <summary> /// Cancels script and resets session. /// </summary> public void Clear() { this.Script.Cancel(); this.Script = null; this.Target = null; this.Response = null; }
/// <summary> /// Adds creature as actor. /// </summary> /// <remarks> /// Officials apparently create copies of the creatures, getting rid /// of the name (replaced by the actor name), stand styles, etc. /// </remarks> /// <param name="name"></param> /// <param name="creature"></param> public void AddActor(string name, Creature creature) { if (creature == null) { creature = new NPC(); creature.Name = name; } this.Actors[name] = creature; }
/// <summary> /// Starts session /// </summary> /// <param name="target"></param> /// <param name="creature"></param> private bool Start(NPC target, Creature creature) { this.Target = target; if (target.ScriptType == null) return false; var script = Activator.CreateInstance(target.ScriptType) as NpcScript; script.NPC = target; script.Player = creature; this.Script = script; return true; }
/// <summary> /// Creates cutscene and fills actor list as specified in the data. /// </summary> /// <param name="name"></param> /// <param name="creature"></param> /// <returns></returns> public static Cutscene FromData(string name, Creature creature) { var result = new Cutscene(name, creature); var partyMembers = creature.Party.GetSortedMembers(); var dummy = new NPC(); foreach (var actorName in result.Data.Actors) { Creature actor = null; // Retrieve actor if (actorName.StartsWith("#")) { var actorData = AuraData.ActorDb.Find(actorName); if (actorData == null) Log.Warning("Unknown actor '{0}'.", actorName); else actor = new NPC(actorData); } else if (actorName == "me") { actor = creature; } else if (actorName == "leader") { actor = creature.Party.Leader; } else if (actorName.StartsWith("player")) { int idx; if (!int.TryParse(actorName.Substring("player".Length), out idx)) Log.Warning("Cutscene.FromData: Invalid party member actor name '{0}'.", actorName); else if (idx > partyMembers.Length - 1) Log.Warning("Cutscene.FromData: Index out of party member range '{0}/{1}'.", idx, partyMembers.Length); else actor = partyMembers[idx]; } else Log.Warning("Cutscene.FromData: Unknown kind of actor ({0}).", actorName); if (actor == null) actor = dummy; result.AddActor(actorName, actor); } return result; }
/// <summary> /// Creates monsters from group data and adds them to internal list. /// </summary> /// <param name="groupData"></param> public void Allocate(DungeonMonsterGroupData groupData) { foreach (var monsterData in groupData) { for (int i = 0; i < monsterData.Amount; ++i) { var monster = new NPC(monsterData.RaceId); monster.State |= CreatureStates.Spawned | CreatureStates.InstantNpc; monster.Death += this.OnDeath; _monsters.Add(monster); } } _remaining = this.Count; this.Puzzle.Script.OnMobAllocated(this.Puzzle, this); }
/// <summary> /// Adds new creature of race as actor. /// </summary> /// <param name="name"></param> /// <param name="raceId"></param> public void AddActor(string name, int raceId) { var creature = new NPC(raceId); this.Actors[name] = creature; }
/// <summary> /// Returns thread-safe list of visible tabs, or all tabs if one of /// the parameters is null. /// </summary> /// <remarks> /// TODO: This could be cached. /// </remarks> /// <param name="creature">Creature opening the shop</param> /// <param name="owner">NPC owning the shop</param> /// <returns></returns> protected IList<NpcShopTab> GetTabs(Creature creature, NPC owner) { lock (_tabs) return creature == null || owner == null ? _tabs.Values.ToList() : _tabs.Values.Where(t => t.ShouldDisplay(creature, owner)).ToList(); }
/// <summary> /// Sends OpenNpcShop for creature and this shop. /// </summary> /// <param name="creature">Creature opening the shop</param> /// <param name="owner">NPC owning the shop</param> public void OpenFor(Creature creature, NPC owner) { // Shops without tabs are weird. if (_tabs.Count == 0) this.Add("Empty"); creature.Temp.CurrentShop = this; Send.OpenNpcShop(creature, this.GetTabs(creature, owner)); }
/// <summary> /// Loads actors from the cutscene's data. /// </summary> public void LoadActorsFromData() { var leader = this.Leader; foreach (var cutsceneActorData in this.Data.Actors) { Creature actor = null; var actorName = cutsceneActorData.Name; var defaultActorName = cutsceneActorData.Default; // Retrieve actor if (actorName.StartsWith("#")) { var actorData = AuraData.ActorDb.Find(actorName); if (actorData == null) Log.Warning("Cutscene.FromData: Unknown actor '{0}'.", actorData); else actor = new NPC(actorData); } else if (actorName == "me") { actor = leader; } else if (actorName == "leader") { actor = _viewers[0]; } else if (actorName.StartsWith("player")) { int idx; if (!int.TryParse(actorName.Substring("player".Length), out idx)) { Log.Warning("Cutscene.FromData: Invalid party member actor name '{0}'.", actorName); } else if (idx > _viewers.Length - 1) { if (!string.IsNullOrWhiteSpace(defaultActorName)) { var actorData = AuraData.ActorDb.Find(defaultActorName); if (actorData == null) Log.Warning("Cutscene.FromData: Unknown default actor '{0}'.", defaultActorName); else actor = new NPC(actorData); } else Log.Warning("Cutscene.FromData: Index out of party member range '{0}/{1}'.", idx, _viewers.Length); } else { actor = _viewers[idx]; } } else { Log.Warning("Cutscene.FromData: Unknown kind of actor ({0}).", actorName); } if (actor == null) { var dummy = new NPC(); actor = dummy; } this.AddActor(actorName, actor); } }
/// <summary> /// Adds new creature of race as actor. /// </summary> /// <param name="name"></param> /// <param name="creature"></param> public void AddActor(string name, int raceId) { var creature = new NPC(); creature.Race = raceId; creature.LoadDefault(); creature.Name = creature.RaceData.Name; creature.Color1 = creature.RaceData.Color1; creature.Color2 = creature.RaceData.Color2; creature.Color3 = creature.RaceData.Color3; creature.Height = creature.RaceData.Size; this.Actors[name] = creature; }
/// <summary> /// Spawns a creature. /// </summary> /// <param name="raceId"></param> /// <param name="regionId"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="spawnId"></param> /// <param name="active"></param> /// <param name="effect"></param> /// <returns></returns> public NPC Spawn(int raceId, int regionId, int x, int y, bool active, bool effect) { // Create NPC var npc = new NPC(raceId); // Warp to spawn point if (!npc.Warp(regionId, x, y)) { Log.Error("Failed to spawn '{0}'s, region '{1}' doesn't exist.", raceId, regionId); return null; } // Save spawn location npc.SpawnLocation = new Location(regionId, x, y); // Activate AI at least once if (npc.AI != null && active) npc.AI.Activate(0); // Spawn effect if (effect) Send.SpawnEffect(SpawnEffect.Monster, npc.RegionId, x, y, npc, npc); return npc; }
/// <summary> /// Spawns one creature based on this spawners settings. /// </summary> /// <returns></returns> private void SpawnOne() { // Create NPC var creature = new NPC(this.RaceId); // Warp to spawn point var pos = this.GetRandomPosition(); if (!creature.Warp(this.RegionId, pos.X, pos.Y)) { Log.Error("CreatureSpawner: Failed to spawn '{0}'s, region '{1}' doesn't exist.", this.RaceId, this.RegionId); return; } // Save spawn location creature.SpawnLocation = new Location(this.RegionId, pos.X, pos.Y); // Random title if (_titles != null && _titles.Length != 0) { var title = (ushort)(_titles[RandomProvider.Get().Next(_titles.Length)]); if (title != 0) { creature.Titles.Enable(title); creature.Titles.ChangeTitle(title, false); } } // Maintenance creature.SpawnId = this.Id; creature.Disappears += this.OnDisappears; // Add to list to keep track of all creatures lock (_creatures) _creatures.Add(creature); }
/// <summary> /// Starts session /// </summary> /// <param name="target"></param> public void Start(NPC target, Creature creature) { this.Target = target; if (target.AI == null) return; var script = Activator.CreateInstance(target.Script.GetType()) as NpcScript; script.NPC = target.Script.NPC; script.Player = creature; this.Script = script; this.Script.TalkAsync(); }
/// <summary> /// Adds boss to list of bosses to spawn. /// </summary> /// <param name="raceId"></param> /// <param name="amount"></param> public void AddBoss(int raceId, int amount = 1) { var rnd = RandomProvider.Get(); var end = this.Generator.Floors.Last().MazeGenerator.EndPos; var endX = end.X * TileSize + TileSize / 2; var endY = end.Y * TileSize + TileSize / 2; var regionId = this.Regions.Last().Id; for (int i = 0; i < amount; ++i) { var pos = new Position(endX, endY + TileSize / 2); pos = pos.GetRandomInRange(TileSize / 2, rnd); var npc = new NPC(raceId); npc.Death += this.OnBossDeath; npc.Spawn(regionId, pos.X, pos.Y); Send.SpawnEffect(SpawnEffect.Monster, regionId, pos.X, pos.Y, npc, npc); if (npc.AI != null) npc.AI.Activate(0); } Interlocked.Add(ref _bossesRemaining, amount); }
/// <summary> /// Spawns a creature. /// </summary> /// <param name="raceId"></param> /// <param name="regionId"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="spawnId"></param> /// <returns></returns> public Creature Spawn(int raceId, int regionId, int x, int y, int spawnId, bool active, bool effect) { // Create NPC var creature = new NPC(); creature.Race = raceId; creature.LoadDefault(); creature.SpawnId = spawnId; creature.Name = creature.RaceData.Name; creature.Color1 = creature.RaceData.Color1; creature.Color2 = creature.RaceData.Color2; creature.Color3 = creature.RaceData.Color3; creature.Height = creature.RaceData.Size; creature.Life = creature.LifeMaxBase = creature.RaceData.Life; creature.State = (CreatureStates)creature.RaceData.DefaultState; creature.Direction = (byte)RandomProvider.Get().Next(256); // Set drops creature.Drops.GoldMin = creature.RaceData.GoldMin; creature.Drops.GoldMax = creature.RaceData.GoldMax; creature.Drops.Add(creature.RaceData.Drops); // Give skills foreach (var skill in creature.RaceData.Skills) creature.Skills.Add((SkillId)skill.SkillId, (SkillRank)skill.Rank, creature.Race); // Set AI if (!string.IsNullOrWhiteSpace(creature.RaceData.AI) && creature.RaceData.AI != "none") { creature.AI = this.GetAi(creature.RaceData.AI, creature); if (creature.AI == null) Log.Warning("Spawn: Missing AI '{0}' for '{1}'.", creature.RaceData.AI, raceId); } // Warp to spawn point if (!creature.Warp(regionId, x, y)) { Log.Error("Failed to spawn '{0}'s.", raceId); return null; } // Activate AI at least once if (creature.AI != null && active) creature.AI.Activate(0); // Spawn effect if (effect) Send.SpawnEffect(SpawnEffect.Monster, creature.RegionId, x, y, creature, creature); return creature; }