diff --git a/GameServer/Controllers/CreatureController.cs b/GameServer/Controllers/CreatureController.cs index fa4049d..7315f6b 100644 --- a/GameServer/Controllers/CreatureController.cs +++ b/GameServer/Controllers/CreatureController.cs @@ -24,7 +24,7 @@ internal class CreatureController : Controller public async Task JoinScene(int instanceId) { _modelManager.Creature.SetSceneLoadingData(instanceId); - CreateInitialPlayer(); + CreateTeamPlayerEntities(); await Session.Push(MessageId.JoinSceneNotify, new JoinSceneNotify { @@ -73,7 +73,7 @@ internal class CreatureController : Controller [GameEvent(GameEventType.VisionSkillChanged)] public async Task OnVisionSkillChanged() { - PlayerEntity? playerEntity = GetPlayerEntity(_modelManager.Player.Id); + PlayerEntity? playerEntity = GetPlayerEntity(); if (playerEntity == null) return; EntityVisionSkillComponent visionSkillComponent = playerEntity.ComponentSystem.Get(); @@ -84,9 +84,25 @@ internal class CreatureController : Controller await Session.Push(MessageId.VisionSkillChangeNotify, skillChangeNotify); } - public PlayerEntity? GetPlayerEntity(int playerId) + public PlayerEntity? GetPlayerEntity() { - return _entitySystem.EnumerateEntities().FirstOrDefault(entity => entity is PlayerEntity p && p.PlayerId == playerId) as PlayerEntity; + return _entitySystem.EnumerateEntities().FirstOrDefault(entity => entity.Id == _modelManager.Creature.PlayerEntityId) as PlayerEntity; + } + + public async Task SwitchPlayerEntity(int roleId) + { + PlayerEntity? prevEntity = GetPlayerEntity(); + if (prevEntity == null) return; + + prevEntity.IsCurrentRole = false; + + PlayerEntity? newEntity = _entitySystem.EnumerateEntities().FirstOrDefault(e => e is PlayerEntity playerEntity && playerEntity.ConfigId == roleId) as PlayerEntity; + if (newEntity == null) return; + + _modelManager.Creature.PlayerEntityId = newEntity.Id; + newEntity.IsCurrentRole = true; + + await OnVisionSkillChanged(); } private SceneInformation CreateSceneInfo() @@ -111,37 +127,44 @@ internal class CreatureController : Controller Y = -2000, Z = 260 }, - FightRoleInfos = - { - new FightRoleInformation - { - EntityId = 1, - CurHp = 1000, - MaxHp = 1000, - IsControl = true, - RoleId = _modelManager.Player.CharacterId, - RoleLevel = 1, - } - }, PlayerName = _modelManager.Player.Name } } }; + for (int i = 0; i < _modelManager.Player.Characters.Length; i++) + { + scene.PlayerInfos[0].FightRoleInfos.Add(new FightRoleInformation + { + EntityId = i + 1, + CurHp = 1000, + MaxHp = 1000, + IsControl = i == 0, + RoleId = _modelManager.Player.Characters[i], + RoleLevel = 1, + }); + } + scene.AoiData.Entities.AddRange(_entitySystem.Pb); return scene; } - private void CreateInitialPlayer() + private void CreateTeamPlayerEntities() { - PlayerEntity entity = _entityFactory.CreatePlayer(1601, _modelManager.Player.Id); - entity.Pos = new() + for (int i = 0; i < _modelManager.Player.Characters.Length; i++) { - X = 4000, - Y = -2000, - Z = 260 - }; + PlayerEntity entity = _entityFactory.CreatePlayer(_modelManager.Player.Characters[i], _modelManager.Player.Id); + entity.Pos = new() + { + X = 4000, + Y = -2000, + Z = 260 + }; + entity.IsCurrentRole = i == 0; - _entitySystem.Create(entity); + _entitySystem.Create(entity); + + if (i == 0) _modelManager.Creature.PlayerEntityId = entity.Id; + } } } diff --git a/GameServer/Controllers/FormationController.cs b/GameServer/Controllers/FormationController.cs index 2d33938..e3558e2 100644 --- a/GameServer/Controllers/FormationController.cs +++ b/GameServer/Controllers/FormationController.cs @@ -21,10 +21,10 @@ internal class FormationController : Controller { new FightFormation { - CurRole = _modelManager.Player.CharacterId, + CurRole = _modelManager.Player.Characters[0], FormationId = 1, IsCurrent = true, - RoleIds = { _modelManager.Player.CharacterId }, + RoleIds = { _modelManager.Player.Characters }, } }, }); diff --git a/GameServer/Controllers/PlayerInfoController.cs b/GameServer/Controllers/PlayerInfoController.cs index 5fd34a1..c5af089 100644 --- a/GameServer/Controllers/PlayerInfoController.cs +++ b/GameServer/Controllers/PlayerInfoController.cs @@ -17,7 +17,7 @@ internal class PlayerInfoController : Controller { PlayerModel player = modelManager.Player; - await Session.Push(MessageId.BasicInfoNotify, new BasicInfoNotify + BasicInfoNotify basicInfo = new() { RandomSeed = 1337, Id = player.Id, @@ -36,15 +36,18 @@ internal class PlayerInfoController : Controller ValueType = (int)PlayerAttrType.Int32, Int32Value = 10 } - }, - RoleShowList = + } + }; + + for (int i = 0; i < player.Characters.Length; i++) + { + basicInfo.RoleShowList.Add(new RoleShowEntry { - new RoleShowEntry - { - Level = 1, - RoleId = player.CharacterId - } - }, - }); + Level = 1, + RoleId = player.Characters[i] + }); + } + + await Session.Push(MessageId.BasicInfoNotify, basicInfo); } } diff --git a/GameServer/Controllers/RoleController.cs b/GameServer/Controllers/RoleController.cs index d488ef6..fca8edb 100644 --- a/GameServer/Controllers/RoleController.cs +++ b/GameServer/Controllers/RoleController.cs @@ -22,15 +22,24 @@ internal class RoleController : Controller { RoleList = { - new roleInfo + player.Characters.Select(i => new roleInfo { - RoleId = player.CharacterId, - Level = 1, - } + RoleId = i, + Level = 1 + }) } }); } + [NetEvent(MessageId.SwitchRoleRequest)] + public ResponseMessage OnSwitchRoleRequest(SwitchRoleRequest request) + { + return Response(MessageId.SwitchRoleResponse, new SwitchRoleResponse + { + RoleId = request.RoleId + }); + } + [NetEvent(MessageId.RoleFavorListRequest)] public ResponseMessage OnRoleFavorListRequest() => Response(MessageId.RoleFavorListResponse, new RoleFavorListResponse()); } diff --git a/GameServer/Controllers/RouletteController.cs b/GameServer/Controllers/RouletteController.cs index 41698c5..c2e4fb8 100644 --- a/GameServer/Controllers/RouletteController.cs +++ b/GameServer/Controllers/RouletteController.cs @@ -41,9 +41,9 @@ internal class RouletteController : Controller } [NetEvent(MessageId.VisionExploreSkillSetRequest)] - public async Task OnVisionExploreSkillSetRequest(VisionExploreSkillSetRequest request, CreatureController creatureController, ModelManager modelManager, EventSystem eventSystem) + public async Task OnVisionExploreSkillSetRequest(VisionExploreSkillSetRequest request, CreatureController creatureController, EventSystem eventSystem) { - PlayerEntity? playerEntity = creatureController.GetPlayerEntity(modelManager.Player.Id); + PlayerEntity? playerEntity = creatureController.GetPlayerEntity(); if (playerEntity == null) return Response(MessageId.VisionExploreSkillSetResponse, new VisionExploreSkillSetResponse { ErrCode = (int)ErrorCode.PlayerNotInAnyScene }); EntityVisionSkillComponent visionSkillComponent = playerEntity.ComponentSystem.Get(); diff --git a/GameServer/GameServer.csproj b/GameServer/GameServer.csproj index 382445a..c77cd8d 100644 --- a/GameServer/GameServer.csproj +++ b/GameServer/GameServer.csproj @@ -20,6 +20,9 @@ PreserveNewest + + PreserveNewest + diff --git a/GameServer/Models/ModelManager.cs b/GameServer/Models/ModelManager.cs index ad135d5..851b318 100644 --- a/GameServer/Models/ModelManager.cs +++ b/GameServer/Models/ModelManager.cs @@ -1,16 +1,25 @@ using GameServer.Controllers.Attributes; +using GameServer.Settings; using GameServer.Systems.Event; +using Microsoft.Extensions.Options; namespace GameServer.Models; internal class ModelManager { + private readonly IOptions _playerStartingValues; + private PlayerModel? _playerModel; private CreatureModel? _creatureModel; + public ModelManager(IOptions playerStartingValues) + { + _playerStartingValues = playerStartingValues; + } + [GameEvent(GameEventType.Login)] public void OnLogin() { - _playerModel = PlayerModel.CreateDefaultPlayer(); + _playerModel = PlayerModel.CreateDefaultPlayer(_playerStartingValues.Value); _creatureModel = new CreatureModel(_playerModel.Id); } diff --git a/GameServer/Models/PlayerModel.cs b/GameServer/Models/PlayerModel.cs index d453cec..94e7fba 100644 --- a/GameServer/Models/PlayerModel.cs +++ b/GameServer/Models/PlayerModel.cs @@ -1,22 +1,25 @@ -namespace GameServer.Models; +using GameServer.Settings; + +namespace GameServer.Models; internal class PlayerModel { public int Id { get; private set; } public string Name { get; private set; } - public int CharacterId { get; set; } + public int[] Characters { get; private set; } public PlayerModel() { Name = string.Empty; + Characters = []; } - public static PlayerModel CreateDefaultPlayer() + public static PlayerModel CreateDefaultPlayer(PlayerStartingValues startingValues) { return new PlayerModel { Id = 1337, - Name = "ReversedRooms", - CharacterId = 1601 + Name = startingValues.Name, + Characters = startingValues.Characters }; } } diff --git a/GameServer/Program.cs b/GameServer/Program.cs index 7c06a2f..427e865 100644 --- a/GameServer/Program.cs +++ b/GameServer/Program.cs @@ -23,8 +23,7 @@ internal static class Program HostApplicationBuilder builder = Host.CreateApplicationBuilder(args); builder.Logging.AddConsole(); - builder.Services.Configure(builder.Configuration.GetRequiredSection("Gateway")); - + builder.SetupConfiguration(); builder.Services.AddControllers() .AddSingleton().AddScoped() .AddScoped().AddSingleton() @@ -36,4 +35,11 @@ internal static class Program await builder.Build().RunAsync(); } + + private static void SetupConfiguration(this HostApplicationBuilder builder) + { + builder.Configuration.AddJsonFile("gameplay.json"); + builder.Services.Configure(builder.Configuration.GetRequiredSection("Gateway")); + builder.Services.Configure(builder.Configuration.GetRequiredSection("StartingValues")); + } } diff --git a/GameServer/Settings/PlayerStartingValues.cs b/GameServer/Settings/PlayerStartingValues.cs new file mode 100644 index 0000000..ed3a630 --- /dev/null +++ b/GameServer/Settings/PlayerStartingValues.cs @@ -0,0 +1,6 @@ +namespace GameServer.Settings; +internal class PlayerStartingValues +{ + public required string Name { get; set; } + public required int[] Characters { get; set; } +} diff --git a/GameServer/Systems/Entity/EntityBase.cs b/GameServer/Systems/Entity/EntityBase.cs index 47af8c6..73e8e36 100644 --- a/GameServer/Systems/Entity/EntityBase.cs +++ b/GameServer/Systems/Entity/EntityBase.cs @@ -29,14 +29,9 @@ internal abstract class EntityBase State = EntityState.Born; } - public void Activate() + public virtual void Activate() { - AddComponents(); - } - - public virtual void AddComponents() - { - // AddComponents. + // Activate. } public virtual LivingStatus LivingStatus => LivingStatus.Alive; diff --git a/GameServer/Systems/Entity/PlayerEntity.cs b/GameServer/Systems/Entity/PlayerEntity.cs index cb7f61b..c76c2ee 100644 --- a/GameServer/Systems/Entity/PlayerEntity.cs +++ b/GameServer/Systems/Entity/PlayerEntity.cs @@ -13,15 +13,23 @@ internal class PlayerEntity : EntityBase public int ConfigId { get; } public int PlayerId { get; } - public override void AddComponents() - { - base.AddComponents(); + public bool IsCurrentRole { get; set; } + public override void OnCreate() + { + base.OnCreate(); + + // Should be created immediately EntityConcomitantsComponent concomitantsComponent = ComponentSystem.Create(); concomitantsComponent.CustomEntityIds.Add(Id); EntityVisionSkillComponent visionSkillComponent = ComponentSystem.Create(); visionSkillComponent.SetExploreTool(1001); + } + + public override void Activate() + { + base.Activate(); _ = ComponentSystem.Create(); InitAttributes(); @@ -40,6 +48,8 @@ internal class PlayerEntity : EntityBase public override EEntityType Type => EEntityType.Player; public override EntityConfigType ConfigType => EntityConfigType.Character; + public override bool IsVisible => IsCurrentRole; + public override EntityPb Pb { get diff --git a/GameServer/gameplay.json b/GameServer/gameplay.json new file mode 100644 index 0000000..d6cb740 --- /dev/null +++ b/GameServer/gameplay.json @@ -0,0 +1,6 @@ +{ + "StartingValues": { + "Name": "ReversedRooms", + "Characters": [ 1601, 1302, 1203 ] + } +} \ No newline at end of file