/// <summary> /// Creates new floor region. /// </summary> /// <param name="regionId"></param> /// <param name="dungeon"></param> /// <param name="floorId"></param> public DungeonFloorRegion(int regionId, Dungeon dungeon, int floorId) : base(regionId, dungeon) { this.FloorId = floorId; this.Floor = dungeon.Generator.Floors[floorId]; this.GenerateAreas(); }
/// <summary> /// Sends DungeonInfo to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="dungeon"></param> public static void DungeonInfo(Creature creature, Dungeon dungeon) { var packet = new Packet(Op.DungeonInfo, MabiId.Broadcast); packet.PutLong(creature.EntityId); packet.PutLong(dungeon.InstanceId); packet.PutByte(1); packet.PutString(dungeon.Name); packet.PutInt(dungeon.ItemId); packet.PutInt(dungeon.Seed); packet.PutInt(dungeon.FloorPlan); packet.PutInt(dungeon.Regions.Count); foreach (var floor in dungeon.Regions) packet.PutInt(floor.Id); packet.PutString(dungeon.Options.ToString()); packet.PutInt(dungeon.Generator.Floors.Count); foreach (var floor in dungeon.Generator.Floors) { var rooms = floor.GetRooms(); packet.PutInt(rooms.Count); foreach (var room in rooms) { packet.PutByte((byte)room.X); packet.PutByte((byte)room.Y); } } packet.PutInt(0); // ? look at ciar info packet.PutInt(dungeon.Generator.Floors.Count); foreach (var floor in dungeon.Generator.Floors) { packet.PutUInt(0); // Floor seed or 0 apparently packet.PutInt(0); // Somethin. } creature.Client.Send(packet); }
/// <summary> /// Creates new lobby region. /// </summary> /// <param name="regionId"></param> /// <param name="baseRegionId"></param> /// <param name="dungeon"></param> public DungeonLobbyRegion(int regionId, int baseRegionId, Dungeon dungeon) : base(regionId, dungeon) { var baseRegionInfoData = AuraData.RegionInfoDb.Find(baseRegionId); if (baseRegionInfoData == null) throw new Exception("DungeonLobbyRegion: No region info data found for '" + baseRegionId + "'."); this.Data = baseRegionInfoData.Copy(); FixIds(this.Data, this.Id); this.InitializeFromData(); }
/// <summary> /// Called when a player leaves a dungeon via the first statue, /// logging out, or similar. /// </summary> /// <param name="dungeon"></param> /// <param name="creature"></param> public virtual void OnLeftEarly(Dungeon dungeon, Creature creature) { }
/// <summary> /// Called when the boss was killed. /// </summary> /// <param name="dungeon"></param> public virtual void OnCleared(Dungeon dungeon) { }
/// <summary> /// Called when one of the boss monsters dies. /// </summary> /// <param name="dungeon"></param> /// <param name="deadBoss"></param> /// <param name="killer"></param> public virtual void OnBossDeath(Dungeon dungeon, Creature deadBoss, Creature killer) { }
/// <summary> /// Called when the boss door opens. /// </summary> /// <param name="dungeon"></param> public virtual void OnBoss(Dungeon dungeon) { }
/// <summary> /// Called when the dungeon was just created. /// </summary> public virtual void OnCreation(Dungeon dungeon) { }
/// <summary> /// Generates instance id and creates dungeon. /// </summary> /// <param name="dungeonName"></param> /// <param name="itemId"></param> /// <param name="creature"></param> /// <returns></returns> private Dungeon CreateDungeon(string dungeonName, int itemId, Creature creature) { Dungeon dungeon; long instanceId = 0; var rnd = RandomProvider.Get(); var itemData = AuraData.ItemDb.Find(itemId); // Create new dungeon for passes (includes quest items). // Since some "passes" don't have the dungeon_pass tag, but do // have quest_item, and quest items are generally supposed to // go to an NPC or onto an altar, we'll assume those are passes // as well. // If this assumption turnes out to be incorrect, we have to // check for some items specifically, like the Goddess Pass in G1. if (itemData != null && itemData.HasTag("/dungeon_pass/|/quest_item/")) { instanceId = this.GetInstanceId(); dungeon = new Dungeon(instanceId, dungeonName, itemId, rnd.Next(), rnd.Next(), creature); } else { // Create new dungeon if there's not one yet var existing = this.Get(a => a.Name == dungeonName && a.ItemId == itemId); if (existing == null || ChannelServer.Instance.Conf.World.PrivateDungeons) { // Random floor plan on Tuesday var day = ErinnTime.Now.Month; var floorPlan = (day == 2 || ChannelServer.Instance.Conf.World.RandomFloors ? rnd.Next() : day); instanceId = this.GetInstanceId(); dungeon = new Dungeon(instanceId, dungeonName, itemId, rnd.Next(), floorPlan, creature); } else dungeon = existing; } // Add new dungeon to list if (instanceId != 0) { lock (_syncLock) _dungeons.Add(instanceId, dungeon); } return dungeon; }
/// <summary> /// Called once, when the entire initial party has entered the /// dungeon's lobby. /// </summary> /// <param name="dungeon"></param> /// <param name="creature">The last creature that entered.</param> public virtual void OnPartyEntered(Dungeon dungeon, Creature creature) { }
/// <summary> /// Called whenever a player enters the dungeon's lobby. /// </summary> /// <param name="dungeon"></param> /// <param name="creature">The creature that entered.</param> public virtual void OnPlayerEntered(Dungeon dungeon, Creature creature) { }
/// <summary> /// Called when a creature enters a floor region. The floor ids start at 1. /// </summary> /// <param name="dungeon"></param> /// <param name="creature"></param> /// <param name="floor"></param> public virtual void OnPlayerEnteredFloor(Dungeon dungeon, Creature creature, int floor) { }
/// <summary> /// Called after an RP character was created, but before the player /// is warped into the dungeon. /// </summary> /// <remarks> /// Allows changes to the RP character, which are created based on /// actor data. /// </remarks> /// <param name="dungeon"></param> /// <param name="rpCharacter"></param> public virtual void OnRpCharacterCreated(Dungeon dungeon, RpCharacter rpCharacter) { }
/// <summary> /// Updates ClearDungeon objectives. /// </summary> /// <param name="creature"></param> /// <param name="dungeon"></param> private void OnPlayerClearedDungeon(Creature creature, Dungeon dungeon) { if (creature == null || dungeon == null) return; var quests = creature.Quests.GetAllIncomplete(this.Id); foreach (var quest in quests) { if (!this.CanMakeProgress(creature, quest)) continue; var progress = quest.CurrentObjectiveOrLast; if (progress == null) return; var objective = this.Objectives[progress.Ident]; if (objective == null || objective.Type != ObjectiveType.ClearDungeon) return; var clearDungeonObjective = (objective as QuestObjectiveClearDungeon); if (!progress.Done && dungeon.Name.ToLower() == clearDungeonObjective.DungeonName.ToLower()) { quest.SetDone(progress.Ident); UpdateQuest(creature, quest); } } }
/// <summary> /// Initializes region. /// </summary> /// <param name="regionId"></param> /// <param name="dungeon"></param> protected DungeonRegion(int regionId, Dungeon dungeon) : base(regionId) { this.Dungeon = dungeon; this.Name = dungeon.Name + "_" + regionId; }
/// <summary> /// Generates instance id and creates dungeon. /// </summary> /// <param name="dungeonName"></param> /// <param name="itemId"></param> /// <param name="creature"></param> /// <returns></returns> private Dungeon CreateDungeon(string dungeonName, int itemId, Creature creature) { Dungeon dungeon; long instanceId = 0; var rnd = RandomProvider.Get(); var itemData = AuraData.ItemDb.Find(itemId); // Create new dungeon for passes (includes quest items) if (itemData != null && itemData.HasTag("/dungeon_pass/")) { instanceId = this.GetInstanceId(); dungeon = new Dungeon(instanceId, dungeonName, itemId, rnd.Next(), rnd.Next(), creature); } else { // Create new dungeon if there's not one yet var existing = this.Get(a => a.Name == dungeonName && a.ItemId == itemId); if (existing == null || ChannelServer.Instance.Conf.World.PrivateDungeons) { // Random floor plan on Tuesday var day = ErinnTime.Now.Month; var floorPlan = (day == 2 || ChannelServer.Instance.Conf.World.RandomFloors ? rnd.Next() : day); instanceId = this.GetInstanceId(); dungeon = new Dungeon(instanceId, dungeonName, itemId, rnd.Next(), floorPlan, creature); } else dungeon = existing; } // Add new dungeon to list if (instanceId != 0) { lock (_syncLock) _dungeons.Add(instanceId, dungeon); } return dungeon; }
/// <summary> /// Called when all puzzles of a section have been solved. /// </summary> /// <param name="dungeon"></param> /// <param name="floor">The floor, starting at 1 (lobby is ignored).</param> /// <param name="section">The section, starting at 1.</param> public virtual void OnSectionCleared(Dungeon dungeon, int floor, int section) { }