CombatManager, Monster AI, monster death

This commit is contained in:
xeon 2024-02-17 16:49:28 +03:00
parent 4e82ccb871
commit d733766909
13 changed files with 636 additions and 207 deletions

View file

@ -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;
}
}

View file

@ -16,14 +16,16 @@ internal class ChatSpawnCommandHandler
private readonly EntityFactory _entityFactory; private readonly EntityFactory _entityFactory;
private readonly PlayerSession _session; private readonly PlayerSession _session;
private readonly ConfigManager _configManager; 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); _helperRoom = modelManager.Chat.GetChatRoom(1338);
_entitySystem = entitySystem; _entitySystem = entitySystem;
_entityFactory = entityFactory; _entityFactory = entityFactory;
_session = session; _session = session;
_configManager = configManager; _configManager = configManager;
_creatureController = creatureController;
} }
[ChatCommand("monster")] [ChatCommand("monster")]
@ -57,6 +59,8 @@ internal class ChatSpawnCommandHandler
EntityPbs = { monster.Pb } EntityPbs = { monster.Pb }
}); });
await _creatureController.UpdateAiHate();
_helperRoom.AddMessage(1338, 0, $"Successfully spawned monster with id {levelEntityId} at ({x}, {y}, {z})"); _helperRoom.AddMessage(1338, 0, $"Successfully spawned monster with id {levelEntityId} at ({x}, {y}, {z})");
} }
} }

View file

@ -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<CombatResponseData> CombatRequestHandler(CombatManager combatManager, CombatRequestContext context);
private static readonly ImmutableDictionary<CombatRequestData.MessageOneofCase, CombatRequestHandler> 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<CombatManager> logger, EntitySystem entitySystem, PlayerSession session, CreatureController creatureController)
{
_logger = logger;
_entitySystem = entitySystem;
_session = session;
_creatureController = creatureController;
}
[CombatRequest(CombatRequestData.MessageOneofCase.DamageExecuteRequest)]
public async Task<CombatResponseData> OnDamageExecuteRequest(CombatRequestContext context)
{
DamageExecuteRequest request = context.Request.DamageExecuteRequest;
EntityBase? entity = _entitySystem.Get<EntityBase>(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<EntityAttributeComponent>();
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<EntityBase>(context.Request.CombatCommon.EntityId);
if (entity == null) return rsp;
EntityLogicStateComponent logicStateComponent = entity.ComponentSystem.Get<EntityLogicStateComponent>();
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<EntityBase>(context.Request.CombatCommon.EntityId);
if (entity == null)
{
rsp.SwitchLogicStateResponse.ErrorCode = (int)ErrorCode.ErrActionEntityNoExist;
return rsp;
}
EntityLogicStateComponent logicStateComponent = entity.ComponentSystem.Get<EntityLogicStateComponent>();
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<EntityBase>(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<CombatResponseData?> 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<CombatResponseData?>(null);
}
private static ImmutableDictionary<CombatRequestData.MessageOneofCase, CombatRequestHandler> MapRequestHandlers()
{
var builder = ImmutableDictionary.CreateBuilder<CombatRequestData.MessageOneofCase, CombatRequestHandler>();
MethodInfo taskFromResultMethod = typeof(Task).GetMethod(nameof(Task.FromResult))!.MakeGenericMethod(typeof(CombatResponseData));
foreach (MethodInfo method in typeof(CombatManager).GetMethods())
{
CombatRequestAttribute? attribute = method.GetCustomAttribute<CombatRequestAttribute>();
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<CombatRequestHandler> lambda = Expression.Lambda<CombatRequestHandler>(call, combatManagerParam, contextParam);
builder.Add(attribute.MessageCase, lambda.Compile());
}
return builder.ToImmutable();
}
}

View file

@ -0,0 +1,14 @@
using Protocol;
namespace GameServer.Controllers.Combat;
internal class CombatRequestContext
{
public CombatRequestData Request { get; }
public List<CombatNotifyData> Notifies { get; }
public CombatRequestContext(CombatRequestData request)
{
Request = request;
Notifies = [];
}
}

View file

@ -1,4 +1,5 @@
using GameServer.Controllers.Attributes; using GameServer.Controllers.Attributes;
using GameServer.Controllers.Combat;
using GameServer.Network; using GameServer.Network;
using GameServer.Network.Messages; using GameServer.Network.Messages;
using Protocol; using Protocol;
@ -12,5 +13,33 @@ internal class CombatMessageController : Controller
} }
[NetEvent(MessageId.CombatSendPackRequest)] // TODO: CombatSendPackRequest is important [NetEvent(MessageId.CombatSendPackRequest)] // TODO: CombatSendPackRequest is important
public ResponseMessage OnCombatSendPackRequest() => Response(MessageId.CombatSendPackResponse, new CombatSendPackResponse()); public async Task<ResponseMessage> 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());
}
} }

View file

@ -67,9 +67,10 @@ internal class CreatureController : Controller
} }
[NetEvent(MessageId.SceneLoadingFinishRequest)] [NetEvent(MessageId.SceneLoadingFinishRequest)]
public ResponseMessage OnSceneLoadingFinishRequest() public async Task<ResponseMessage> OnSceneLoadingFinishRequest()
{ {
_modelManager.Creature.OnWorldDone(); _modelManager.Creature.OnWorldDone();
await UpdateAiHate();
return Response(MessageId.SceneLoadingFinishResponse, new SceneLoadingFinishResponse()); return Response(MessageId.SceneLoadingFinishResponse, new SceneLoadingFinishResponse());
} }
@ -79,10 +80,7 @@ internal class CreatureController : Controller
{ {
// Remove old entities // Remove old entities
IEnumerable<PlayerEntity> oldEntities = _entitySystem.EnumerateEntities() IEnumerable<PlayerEntity> oldEntities = GetPlayerEntities().ToArray();
.Where(e => e is PlayerEntity entity && entity.PlayerId == _modelManager.Player.Id)
.Cast<PlayerEntity>().ToArray();
foreach (PlayerEntity oldEntity in oldEntities) foreach (PlayerEntity oldEntity in oldEntities)
{ {
_entitySystem.Destroy(oldEntity); _entitySystem.Destroy(oldEntity);
@ -105,10 +103,7 @@ internal class CreatureController : Controller
CreateTeamPlayerEntities(); CreateTeamPlayerEntities();
IEnumerable<PlayerEntity> newEntities = _entitySystem.EnumerateEntities() IEnumerable<PlayerEntity> newEntities = GetPlayerEntities();
.Where(e => e is PlayerEntity entity && entity.PlayerId == _modelManager.Player.Id)
.Cast<PlayerEntity>();
await Session.Push(MessageId.EntityAddNotify, new EntityAddNotify await Session.Push(MessageId.EntityAddNotify, new EntityAddNotify
{ {
IsAdd = true, IsAdd = true,
@ -124,6 +119,8 @@ internal class CreatureController : Controller
PlayerId = _modelManager.Player.Id, PlayerId = _modelManager.Player.Id,
FightRoleInfos = { GetFightRoleInfos() } FightRoleInfos = { GetFightRoleInfos() }
}); });
await UpdateAiHate();
} }
[GameEvent(GameEventType.VisionSkillChanged)] [GameEvent(GameEventType.VisionSkillChanged)]
@ -165,13 +162,43 @@ internal class CreatureController : Controller
prevEntity.IsCurrentRole = false; prevEntity.IsCurrentRole = false;
PlayerEntity? newEntity = _entitySystem.EnumerateEntities().FirstOrDefault(e => e is PlayerEntity playerEntity && playerEntity.ConfigId == roleId) as PlayerEntity; if (_entitySystem.EnumerateEntities().FirstOrDefault(e => e is PlayerEntity playerEntity && playerEntity.ConfigId == roleId) is not PlayerEntity newEntity) return;
if (newEntity == null) return;
_modelManager.Creature.PlayerEntityId = newEntity.Id; _modelManager.Creature.PlayerEntityId = newEntity.Id;
newEntity.IsCurrentRole = true; newEntity.IsCurrentRole = true;
await OnVisionSkillChanged(); await UpdateAiHate();
}
public async Task UpdateAiHate()
{
IEnumerable<EntityBase> 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() private SceneInformation CreateSceneInfo() => new()
@ -200,11 +227,7 @@ internal class CreatureController : Controller
private IEnumerable<FightRoleInformation> GetFightRoleInfos() private IEnumerable<FightRoleInformation> GetFightRoleInfos()
{ {
IEnumerable<PlayerEntity> playerEntities = _entitySystem.EnumerateEntities() return GetPlayerEntities().Select(playerEntity => new FightRoleInformation
.Where(e => e is PlayerEntity entity && entity.PlayerId == _modelManager.Player.Id)
.Cast<PlayerEntity>();
return playerEntities.Select(playerEntity => new FightRoleInformation
{ {
EntityId = playerEntity.Id, EntityId = playerEntity.Id,
CurHp = playerEntity.Health, CurHp = playerEntity.Health,

View file

@ -35,8 +35,9 @@ internal class RoleController : Controller
} }
[NetEvent(MessageId.SwitchRoleRequest)] [NetEvent(MessageId.SwitchRoleRequest)]
public ResponseMessage OnSwitchRoleRequest(SwitchRoleRequest request) public async Task<ResponseMessage> OnSwitchRoleRequest(SwitchRoleRequest request, CreatureController creatureController)
{ {
await creatureController.SwitchPlayerEntity(request.RoleId);
return Response(MessageId.SwitchRoleResponse, new SwitchRoleResponse return Response(MessageId.SwitchRoleResponse, new SwitchRoleResponse
{ {
RoleId = request.RoleId RoleId = request.RoleId

View file

@ -1,6 +1,7 @@
using Core.Config; using Core.Config;
using Core.Extensions; using Core.Extensions;
using GameServer.Controllers.ChatCommands; using GameServer.Controllers.ChatCommands;
using GameServer.Controllers.Combat;
using GameServer.Controllers.Factory; using GameServer.Controllers.Factory;
using GameServer.Controllers.Manager; using GameServer.Controllers.Manager;
using GameServer.Extensions; using GameServer.Extensions;
@ -39,7 +40,8 @@ internal static class Program
.AddScoped<RpcManager>().AddScoped<IRpcEndPoint, RpcSessionEndPoint>() .AddScoped<RpcManager>().AddScoped<IRpcEndPoint, RpcSessionEndPoint>()
.AddSingleton<SessionManager>() .AddSingleton<SessionManager>()
.AddScoped<EventSystem>().AddScoped<EntitySystem>().AddScoped<EntityFactory>() .AddScoped<EventSystem>().AddScoped<EntitySystem>().AddScoped<EntityFactory>()
.AddScoped<ModelManager>().AddScoped<ControllerManager>().AddScoped<ChatCommandManager>() .AddScoped<ModelManager>().AddScoped<ControllerManager>()
.AddScoped<CombatManager>().AddScoped<ChatCommandManager>()
.AddHostedService<WWGameServer>(); .AddHostedService<WWGameServer>();
IHost host = builder.Build(); IHost host = builder.Build();

View file

@ -37,6 +37,7 @@ internal class EntityAttributeComponent : EntityComponentBase
} }
attribute.CurrentValue = currentValue; attribute.CurrentValue = currentValue;
attribute.BaseValue = currentValue;
} }
public int GetAttribute(EAttributeType type) public int GetAttribute(EAttributeType type)

View file

@ -1,4 +1,5 @@
using Protocol; using System.Diagnostics.CodeAnalysis;
using Protocol;
namespace GameServer.Systems.Entity.Component; namespace GameServer.Systems.Entity.Component;
internal class EntityComponentSystem internal class EntityComponentSystem
@ -25,7 +26,7 @@ internal class EntityComponentSystem
return (_components.Single(component => component is TEntityComponent) as TEntityComponent)!; return (_components.Single(component => component is TEntityComponent) as TEntityComponent)!;
} }
public bool TryGet<TEntityComponent>(out TEntityComponent? component) where TEntityComponent : EntityComponentBase public bool TryGet<TEntityComponent>([NotNullWhen(true)] out TEntityComponent? component) where TEntityComponent : EntityComponentBase
{ {
return (component = _components.SingleOrDefault(component => component is TEntityComponent) as TEntityComponent) != null; return (component = _components.SingleOrDefault(component => component is TEntityComponent) as TEntityComponent) != null;
} }

View file

@ -0,0 +1,22 @@
using Protocol;
namespace GameServer.Systems.Entity.Component;
internal class EntityLogicStateComponent : EntityComponentBase
{
public List<int> States { get; set; }
public EntityLogicStateComponent()
{
States = [];
}
public override EntityComponentType Type => EntityComponentType.LogicState;
public override EntityComponentPb Pb => new()
{
LogicStateComponentPb = new()
{
States = { States }
}
};
}

View file

@ -28,6 +28,8 @@ internal abstract class EntityBase
public virtual void OnCreate() public virtual void OnCreate()
{ {
State = EntityState.Born; State = EntityState.Born;
_ = ComponentSystem.Create<EntityLogicStateComponent>();
} }
public virtual void Activate() public virtual void Activate()

View file

@ -1604,6 +1604,7 @@ message CombatMaxCaseMessageResponse { // MessageId: 11987
message CombatNotifyData { message CombatNotifyData {
CombatCommon combat_common = 1; CombatCommon combat_common = 1;
oneof message {
CreateBulletNotify create_bullet_notify = 2; CreateBulletNotify create_bullet_notify = 2;
DestroyBulletNotify destroy_bullet_notify = 3; DestroyBulletNotify destroy_bullet_notify = 3;
DamageExecuteNotify damage_execute_notify = 4; DamageExecuteNotify damage_execute_notify = 4;
@ -1661,21 +1662,26 @@ message CombatNotifyData {
RecoverPropChangedNotify recover_prop_changed_notify = 58; RecoverPropChangedNotify recover_prop_changed_notify = 58;
RemoveBuffByIdS2cRequestNotify remove_buff_by_id_s2c_request_notify = 59; RemoveBuffByIdS2cRequestNotify remove_buff_by_id_s2c_request_notify = 59;
FormationBuffRemoveByIdS2cRequestNotify formation_buff_remove_by_id_s2c_request_notify = 60; FormationBuffRemoveByIdS2cRequestNotify formation_buff_remove_by_id_s2c_request_notify = 60;
}
} }
message CombatPushData { message CombatPushData {
CombatCommon combat_common = 1; CombatCommon combat_common = 1;
oneof message {
FormationBuffApplyS2cResponsePush formation_buff_apply_s2c_response_push = 2; FormationBuffApplyS2cResponsePush formation_buff_apply_s2c_response_push = 2;
FormationBuffRemoveS2cResponsePush formation_buff_remove_s2c_response_push = 3; FormationBuffRemoveS2cResponsePush formation_buff_remove_s2c_response_push = 3;
ApplyBuffS2cResponsePush apply_buff_s2c_response_push = 4; ApplyBuffS2cResponsePush apply_buff_s2c_response_push = 4;
RemoveBuffS2cResponsePush remove_buff_s2c_response_push = 5; RemoveBuffS2cResponsePush remove_buff_s2c_response_push = 5;
RemoveBuffByIdS2cResponsePush remove_buff_by_id_s2c_response_push = 6; RemoveBuffByIdS2cResponsePush remove_buff_by_id_s2c_response_push = 6;
FormationBuffRemoveByIdS2cResponsePush formation_buff_remove_by_id_s2c_response_push = 7; FormationBuffRemoveByIdS2cResponsePush formation_buff_remove_by_id_s2c_response_push = 7;
}
} }
message CombatReceiveData { message CombatReceiveData {
oneof message {
CombatNotifyData combat_notify_data = 2; CombatNotifyData combat_notify_data = 2;
CombatResponseData combat_response_data = 3; CombatResponseData combat_response_data = 3;
}
} }
message CombatReceivePackNotify { // MessageId: 1332 message CombatReceivePackNotify { // MessageId: 1332
@ -1685,6 +1691,7 @@ message CombatReceivePackNotify { // MessageId: 1332
message CombatRequestData { message CombatRequestData {
CombatCommon combat_common = 1; CombatCommon combat_common = 1;
int32 request_id = 2; int32 request_id = 2;
oneof message {
CreateBulletRequest create_bullet_request = 3; CreateBulletRequest create_bullet_request = 3;
DestroyBulletRequest destroy_bullet_request = 4; DestroyBulletRequest destroy_bullet_request = 4;
DamageExecuteRequest damage_execute_request = 5; DamageExecuteRequest damage_execute_request = 5;
@ -1745,12 +1752,14 @@ message CombatRequestData {
DrownEndTeleportRequest drown_end_teleport_request = 60; DrownEndTeleportRequest drown_end_teleport_request = 60;
MonsterDrownRequest monster_drown_request = 61; MonsterDrownRequest monster_drown_request = 61;
CombatMaxCaseMessageRequest combat_max_case_message_request = 62; CombatMaxCaseMessageRequest combat_max_case_message_request = 62;
}
CombatContext context = 100; CombatContext context = 100;
} }
message CombatResponseData { message CombatResponseData {
CombatCommon combat_common = 1; CombatCommon combat_common = 1;
int32 request_id = 2; int32 request_id = 2;
oneof message {
CreateBulletResponse create_bullet_response = 3; CreateBulletResponse create_bullet_response = 3;
DestroyBulletResponse destroy_bullet_response = 4; DestroyBulletResponse destroy_bullet_response = 4;
DamageExecuteResponse damage_execute_response = 5; DamageExecuteResponse damage_execute_response = 5;
@ -1810,6 +1819,7 @@ message CombatResponseData {
RTimeStopResponse r_time_stop_response = 59; RTimeStopResponse r_time_stop_response = 59;
DrownEndTeleportResponse drown_end_teleport_response = 60; DrownEndTeleportResponse drown_end_teleport_response = 60;
MonsterDrownResponse monster_drown_response = 61; MonsterDrownResponse monster_drown_response = 61;
}
} }
message CombatSendData { message CombatSendData {