public static void UpdatePlayer(GameSession session, SyncState[] syncStates) { CoordF coord = syncStates[0].Coord.ToFloat(); CoordF closestBlock = Block.ClosestBlock(coord); closestBlock.Z -= Block.BLOCK_SIZE; // Get block under player if (IsCoordSafe(session, syncStates[0].Coord, closestBlock)) { session.Player.SafeBlock = closestBlock; } session.FieldPlayer.Coord = syncStates[0].Coord.ToFloat(); CoordF rotation = new CoordF(); rotation.Z = syncStates[0].Rotation / 10; session.FieldPlayer.Rotation = rotation; if (IsOutOfBounds(session.FieldPlayer.Coord, session.FieldManager.BoundingBox)) { int currentHp = session.Player.Stats[PlayerStatId.Hp].Current; int fallDamage = currentHp * Math.Clamp(currentHp * 4 / 100 - 1, 0, 25) / 100; // TODO: Create accurate damage model CoordF safeBlock = session.Player.SafeBlock; safeBlock.Z += Block.BLOCK_SIZE + 1; // Without this player will spawn inside the block session.Player.ConsumeHp(fallDamage); session.Send(UserMoveByPortalPacket.Move(session.FieldPlayer, safeBlock, session.Player.Rotation)); session.Send(StatPacket.UpdateStats(session.FieldPlayer, PlayerStatId.Hp)); session.Send(FallDamagePacket.FallDamage(session, fallDamage)); } // not sure if this needs to be synced here session.Player.Animation = syncStates[0].Animation1; }
public override void Handle(GameSession session, PacketReader packet) { byte function = packet.ReadByte(); // Unknown what this is for session.ServerTick = packet.ReadInt(); session.ClientTick = packet.ReadInt(); byte segments = packet.ReadByte(); if (segments < 1) { return; } SyncState[] syncStates = new SyncState[segments]; for (int i = 0; i < segments; i++) { syncStates[i] = packet.ReadSyncState(); packet.ReadInt(); // ClientTicks packet.ReadInt(); // ServerTicks } Packet syncPacket = SyncStatePacket.UserSync(session.FieldPlayer, syncStates); session.FieldManager.BroadcastPacket(syncPacket, session); CoordF coord = syncStates[0].Coord.ToFloat(); CoordF closestBlock = Block.ClosestBlock(coord); closestBlock.Z -= Block.BLOCK_SIZE; // Get block under player if (IsCoordSafe(session, syncStates[0].Coord, closestBlock)) { session.Player.SafeBlock = closestBlock; } session.FieldPlayer.Coord = syncStates[0].Coord.ToFloat(); CoordF rotation = new CoordF(); rotation.Z = syncStates[0].Rotation / 10; session.FieldPlayer.Rotation = rotation; if (IsOutOfBounds(session.FieldPlayer.Coord, session.FieldManager.BoundingBox)) { int currentHp = session.Player.Stats[PlayerStatId.Hp].Current; int fallDamage = currentHp * Math.Clamp(currentHp * 4 / 100 - 1, 0, 25) / 100; // TODO: Create accurate damage model CoordF safeBlock = session.Player.SafeBlock; safeBlock.Z += Block.BLOCK_SIZE + 1; // Without this player will spawn inside the block session.Player.ConsumeHp(fallDamage); session.Send(UserMoveByPortalPacket.Move(session, safeBlock, session.Player.Rotation)); session.Send(StatPacket.UpdateStats(session.FieldPlayer, PlayerStatId.Hp)); session.Send(FallDamagePacket.FallDamage(session, fallDamage)); } // not sure if this needs to be synced here session.Player.Animation = syncStates[0].Animation1; }
public override void Handle(GameSession session, PacketReader packet) { byte function = packet.ReadByte(); // Unknown what this is for session.ClientTick = packet.ReadInt(); //ClientTicks packet.ReadInt(); // ServerTicks byte segments = packet.ReadByte(); if (segments < 1) { return; } SyncState[] syncStates = new SyncState[segments]; for (int i = 0; i < segments; i++) { syncStates[i] = packet.ReadSyncState(); packet.ReadInt(); // ClientTicks packet.ReadInt(); // ServerTicks } Packet syncPacket = SyncStatePacket.UserSync(session.FieldPlayer, syncStates); session.FieldManager.BroadcastPacket(syncPacket, session); CoordF coord = syncStates[0].Coord.ToFloat(); CoordF closestBlock = Block.ClosestBlock(coord); closestBlock.Z -= Block.BLOCK_SIZE; // Get block under player if (IsCoordSafe(session, syncStates[0].Coord, closestBlock)) { session.Player.SafeBlock = closestBlock; } session.FieldPlayer.Coord = syncStates[0].Coord.ToFloat(); if (IsOutOfBounds(session.FieldPlayer.Coord, session.FieldManager.BoundingBox)) { CoordF safeBlock = session.Player.SafeBlock; safeBlock.Z += Block.BLOCK_SIZE + 1; // Without this player will spawn inside the block // for some reason if coord is negative player is teleported one block over, which can result player being stuck inside a block if (session.FieldPlayer.Coord.X < 0) { safeBlock.X -= Block.BLOCK_SIZE; } if (session.FieldPlayer.Coord.Y < 0) { safeBlock.Y -= Block.BLOCK_SIZE; } session.Send(UserMoveByPortalPacket.Move(session, safeBlock)); session.Send(FallDamagePacket.FallDamage(session, 150)); // TODO: create a formula to determine HP loss } // not sure if this needs to be synced here session.Player.Animation = syncStates[0].Animation1; }
public override void Execute(GameCommandTrigger trigger) { CoordF coordF = trigger.Get <CoordF>("pos"); if (coordF == default) { trigger.Session.SendNotice(trigger.Session.FieldPlayer.Coord.ToString()); return; } trigger.Session.Player.Coord = coordF; trigger.Session.Send(UserMoveByPortalPacket.Move(trigger.Session.FieldPlayer, coordF, trigger.Session.Player.Rotation)); }
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())); }
private static void HandleHomePortal(GameSession session, IFieldObject <Portal> fieldPortal) { IFieldObject <Cube> srcCube = session.FieldManager.State.Cubes.Values .FirstOrDefault(x => x.Value.PortalSettings is not null && x.Value.PortalSettings.PortalObjectId == fieldPortal.ObjectId); if (srcCube is null) { return; } string destinationTarget = srcCube.Value.PortalSettings.DestinationTarget; if (string.IsNullOrEmpty(destinationTarget)) { return; } switch (srcCube.Value.PortalSettings.Destination) { case UGCPortalDestination.PortalInHome: IFieldObject <Cube> destinationCube = session.FieldManager.State.Cubes.Values .FirstOrDefault(x => x.Value.PortalSettings is not null && x.Value.PortalSettings.PortalName == destinationTarget); if (destinationCube is null) { return; } session.Player.Coord = destinationCube.Coord; CoordF coordF = destinationCube.Coord; coordF.Z += 25; // Without this the player falls through the ground. session.Send(UserMoveByPortalPacket.Move(session.FieldPlayer, coordF, session.Player.Rotation)); break; case UGCPortalDestination.SelectedMap: session.Player.Warp(int.Parse(destinationTarget)); break; case UGCPortalDestination.FriendHome: long friendAccountId = long.Parse(destinationTarget); Home home = GameServer.HomeManager.GetHomeById(friendAccountId); if (home is null) { return; } session.Player.Warp((int)Map.PrivateResidence, instanceId: home.InstanceId); break; } }
private static void HandleStopMultiPersonRide(GameSession session) { IFieldObject <Player> otherPlayer = session.Player.Mount.Value.Players[0]; if (otherPlayer == null) { return; } session.FieldManager.BroadcastPacket(MountPacket.StopTwoPersonRide(otherPlayer.ObjectId, session.FieldPlayer.ObjectId)); session.Send(UserMoveByPortalPacket.Move(session.FieldPlayer, otherPlayer.Coord, otherPlayer.Rotation)); session.Player.Mount = null; if (otherPlayer.Value.Mount != null) { int index = Array.FindIndex(otherPlayer.Value.Mount.Value.Players, 0, otherPlayer.Value.Mount.Value.Players.Length, x => x.ObjectId == session.FieldPlayer.ObjectId); otherPlayer.Value.Mount.Value.Players[index] = null; } }
public override void Execute(GameCommandTrigger trigger) { string name = trigger.Get <string>("name"); Player target = GameServer.Storage.GetPlayerByName(name); if (target is null) { trigger.Session.SendNotice($"Couldn't find player with name: {name}!"); return; } IFieldObject <Player> fieldPlayer = target.Session.FieldPlayer; if (target.MapId == trigger.Session.Player.MapId && target.InstanceId == trigger.Session.Player.InstanceId) { trigger.Session.Send(UserMoveByPortalPacket.Move(trigger.Session.FieldPlayer, fieldPlayer.Coord, fieldPlayer.Rotation)); return; } trigger.Session.Player.Warp(mapId: target.MapId, coord: fieldPlayer.Coord, instanceId: target.InstanceId); }
public static void UpdatePlayer(GameSession session, SyncState[] syncStates) { Player player = session.Player; IFieldActor <Player> fieldPlayer = player.FieldPlayer; CoordF coord = syncStates[0].Coord.ToFloat(); CoordF coordUnderneath = coord; coordUnderneath.Z -= 50; CoordF blockUnderneath = Block.ClosestBlock(coordUnderneath); if (IsCoordSafe(player, syncStates[0].Coord, blockUnderneath)) { CoordF safeBlock = Block.ClosestBlock(coord); // TODO: Knowing the state of the player using the animation is probably not the correct way to do this // we will need to know the state of the player for other things like counting time spent on ropes/running/walking/swimming if (syncStates[0].Animation2 is 7 or 132) // swimming { safeBlock.Z += Block.BLOCK_SIZE; // Without this player will spawn under the water } safeBlock.Z += 10; // Without this player will spawn inside the block player.SafeBlock = safeBlock; } fieldPlayer.Coord = coord; fieldPlayer.Rotation = new() { Z = syncStates[0].Rotation / 10 }; if (IsOutOfBounds(fieldPlayer.Coord, session.FieldManager.BoundingBox)) { session.Send(UserMoveByPortalPacket.Move(fieldPlayer, player.SafeBlock, fieldPlayer.Rotation)); player.FallDamage(); } // not sure if this needs to be synced here fieldPlayer.Animation = syncStates[0].Animation1; }
public void MoveUser(int mapId, int triggerId, int boxId) { 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; } // move player back to return map if (mapId == 0 && triggerId == 0) { foreach (IFieldObject <Player> player in players) { player.Value.Warp(player.Value.ReturnMapId, player.Value.ReturnCoord); } return; } if (mapId == Field.MapId) { IFieldObject <Portal> portal = Field.State.Portals.Values.First(p => p.Value.Id == triggerId); foreach (IFieldObject <Player> player in players) { player.Coord = portal.Coord; player.Rotation = portal.Rotation; player.Value.Session.Send(UserMoveByPortalPacket.Move(player, portal.Coord, portal.Rotation)); } return; } CoordF moveCoord; CoordF moveRotation; MapPortal dstPortal = MapEntityStorage.GetPortals(mapId).FirstOrDefault(portal => portal.Id == triggerId); if (dstPortal == null) { MapPlayerSpawn spawn = MapEntityStorage.GetRandomPlayerSpawn(mapId); moveCoord = spawn.Coord.ToFloat(); moveRotation = spawn.Rotation.ToFloat(); } else { moveCoord = dstPortal.Coord.ToFloat(); moveRotation = dstPortal.Rotation.ToFloat(); } foreach (IFieldObject <Player> player in players) { player.Value.Warp(mapId, moveCoord, moveRotation); } }
public override void Handle(GameSession session, PacketReader packet) { byte function = packet.ReadByte(); switch (function) { case 0: // Cancel return; case 1: int objectId = packet.ReadInt(); if (!session.FieldManager.State.Npcs.TryGetValue(objectId, out IFieldObject <Npc> npc)) { return; // Invalid NPC } session.Player.NpcTalk = npc; // If NPC is a shop, load and open the shop if (npc.Value.IsShop()) { ShopHandler.HandleOpen(session, npc); return; } else if (npc.Value.IsBank()) { session.Send(HomeBank.OpenBank()); return; } else if (npc.Value.IsBeauty()) { session.Send(NpcTalkPacket.Respond(npc, NpcType.Default, DialogType.Beauty, 1)); return; } // Stellar Chest: 11004215 session.Send(NpcTalkPacket.Respond(npc, NpcType.Unk2, DialogType.TalkOption, 0)); break; case 2: // Continue chat? int index = packet.ReadInt(); // selection index if (session.Player.NpcTalk.Value.IsBeauty()) // This may need a cleaner method { MapPortal portal = MapEntityStorage.GetPortals(session.Player.MapId).FirstOrDefault(portal => portal.Id == 99); // unsure how the portalId is determined session.Send(NpcTalkPacket.Action(ActionType.Portal, "", "", portal.Id)); NpcMetadata npcTarget = NpcMetadataStorage.GetNpc(session.Player.NpcTalk.Value.Id); 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, portal.Coord.ToFloat(), portal.Rotation.ToFloat())); } session.Send(NpcTalkPacket.Close()); session.Player.NpcTalk = null; break; } }