public bool MonsterDead(int[] spawnPointIds, bool arg2) { // TODO: Needs a better check for multiple mob spawns foreach (int spawnPointId in spawnPointIds) { MapEventNpcSpawnPoint spawnPoint = MapEntityStorage.GetMapEventNpcSpawnPoint(Field.MapId, spawnPointId); if (spawnPoint == null) { continue; } foreach (string npcId in spawnPoint.NpcIds) { if (int.TryParse(npcId, out int id)) { if (Field.State.Mobs.Values.Where(x => x.Value.Id == id).Any()) { return false; } } } } return true; }
public void CreateMonster(int[] spawnPointIds, bool arg2, int arg3) { foreach (int spawnPointId in spawnPointIds) { MapEventNpcSpawnPoint spawnPoint = MapEntityStorage.GetMapEventNpcSpawnPoint(Field.MapId, spawnPointId); if (spawnPoint == null) { continue; } for (int i = 0; i < spawnPoint.Count; i++) { foreach (string npcId in spawnPoint.NpcIds) { if (int.TryParse(npcId, out int id)) { Mob mob = new Mob(id); if (mob.Friendly != 2) { IFieldObject <Mob> fieldMob = Field.RequestFieldObject(mob); fieldMob.Coord = spawnPoint.Position; fieldMob.Rotation = spawnPoint.Rotation; Field.AddMob(fieldMob); continue; } IFieldObject <Npc> fieldNpc = Field.RequestFieldObject(new Npc(mob.Id)); fieldNpc.Coord = spawnPoint.Position; fieldNpc.Rotation = spawnPoint.Rotation; Field.AddNpc(fieldNpc); } } } } }
private static void HandleUse(GameSession session, PacketReader packet) { string uuid = packet.ReadMapleString(); MapInteractActor actor = MapEntityStorage.GetInteractActors(session.Player.MapId).FirstOrDefault(x => x.Uuid == uuid); if (actor == null) { return; } if (actor.Type == InteractActorType.Binoculars) { List <QuestStatus> questList = session.Player.QuestList; foreach (QuestStatus item in questList.Where(x => x.Basic.QuestID >= 72000000 && x.Condition != null)) { QuestCondition condition = item.Condition.FirstOrDefault(x => x.Code != "" && int.Parse(x.Code) == actor.Id); if (condition == null) { continue; } item.Completed = true; item.CompleteTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); session.Send(QuestPacket.CompleteExplorationGoal(item.Basic.QuestID)); session.Send(QuestPacket.CompleteQuest(item.Basic.QuestID)); break; } } session.Send(InteractActorPacket.UseObject(actor)); session.Send(InteractActorPacket.Extra(actor)); }
public void DestroyMonster(int[] rangeId, bool arg2) { foreach (int spawnPointId in rangeId) { MapEventNpcSpawnPoint spawnPoint = MapEntityStorage.GetMapEventNpcSpawnPoint(Field.MapId, spawnPointId); if (spawnPoint is null) { continue; } foreach (string npcId in spawnPoint.NpcIds) { if (!int.TryParse(npcId, out int id)) { continue; } IFieldActor <NpcMetadata> fieldNpc = Field.State.Npcs.Values.FirstOrDefault(x => x.Value.Id == id); if (fieldNpc is null) { continue; } Field.RemoveNpc(fieldNpc); } } }
public override void Handle(GameSession session, PacketReader packet) { byte function = packet.ReadByte(); if (function == 0) { int srcMapId = packet.ReadInt(); if (srcMapId != session.FieldManager.MapId) { return; } int portalId = packet.ReadInt(); MapPortal srcPortal = MapEntityStorage.GetPortals(srcMapId) .FirstOrDefault(portal => portal.Id == portalId); if (srcPortal == default) { logger.Warning($"Unable to find portal:{portalId} in map:{srcMapId}"); return; } MapPortal dstPortal = MapEntityStorage.GetPortals(srcPortal.Target) .FirstOrDefault(portal => portal.Target == srcMapId); if (dstPortal == default) { logger.Warning($"Unable to find return portal to map:{srcMapId} in map:{srcPortal.Target}"); return; } // TODO: There needs to be a more centralized way to set coordinates... session.Player.MapId = srcPortal.Target; session.Player.Coord = dstPortal.Coord.ToFloat(); session.Send(FieldPacket.RequestEnter(session.FieldPlayer)); } }
public bool UserDetected(int[] boxIds, byte jobId) { Job job = (Job)jobId; List <IFieldObject <Player> > players = Field.State.Players.Values.ToList(); if (job != Job.None) { players = players.Where(x => x.Value.Job == job).ToList(); } foreach (int boxId in boxIds) { MapTriggerBox box = MapEntityStorage.GetTriggerBox(Field.MapId, boxId); if (box == null) { return(false); } foreach (IFieldObject <Player> player in players) { if (FieldManager.IsPlayerInBox(box, player)) { return(true); } } } return(false); }
public void MoveNpc(int spawnTriggerId, string patrolDataName) { (PatrolData, List <WayPoint>)patrolData = MapEntityStorage.GetPatrolData(Field.MapId, patrolDataName); MapEventNpcSpawnPoint spawnPoint = MapEntityStorage.GetMapEventNpcSpawnPoint(Field.MapId, spawnTriggerId); if (spawnPoint is null) { return; } foreach (string npcId in spawnPoint.NpcIds) { if (!int.TryParse(npcId, out int id)) { continue; } IFieldActor <NpcMetadata> fieldNpc = Field.State.Npcs.Values.FirstOrDefault(x => x.Value.Id == id); if (fieldNpc is null) { continue; } // Just setting the coord as the last waypoint for now, replace with moveTo later // fieldNpc.MoveTo(patrolData.Item2.Last().Position); fieldNpc.Coord = patrolData.Item2.Last().Position.ToFloat(); } }
// Example: "map -> return current map id" // Example: "map id:200001 -> teleport to map" private static void ProcessMapCommand(GameSession session, string command) { Dictionary <string, string> config = command.ToMap(); int.TryParse(config.GetValueOrDefault("id", "0"), out int mapId); if (mapId == 0) { session.SendNotice($"Current map id:{session.Player.MapId}"); return; } if (session.Player.MapId == mapId) { session.SendNotice("You are already on that map."); return; } MapPlayerSpawn spawn = MapEntityStorage.GetRandomPlayerSpawn(mapId); if (spawn != null) { session.Player.MapId = mapId; session.Player.Coord = spawn.Coord.ToFloat(); session.Player.Rotation = spawn.Rotation.ToFloat(); session.Send(FieldPacket.RequestEnter(session.FieldPlayer)); } else { session.SendNotice("Could not find coordinates to spawn on that map."); } }
public void SetAchievement(int boxId, string type, string trophySet) { List <IFieldActor <Player> > players = Field.State.Players.Values.ToList(); if (boxId != 0) { MapTriggerBox box = MapEntityStorage.GetTriggerBox(Field.MapId, boxId); List <IFieldActor <Player> > boxedPlayers = new(); foreach (IFieldActor <Player> player in players) { if (FieldManager.IsPlayerInBox(box, player)) { boxedPlayers.Add(player); } } players = boxedPlayers; } foreach (IFieldObject <Player> player in players) { if (type == "trigger") { TrophyManager.OnTrigger(player.Value, trophySet); } } }
public void SetAchievement(int boxId, string type, string trophySet) { List <IFieldObject <Player> > players = Field.State.Players.Values.ToList(); if (boxId != 0) { MapTriggerBox box = MapEntityStorage.GetTriggerBox(Field.MapId, boxId); List <IFieldObject <Player> > boxedPlayers = new List <IFieldObject <Player> >(); foreach (IFieldObject <Player> player in players) { if (FieldManager.IsPlayerInBox(box, player)) { boxedPlayers.Add(player); } } players = boxedPlayers; } foreach (IFieldObject <Player> player in players) { if (type == "trigger") { switch (trophySet) { case "oxquiz_start": player.Value.TrophyUpdate(23400009, 1); break; case "oxquiz_correct": player.Value.TrophyUpdate(23400010, 1); break; case "oxquiz_win": player.Value.TrophyUpdate(23400011, 1); break; case "trapmaster_start": player.Value.TrophyUpdate(23400001, 1); break; case "trapmaster_win": player.Value.TrophyUpdate(23400002, 1); break; case "finalsurvivor_start": player.Value.TrophyUpdate(23400003, 1); break; case "finalsurvivor_win": player.Value.TrophyUpdate(23400004, 1); break; default: Logger.Warn($"Unhandled trophy set: {trophySet}"); break; } } } }
public override void Handle(GameSession session, PacketReader packet) { byte function = packet.ReadByte(); if (function == 0) { int srcMapId = packet.ReadInt(); if (srcMapId != session.FieldManager.MapId) { return; } int portalId = packet.ReadInt(); MapPortal srcPortal = MapEntityStorage.GetPortals(srcMapId) .FirstOrDefault(portal => portal.Id == portalId); if (srcPortal == default) { Logger.Warning($"Unable to find portal:{portalId} in map:{srcMapId}"); return; } MapPortal dstPortal = MapEntityStorage.GetPortals(srcPortal.Target) .FirstOrDefault(portal => portal.Target == srcMapId); if (dstPortal == default) { Logger.Warning($"Unable to find return portal to map:{srcMapId} in map:{srcPortal.Target}"); return; } // TODO: There needs to be a more centralized way to set coordinates... session.Player.MapId = srcPortal.Target; session.Player.Rotation = dstPortal.Rotation.ToFloat(); session.Player.Coord = dstPortal.Coord.ToFloat(); if (dstPortal.Name == "Portal_cube") // spawn on the next block if portal is a cube { if (dstPortal.Rotation.Z == 0) // Facing SE { session.Player.Coord.Y -= Block.BLOCK_SIZE; } else if (dstPortal.Rotation.Z == 90) // Facing NE { session.Player.Coord.X += Block.BLOCK_SIZE; } else if (dstPortal.Rotation.Z == 180) // Facing NW { session.Player.Coord.Y += Block.BLOCK_SIZE; } else if (dstPortal.Rotation.Z == 270) // Facing SW { session.Player.Coord.X -= Block.BLOCK_SIZE; } } session.Player.SafeBlock = session.Player.Coord; session.Send(FieldPacket.RequestEnter(session.FieldPlayer)); } }
private static void HandleTeleport(GameSession session, int mapId) { MapPlayerSpawn spawn = MapEntityStorage.GetRandomPlayerSpawn(mapId); if (spawn != null) { session.Player.Warp(spawn, mapId); } }
public FieldManager(int mapId) { MapId = mapId; BoundingBox = MapEntityStorage.GetBoundingBox(mapId); // Load default npcs for map from config foreach (MapNpc npc in MapEntityStorage.GetNpcs(mapId)) { IFieldObject <Npc> fieldNpc = RequestFieldObject(new Npc(npc.Id) { ZRotation = (short)(npc.Rotation.Z * 10) }); IFieldObject <Mob> fieldMob = RequestFieldObject(new Mob(npc.Id) { ZRotation = (short)(npc.Rotation.Z * 10) }); if (fieldNpc.Value.Friendly == 2) { fieldNpc.Coord = npc.Coord.ToFloat(); AddNpc(fieldNpc); } else { fieldMob.Coord = npc.Coord.ToFloat(); AddMob(fieldMob); } } // Load default portals for map from config foreach (MapPortal portal in MapEntityStorage.GetPortals(mapId)) { IFieldObject <Portal> fieldPortal = RequestFieldObject(new Portal(portal.Id) { IsVisible = portal.Flags.HasFlag(MapPortalFlag.Visible), IsEnabled = portal.Flags.HasFlag(MapPortalFlag.Enabled), IsMinimapVisible = portal.Flags.HasFlag(MapPortalFlag.MinimapVisible), Rotation = portal.Rotation.ToFloat(), TargetMapId = portal.Target, }); fieldPortal.Coord = portal.Coord.ToFloat(); AddPortal(fieldPortal); } // Load default InteractActors List <IFieldObject <InteractActor> > actors = new List <IFieldObject <InteractActor> > { }; foreach (MapInteractActor actor in MapEntityStorage.GetInteractActors(mapId)) { // TODO: Group these fieldActors by their correct packet type. actors.Add(RequestFieldObject(new InteractActor(actor.Uuid, actor.Name, actor.Type) { })); } AddInteractActor(actors); }
public void AddPlayer(GameSession sender, IFieldObject <Player> player) { Debug.Assert(player.ObjectId > 0, "Player was added to field without initialized objectId."); player.Coord = player.Value.Coord; player.Value.MapId = MapId; // TODO: Determine new coordinates for player as well lock (Sessions) { Sessions.Add(sender); } // TODO: Send the initialization state of the field foreach (IFieldObject <Player> existingPlayer in State.Players.Values) { sender.Send(FieldPacket.AddPlayer(existingPlayer)); sender.Send(FieldObjectPacket.LoadPlayer(existingPlayer)); } foreach (IFieldObject <Item> existingItem in State.Items.Values) { sender.Send(FieldPacket.AddItem(existingItem, 123456)); } foreach (IFieldObject <Npc> existingNpc in State.Npcs.Values) { sender.Send(FieldPacket.AddNpc(existingNpc)); sender.Send(FieldObjectPacket.LoadNpc(existingNpc)); } foreach (IFieldObject <Portal> existingPortal in State.Portals.Values) { sender.Send(FieldPacket.AddPortal(existingPortal)); } foreach (IFieldObject <Mob> existingMob in State.Mobs.Values) { sender.Send(FieldPacket.AddMob(existingMob)); sender.Send(FieldObjectPacket.LoadMob(existingMob)); } if (State.InteractActors.Values.Count > 0) { sender.Send(InteractActorPacket.AddInteractActors(State.InteractActors.Values)); } if (MapEntityStorage.HasHealingSpot(MapId)) { if (HealingSpotThread == null || HealingSpotThread.IsCompleted) { HealingSpotThread = StartHealingSpot(sender, player); } sender.Send(RegionSkillPacket.Send(player, MapEntityStorage.GetHealingSpot(MapId), new SkillCast(70000018, 1, 0, 1))); } State.AddPlayer(player); // Broadcast new player to all players in map Broadcast(session => { session.Send(FieldPacket.AddPlayer(player)); session.Send(FieldObjectPacket.LoadPlayer(player)); }); }
public static void HandleCallAirTaxi(GameSession session, PacketReader packet, Item item) { int fieldID = int.Parse(packet.ReadUnicodeString()); MapPlayerSpawn spawn = MapEntityStorage.GetRandomPlayerSpawn(fieldID); if (spawn != null) { InventoryController.Consume(session, item.Uid, 1); session.Player.Warp(spawn, fieldID); } }
private static void HandleBeauty(GameSession session) { MapPortal portal = MapEntityStorage.GetPortals(session.Player.MapId).FirstOrDefault(portal => portal.Id == 99); // unsure how the portalId is determined if (portal is null) { return; } session.Send(NpcTalkPacket.Action(ActionType.Portal, "", "", portal.Id)); NpcMetadata npcTarget = NpcMetadataStorage.GetNpcMetadata(session.Player.NpcTalk.Npc.Id); session.Player.ShopId = npcTarget.ShopId; switch (npcTarget.ShopId) { case 500: // Dr Dixon session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "face")); // unsure how these strings are determined break; case 501: // Dr Zenko session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "skin")); break; case 504: // Rosetta case 509: //Lolly session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "hair,style")); break; case 505: // Ren session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "makeup")); break; case 506: // Douglas session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "itemcolor")); break; case 507: // Mirror session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "mirror")); break; case 508: // Paulie session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "hair,random")); break; case 510: // Mino session.Send(NpcTalkPacket.Action(ActionType.OpenWindow, "BeautyShopDialog", "hair,styleSave")); break; } session.Send(UserMoveByPortalPacket.Move(session.Player.FieldPlayer, portal.Coord.ToFloat(), portal.Rotation.ToFloat())); }
public void EndMiniGameRound(int winnerBoxId, float expRate, bool isOnlyWinner, bool isGainLoserBonus, bool meso, MiniGame type) { MapTriggerBox box = MapEntityStorage.GetTriggerBox(Field.MapId, winnerBoxId); foreach (IFieldObject <Player> player in Field.State.Players.Values) { if (FieldManager.IsPlayerInBox(box, player)) { // TODO: calculate correct amount of exp; player.Value.Levels.GainExp(10000); } } }
public override void Handle(GameSession session, PacketReader packet) { string entityId = packet.ReadMapleString(); long skillSN = packet.ReadLong(); int skillId = packet.ReadInt(); short skillLevel = packet.ReadShort(); short unkShort = packet.ReadShort(); int unkInt = packet.ReadInt(); CoordF playerCoords = packet.Read <CoordF>(); if (!MapEntityStorage.IsVibrateObject(session.Player.MapId, entityId)) { return; } SkillCast skillCast = new SkillCast(skillId, skillLevel, skillSN, session.ServerTick); session.FieldManager.BroadcastPacket(VibratePacket.Vibrate(entityId, skillCast, session.FieldPlayer)); }
public int GetUserCount(int boxId, int userTagId) { if (boxId != 0) { List <IFieldObject <Player> > players = Field.State.Players.Values.ToList(); MapTriggerBox box = MapEntityStorage.GetTriggerBox(Field.MapId, boxId); int userCount = 0; foreach (IFieldObject <Player> player in players) { if (FieldManager.IsPlayerInBox(box, player)) { userCount++; } } return(userCount); } return(Field.State.Players.Values.Count); }
public void PlaySystemSoundInBox(int[] boxIds, string sound) { if (boxIds != null) { foreach (int boxId in boxIds) { MapTriggerBox box = MapEntityStorage.GetTriggerBox(Field.MapId, boxId); foreach (IFieldObject <Player> player in Field.State.Players.Values) { if (FieldManager.IsPlayerInBox(box, player)) { player.Value.Session.Send(SystemSoundPacket.Play(sound)); } } } return; } Field.BroadcastPacket(SystemSoundPacket.Play(sound)); }
public void SpawnNpcRange(int[] rangeId, bool isAutoTargeting, byte randomPickCount, int score) { foreach (int spawnPointId in rangeId) { MapEventNpcSpawnPoint spawnPoint = MapEntityStorage.GetMapEventNpcSpawnPoint(Field.MapId, spawnPointId); if (spawnPoint == null) { continue; } foreach (string npcId in spawnPoint.NpcIds) { if (!int.TryParse(npcId, out int id)) { continue; } Field.RequestNpc(id, spawnPoint.Position, spawnPoint.Rotation); } } }
public void Warp(int mapId, CoordF coord = default, CoordF rotation = default, long instanceId = 0) { if (MapEntityStorage.HasSafePortal(MapId)) { ReturnCoord = Coord; ReturnMapId = MapId; } Coord = coord; Rotation = rotation; SafeBlock = coord; MapId = mapId; InstanceId = instanceId; if (coord == default || rotation == default) { MapPlayerSpawn spawn = MapEntityStorage.GetRandomPlayerSpawn(mapId); if (spawn == null) { Session.SendNotice($"Could not find a spawn for map {mapId}"); return; } if (coord == default) { Coord = spawn.Coord.ToFloat(); SafeBlock = spawn.Coord.ToFloat(); } if (rotation == default) { Rotation = spawn.Rotation.ToFloat(); } } if (!UnlockedMaps.Contains(MapId)) { UnlockedMaps.Add(MapId); } DatabaseManager.Characters.Update(this); Session.Send(FieldPacket.RequestEnter(this)); }
public void EndMiniGame(int winnerBoxId, MiniGame type, bool isOnlyWinner) { MapTriggerBox box = MapEntityStorage.GetTriggerBox(Field.MapId, winnerBoxId); List <IFieldObject <Player> > players = new List <IFieldObject <Player> >(); foreach (IFieldObject <Player> player in Field.State.Players.Values) { if (FieldManager.IsPlayerInBox(box, player)) { if (type == MiniGame.LudibriumEscape) { PlayerTrigger trigger = player.Value.Triggers.FirstOrDefault(x => x.Key == "gameStart"); player.Value.Triggers.Remove(trigger); player.Value.Session.Send(ResultsPacket.Rounds(1, 1)); } else if (type == MiniGame.OXQuiz) { player.Value.Session.Send(ResultsPacket.Rounds(10, 10)); } } } }