From d73376690927aeada96498a84c8d3c60745c45da Mon Sep 17 00:00:00 2001 From: xeon Date: Sat, 17 Feb 2024 16:49:28 +0300 Subject: [PATCH] CombatManager, Monster AI, monster death --- .../Attributes/CombatRequestAttribute.cs | 14 + .../ChatCommands/ChatSpawnCommandHandler.cs | 6 +- .../Controllers/Combat/CombatManager.cs | 306 ++++++++++++++ .../Combat/CombatRequestContext.cs | 14 + .../Controllers/CombatMessageController.cs | 31 +- GameServer/Controllers/CreatureController.cs | 57 ++- GameServer/Controllers/RoleController.cs | 3 +- GameServer/Program.cs | 4 +- .../Component/EntityAttributeComponent.cs | 1 + .../Entity/Component/EntityComponentSystem.cs | 5 +- .../Component/EntityLogicStateComponent.cs | 22 + GameServer/Systems/Entity/EntityBase.cs | 2 + Protocol/message.proto | 378 +++++++++--------- 13 files changed, 636 insertions(+), 207 deletions(-) create mode 100644 GameServer/Controllers/Attributes/CombatRequestAttribute.cs create mode 100644 GameServer/Controllers/Combat/CombatManager.cs create mode 100644 GameServer/Controllers/Combat/CombatRequestContext.cs create mode 100644 GameServer/Systems/Entity/Component/EntityLogicStateComponent.cs diff --git a/GameServer/Controllers/Attributes/CombatRequestAttribute.cs b/GameServer/Controllers/Attributes/CombatRequestAttribute.cs new file mode 100644 index 0000000..8be12c1 --- /dev/null +++ b/GameServer/Controllers/Attributes/CombatRequestAttribute.cs @@ -0,0 +1,14 @@ +using Protocol; + +namespace GameServer.Controllers.Attributes; + +[AttributeUsage(AttributeTargets.Method)] +internal class CombatRequestAttribute : Attribute +{ + public CombatRequestData.MessageOneofCase MessageCase { get; } + + public CombatRequestAttribute(CombatRequestData.MessageOneofCase messageCase) + { + MessageCase = messageCase; + } +} diff --git a/GameServer/Controllers/ChatCommands/ChatSpawnCommandHandler.cs b/GameServer/Controllers/ChatCommands/ChatSpawnCommandHandler.cs index 2a9fe7e..5f02925 100644 --- a/GameServer/Controllers/ChatCommands/ChatSpawnCommandHandler.cs +++ b/GameServer/Controllers/ChatCommands/ChatSpawnCommandHandler.cs @@ -16,14 +16,16 @@ internal class ChatSpawnCommandHandler private readonly EntityFactory _entityFactory; private readonly PlayerSession _session; private readonly ConfigManager _configManager; + private readonly CreatureController _creatureController; - public ChatSpawnCommandHandler(ModelManager modelManager, EntitySystem entitySystem, EntityFactory entityFactory, PlayerSession session, ConfigManager configManager) + public ChatSpawnCommandHandler(ModelManager modelManager, EntitySystem entitySystem, EntityFactory entityFactory, PlayerSession session, ConfigManager configManager, CreatureController creatureController) { _helperRoom = modelManager.Chat.GetChatRoom(1338); _entitySystem = entitySystem; _entityFactory = entityFactory; _session = session; _configManager = configManager; + _creatureController = creatureController; } [ChatCommand("monster")] @@ -57,6 +59,8 @@ internal class ChatSpawnCommandHandler EntityPbs = { monster.Pb } }); + await _creatureController.UpdateAiHate(); + _helperRoom.AddMessage(1338, 0, $"Successfully spawned monster with id {levelEntityId} at ({x}, {y}, {z})"); } } diff --git a/GameServer/Controllers/Combat/CombatManager.cs b/GameServer/Controllers/Combat/CombatManager.cs new file mode 100644 index 0000000..0e65296 --- /dev/null +++ b/GameServer/Controllers/Combat/CombatManager.cs @@ -0,0 +1,306 @@ +using System.Collections.Immutable; +using System.Linq.Expressions; +using System.Reflection; +using System.Security.Cryptography; +using GameServer.Controllers.Attributes; +using GameServer.Network; +using GameServer.Systems.Entity; +using GameServer.Systems.Entity.Component; +using Microsoft.Extensions.Logging; +using Protocol; + +namespace GameServer.Controllers.Combat; +internal class CombatManager +{ + private delegate Task CombatRequestHandler(CombatManager combatManager, CombatRequestContext context); + private static readonly ImmutableDictionary s_requestHandlers; + + private readonly ILogger _logger; + private readonly EntitySystem _entitySystem; + private readonly PlayerSession _session; + private readonly CreatureController _creatureController; + + static CombatManager() + { + s_requestHandlers = MapRequestHandlers(); + } + + public CombatManager(ILogger logger, EntitySystem entitySystem, PlayerSession session, CreatureController creatureController) + { + _logger = logger; + _entitySystem = entitySystem; + _session = session; + _creatureController = creatureController; + } + + [CombatRequest(CombatRequestData.MessageOneofCase.DamageExecuteRequest)] + public async Task OnDamageExecuteRequest(CombatRequestContext context) + { + DamageExecuteRequest request = context.Request.DamageExecuteRequest; + + EntityBase? entity = _entitySystem.Get(request.TargetEntityId); + if (entity == null) + { + return new CombatResponseData + { + RequestId = context.Request.RequestId, + CombatCommon = context.Request.CombatCommon, + DamageExecuteResponse = new() + { + ErrorCode = (int)ErrorCode.ErrThrowDamageReqEntityIsAlreadyDead + } + }; + } + + EntityAttributeComponent attr = entity.ComponentSystem.Get(); + attr.SetAttribute(EAttributeType.Life, (int)request.DamageId); // Pakchunk patch! (cur hp instead of damageid) + + if (request.DamageId <= 0 && entity.Type != EEntityType.Player) // Player death not implemented + { + _entitySystem.Destroy(entity); + await _session.Push(MessageId.EntityRemoveNotify, new EntityRemoveNotify + { + IsRemove = true, + RemoveInfos = + { + new EntityRemoveInfo + { + EntityId = entity.Id, + Type = (int)ERemoveEntityType.RemoveTypeNormal + } + } + }); + } + + return new CombatResponseData + { + RequestId = context.Request.RequestId, + CombatCommon = context.Request.CombatCommon, + DamageExecuteResponse = new() + { + AttackerEntityId = request.AttackerEntityId, + TargetEntityId = request.TargetEntityId, + ShieldCoverDamage = 0, + Damage = (int)request.DamageId, + PartId = request.PartId + } + }; + } + + [CombatRequest(CombatRequestData.MessageOneofCase.HitRequest)] + public CombatResponseData OnHitRequest(CombatRequestContext context) + { + return new CombatResponseData + { + RequestId = context.Request.RequestId, + CombatCommon = context.Request.CombatCommon, + HitResponse = new() + { + HitInfo = context.Request.HitRequest.HitInfo + } + }; + } + + + [CombatRequest(CombatRequestData.MessageOneofCase.LogicStateInitRequest)] + public CombatResponseData OnLogicStateInitRequest(CombatRequestContext context) + { + CombatResponseData rsp = new() + { + CombatCommon = context.Request.CombatCommon, + RequestId = context.Request.RequestId, + LogicStateInitResponse = new() + }; + + EntityBase? entity = _entitySystem.Get(context.Request.CombatCommon.EntityId); + if (entity == null) return rsp; + + EntityLogicStateComponent logicStateComponent = entity.ComponentSystem.Get(); + logicStateComponent.States = [.. context.Request.LogicStateInitRequest.InitData.States]; + + context.Notifies.Add(new CombatNotifyData + { + CombatCommon = context.Request.CombatCommon, + LogicStateInitNotify = new() + { + CombatCommon = context.Request.CombatCommon, + EntityId = entity.Id, + InitData = logicStateComponent.Pb.LogicStateComponentPb + } + }); + + return rsp; + } + + [CombatRequest(CombatRequestData.MessageOneofCase.SwitchLogicStateRequest)] + public CombatResponseData OnSwitchLogicStateRequest(CombatRequestContext context) + { + CombatResponseData rsp = new() + { + CombatCommon = context.Request.CombatCommon, + RequestId = context.Request.RequestId, + SwitchLogicStateResponse = new() + }; + + EntityBase? entity = _entitySystem.Get(context.Request.CombatCommon.EntityId); + if (entity == null) + { + rsp.SwitchLogicStateResponse.ErrorCode = (int)ErrorCode.ErrActionEntityNoExist; + return rsp; + } + + EntityLogicStateComponent logicStateComponent = entity.ComponentSystem.Get(); + logicStateComponent.States = [.. context.Request.SwitchLogicStateRequest.States]; + + context.Notifies.Add(new CombatNotifyData + { + CombatCommon = context.Request.CombatCommon, + SwitchLogicStateNotify = new() + { + States = { logicStateComponent.States } + } + }); + + return rsp; + } + + [CombatRequest(CombatRequestData.MessageOneofCase.BattleStateChangeRequest)] + public CombatResponseData OnBattleStateChangeRequest(CombatRequestContext context) + { + return new CombatResponseData + { + CombatCommon = context.Request.CombatCommon, + RequestId = context.Request.RequestId, + BattleStateChangeResponse = new() + }; + } + + [CombatRequest(CombatRequestData.MessageOneofCase.ChangeStateConfirmRequest)] + public CombatResponseData OnChangeStateConfirmRequest(CombatRequestContext context) + { + CombatResponseData rsp = new() + { + CombatCommon = context.Request.CombatCommon, + RequestId = context.Request.RequestId, + ChangeStateConfirmResponse = new() + { + Error = new() + } + }; + + EntityBase? entity = _entitySystem.Get(context.Request.CombatCommon.EntityId); + if (entity == null) + { + rsp.ChangeStateConfirmResponse.Error.ErrorCode = (int)ErrorCode.ErrEntityIsNotAlive; + return rsp; + } + + ChangeStateConfirmRequest request = context.Request.ChangeStateConfirmRequest; + if (entity.ComponentSystem.TryGet(out EntityFsmComponent? fsmComponent)) + { + DFsm? dfsm = fsmComponent.Fsms.FirstOrDefault(fsm => fsm.FsmId == request.FsmId); + dfsm ??= new() + { + FsmId = request.FsmId, + Status = 1, + Flag = (int)EFsmStateFlag.Confirmed + }; + + dfsm.CurrentState = request.State; + context.Notifies.Add(new CombatNotifyData + { + CombatCommon = context.Request.CombatCommon, + ChangeStateConfirmNotify = new ChangeStateConfirmNotify + { + State = request.State, + FsmId = request.FsmId + } + }); + } + + rsp.ChangeStateConfirmResponse.State = context.Request.ChangeStateConfirmRequest.State; + rsp.ChangeStateConfirmResponse.FsmId = context.Request.ChangeStateConfirmRequest.FsmId; + + return rsp; + } + + [CombatRequest(CombatRequestData.MessageOneofCase.FsmConditionPassRequest)] + public CombatResponseData OnFsmConditionPassRequest(CombatRequestContext context) + { + return new CombatResponseData + { + CombatCommon = context.Request.CombatCommon, + RequestId = context.Request.RequestId, + FsmConditionPassResponse = new() + { + FsmId = context.Request.FsmConditionPassRequest.FsmId, + Error = new() + } + }; + } + + [CombatRequest(CombatRequestData.MessageOneofCase.AiInformationRequest)] + public CombatResponseData OnAiInformationRequest(CombatRequestContext context) + { + // Currently like this, TODO! + context.Notifies.Add(new CombatNotifyData + { + CombatCommon = new CombatCommon + { + EntityId = context.Request.CombatCommon.EntityId, // id of monster + }, + AiHateNotify = new AiHateNotify + { + HateList = + { + new AiHateEntity + { + EntityId = _creatureController.GetPlayerEntity()!.Id, // id of hated entity (the player) + HatredValue = 99999 + } + } + } + }); + + return new CombatResponseData + { + CombatCommon = context.Request.CombatCommon, + RequestId = context.Request.RequestId, + AiInformationResponse = new() // ?? contains nothing + }; + } + + public Task HandleRequest(CombatRequestContext context) + { + if (s_requestHandlers.TryGetValue(context.Request.MessageCase, out CombatRequestHandler? handler)) + return handler(this, context)!; + + _logger.LogWarning("Combat request not handled: {type}", context.Request.MessageCase); + return Task.FromResult(null); + } + + private static ImmutableDictionary MapRequestHandlers() + { + var builder = ImmutableDictionary.CreateBuilder(); + + MethodInfo taskFromResultMethod = typeof(Task).GetMethod(nameof(Task.FromResult))!.MakeGenericMethod(typeof(CombatResponseData)); + + foreach (MethodInfo method in typeof(CombatManager).GetMethods()) + { + CombatRequestAttribute? attribute = method.GetCustomAttribute(); + if (attribute == null) continue; + + ParameterExpression combatManagerParam = Expression.Parameter(typeof(CombatManager)); + ParameterExpression contextParam = Expression.Parameter(typeof(CombatRequestContext)); + + Expression call = Expression.Call(combatManagerParam, method, contextParam); + if (method.ReturnType == typeof(CombatResponseData)) + call = Expression.Call(taskFromResultMethod, call); + + Expression lambda = Expression.Lambda(call, combatManagerParam, contextParam); + builder.Add(attribute.MessageCase, lambda.Compile()); + } + + return builder.ToImmutable(); + } +} diff --git a/GameServer/Controllers/Combat/CombatRequestContext.cs b/GameServer/Controllers/Combat/CombatRequestContext.cs new file mode 100644 index 0000000..51e9313 --- /dev/null +++ b/GameServer/Controllers/Combat/CombatRequestContext.cs @@ -0,0 +1,14 @@ +using Protocol; + +namespace GameServer.Controllers.Combat; +internal class CombatRequestContext +{ + public CombatRequestData Request { get; } + public List Notifies { get; } + + public CombatRequestContext(CombatRequestData request) + { + Request = request; + Notifies = []; + } +} diff --git a/GameServer/Controllers/CombatMessageController.cs b/GameServer/Controllers/CombatMessageController.cs index 96c5b26..cf4837c 100644 --- a/GameServer/Controllers/CombatMessageController.cs +++ b/GameServer/Controllers/CombatMessageController.cs @@ -1,4 +1,5 @@ using GameServer.Controllers.Attributes; +using GameServer.Controllers.Combat; using GameServer.Network; using GameServer.Network.Messages; using Protocol; @@ -12,5 +13,33 @@ internal class CombatMessageController : Controller } [NetEvent(MessageId.CombatSendPackRequest)] // TODO: CombatSendPackRequest is important - public ResponseMessage OnCombatSendPackRequest() => Response(MessageId.CombatSendPackResponse, new CombatSendPackResponse()); + public async Task OnCombatSendPackRequest(CombatSendPackRequest request, CombatManager combatManager) + { + CombatReceivePackNotify combatPackNotify = new(); + + foreach (CombatSendData sendData in request.Data) + { + if (sendData.Request != null) + { + CombatRequestContext context = new(sendData.Request); + CombatResponseData? responseData = await combatManager.HandleRequest(context); + + combatPackNotify.Data.AddRange(context.Notifies.Select(notify => new CombatReceiveData + { + CombatNotifyData = notify + })); + + if (responseData != null) + { + combatPackNotify.Data.Add(new CombatReceiveData + { + CombatResponseData = responseData + }); + } + } + } + + await Session.Push(MessageId.CombatReceivePackNotify, combatPackNotify); + return Response(MessageId.CombatSendPackResponse, new CombatSendPackResponse()); + } } diff --git a/GameServer/Controllers/CreatureController.cs b/GameServer/Controllers/CreatureController.cs index 8bc2353..bde2f2d 100644 --- a/GameServer/Controllers/CreatureController.cs +++ b/GameServer/Controllers/CreatureController.cs @@ -67,9 +67,10 @@ internal class CreatureController : Controller } [NetEvent(MessageId.SceneLoadingFinishRequest)] - public ResponseMessage OnSceneLoadingFinishRequest() + public async Task OnSceneLoadingFinishRequest() { _modelManager.Creature.OnWorldDone(); + await UpdateAiHate(); return Response(MessageId.SceneLoadingFinishResponse, new SceneLoadingFinishResponse()); } @@ -79,10 +80,7 @@ internal class CreatureController : Controller { // Remove old entities - IEnumerable oldEntities = _entitySystem.EnumerateEntities() - .Where(e => e is PlayerEntity entity && entity.PlayerId == _modelManager.Player.Id) - .Cast().ToArray(); - + IEnumerable oldEntities = GetPlayerEntities().ToArray(); foreach (PlayerEntity oldEntity in oldEntities) { _entitySystem.Destroy(oldEntity); @@ -105,10 +103,7 @@ internal class CreatureController : Controller CreateTeamPlayerEntities(); - IEnumerable newEntities = _entitySystem.EnumerateEntities() - .Where(e => e is PlayerEntity entity && entity.PlayerId == _modelManager.Player.Id) - .Cast(); - + IEnumerable newEntities = GetPlayerEntities(); await Session.Push(MessageId.EntityAddNotify, new EntityAddNotify { IsAdd = true, @@ -124,6 +119,8 @@ internal class CreatureController : Controller PlayerId = _modelManager.Player.Id, FightRoleInfos = { GetFightRoleInfos() } }); + + await UpdateAiHate(); } [GameEvent(GameEventType.VisionSkillChanged)] @@ -165,13 +162,43 @@ internal class CreatureController : Controller prevEntity.IsCurrentRole = false; - PlayerEntity? newEntity = _entitySystem.EnumerateEntities().FirstOrDefault(e => e is PlayerEntity playerEntity && playerEntity.ConfigId == roleId) as PlayerEntity; - if (newEntity == null) return; + if (_entitySystem.EnumerateEntities().FirstOrDefault(e => e is PlayerEntity playerEntity && playerEntity.ConfigId == roleId) is not PlayerEntity newEntity) return; _modelManager.Creature.PlayerEntityId = newEntity.Id; newEntity.IsCurrentRole = true; - await OnVisionSkillChanged(); + await UpdateAiHate(); + } + + public async Task UpdateAiHate() + { + IEnumerable monsters = _entitySystem.EnumerateEntities().Where(e => e is MonsterEntity); + if (!monsters.Any()) return; + + await Session.Push(MessageId.CombatReceivePackNotify, new CombatReceivePackNotify + { + Data = + { + monsters.Select(monster => new CombatReceiveData + { + CombatNotifyData = new() + { + CombatCommon = new() { EntityId = monster.Id }, + AiHateNotify = new() + { + HateList = + { + GetPlayerEntities().Select(player => new AiHateEntity + { + EntityId = player.Id, + HatredValue = 99999 // currently this, TODO! + }) + } + } + } + }) + } + }); } private SceneInformation CreateSceneInfo() => new() @@ -200,11 +227,7 @@ internal class CreatureController : Controller private IEnumerable GetFightRoleInfos() { - IEnumerable playerEntities = _entitySystem.EnumerateEntities() - .Where(e => e is PlayerEntity entity && entity.PlayerId == _modelManager.Player.Id) - .Cast(); - - return playerEntities.Select(playerEntity => new FightRoleInformation + return GetPlayerEntities().Select(playerEntity => new FightRoleInformation { EntityId = playerEntity.Id, CurHp = playerEntity.Health, diff --git a/GameServer/Controllers/RoleController.cs b/GameServer/Controllers/RoleController.cs index 5d8bdb6..150354c 100644 --- a/GameServer/Controllers/RoleController.cs +++ b/GameServer/Controllers/RoleController.cs @@ -35,8 +35,9 @@ internal class RoleController : Controller } [NetEvent(MessageId.SwitchRoleRequest)] - public ResponseMessage OnSwitchRoleRequest(SwitchRoleRequest request) + public async Task OnSwitchRoleRequest(SwitchRoleRequest request, CreatureController creatureController) { + await creatureController.SwitchPlayerEntity(request.RoleId); return Response(MessageId.SwitchRoleResponse, new SwitchRoleResponse { RoleId = request.RoleId diff --git a/GameServer/Program.cs b/GameServer/Program.cs index 945ec11..1d1f6fc 100644 --- a/GameServer/Program.cs +++ b/GameServer/Program.cs @@ -1,6 +1,7 @@ using Core.Config; using Core.Extensions; using GameServer.Controllers.ChatCommands; +using GameServer.Controllers.Combat; using GameServer.Controllers.Factory; using GameServer.Controllers.Manager; using GameServer.Extensions; @@ -39,7 +40,8 @@ internal static class Program .AddScoped().AddScoped() .AddSingleton() .AddScoped().AddScoped().AddScoped() - .AddScoped().AddScoped().AddScoped() + .AddScoped().AddScoped() + .AddScoped().AddScoped() .AddHostedService(); IHost host = builder.Build(); diff --git a/GameServer/Systems/Entity/Component/EntityAttributeComponent.cs b/GameServer/Systems/Entity/Component/EntityAttributeComponent.cs index fac9ade..4fd4d3a 100644 --- a/GameServer/Systems/Entity/Component/EntityAttributeComponent.cs +++ b/GameServer/Systems/Entity/Component/EntityAttributeComponent.cs @@ -37,6 +37,7 @@ internal class EntityAttributeComponent : EntityComponentBase } attribute.CurrentValue = currentValue; + attribute.BaseValue = currentValue; } public int GetAttribute(EAttributeType type) diff --git a/GameServer/Systems/Entity/Component/EntityComponentSystem.cs b/GameServer/Systems/Entity/Component/EntityComponentSystem.cs index f60090b..a5340e1 100644 --- a/GameServer/Systems/Entity/Component/EntityComponentSystem.cs +++ b/GameServer/Systems/Entity/Component/EntityComponentSystem.cs @@ -1,4 +1,5 @@ -using Protocol; +using System.Diagnostics.CodeAnalysis; +using Protocol; namespace GameServer.Systems.Entity.Component; internal class EntityComponentSystem @@ -25,7 +26,7 @@ internal class EntityComponentSystem return (_components.Single(component => component is TEntityComponent) as TEntityComponent)!; } - public bool TryGet(out TEntityComponent? component) where TEntityComponent : EntityComponentBase + public bool TryGet([NotNullWhen(true)] out TEntityComponent? component) where TEntityComponent : EntityComponentBase { return (component = _components.SingleOrDefault(component => component is TEntityComponent) as TEntityComponent) != null; } diff --git a/GameServer/Systems/Entity/Component/EntityLogicStateComponent.cs b/GameServer/Systems/Entity/Component/EntityLogicStateComponent.cs new file mode 100644 index 0000000..8b6a614 --- /dev/null +++ b/GameServer/Systems/Entity/Component/EntityLogicStateComponent.cs @@ -0,0 +1,22 @@ +using Protocol; + +namespace GameServer.Systems.Entity.Component; +internal class EntityLogicStateComponent : EntityComponentBase +{ + public List States { get; set; } + + public EntityLogicStateComponent() + { + States = []; + } + + public override EntityComponentType Type => EntityComponentType.LogicState; + + public override EntityComponentPb Pb => new() + { + LogicStateComponentPb = new() + { + States = { States } + } + }; +} diff --git a/GameServer/Systems/Entity/EntityBase.cs b/GameServer/Systems/Entity/EntityBase.cs index 0803c9a..07b28ae 100644 --- a/GameServer/Systems/Entity/EntityBase.cs +++ b/GameServer/Systems/Entity/EntityBase.cs @@ -28,6 +28,8 @@ internal abstract class EntityBase public virtual void OnCreate() { State = EntityState.Born; + + _ = ComponentSystem.Create(); } public virtual void Activate() diff --git a/Protocol/message.proto b/Protocol/message.proto index a68b9f6..dfa0eaa 100644 --- a/Protocol/message.proto +++ b/Protocol/message.proto @@ -1604,78 +1604,84 @@ message CombatMaxCaseMessageResponse { // MessageId: 11987 message CombatNotifyData { CombatCommon combat_common = 1; - CreateBulletNotify create_bullet_notify = 2; - DestroyBulletNotify destroy_bullet_notify = 3; - DamageExecuteNotify damage_execute_notify = 4; - ApplyGameplayEffectNotify apply_gameplay_effect_notify = 5; - RemoveGameplayEffectNotify remove_gameplay_effect_notify = 6; - HitNotify hit_notify = 7; - SkillNotify skill_notify = 8; - UseSkillNotify use_skill_notify = 9; - EndSkillNotify end_skill_notify = 10; - EntityLoadCompleteNotify entity_load_complete_notify = 11; - PartUpdateNotify part_update_notify = 12; - PartComponentInitNotify part_component_init_notify = 14; - MaterialNotify material_notify = 15; - ParticleNotify particle_notify = 16; - EntityIsVisibleNotify entity_is_visible_notify = 17; - SwitchCharacterStateNotify switch_character_state_notify = 18; - PlayerRebackSceneNotify player_reback_scene_notify = 19; - LogicStateInitNotify logic_state_init_notify = 20; - SwitchLogicStateNotify switch_logic_state_notify = 21; - AttributeChangedNotify attribute_changed_notify = 22; - AnimationStateChangedNotify animation_state_changed_notify = 23; - AnimationStateInitNotify animation_state_init_notify = 24; - ModifyBulletParamsNotify modify_bullet_params_notify = 25; - DrownNotify drown_notify = 26; - OrderApplyBuffNotify order_apply_buff_notify = 27; - OrderRemoveBuffNotify order_remove_buff_notify = 28; - ActivateBuffNotify activate_buff_notify = 29; - OrderRemoveBuffByTagsNotify order_remove_buff_by_tags_notify = 30; - AiInformationNotify ai_information_notify = 31; - BattleStateChangeNotify battle_state_change_notify = 32; - AnimationGameplayTagNotify animation_gameplay_tag_notify = 33; - BoneVisibleChangeNotify bone_visible_change_notify = 34; - AiBlackboardCdNotify ai_blackboard_cd_notify = 35; - CaughtNotify caught_notify = 36; - EntityStaticHookMoveNotify entity_static_hook_move_notify = 37; - ChangeStateNotify change_state_notify = 38; - ChangeStateConfirmNotify change_state_confirm_notify = 40; - BuffStackCountNotify buff_stack_count_notify = 41; - MontagePlayNotify montage_play_notify = 42; - ANStartNotify an_start_notify = 43; - FsmResetNotify fsm_reset_notify = 44; - DamageRecordNotify damage_record_notify = 45; - AiHateNotify ai_hate_notify = 46; - FsmBlackboardNotify fsm_blackboard_notify = 47; - CharacterBattleStateChangeNotify character_battle_state_change_notify = 48; - FormationBuffApplyNotify formation_buff_apply_notify = 49; - FormationBuffStackNotify formation_buff_stack_notify = 50; - FormationBuffApplyS2cRequestNotify formation_buff_apply_s2c_request_notify = 51; - FormationBuffRemoveS2cRequestNotify formation_buff_remove_s2c_request_notify = 52; - ApplyBuffS2cRequestNotify apply_buff_s2c_request_notify = 53; - RemoveBuffS2cRequestNotify remove_buff_s2c_request_notify = 54; - FormationBuffRemoveNotify formation_buff_remove_notify = 55; - FormationBuffActivateNotify formation_buff_activate_notify = 56; - ActorVisibleNotify actor_visible_notify = 57; - RecoverPropChangedNotify recover_prop_changed_notify = 58; - RemoveBuffByIdS2cRequestNotify remove_buff_by_id_s2c_request_notify = 59; - FormationBuffRemoveByIdS2cRequestNotify formation_buff_remove_by_id_s2c_request_notify = 60; + oneof message { + CreateBulletNotify create_bullet_notify = 2; + DestroyBulletNotify destroy_bullet_notify = 3; + DamageExecuteNotify damage_execute_notify = 4; + ApplyGameplayEffectNotify apply_gameplay_effect_notify = 5; + RemoveGameplayEffectNotify remove_gameplay_effect_notify = 6; + HitNotify hit_notify = 7; + SkillNotify skill_notify = 8; + UseSkillNotify use_skill_notify = 9; + EndSkillNotify end_skill_notify = 10; + EntityLoadCompleteNotify entity_load_complete_notify = 11; + PartUpdateNotify part_update_notify = 12; + PartComponentInitNotify part_component_init_notify = 14; + MaterialNotify material_notify = 15; + ParticleNotify particle_notify = 16; + EntityIsVisibleNotify entity_is_visible_notify = 17; + SwitchCharacterStateNotify switch_character_state_notify = 18; + PlayerRebackSceneNotify player_reback_scene_notify = 19; + LogicStateInitNotify logic_state_init_notify = 20; + SwitchLogicStateNotify switch_logic_state_notify = 21; + AttributeChangedNotify attribute_changed_notify = 22; + AnimationStateChangedNotify animation_state_changed_notify = 23; + AnimationStateInitNotify animation_state_init_notify = 24; + ModifyBulletParamsNotify modify_bullet_params_notify = 25; + DrownNotify drown_notify = 26; + OrderApplyBuffNotify order_apply_buff_notify = 27; + OrderRemoveBuffNotify order_remove_buff_notify = 28; + ActivateBuffNotify activate_buff_notify = 29; + OrderRemoveBuffByTagsNotify order_remove_buff_by_tags_notify = 30; + AiInformationNotify ai_information_notify = 31; + BattleStateChangeNotify battle_state_change_notify = 32; + AnimationGameplayTagNotify animation_gameplay_tag_notify = 33; + BoneVisibleChangeNotify bone_visible_change_notify = 34; + AiBlackboardCdNotify ai_blackboard_cd_notify = 35; + CaughtNotify caught_notify = 36; + EntityStaticHookMoveNotify entity_static_hook_move_notify = 37; + ChangeStateNotify change_state_notify = 38; + ChangeStateConfirmNotify change_state_confirm_notify = 40; + BuffStackCountNotify buff_stack_count_notify = 41; + MontagePlayNotify montage_play_notify = 42; + ANStartNotify an_start_notify = 43; + FsmResetNotify fsm_reset_notify = 44; + DamageRecordNotify damage_record_notify = 45; + AiHateNotify ai_hate_notify = 46; + FsmBlackboardNotify fsm_blackboard_notify = 47; + CharacterBattleStateChangeNotify character_battle_state_change_notify = 48; + FormationBuffApplyNotify formation_buff_apply_notify = 49; + FormationBuffStackNotify formation_buff_stack_notify = 50; + FormationBuffApplyS2cRequestNotify formation_buff_apply_s2c_request_notify = 51; + FormationBuffRemoveS2cRequestNotify formation_buff_remove_s2c_request_notify = 52; + ApplyBuffS2cRequestNotify apply_buff_s2c_request_notify = 53; + RemoveBuffS2cRequestNotify remove_buff_s2c_request_notify = 54; + FormationBuffRemoveNotify formation_buff_remove_notify = 55; + FormationBuffActivateNotify formation_buff_activate_notify = 56; + ActorVisibleNotify actor_visible_notify = 57; + RecoverPropChangedNotify recover_prop_changed_notify = 58; + RemoveBuffByIdS2cRequestNotify remove_buff_by_id_s2c_request_notify = 59; + FormationBuffRemoveByIdS2cRequestNotify formation_buff_remove_by_id_s2c_request_notify = 60; + } } message CombatPushData { CombatCommon combat_common = 1; - FormationBuffApplyS2cResponsePush formation_buff_apply_s2c_response_push = 2; - FormationBuffRemoveS2cResponsePush formation_buff_remove_s2c_response_push = 3; - ApplyBuffS2cResponsePush apply_buff_s2c_response_push = 4; - RemoveBuffS2cResponsePush remove_buff_s2c_response_push = 5; - RemoveBuffByIdS2cResponsePush remove_buff_by_id_s2c_response_push = 6; - FormationBuffRemoveByIdS2cResponsePush formation_buff_remove_by_id_s2c_response_push = 7; + oneof message { + FormationBuffApplyS2cResponsePush formation_buff_apply_s2c_response_push = 2; + FormationBuffRemoveS2cResponsePush formation_buff_remove_s2c_response_push = 3; + ApplyBuffS2cResponsePush apply_buff_s2c_response_push = 4; + RemoveBuffS2cResponsePush remove_buff_s2c_response_push = 5; + RemoveBuffByIdS2cResponsePush remove_buff_by_id_s2c_response_push = 6; + FormationBuffRemoveByIdS2cResponsePush formation_buff_remove_by_id_s2c_response_push = 7; + } } message CombatReceiveData { - CombatNotifyData combat_notify_data = 2; - CombatResponseData combat_response_data = 3; + oneof message { + CombatNotifyData combat_notify_data = 2; + CombatResponseData combat_response_data = 3; + } } message CombatReceivePackNotify { // MessageId: 1332 @@ -1685,131 +1691,135 @@ message CombatReceivePackNotify { // MessageId: 1332 message CombatRequestData { CombatCommon combat_common = 1; int32 request_id = 2; - CreateBulletRequest create_bullet_request = 3; - DestroyBulletRequest destroy_bullet_request = 4; - DamageExecuteRequest damage_execute_request = 5; - ApplyGameplayEffectRequest apply_gameplay_effect_request = 6; - RemoveGameplayEffectRequest remove_gameplay_effect_request = 7; - HitRequest hit_request = 8; - HitEndRequest hit_end_request = 9; - SkillRequest skill_request = 10; - UseSkillRequest use_skill_request = 11; - EndSkillRequest end_skill_request = 12; - PartUpdateRequest part_update_request = 13; - MaterialRequest material_request = 14; - ParticleRequest particle_request = 15; - EntityIsVisibleRequest entity_is_visible_request = 16; - SwitchCharacterStateRequest switch_character_state_request = 17; - LogicStateInitRequest logic_state_init_request = 18; - SwitchLogicStateRequest switch_logic_state_request = 19; - AnimationStateChangedRequest animation_state_changed_request = 20; - AnimationStateInitRequest animation_state_init_request = 21; - ModifyBulletParamsRequest modify_bullet_params_request = 22; - DrownRequest drown_request = 23; - OrderApplyBuffRequest order_apply_buff_request = 24; - OrderRemoveBuffRequest order_remove_buff_request = 25; - ActivateBuffRequest activate_buff_request = 26; - OrderRemoveBuffByTagsRequest order_remove_buff_by_tags_request = 27; - AiInformationRequest ai_information_request = 28; - ToughCalcExtraRatioChangeRequest tough_calc_extra_ratio_change_request = 29; - BattleStateChangeRequest battle_state_change_request = 30; - AnimationGameplayTagRequest animation_gameplay_tag_request = 31; - BoneVisibleChangeRequest bone_visible_change_request = 32; - AiBlackboardsRequest ai_blackboards_request = 33; - AiBlackboardCdRequest ai_blackboard_cd_request = 34; - AiHateRequest ai_hate_request = 35; - MonsterBoomRequest monster_boom_request = 36; - CaughtRequest caught_request = 37; - EntityStaticHookMoveRequest entity_static_hook_move_request = 38; - ChangeStateRequest change_state_request = 39; - ChangeStateConfirmRequest change_state_confirm_request = 40; - FsmConditionPassRequest fsm_condition_pass_request = 41; - BuffStackCountRequest buff_stack_count_request = 42; - MontagePlayRequest montage_play_request = 43; - ANStartRequest an_start_request = 44; - UseSkillFailRequest use_skill_fail_request = 45; - EnterViewDirectionRequest enter_view_direction_request = 46; - ExitViewDirectionRequest exit_view_direction_request = 47; - PassiveSkillAddRequest passive_skill_add_request = 48; - PassiveSkillActiveRequest passive_skill_active_request = 49; - InterruptSkillInDelayRequest interrupt_skill_in_delay_request = 50; - TriggerExitSkillRequest trigger_exit_skill_request = 51; - FormationBuffApplyRequest formation_buff_apply_request = 52; - FormationBuffStackRequest formation_buff_stack_request = 53; - FormationBuffRemoveRequest formation_buff_remove_request = 54; - FormationBuffActivateRequest formation_buff_activate_request = 55; - ActorVisibleRequest actor_visible_request = 56; - BuffEffectRequest buff_effect_request = 57; - FragileChangeRequest fragile_change_request = 58; - RTimeStopRequest r_time_stop_request = 59; - DrownEndTeleportRequest drown_end_teleport_request = 60; - MonsterDrownRequest monster_drown_request = 61; - CombatMaxCaseMessageRequest combat_max_case_message_request = 62; + oneof message { + CreateBulletRequest create_bullet_request = 3; + DestroyBulletRequest destroy_bullet_request = 4; + DamageExecuteRequest damage_execute_request = 5; + ApplyGameplayEffectRequest apply_gameplay_effect_request = 6; + RemoveGameplayEffectRequest remove_gameplay_effect_request = 7; + HitRequest hit_request = 8; + HitEndRequest hit_end_request = 9; + SkillRequest skill_request = 10; + UseSkillRequest use_skill_request = 11; + EndSkillRequest end_skill_request = 12; + PartUpdateRequest part_update_request = 13; + MaterialRequest material_request = 14; + ParticleRequest particle_request = 15; + EntityIsVisibleRequest entity_is_visible_request = 16; + SwitchCharacterStateRequest switch_character_state_request = 17; + LogicStateInitRequest logic_state_init_request = 18; + SwitchLogicStateRequest switch_logic_state_request = 19; + AnimationStateChangedRequest animation_state_changed_request = 20; + AnimationStateInitRequest animation_state_init_request = 21; + ModifyBulletParamsRequest modify_bullet_params_request = 22; + DrownRequest drown_request = 23; + OrderApplyBuffRequest order_apply_buff_request = 24; + OrderRemoveBuffRequest order_remove_buff_request = 25; + ActivateBuffRequest activate_buff_request = 26; + OrderRemoveBuffByTagsRequest order_remove_buff_by_tags_request = 27; + AiInformationRequest ai_information_request = 28; + ToughCalcExtraRatioChangeRequest tough_calc_extra_ratio_change_request = 29; + BattleStateChangeRequest battle_state_change_request = 30; + AnimationGameplayTagRequest animation_gameplay_tag_request = 31; + BoneVisibleChangeRequest bone_visible_change_request = 32; + AiBlackboardsRequest ai_blackboards_request = 33; + AiBlackboardCdRequest ai_blackboard_cd_request = 34; + AiHateRequest ai_hate_request = 35; + MonsterBoomRequest monster_boom_request = 36; + CaughtRequest caught_request = 37; + EntityStaticHookMoveRequest entity_static_hook_move_request = 38; + ChangeStateRequest change_state_request = 39; + ChangeStateConfirmRequest change_state_confirm_request = 40; + FsmConditionPassRequest fsm_condition_pass_request = 41; + BuffStackCountRequest buff_stack_count_request = 42; + MontagePlayRequest montage_play_request = 43; + ANStartRequest an_start_request = 44; + UseSkillFailRequest use_skill_fail_request = 45; + EnterViewDirectionRequest enter_view_direction_request = 46; + ExitViewDirectionRequest exit_view_direction_request = 47; + PassiveSkillAddRequest passive_skill_add_request = 48; + PassiveSkillActiveRequest passive_skill_active_request = 49; + InterruptSkillInDelayRequest interrupt_skill_in_delay_request = 50; + TriggerExitSkillRequest trigger_exit_skill_request = 51; + FormationBuffApplyRequest formation_buff_apply_request = 52; + FormationBuffStackRequest formation_buff_stack_request = 53; + FormationBuffRemoveRequest formation_buff_remove_request = 54; + FormationBuffActivateRequest formation_buff_activate_request = 55; + ActorVisibleRequest actor_visible_request = 56; + BuffEffectRequest buff_effect_request = 57; + FragileChangeRequest fragile_change_request = 58; + RTimeStopRequest r_time_stop_request = 59; + DrownEndTeleportRequest drown_end_teleport_request = 60; + MonsterDrownRequest monster_drown_request = 61; + CombatMaxCaseMessageRequest combat_max_case_message_request = 62; + } CombatContext context = 100; } message CombatResponseData { CombatCommon combat_common = 1; int32 request_id = 2; - CreateBulletResponse create_bullet_response = 3; - DestroyBulletResponse destroy_bullet_response = 4; - DamageExecuteResponse damage_execute_response = 5; - ApplyGameplayEffectResponse apply_gameplay_effect_response = 6; - RemoveGameplayEffectResponse remove_gameplay_effect_response = 7; - HitResponse hit_response = 8; - HitEndResponse hit_end_response = 9; - SkillResponse skill_response = 10; - UseSkillResponse use_skill_response = 11; - EndSkillResponse end_skill_response = 12; - PartUpdateResponse part_update_response = 13; - MaterialResponse material_response = 14; - ParticleResponse particle_response = 15; - EntityIsVisibleResponse entity_is_visible_response = 16; - SwitchCharacterStateResponse switch_character_state_response = 17; - LogicStateInitResponse logic_state_init_response = 18; - SwitchLogicStateResponse switch_logic_state_response = 19; - AnimationStateChangedResponse animation_state_changed_response = 20; - AnimationStateInitResponse animation_state_init_response = 21; - ModifyBulletParamsResponse modify_bullet_params_response = 22; - DrownResponse drown_response = 23; - OrderApplyBuffResponse order_apply_buff_response = 24; - OrderRemoveBuffResponse order_remove_buff_response = 25; - ActivateBuffResponse activate_buff_response = 26; - OrderRemoveBuffByTagsResponse order_remove_buff_by_tags_response = 27; - AiInformationResponse ai_information_response = 28; - ToughCalcExtraRatioChangeResponse tough_calc_extra_ratio_change_response = 29; - BattleStateChangeResponse battle_state_change_response = 30; - AnimationGameplayTagResponse animation_gameplay_tag_response = 31; - BoneVisibleChangeResponse bone_visible_change_response = 32; - AiBlackboardsResponse ai_blackboards_response = 33; - AiBlackboardCdResponse ai_blackboard_cd_response = 34; - AiHateResponse ai_hate_response = 35; - MonsterBoomResponse monster_boom_response = 36; - CaughtResponse caught_response = 37; - EntityStaticHookMoveResponse entity_static_hook_move_response = 38; - ChangeStateResponse change_state_response = 39; - ChangeStateConfirmResponse change_state_confirm_response = 40; - FsmConditionPassResponse fsm_condition_pass_response = 41; - BuffStackCountResponse buff_stack_count_response = 42; - MontagePlayResponse montage_play_response = 43; - ANStartResponse an_start_response = 44; - UseSkillFailResponse use_skill_fail_response = 45; - EnterViewDirectionResponse enter_view_direction_response = 46; - ExitViewDirectionResponse exit_view_direction_response = 47; - PassiveSkillAddResponse passive_skill_add_response = 48; - PassiveSkillActiveResponse passive_skill_active_response = 49; - InterruptSkillInDelayResponse interrupt_skill_in_delay_response = 50; - TriggerExitSkillResponse trigger_exit_skill_response = 51; - FormationBuffApplyResponse formation_buff_apply_response = 52; - FormationBuffStackResponse formation_buff_stack_response = 53; - FormationBuffRemoveResponse formation_buff_remove_response = 54; - FormationBuffActivateResponse formation_buff_activate_response = 55; - ActorVisibleResponse actor_visible_response = 56; - BuffEffectResponse buff_effect_response = 57; - FragileChangeResponse fragile_change_response = 58; - RTimeStopResponse r_time_stop_response = 59; - DrownEndTeleportResponse drown_end_teleport_response = 60; - MonsterDrownResponse monster_drown_response = 61; + oneof message { + CreateBulletResponse create_bullet_response = 3; + DestroyBulletResponse destroy_bullet_response = 4; + DamageExecuteResponse damage_execute_response = 5; + ApplyGameplayEffectResponse apply_gameplay_effect_response = 6; + RemoveGameplayEffectResponse remove_gameplay_effect_response = 7; + HitResponse hit_response = 8; + HitEndResponse hit_end_response = 9; + SkillResponse skill_response = 10; + UseSkillResponse use_skill_response = 11; + EndSkillResponse end_skill_response = 12; + PartUpdateResponse part_update_response = 13; + MaterialResponse material_response = 14; + ParticleResponse particle_response = 15; + EntityIsVisibleResponse entity_is_visible_response = 16; + SwitchCharacterStateResponse switch_character_state_response = 17; + LogicStateInitResponse logic_state_init_response = 18; + SwitchLogicStateResponse switch_logic_state_response = 19; + AnimationStateChangedResponse animation_state_changed_response = 20; + AnimationStateInitResponse animation_state_init_response = 21; + ModifyBulletParamsResponse modify_bullet_params_response = 22; + DrownResponse drown_response = 23; + OrderApplyBuffResponse order_apply_buff_response = 24; + OrderRemoveBuffResponse order_remove_buff_response = 25; + ActivateBuffResponse activate_buff_response = 26; + OrderRemoveBuffByTagsResponse order_remove_buff_by_tags_response = 27; + AiInformationResponse ai_information_response = 28; + ToughCalcExtraRatioChangeResponse tough_calc_extra_ratio_change_response = 29; + BattleStateChangeResponse battle_state_change_response = 30; + AnimationGameplayTagResponse animation_gameplay_tag_response = 31; + BoneVisibleChangeResponse bone_visible_change_response = 32; + AiBlackboardsResponse ai_blackboards_response = 33; + AiBlackboardCdResponse ai_blackboard_cd_response = 34; + AiHateResponse ai_hate_response = 35; + MonsterBoomResponse monster_boom_response = 36; + CaughtResponse caught_response = 37; + EntityStaticHookMoveResponse entity_static_hook_move_response = 38; + ChangeStateResponse change_state_response = 39; + ChangeStateConfirmResponse change_state_confirm_response = 40; + FsmConditionPassResponse fsm_condition_pass_response = 41; + BuffStackCountResponse buff_stack_count_response = 42; + MontagePlayResponse montage_play_response = 43; + ANStartResponse an_start_response = 44; + UseSkillFailResponse use_skill_fail_response = 45; + EnterViewDirectionResponse enter_view_direction_response = 46; + ExitViewDirectionResponse exit_view_direction_response = 47; + PassiveSkillAddResponse passive_skill_add_response = 48; + PassiveSkillActiveResponse passive_skill_active_response = 49; + InterruptSkillInDelayResponse interrupt_skill_in_delay_response = 50; + TriggerExitSkillResponse trigger_exit_skill_response = 51; + FormationBuffApplyResponse formation_buff_apply_response = 52; + FormationBuffStackResponse formation_buff_stack_response = 53; + FormationBuffRemoveResponse formation_buff_remove_response = 54; + FormationBuffActivateResponse formation_buff_activate_response = 55; + ActorVisibleResponse actor_visible_response = 56; + BuffEffectResponse buff_effect_response = 57; + FragileChangeResponse fragile_change_response = 58; + RTimeStopResponse r_time_stop_response = 59; + DrownEndTeleportResponse drown_end_teleport_response = 60; + MonsterDrownResponse monster_drown_response = 61; + } } message CombatSendData {