diff --git a/GameServer/Controllers/CreatureController.cs b/GameServer/Controllers/CreatureController.cs index ee493c7..24726d3 100644 --- a/GameServer/Controllers/CreatureController.cs +++ b/GameServer/Controllers/CreatureController.cs @@ -1,5 +1,6 @@ using Core.Config; using GameServer.Controllers.Attributes; +using GameServer.Extensions.Logic; using GameServer.Models; using GameServer.Network; using GameServer.Network.Messages; @@ -243,12 +244,14 @@ internal class CreatureController : Controller { for (int i = 0; i < _modelManager.Formation.RoleIds.Length; i++) { - PlayerEntity entity = _entityFactory.CreatePlayer(_modelManager.Formation.RoleIds[i], _modelManager.Player.Id); + int roleId = _modelManager.Formation.RoleIds[i]; + + PlayerEntity entity = _entityFactory.CreatePlayer(roleId, _modelManager.Player.Id); entity.Pos = _modelManager.Player.Position.Clone(); entity.IsCurrentRole = i == 0; _entitySystem.Create(entity); - entity.InitProps(_configManager.GetConfig(entity.ConfigId)!); + entity.ComponentSystem.Get().SetAll(_modelManager.Roles.GetRoleById(roleId)!.GetAttributeList()); CreateConcomitants(entity); diff --git a/GameServer/Controllers/InventoryController.cs b/GameServer/Controllers/InventoryController.cs index d04aafd..0bde569 100644 --- a/GameServer/Controllers/InventoryController.cs +++ b/GameServer/Controllers/InventoryController.cs @@ -1,5 +1,6 @@ using Core.Config; using GameServer.Controllers.Attributes; +using GameServer.Extensions.Logic; using GameServer.Models; using GameServer.Network; using GameServer.Systems.Entity; @@ -34,7 +35,7 @@ internal class InventoryController : Controller public RpcResult OnItemExchangeInfoRequest() => Response(MessageId.ItemExchangeInfoResponse, new ItemExchangeInfoResponse()); [NetEvent(MessageId.EquipTakeOnRequest)] - public async Task OnEquipTakeOnRequest(EquipTakeOnRequest request, ModelManager modelManager, CreatureController creatureController) + public async Task OnEquipTakeOnRequest(EquipTakeOnRequest request, ModelManager modelManager, CreatureController creatureController, ConfigManager configManager) { WeaponItem? weapon = modelManager.Inventory.GetWeaponById(request.Data.EquipIncId); if (weapon == null) return Response(MessageId.EquipTakeOnResponse, new EquipTakeOnResponse @@ -42,9 +43,34 @@ internal class InventoryController : Controller ErrorCode = (int)ErrorCode.ErrItemIdInvaild }); - PlayerEntity? entity = creatureController.GetPlayerEntityByRoleId(request.Data.RoleId); - if (entity != null) + WeaponConfig weaponConf = configManager.GetConfig(weapon.Id)!; + + roleInfo? role = modelManager.Roles.GetRoleById(request.Data.RoleId); + if (role == null) return Response(MessageId.EquipTakeOnResponse, new EquipTakeOnResponse { + ErrorCode = (int)ErrorCode.NotValidRole + }); + + // Take off previous weapon + WeaponItem? prevWeapon = modelManager.Inventory.WeaponList.SingleOrDefault(weapon => weapon.RoleId == role.RoleId); + if (prevWeapon != null) prevWeapon.RoleId = 0; + + // Set new weapon + weapon.RoleId = role.RoleId; + role.ApplyWeaponProperties(weaponConf); + + // Update role prop data on client + await Session.Push(MessageId.PbRolePropsNotify, new PbRolePropsNotify + { + RoleId = role.RoleId, + BaseProp = { role.BaseProp }, + AddProp = { role.AddProp } + }); + + PlayerEntity? entity = creatureController.GetPlayerEntityByRoleId(request.Data.RoleId); + if (entity != null) + { + // Update entity equipment EntityEquipComponent equipComponent = entity.ComponentSystem.Get(); equipComponent.WeaponId = weapon.Id; @@ -53,6 +79,41 @@ internal class InventoryController : Controller EntityId = entity.Id, EquipComponent = equipComponent.Pb.EquipComponent }); + + // Update entity gameplay attributes + EntityAttributeComponent attrComponent = entity.ComponentSystem.Get(); + attrComponent.SetAll(role.GetAttributeList()); + + await Session.Push(MessageId.AttributeChangedNotify, new AttributeChangedNotify + { + Id = entity.Id, + Attributes = { attrComponent.Pb.AttributeComponent.GameAttributes } + }); + } + + // Notify to take off previous one + { + EquipTakeOnNotify equipTakeOnNotify = new() + { + DataList = + { + new RoleLoadEquipData + { + EquipIncId = weapon.IncrId, + RoleId = role.RoleId + } + } + }; + + if (prevWeapon != null) + { + equipTakeOnNotify.DataList.Add(new RoleLoadEquipData + { + EquipIncId = prevWeapon.IncrId + }); + } + + await Session.Push(MessageId.EquipTakeOnNotify, equipTakeOnNotify); } return Response(MessageId.EquipTakeOnResponse, new EquipTakeOnResponse diff --git a/GameServer/Controllers/RoleController.cs b/GameServer/Controllers/RoleController.cs index 764b110..8fc333f 100644 --- a/GameServer/Controllers/RoleController.cs +++ b/GameServer/Controllers/RoleController.cs @@ -1,5 +1,6 @@ using Core.Config; using GameServer.Controllers.Attributes; +using GameServer.Extensions.Logic; using GameServer.Models; using GameServer.Network; using GameServer.Systems.Event; @@ -23,6 +24,8 @@ internal class RoleController : Controller WeaponItem weapon = modelManager.Inventory.AddNewWeapon(roleConfig.InitWeaponItemId); weapon.RoleId = role.RoleId; + + role.ApplyWeaponProperties(configManager.GetConfig(weapon.Id)!); } } diff --git a/GameServer/Extensions/Logic/RoleInfoExtensions.cs b/GameServer/Extensions/Logic/RoleInfoExtensions.cs new file mode 100644 index 0000000..53b4975 --- /dev/null +++ b/GameServer/Extensions/Logic/RoleInfoExtensions.cs @@ -0,0 +1,39 @@ +using Core.Config; +using Protocol; + +namespace GameServer.Extensions.Logic; +internal static class RoleInfoExtensions +{ + public static IEnumerable GetAttributeList(this roleInfo role) + { + return role.BaseProp.Select(prop => new GameplayAttributeData + { + AttributeType = prop.Key, + BaseValue = prop.Value, + CurrentValue = prop.Value + ((role.AddProp.SingleOrDefault(p => p.Key == prop.Key)?.Value) ?? 0), + }); + } + + public static void ApplyWeaponProperties(this roleInfo role, WeaponConfig weaponConf) + { + role.AddProp.Clear(); + + if (weaponConf.FirstPropId != null) + { + role.AddProp.Add(new ArrayIntInt + { + Key = weaponConf.FirstPropId.Id, + Value = (int)weaponConf.FirstPropId.Value + }); + } + + if (weaponConf.SecondPropId != null) + { + role.AddProp.Add(new ArrayIntInt + { + Key = weaponConf.SecondPropId.Id, + Value = (int)weaponConf.SecondPropId.Value + }); + } + } +} diff --git a/GameServer/Models/RoleModel.cs b/GameServer/Models/RoleModel.cs index b0c6d47..488d354 100644 --- a/GameServer/Models/RoleModel.cs +++ b/GameServer/Models/RoleModel.cs @@ -18,6 +18,11 @@ internal class RoleModel return info; } + public roleInfo? GetRoleById(int roleId) + { + return Roles.SingleOrDefault(role => role.RoleId == roleId); + } + private static List CreateBasePropList(BasePropertyConfig? config) { List baseProp = []; diff --git a/GameServer/Systems/Entity/Component/EntityAttributeComponent.cs b/GameServer/Systems/Entity/Component/EntityAttributeComponent.cs index 4fd4d3a..9687dbb 100644 --- a/GameServer/Systems/Entity/Component/EntityAttributeComponent.cs +++ b/GameServer/Systems/Entity/Component/EntityAttributeComponent.cs @@ -12,6 +12,14 @@ internal class EntityAttributeComponent : EntityComponentBase _gameplayAttributes = []; } + public void SetAll(IEnumerable attributes) + { + foreach (GameplayAttributeData attr in attributes) + { + SetAttribute((EAttributeType)attr.AttributeType, attr.CurrentValue, attr.BaseValue); + } + } + public void SetAttribute(EAttributeType type, int currentValue, int baseValue) { if (!_gameplayAttributes.TryGetValue(type, out GameplayAttributeData? attribute))