Entity system
This commit is contained in:
parent
13cfd2468f
commit
7392b2d20a
26 changed files with 595 additions and 216 deletions
|
@ -1,4 +1,4 @@
|
||||||
using GameServer.Controllers.Event;
|
using GameServer.Systems.Event;
|
||||||
|
|
||||||
namespace GameServer.Controllers.Attributes;
|
namespace GameServer.Controllers.Attributes;
|
||||||
|
|
||||||
|
|
147
GameServer/Controllers/CreatureController.cs
Normal file
147
GameServer/Controllers/CreatureController.cs
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
using GameServer.Controllers.Attributes;
|
||||||
|
using GameServer.Models;
|
||||||
|
using GameServer.Network;
|
||||||
|
using GameServer.Network.Messages;
|
||||||
|
using GameServer.Systems.Entity;
|
||||||
|
using GameServer.Systems.Entity.Component;
|
||||||
|
using GameServer.Systems.Event;
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Controllers;
|
||||||
|
internal class CreatureController : Controller
|
||||||
|
{
|
||||||
|
private readonly EntitySystem _entitySystem;
|
||||||
|
private readonly EntityFactory _entityFactory;
|
||||||
|
private readonly ModelManager _modelManager;
|
||||||
|
|
||||||
|
public CreatureController(PlayerSession session, EntitySystem entitySystem, EntityFactory entityFactory, ModelManager modelManager) : base(session)
|
||||||
|
{
|
||||||
|
_entitySystem = entitySystem;
|
||||||
|
_entityFactory = entityFactory;
|
||||||
|
_modelManager = modelManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task JoinScene(int instanceId)
|
||||||
|
{
|
||||||
|
_modelManager.Creature.SetSceneLoadingData(instanceId);
|
||||||
|
CreateInitialPlayer();
|
||||||
|
|
||||||
|
await Session.Push(MessageId.JoinSceneNotify, new JoinSceneNotify
|
||||||
|
{
|
||||||
|
MaxEntityId = 10000,
|
||||||
|
TransitionOption = new TransitionOptionPb
|
||||||
|
{
|
||||||
|
TransitionType = (int)TransitionType.Empty
|
||||||
|
},
|
||||||
|
SceneInfo = CreateSceneInfo()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[NetEvent(MessageId.EntityActiveRequest)]
|
||||||
|
public async Task<ResponseMessage> OnEntityActiveRequest(EntityActiveRequest request)
|
||||||
|
{
|
||||||
|
EntityActiveResponse response;
|
||||||
|
|
||||||
|
EntityBase? entity = _entitySystem.Get<EntityBase>(request.EntityId);
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
_entitySystem.Activate(entity);
|
||||||
|
response = new EntityActiveResponse
|
||||||
|
{
|
||||||
|
ErrorCode = (int)ErrorCode.Success
|
||||||
|
};
|
||||||
|
|
||||||
|
response.ComponentPbs.AddRange(entity.ComponentSystem.Pb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response = new EntityActiveResponse { ErrorCode = (int)ErrorCode.ErrActionEntityNoExist };
|
||||||
|
}
|
||||||
|
|
||||||
|
await OnVisionSkillChanged();
|
||||||
|
return Response(MessageId.EntityActiveResponse, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NetEvent(MessageId.SceneLoadingFinishRequest)]
|
||||||
|
public ResponseMessage OnSceneLoadingFinishRequest()
|
||||||
|
{
|
||||||
|
_modelManager.Creature.OnWorldDone();
|
||||||
|
|
||||||
|
return Response(MessageId.SceneLoadingFinishResponse, new SceneLoadingFinishResponse());
|
||||||
|
}
|
||||||
|
|
||||||
|
[GameEvent(GameEventType.VisionSkillChanged)]
|
||||||
|
public async Task OnVisionSkillChanged()
|
||||||
|
{
|
||||||
|
PlayerEntity? playerEntity = GetPlayerEntity(_modelManager.Player.Id);
|
||||||
|
if (playerEntity == null) return;
|
||||||
|
|
||||||
|
EntityVisionSkillComponent visionSkillComponent = playerEntity.ComponentSystem.Get<EntityVisionSkillComponent>();
|
||||||
|
|
||||||
|
VisionSkillChangeNotify skillChangeNotify = new() { EntityId = playerEntity.Id };
|
||||||
|
skillChangeNotify.VisionSkillInfos.AddRange(visionSkillComponent.Skills);
|
||||||
|
|
||||||
|
await Session.Push(MessageId.VisionSkillChangeNotify, skillChangeNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerEntity? GetPlayerEntity(int playerId)
|
||||||
|
{
|
||||||
|
return _entitySystem.EnumerateEntities().FirstOrDefault(entity => entity is PlayerEntity p && p.PlayerId == playerId) as PlayerEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SceneInformation CreateSceneInfo()
|
||||||
|
{
|
||||||
|
SceneInformation scene = new()
|
||||||
|
{
|
||||||
|
InstanceId = _modelManager.Creature.InstanceId,
|
||||||
|
OwnerId = _modelManager.Creature.OwnerId,
|
||||||
|
CurContextId = _modelManager.Player.Id,
|
||||||
|
TimeInfo = new(),
|
||||||
|
AoiData = new(),
|
||||||
|
PlayerInfos =
|
||||||
|
{
|
||||||
|
new ScenePlayerInformation
|
||||||
|
{
|
||||||
|
PlayerId = _modelManager.Player.Id,
|
||||||
|
Level = 1,
|
||||||
|
IsOffline = false,
|
||||||
|
Location = new()
|
||||||
|
{
|
||||||
|
X = 4000,
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
scene.AoiData.Entities.AddRange(_entitySystem.Pb);
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateInitialPlayer()
|
||||||
|
{
|
||||||
|
PlayerEntity entity = _entityFactory.CreatePlayer(1601, _modelManager.Player.Id);
|
||||||
|
entity.Pos = new()
|
||||||
|
{
|
||||||
|
X = 4000,
|
||||||
|
Y = -2000,
|
||||||
|
Z = 260
|
||||||
|
};
|
||||||
|
|
||||||
|
_entitySystem.Create(entity);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +0,0 @@
|
||||||
namespace GameServer.Controllers.Event;
|
|
||||||
internal enum GameEventType
|
|
||||||
{
|
|
||||||
Login = 1,
|
|
||||||
EnterGame
|
|
||||||
}
|
|
|
@ -2,8 +2,8 @@
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Controllers.Event;
|
|
||||||
using GameServer.Network.Messages;
|
using GameServer.Network.Messages;
|
||||||
|
using GameServer.Systems.Event;
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Controllers.Event;
|
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
|
using GameServer.Systems.Event;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Controllers.Event;
|
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
using GameServer.Network.Messages;
|
||||||
|
using GameServer.Systems.Event;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Event;
|
using GameServer.Controllers.Factory;
|
||||||
using GameServer.Controllers.Factory;
|
using GameServer.Systems.Event;
|
||||||
using GameServer.Network;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace GameServer.Controllers.Manager;
|
namespace GameServer.Controllers.Manager;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Controllers.Event;
|
|
||||||
using GameServer.Models;
|
using GameServer.Models;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
|
using GameServer.Systems.Event;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Controllers.Event;
|
|
||||||
using GameServer.Models;
|
using GameServer.Models;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
using GameServer.Network.Messages;
|
||||||
|
using GameServer.Systems.Event;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Controllers.Event;
|
using GameServer.Models;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
using GameServer.Network.Messages;
|
||||||
|
using GameServer.Systems.Entity;
|
||||||
|
using GameServer.Systems.Entity.Component;
|
||||||
|
using GameServer.Systems.Event;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
@ -38,19 +41,15 @@ internal class RouletteController : Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
[NetEvent(MessageId.VisionExploreSkillSetRequest)]
|
[NetEvent(MessageId.VisionExploreSkillSetRequest)]
|
||||||
public async Task<ResponseMessage> OnVisionExploreSkillSetRequest(VisionExploreSkillSetRequest request)
|
public async Task<ResponseMessage> OnVisionExploreSkillSetRequest(VisionExploreSkillSetRequest request, CreatureController creatureController, ModelManager modelManager, EventSystem eventSystem)
|
||||||
{
|
{
|
||||||
await Session.Push(MessageId.VisionSkillChangeNotify, new VisionSkillChangeNotify
|
PlayerEntity? playerEntity = creatureController.GetPlayerEntity(modelManager.Player.Id);
|
||||||
{
|
if (playerEntity == null) return Response(MessageId.VisionExploreSkillSetResponse, new VisionExploreSkillSetResponse { ErrCode = (int)ErrorCode.PlayerNotInAnyScene });
|
||||||
EntityId = 1,
|
|
||||||
VisionSkillInfos =
|
EntityVisionSkillComponent visionSkillComponent = playerEntity.ComponentSystem.Get<EntityVisionSkillComponent>();
|
||||||
{
|
visionSkillComponent.SetExploreTool(request.SkillId);
|
||||||
new VisionSkillInformation
|
|
||||||
{
|
await eventSystem.Emit(GameEventType.VisionSkillChanged);
|
||||||
SkillId = request.SkillId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return Response(MessageId.VisionExploreSkillSetResponse, new VisionExploreSkillSetResponse
|
return Response(MessageId.VisionExploreSkillSetResponse, new VisionExploreSkillSetResponse
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Controllers.Event;
|
|
||||||
using GameServer.Models;
|
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
using GameServer.Network.Messages;
|
||||||
|
using GameServer.Systems.Event;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
@ -14,187 +13,11 @@ internal class WorldController : Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
[GameEvent(GameEventType.EnterGame)]
|
[GameEvent(GameEventType.EnterGame)]
|
||||||
public async Task OnEnterGame(ModelManager modelManager)
|
public async Task OnEnterGame(CreatureController creatureController)
|
||||||
{
|
{
|
||||||
PlayerModel player = modelManager.Player;
|
await creatureController.JoinScene(8);
|
||||||
|
|
||||||
await Session.Push(MessageId.JoinSceneNotify, new JoinSceneNotify
|
|
||||||
{
|
|
||||||
MaxEntityId = 2,
|
|
||||||
TransitionOption = new TransitionOptionPb
|
|
||||||
{
|
|
||||||
TransitionType = (int)TransitionType.Empty
|
|
||||||
},
|
|
||||||
SceneInfo = new SceneInformation
|
|
||||||
{
|
|
||||||
OwnerId = player.Id,
|
|
||||||
Mode = (int)SceneMode.Single,
|
|
||||||
InstanceId = 8,
|
|
||||||
AoiData = new PlayerSceneAoiData
|
|
||||||
{
|
|
||||||
GenIds = { 1 },
|
|
||||||
Entities =
|
|
||||||
{
|
|
||||||
new EntityPb
|
|
||||||
{
|
|
||||||
EntityState = (int)EntityState.Born,
|
|
||||||
EntityType = (int)EEntityType.Player,
|
|
||||||
PlayerId = player.Id,
|
|
||||||
LivingStatus = (int)LivingStatus.Alive,
|
|
||||||
ConfigId = player.CharacterId,
|
|
||||||
ConfigType = (int)EntityConfigType.Character,
|
|
||||||
Id = 1,
|
|
||||||
IsVisible = true,
|
|
||||||
Pos = new Vector
|
|
||||||
{
|
|
||||||
X = 4000,
|
|
||||||
Y = -2000,
|
|
||||||
Z = 260
|
|
||||||
},
|
|
||||||
Rot = new(),
|
|
||||||
InitLinearVelocity = new(),
|
|
||||||
PrefabIncId = 0,
|
|
||||||
InitPos = new Vector
|
|
||||||
{
|
|
||||||
X = 4000,
|
|
||||||
Y = -2000,
|
|
||||||
Z = 260
|
|
||||||
},
|
|
||||||
ComponentPbs =
|
|
||||||
{
|
|
||||||
new EntityComponentPb
|
|
||||||
{
|
|
||||||
VisionSkillComponent = new VisionSkillComponentPb
|
|
||||||
{
|
|
||||||
VisionSkillInfos =
|
|
||||||
{
|
|
||||||
new VisionSkillInformation
|
|
||||||
{
|
|
||||||
SkillId = 1001
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new EntityComponentPb
|
|
||||||
{
|
|
||||||
AttributeComponent = new AttributeComponentPb
|
|
||||||
{
|
|
||||||
GameAttributes =
|
|
||||||
{
|
|
||||||
new GameplayAttributeData
|
|
||||||
{
|
|
||||||
AttributeType = (int)EAttributeType.Life,
|
|
||||||
BaseValue = 1000,
|
|
||||||
CurrentValue = 1000
|
|
||||||
},
|
|
||||||
new GameplayAttributeData
|
|
||||||
{
|
|
||||||
AttributeType = (int)EAttributeType.LifeMax,
|
|
||||||
BaseValue = 1000,
|
|
||||||
CurrentValue = 1000
|
|
||||||
},
|
|
||||||
new GameplayAttributeData
|
|
||||||
{
|
|
||||||
AttributeType = (int)EAttributeType.EnergyMax,
|
|
||||||
BaseValue = 10,
|
|
||||||
CurrentValue = 10
|
|
||||||
},
|
|
||||||
new GameplayAttributeData
|
|
||||||
{
|
|
||||||
AttributeType = (int)EAttributeType.Energy,
|
|
||||||
BaseValue = 10,
|
|
||||||
CurrentValue = 10
|
|
||||||
},
|
|
||||||
new GameplayAttributeData
|
|
||||||
{
|
|
||||||
AttributeType = (int)EAttributeType.SpecialEnergy3,
|
|
||||||
BaseValue = 10,
|
|
||||||
CurrentValue = 10
|
|
||||||
},
|
|
||||||
new GameplayAttributeData
|
|
||||||
{
|
|
||||||
AttributeType = (int)EAttributeType.SpecialEnergy3Max,
|
|
||||||
BaseValue = 10,
|
|
||||||
CurrentValue = 10
|
|
||||||
},
|
|
||||||
new GameplayAttributeData
|
|
||||||
{
|
|
||||||
AttributeType = (int)EAttributeType.AutoAttackSpeed,
|
|
||||||
BaseValue = 10000,
|
|
||||||
CurrentValue = 10000
|
|
||||||
},
|
|
||||||
new GameplayAttributeData
|
|
||||||
{
|
|
||||||
AttributeType = (int)EAttributeType.CastAttackSpeed,
|
|
||||||
BaseValue = 10000,
|
|
||||||
CurrentValue = 10000
|
|
||||||
},
|
|
||||||
new GameplayAttributeData
|
|
||||||
{
|
|
||||||
AttributeType = (int)EAttributeType.Atk,
|
|
||||||
BaseValue = 1,
|
|
||||||
CurrentValue = 1
|
|
||||||
},
|
|
||||||
new GameplayAttributeData
|
|
||||||
{
|
|
||||||
AttributeType = (int)EAttributeType.Lv,
|
|
||||||
BaseValue = 1,
|
|
||||||
CurrentValue = 1
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new EntityComponentPb
|
|
||||||
{
|
|
||||||
ConcomitantsComponentPb = new ConcomitantsComponentPb
|
|
||||||
{
|
|
||||||
CustomEntityIds = {1},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TimeInfo = new SceneTimeInfo
|
|
||||||
{
|
|
||||||
Hour = 23
|
|
||||||
},
|
|
||||||
PlayerInfos =
|
|
||||||
{
|
|
||||||
new ScenePlayerInformation
|
|
||||||
{
|
|
||||||
PlayerId = player.Id,
|
|
||||||
Level = 1,
|
|
||||||
IsOffline = false,
|
|
||||||
Location = new()
|
|
||||||
{
|
|
||||||
X = 4000,
|
|
||||||
Y = -2000,
|
|
||||||
Z = 260
|
|
||||||
},
|
|
||||||
FightRoleInfos =
|
|
||||||
{
|
|
||||||
new FightRoleInformation
|
|
||||||
{
|
|
||||||
EntityId = 1,
|
|
||||||
CurHp = 1000,
|
|
||||||
MaxHp = 1000,
|
|
||||||
IsControl = true,
|
|
||||||
RoleId = player.CharacterId,
|
|
||||||
RoleLevel = 1,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
PlayerName = player.Name
|
|
||||||
}
|
|
||||||
},
|
|
||||||
CurContextId = player.Id
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[NetEvent(MessageId.EntityActiveRequest)]
|
|
||||||
public ResponseMessage OnEntityActiveRequest() => Response(MessageId.EntityActiveResponse, new EntityActiveResponse());
|
|
||||||
|
|
||||||
[NetEvent(MessageId.EntityOnLandedRequest)]
|
[NetEvent(MessageId.EntityOnLandedRequest)]
|
||||||
public ResponseMessage OnEntityOnLandedRequest() => Response(MessageId.EntityOnLandedResponse, new EntityOnLandedResponse());
|
public ResponseMessage OnEntityOnLandedRequest() => Response(MessageId.EntityOnLandedResponse, new EntityOnLandedResponse());
|
||||||
|
|
||||||
|
@ -204,9 +27,6 @@ internal class WorldController : Controller
|
||||||
[NetEvent(MessageId.EntityLoadCompleteRequest)]
|
[NetEvent(MessageId.EntityLoadCompleteRequest)]
|
||||||
public ResponseMessage OnEntityLoadCompleteRequest() => Response(MessageId.EntityLoadCompleteResponse, new EntityLoadCompleteResponse());
|
public ResponseMessage OnEntityLoadCompleteRequest() => Response(MessageId.EntityLoadCompleteResponse, new EntityLoadCompleteResponse());
|
||||||
|
|
||||||
[NetEvent(MessageId.SceneLoadingFinishRequest)]
|
|
||||||
public ResponseMessage OnSceneLoadingFinishRequest() => Response(MessageId.SceneLoadingFinishResponse, new SceneLoadingFinishResponse());
|
|
||||||
|
|
||||||
[NetEvent(MessageId.UpdateSceneDateRequest)]
|
[NetEvent(MessageId.UpdateSceneDateRequest)]
|
||||||
public ResponseMessage OnUpdateSceneDateRequest() => Response(MessageId.UpdateSceneDateResponse, new UpdateSceneDateResponse());
|
public ResponseMessage OnUpdateSceneDateRequest() => Response(MessageId.UpdateSceneDateResponse, new UpdateSceneDateResponse());
|
||||||
}
|
}
|
||||||
|
|
26
GameServer/Models/CreatureModel.cs
Normal file
26
GameServer/Models/CreatureModel.cs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
namespace GameServer.Models;
|
||||||
|
internal class CreatureModel
|
||||||
|
{
|
||||||
|
public int OwnerId { get; }
|
||||||
|
|
||||||
|
public int InstanceId { get; private set; }
|
||||||
|
public bool LoadingWorld { get; private set; }
|
||||||
|
|
||||||
|
public long PlayerEntityId { get; set; }
|
||||||
|
|
||||||
|
public CreatureModel(int ownerId)
|
||||||
|
{
|
||||||
|
OwnerId = ownerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSceneLoadingData(int instanceId)
|
||||||
|
{
|
||||||
|
InstanceId = instanceId;
|
||||||
|
LoadingWorld = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnWorldDone()
|
||||||
|
{
|
||||||
|
LoadingWorld = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,20 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Controllers.Event;
|
using GameServer.Systems.Event;
|
||||||
|
|
||||||
namespace GameServer.Models;
|
namespace GameServer.Models;
|
||||||
internal class ModelManager
|
internal class ModelManager
|
||||||
{
|
{
|
||||||
private PlayerModel? _playerModel;
|
private PlayerModel? _playerModel;
|
||||||
|
private CreatureModel? _creatureModel;
|
||||||
|
|
||||||
[GameEvent(GameEventType.Login)]
|
[GameEvent(GameEventType.Login)]
|
||||||
public void OnLogin()
|
public void OnLogin()
|
||||||
{
|
{
|
||||||
_playerModel = PlayerModel.CreateDefaultPlayer();
|
_playerModel = PlayerModel.CreateDefaultPlayer();
|
||||||
|
_creatureModel = new CreatureModel(_playerModel.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerModel Player => _playerModel ?? throw new InvalidOperationException($"Trying to access {nameof(PlayerModel)} instance before initialization!");
|
public PlayerModel Player => _playerModel ?? throw new InvalidOperationException($"Trying to access {nameof(PlayerModel)} instance before initialization!");
|
||||||
|
|
||||||
|
public CreatureModel Creature => _creatureModel ?? throw new InvalidOperationException($"Trying to access {nameof(CreatureModel)} instance before initialization!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using GameServer.Controllers.Event;
|
using GameServer.Controllers.Factory;
|
||||||
using GameServer.Controllers.Factory;
|
|
||||||
using GameServer.Controllers.Manager;
|
using GameServer.Controllers.Manager;
|
||||||
using GameServer.Extensions;
|
using GameServer.Extensions;
|
||||||
using GameServer.Models;
|
using GameServer.Models;
|
||||||
|
@ -7,6 +6,8 @@ using GameServer.Network;
|
||||||
using GameServer.Network.Kcp;
|
using GameServer.Network.Kcp;
|
||||||
using GameServer.Network.Messages;
|
using GameServer.Network.Messages;
|
||||||
using GameServer.Network.Rpc;
|
using GameServer.Network.Rpc;
|
||||||
|
using GameServer.Systems.Entity;
|
||||||
|
using GameServer.Systems.Event;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
@ -25,7 +26,8 @@ internal static class Program
|
||||||
.AddScoped<MessageManager>().AddSingleton<EventHandlerFactory>()
|
.AddScoped<MessageManager>().AddSingleton<EventHandlerFactory>()
|
||||||
.AddScoped<RpcManager>().AddScoped<IRpcEndPoint, RpcSessionEndPoint>()
|
.AddScoped<RpcManager>().AddScoped<IRpcEndPoint, RpcSessionEndPoint>()
|
||||||
.AddSingleton<SessionManager>()
|
.AddSingleton<SessionManager>()
|
||||||
.AddScoped<EventSystem>().AddScoped<ModelManager>().AddScoped<ControllerManager>()
|
.AddScoped<EventSystem>().AddScoped<EntitySystem>().AddScoped<EntityFactory>()
|
||||||
|
.AddScoped<ModelManager>().AddScoped<ControllerManager>()
|
||||||
.AddHostedService<WWGameServer>();
|
.AddHostedService<WWGameServer>();
|
||||||
|
|
||||||
await builder.Build().RunAsync();
|
await builder.Build().RunAsync();
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Entity.Component;
|
||||||
|
internal class EntityAttributeComponent : EntityComponentBase
|
||||||
|
{
|
||||||
|
public override EntityComponentType Type => EntityComponentType.Attribute;
|
||||||
|
|
||||||
|
private readonly Dictionary<EAttributeType, GameplayAttributeData> _gameplayAttributes;
|
||||||
|
|
||||||
|
public EntityAttributeComponent()
|
||||||
|
{
|
||||||
|
_gameplayAttributes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAttribute(EAttributeType type, int currentValue, int baseValue)
|
||||||
|
{
|
||||||
|
if (!_gameplayAttributes.TryGetValue(type, out GameplayAttributeData? attribute))
|
||||||
|
{
|
||||||
|
attribute = new GameplayAttributeData
|
||||||
|
{
|
||||||
|
AttributeType = (int)type
|
||||||
|
};
|
||||||
|
|
||||||
|
_gameplayAttributes.Add(type, attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
attribute.CurrentValue = currentValue;
|
||||||
|
attribute.BaseValue = baseValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAttribute(EAttributeType type, int currentValue)
|
||||||
|
{
|
||||||
|
if (!_gameplayAttributes.TryGetValue(type, out GameplayAttributeData? attribute))
|
||||||
|
{
|
||||||
|
SetAttribute(type, currentValue, currentValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
attribute.CurrentValue = currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetAttribute(EAttributeType type)
|
||||||
|
{
|
||||||
|
if (_gameplayAttributes.TryGetValue(type, out GameplayAttributeData? attribute))
|
||||||
|
return attribute.CurrentValue;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetAttributeBase(EAttributeType type)
|
||||||
|
{
|
||||||
|
if (_gameplayAttributes.TryGetValue(type, out GameplayAttributeData? attribute))
|
||||||
|
return attribute.BaseValue;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override EntityComponentPb Pb
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
EntityComponentPb pb = new()
|
||||||
|
{
|
||||||
|
AttributeComponent = new()
|
||||||
|
};
|
||||||
|
|
||||||
|
pb.AttributeComponent.GameAttributes.AddRange(_gameplayAttributes.Values);
|
||||||
|
|
||||||
|
return pb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Entity.Component;
|
||||||
|
internal abstract class EntityComponentBase
|
||||||
|
{
|
||||||
|
public abstract EntityComponentType Type { get; }
|
||||||
|
public abstract EntityComponentPb Pb { get; }
|
||||||
|
}
|
34
GameServer/Systems/Entity/Component/EntityComponentSystem.cs
Normal file
34
GameServer/Systems/Entity/Component/EntityComponentSystem.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Entity.Component;
|
||||||
|
internal class EntityComponentSystem
|
||||||
|
{
|
||||||
|
private readonly List<EntityComponentBase> _components;
|
||||||
|
|
||||||
|
public EntityComponentSystem()
|
||||||
|
{
|
||||||
|
_components = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public TEntityComponent Create<TEntityComponent>() where TEntityComponent : EntityComponentBase, new()
|
||||||
|
{
|
||||||
|
if (_components.Any(component => component is TEntityComponent)) throw new InvalidOperationException($"Component of type {nameof(TEntityComponent)} already exists");
|
||||||
|
|
||||||
|
TEntityComponent component = new();
|
||||||
|
_components.Add(component);
|
||||||
|
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TEntityComponent Get<TEntityComponent>() where TEntityComponent : EntityComponentBase
|
||||||
|
{
|
||||||
|
return (_components.Single(component => component is TEntityComponent) as TEntityComponent)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGet<TEntityComponent>(out TEntityComponent? component) where TEntityComponent : EntityComponentBase
|
||||||
|
{
|
||||||
|
return (component = _components.SingleOrDefault(component => component is TEntityComponent) as TEntityComponent) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EntityComponentPb> Pb => _components.Select(component => component.Pb);
|
||||||
|
}
|
37
GameServer/Systems/Entity/Component/EntityComponentType.cs
Normal file
37
GameServer/Systems/Entity/Component/EntityComponentType.cs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
namespace GameServer.Systems.Entity.Component;
|
||||||
|
internal enum EntityComponentType
|
||||||
|
{
|
||||||
|
Attribute,
|
||||||
|
Tag,
|
||||||
|
Trigger,
|
||||||
|
Summoner,
|
||||||
|
Part,
|
||||||
|
VisionSkill,
|
||||||
|
AnimationState,
|
||||||
|
BlackboardParam,
|
||||||
|
SysBuff,
|
||||||
|
ClientData,
|
||||||
|
MonsterWeapon,
|
||||||
|
MonsterAi,
|
||||||
|
FightBuff,
|
||||||
|
NearbyTracking,
|
||||||
|
Drop,
|
||||||
|
MonsterCapture,
|
||||||
|
LogicState,
|
||||||
|
Advice,
|
||||||
|
Lift,
|
||||||
|
Interact,
|
||||||
|
Equip,
|
||||||
|
BeControlled,
|
||||||
|
Concomitants,
|
||||||
|
TimelineTrack,
|
||||||
|
Summons,
|
||||||
|
EntityFsm,
|
||||||
|
Board,
|
||||||
|
PlacementItem,
|
||||||
|
StateTag,
|
||||||
|
MonsterGachaData,
|
||||||
|
Fan,
|
||||||
|
Npc,
|
||||||
|
Bubble
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Entity.Component;
|
||||||
|
internal class EntityConcomitantsComponent : EntityComponentBase
|
||||||
|
{
|
||||||
|
public List<long> CustomEntityIds { get; }
|
||||||
|
|
||||||
|
public EntityConcomitantsComponent()
|
||||||
|
{
|
||||||
|
CustomEntityIds = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public override EntityComponentType Type => EntityComponentType.Concomitants;
|
||||||
|
|
||||||
|
public override EntityComponentPb Pb
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
EntityComponentPb pb = new()
|
||||||
|
{
|
||||||
|
ConcomitantsComponentPb = new()
|
||||||
|
};
|
||||||
|
|
||||||
|
pb.ConcomitantsComponentPb.CustomEntityIds.AddRange(CustomEntityIds);
|
||||||
|
return pb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Entity.Component;
|
||||||
|
internal class EntityVisionSkillComponent : EntityComponentBase
|
||||||
|
{
|
||||||
|
public List<VisionSkillInformation> Skills { get; }
|
||||||
|
|
||||||
|
public EntityVisionSkillComponent()
|
||||||
|
{
|
||||||
|
Skills = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetExploreTool(int toolId)
|
||||||
|
{
|
||||||
|
Skills.Clear();
|
||||||
|
Skills.Add(new VisionSkillInformation
|
||||||
|
{
|
||||||
|
SkillId = toolId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override EntityComponentType Type => EntityComponentType.VisionSkill;
|
||||||
|
|
||||||
|
public override EntityComponentPb Pb
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
EntityComponentPb pb = new()
|
||||||
|
{
|
||||||
|
VisionSkillComponent = new VisionSkillComponentPb()
|
||||||
|
};
|
||||||
|
|
||||||
|
pb.VisionSkillComponent.VisionSkillInfos.AddRange(Skills);
|
||||||
|
return pb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
49
GameServer/Systems/Entity/EntityBase.cs
Normal file
49
GameServer/Systems/Entity/EntityBase.cs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
using GameServer.Systems.Entity.Component;
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Entity;
|
||||||
|
internal abstract class EntityBase
|
||||||
|
{
|
||||||
|
public long Id { get; }
|
||||||
|
public EntityComponentSystem ComponentSystem { get; }
|
||||||
|
|
||||||
|
public Vector Pos { get; set; }
|
||||||
|
public Rotator Rot { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
|
||||||
|
public EntityState State { get; protected set; }
|
||||||
|
|
||||||
|
public EntityBase(long id)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
|
||||||
|
Pos = new Vector();
|
||||||
|
Rot = new Rotator();
|
||||||
|
|
||||||
|
ComponentSystem = new EntityComponentSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnCreate()
|
||||||
|
{
|
||||||
|
State = EntityState.Born;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Activate()
|
||||||
|
{
|
||||||
|
AddComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void AddComponents()
|
||||||
|
{
|
||||||
|
// AddComponents.
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual LivingStatus LivingStatus => LivingStatus.Alive;
|
||||||
|
public virtual bool IsVisible => true;
|
||||||
|
|
||||||
|
public abstract EEntityType Type { get; }
|
||||||
|
public abstract EntityConfigType ConfigType { get; }
|
||||||
|
|
||||||
|
public abstract EntityPb Pb { get; }
|
||||||
|
}
|
10
GameServer/Systems/Entity/EntityFactory.cs
Normal file
10
GameServer/Systems/Entity/EntityFactory.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace GameServer.Systems.Entity;
|
||||||
|
internal class EntityFactory
|
||||||
|
{
|
||||||
|
private long _entityIdCounter;
|
||||||
|
|
||||||
|
public PlayerEntity CreatePlayer(int characterConfigId, int playerId)
|
||||||
|
=> new(NextId(), characterConfigId, playerId);
|
||||||
|
|
||||||
|
private long NextId() => Interlocked.Increment(ref _entityIdCounter);
|
||||||
|
}
|
38
GameServer/Systems/Entity/EntitySystem.cs
Normal file
38
GameServer/Systems/Entity/EntitySystem.cs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Entity;
|
||||||
|
internal class EntitySystem
|
||||||
|
{
|
||||||
|
private readonly List<EntityBase> _entities;
|
||||||
|
|
||||||
|
public EntitySystem()
|
||||||
|
{
|
||||||
|
_entities = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EntityBase> EnumerateEntities()
|
||||||
|
{
|
||||||
|
return _entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Create(EntityBase entity)
|
||||||
|
{
|
||||||
|
if (_entities.Any(e => e.Id == entity.Id))
|
||||||
|
throw new InvalidOperationException($"EntitySystem::Create - entity with id {entity.Id} already exists");
|
||||||
|
|
||||||
|
entity.OnCreate();
|
||||||
|
_entities.Add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Activate(EntityBase entity)
|
||||||
|
{
|
||||||
|
entity.Activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TEntity? Get<TEntity>(long id) where TEntity : EntityBase
|
||||||
|
{
|
||||||
|
return _entities.SingleOrDefault(e => e.Id == id) as TEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EntityPb> Pb => _entities.Select(e => e.Pb);
|
||||||
|
}
|
66
GameServer/Systems/Entity/PlayerEntity.cs
Normal file
66
GameServer/Systems/Entity/PlayerEntity.cs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
using GameServer.Systems.Entity.Component;
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Entity;
|
||||||
|
internal class PlayerEntity : EntityBase
|
||||||
|
{
|
||||||
|
public PlayerEntity(long id, int configId, int playerId) : base(id)
|
||||||
|
{
|
||||||
|
ConfigId = configId;
|
||||||
|
PlayerId = playerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ConfigId { get; }
|
||||||
|
public int PlayerId { get; }
|
||||||
|
|
||||||
|
public override void AddComponents()
|
||||||
|
{
|
||||||
|
base.AddComponents();
|
||||||
|
|
||||||
|
EntityConcomitantsComponent concomitantsComponent = ComponentSystem.Create<EntityConcomitantsComponent>();
|
||||||
|
concomitantsComponent.CustomEntityIds.Add(Id);
|
||||||
|
|
||||||
|
EntityVisionSkillComponent visionSkillComponent = ComponentSystem.Create<EntityVisionSkillComponent>();
|
||||||
|
visionSkillComponent.SetExploreTool(1001);
|
||||||
|
|
||||||
|
_ = ComponentSystem.Create<EntityAttributeComponent>();
|
||||||
|
InitAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitAttributes()
|
||||||
|
{
|
||||||
|
EntityAttributeComponent attributeComponent = ComponentSystem.Get<EntityAttributeComponent>();
|
||||||
|
attributeComponent.SetAttribute(EAttributeType.Life, 1000);
|
||||||
|
attributeComponent.SetAttribute(EAttributeType.LifeMax, 1000);
|
||||||
|
attributeComponent.SetAttribute(EAttributeType.Lv, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override EEntityType Type => EEntityType.Player;
|
||||||
|
public override EntityConfigType ConfigType => EntityConfigType.Character;
|
||||||
|
|
||||||
|
public override EntityPb Pb
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
EntityPb pb = new()
|
||||||
|
{
|
||||||
|
Id = Id,
|
||||||
|
EntityType = (int)Type,
|
||||||
|
ConfigType = (int)ConfigType,
|
||||||
|
EntityState = (int)State,
|
||||||
|
ConfigId = ConfigId,
|
||||||
|
Pos = Pos,
|
||||||
|
Rot = Rot,
|
||||||
|
PlayerId = PlayerId,
|
||||||
|
LivingStatus = (int)LivingStatus,
|
||||||
|
IsVisible = IsVisible,
|
||||||
|
InitLinearVelocity = new(),
|
||||||
|
InitPos = new()
|
||||||
|
};
|
||||||
|
|
||||||
|
pb.ComponentPbs.AddRange(ComponentSystem.Pb);
|
||||||
|
|
||||||
|
return pb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ using GameServer.Controllers.Manager;
|
||||||
using GameServer.Models;
|
using GameServer.Models;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace GameServer.Controllers.Event;
|
namespace GameServer.Systems.Event;
|
||||||
internal class EventSystem
|
internal class EventSystem
|
||||||
{
|
{
|
||||||
private static readonly ImmutableDictionary<GameEventType, Func<ModelManager, Task>> s_modelManagerEventHandlers = RegisterModelManagerEvents();
|
private static readonly ImmutableDictionary<GameEventType, Func<ModelManager, Task>> s_modelManagerEventHandlers = RegisterModelManagerEvents();
|
9
GameServer/Systems/Event/GameEventType.cs
Normal file
9
GameServer/Systems/Event/GameEventType.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace GameServer.Systems.Event;
|
||||||
|
internal enum GameEventType
|
||||||
|
{
|
||||||
|
Login = 1,
|
||||||
|
EnterGame,
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
VisionSkillChanged
|
||||||
|
}
|
Loading…
Reference in a new issue