Compare commits
3 commits
Author | SHA1 | Date | |
---|---|---|---|
a1736317a1 | |||
5d58821be4 | |||
5fce82048f |
38 changed files with 338 additions and 176 deletions
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Core.Config;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Controllers.Attributes;
|
|
||||||
using GameServer.Models;
|
using GameServer.Models;
|
||||||
using GameServer.Models.Chat;
|
using GameServer.Models.Chat;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
|
|
|
@ -4,7 +4,6 @@ using GameServer.Models;
|
||||||
using GameServer.Models.Chat;
|
using GameServer.Models.Chat;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Systems.Entity;
|
using GameServer.Systems.Entity;
|
||||||
using Protocol;
|
|
||||||
|
|
||||||
namespace GameServer.Controllers.ChatCommands;
|
namespace GameServer.Controllers.ChatCommands;
|
||||||
|
|
||||||
|
@ -50,14 +49,8 @@ internal class ChatSpawnCommandHandler
|
||||||
Z = z * 100
|
Z = z * 100
|
||||||
};
|
};
|
||||||
|
|
||||||
_entitySystem.Create(monster);
|
|
||||||
monster.InitProps(_configManager.GetConfig<BasePropertyConfig>(600000100)!); // TODO: monster property config
|
monster.InitProps(_configManager.GetConfig<BasePropertyConfig>(600000100)!); // TODO: monster property config
|
||||||
|
_entitySystem.Add([monster]);
|
||||||
await _session.Push(MessageId.EntityAddNotify, new EntityAddNotify
|
|
||||||
{
|
|
||||||
IsAdd = true,
|
|
||||||
EntityPbs = { monster.Pb }
|
|
||||||
});
|
|
||||||
|
|
||||||
await _creatureController.UpdateAiHate();
|
await _creatureController.UpdateAiHate();
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ using GameServer.Controllers.ChatCommands;
|
||||||
using GameServer.Models;
|
using GameServer.Models;
|
||||||
using GameServer.Models.Chat;
|
using GameServer.Models.Chat;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -82,7 +82,7 @@ internal class CombatManager
|
||||||
}
|
}
|
||||||
|
|
||||||
[CombatRequest(CombatRequestData.MessageOneofCase.DamageExecuteRequest)]
|
[CombatRequest(CombatRequestData.MessageOneofCase.DamageExecuteRequest)]
|
||||||
public async Task<CombatResponseData> OnDamageExecuteRequest(CombatRequestContext context)
|
public CombatResponseData OnDamageExecuteRequest(CombatRequestContext context)
|
||||||
{
|
{
|
||||||
DamageExecuteRequest request = context.Request.DamageExecuteRequest;
|
DamageExecuteRequest request = context.Request.DamageExecuteRequest;
|
||||||
|
|
||||||
|
@ -105,19 +105,7 @@ internal class CombatManager
|
||||||
|
|
||||||
if (request.DamageId <= 0 && entity.Type != EEntityType.Player) // Player death not implemented
|
if (request.DamageId <= 0 && entity.Type != EEntityType.Player) // Player death not implemented
|
||||||
{
|
{
|
||||||
_entitySystem.Destroy(entity);
|
_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
|
return new CombatResponseData
|
||||||
|
|
|
@ -3,31 +3,39 @@ using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Extensions.Logic;
|
using GameServer.Extensions.Logic;
|
||||||
using GameServer.Models;
|
using GameServer.Models;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using GameServer.Settings;
|
using GameServer.Settings;
|
||||||
using GameServer.Systems.Entity;
|
using GameServer.Systems.Entity;
|
||||||
using GameServer.Systems.Entity.Component;
|
using GameServer.Systems.Entity.Component;
|
||||||
using GameServer.Systems.Event;
|
using GameServer.Systems.Event;
|
||||||
|
using GameServer.Systems.Notify;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
internal class CreatureController : Controller
|
internal class CreatureController : Controller
|
||||||
{
|
{
|
||||||
|
private const float DynamicSpawnRadius = 5000;
|
||||||
|
private const float DynamicSpawnPositionDelta = 2500;
|
||||||
|
|
||||||
private readonly EntitySystem _entitySystem;
|
private readonly EntitySystem _entitySystem;
|
||||||
private readonly EntityFactory _entityFactory;
|
private readonly EntityFactory _entityFactory;
|
||||||
private readonly ModelManager _modelManager;
|
private readonly ModelManager _modelManager;
|
||||||
private readonly ConfigManager _configManager;
|
private readonly ConfigManager _configManager;
|
||||||
|
private readonly IGameActionListener _listener;
|
||||||
|
|
||||||
private readonly GameplayFeatureSettings _gameplayFeatures;
|
private readonly GameplayFeatureSettings _gameplayFeatures;
|
||||||
|
private readonly Vector _lastDynamicSpawnPos;
|
||||||
|
|
||||||
public CreatureController(PlayerSession session, EntitySystem entitySystem, EntityFactory entityFactory, ModelManager modelManager, ConfigManager configManager, IOptions<GameplayFeatureSettings> gameplayFeatures) : base(session)
|
public CreatureController(PlayerSession session, EntitySystem entitySystem, EntityFactory entityFactory, ModelManager modelManager, ConfigManager configManager, IOptions<GameplayFeatureSettings> gameplayFeatures, IGameActionListener listener) : base(session)
|
||||||
{
|
{
|
||||||
_entitySystem = entitySystem;
|
_entitySystem = entitySystem;
|
||||||
_entityFactory = entityFactory;
|
_entityFactory = entityFactory;
|
||||||
_modelManager = modelManager;
|
_modelManager = modelManager;
|
||||||
_configManager = configManager;
|
_configManager = configManager;
|
||||||
|
_listener = listener;
|
||||||
_gameplayFeatures = gameplayFeatures.Value;
|
_gameplayFeatures = gameplayFeatures.Value;
|
||||||
|
|
||||||
|
_lastDynamicSpawnPos = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task JoinScene(int instanceId)
|
public async Task JoinScene(int instanceId)
|
||||||
|
@ -36,15 +44,7 @@ internal class CreatureController : Controller
|
||||||
CreateTeamPlayerEntities();
|
CreateTeamPlayerEntities();
|
||||||
CreateWorldEntities();
|
CreateWorldEntities();
|
||||||
|
|
||||||
await Session.Push(MessageId.JoinSceneNotify, new JoinSceneNotify
|
await _listener.OnJoinedScene(CreateSceneInfo(), TransitionType.Empty);
|
||||||
{
|
|
||||||
MaxEntityId = 10000000,
|
|
||||||
TransitionOption = new TransitionOptionPb
|
|
||||||
{
|
|
||||||
TransitionType = (int)TransitionType.Empty
|
|
||||||
},
|
|
||||||
SceneInfo = CreateSceneInfo()
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[NetEvent(MessageId.EntityActiveRequest)]
|
[NetEvent(MessageId.EntityActiveRequest)]
|
||||||
|
@ -85,47 +85,11 @@ internal class CreatureController : Controller
|
||||||
[GameEvent(GameEventType.FormationUpdated)]
|
[GameEvent(GameEventType.FormationUpdated)]
|
||||||
public async Task OnFormationUpdated()
|
public async Task OnFormationUpdated()
|
||||||
{
|
{
|
||||||
// Remove old entities
|
_entitySystem.Destroy(GetPlayerEntities().ToArray());
|
||||||
|
|
||||||
IEnumerable<PlayerEntity> oldEntities = GetPlayerEntities().ToArray();
|
|
||||||
foreach (PlayerEntity oldEntity in oldEntities)
|
|
||||||
{
|
|
||||||
_entitySystem.Destroy(oldEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
await Session.Push(MessageId.EntityRemoveNotify, new EntityRemoveNotify
|
|
||||||
{
|
|
||||||
IsRemove = true,
|
|
||||||
RemoveInfos =
|
|
||||||
{
|
|
||||||
oldEntities.Select(entity => new EntityRemoveInfo
|
|
||||||
{
|
|
||||||
EntityId = entity.Id,
|
|
||||||
Type = (int)entity.Type
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Spawn new entities
|
|
||||||
|
|
||||||
CreateTeamPlayerEntities();
|
CreateTeamPlayerEntities();
|
||||||
|
|
||||||
IEnumerable<PlayerEntity> newEntities = GetPlayerEntities();
|
_modelManager.Creature.PlayerEntityId = GetPlayerEntities().First().Id;
|
||||||
await Session.Push(MessageId.EntityAddNotify, new EntityAddNotify
|
await _listener.OnPlayerFightRoleInfoUpdated(_modelManager.Player.Id, GetFightRoleInfos());
|
||||||
{
|
|
||||||
IsAdd = true,
|
|
||||||
EntityPbs =
|
|
||||||
{
|
|
||||||
newEntities.Select(entity => entity.Pb)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_modelManager.Creature.PlayerEntityId = newEntities.First().Id;
|
|
||||||
await Session.Push(MessageId.UpdatePlayerAllFightRoleNotify, new UpdatePlayerAllFightRoleNotify
|
|
||||||
{
|
|
||||||
PlayerId = _modelManager.Player.Id,
|
|
||||||
FightRoleInfos = { GetFightRoleInfos() }
|
|
||||||
});
|
|
||||||
|
|
||||||
await UpdateAiHate();
|
await UpdateAiHate();
|
||||||
}
|
}
|
||||||
|
@ -134,6 +98,14 @@ internal class CreatureController : Controller
|
||||||
public void OnPlayerPositionChanged()
|
public void OnPlayerPositionChanged()
|
||||||
{
|
{
|
||||||
_modelManager.Player.Position.MergeFrom(GetPlayerEntity()!.Pos);
|
_modelManager.Player.Position.MergeFrom(GetPlayerEntity()!.Pos);
|
||||||
|
|
||||||
|
if (_lastDynamicSpawnPos.GetDistance(_modelManager.Player.Position) >= DynamicSpawnPositionDelta)
|
||||||
|
{
|
||||||
|
_lastDynamicSpawnPos.MergeFrom(_modelManager.Player.Position);
|
||||||
|
|
||||||
|
ClearInactiveEntities();
|
||||||
|
SpawnDynamicEntities();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[GameEvent(GameEventType.VisionSkillChanged)]
|
[GameEvent(GameEventType.VisionSkillChanged)]
|
||||||
|
@ -256,6 +228,8 @@ internal class CreatureController : Controller
|
||||||
|
|
||||||
private void CreateTeamPlayerEntities()
|
private void CreateTeamPlayerEntities()
|
||||||
{
|
{
|
||||||
|
PlayerEntity[] playerEntities = new PlayerEntity[_modelManager.Formation.RoleIds.Length];
|
||||||
|
|
||||||
for (int i = 0; i < _modelManager.Formation.RoleIds.Length; i++)
|
for (int i = 0; i < _modelManager.Formation.RoleIds.Length; i++)
|
||||||
{
|
{
|
||||||
int roleId = _modelManager.Formation.RoleIds[i];
|
int roleId = _modelManager.Formation.RoleIds[i];
|
||||||
|
@ -264,7 +238,6 @@ internal class CreatureController : Controller
|
||||||
entity.Pos = _modelManager.Player.Position.Clone();
|
entity.Pos = _modelManager.Player.Position.Clone();
|
||||||
entity.IsCurrentRole = i == 0;
|
entity.IsCurrentRole = i == 0;
|
||||||
|
|
||||||
_entitySystem.Create(entity);
|
|
||||||
entity.ComponentSystem.Get<EntityAttributeComponent>().SetAll(_modelManager.Roles.GetRoleById(roleId)!.GetAttributeList());
|
entity.ComponentSystem.Get<EntityAttributeComponent>().SetAll(_modelManager.Roles.GetRoleById(roleId)!.GetAttributeList());
|
||||||
|
|
||||||
CreateConcomitants(entity);
|
CreateConcomitants(entity);
|
||||||
|
@ -281,7 +254,11 @@ internal class CreatureController : Controller
|
||||||
attr.SetAttribute(EAttributeType.SpecialEnergy3Max, 0);
|
attr.SetAttribute(EAttributeType.SpecialEnergy3Max, 0);
|
||||||
attr.SetAttribute(EAttributeType.SpecialEnergy4Max, 0);
|
attr.SetAttribute(EAttributeType.SpecialEnergy4Max, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playerEntities[i] = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_entitySystem.Add(playerEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateConcomitants(PlayerEntity entity)
|
private void CreateConcomitants(PlayerEntity entity)
|
||||||
|
@ -295,7 +272,6 @@ internal class CreatureController : Controller
|
||||||
if (roleId != -1)
|
if (roleId != -1)
|
||||||
{
|
{
|
||||||
PlayerEntity concomitant = _entityFactory.CreatePlayer(roleId, 0);
|
PlayerEntity concomitant = _entityFactory.CreatePlayer(roleId, 0);
|
||||||
_entitySystem.Create(concomitant);
|
|
||||||
|
|
||||||
EntityConcomitantsComponent concomitants = entity.ComponentSystem.Create<EntityConcomitantsComponent>();
|
EntityConcomitantsComponent concomitants = entity.ComponentSystem.Create<EntityConcomitantsComponent>();
|
||||||
concomitants.CustomEntityIds.Clear();
|
concomitants.CustomEntityIds.Clear();
|
||||||
|
@ -309,23 +285,49 @@ internal class CreatureController : Controller
|
||||||
summoner.PlayerId = _modelManager.Player.Id;
|
summoner.PlayerId = _modelManager.Player.Id;
|
||||||
|
|
||||||
concomitant.InitProps(_configManager.GetConfig<BasePropertyConfig>(roleId)!);
|
concomitant.InitProps(_configManager.GetConfig<BasePropertyConfig>(roleId)!);
|
||||||
|
_entitySystem.Add([concomitant]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateWorldEntities()
|
private void CreateWorldEntities()
|
||||||
|
{
|
||||||
|
_lastDynamicSpawnPos.MergeFrom(_modelManager.Player.Position.Clone());
|
||||||
|
SpawnDynamicEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearInactiveEntities()
|
||||||
|
{
|
||||||
|
_entitySystem.Destroy(_entitySystem.EnumerateEntities()
|
||||||
|
.Where(e => e is MonsterEntity && e.DynamicId != 0 &&
|
||||||
|
e.Pos.GetDistance(_modelManager.Player.Position) > DynamicSpawnRadius).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SpawnDynamicEntities()
|
||||||
{
|
{
|
||||||
Vector playerPos = _modelManager.Player.Position;
|
Vector playerPos = _modelManager.Player.Position;
|
||||||
|
|
||||||
// Test monster
|
// Currently only monsters
|
||||||
MonsterEntity monster = _entityFactory.CreateMonster(106003002); // Turtle.
|
IEnumerable<LevelEntityConfig> entitiesToSpawn = _configManager.Enumerate<LevelEntityConfig>()
|
||||||
monster.Pos = new()
|
.Where(config => config.MapId == 8 && Math.Abs(config.Transform[0].X / 100 - playerPos.X) < DynamicSpawnRadius && Math.Abs(config.Transform[0].Y / 100 - playerPos.Y) < DynamicSpawnRadius &&
|
||||||
{
|
config.BlueprintType.StartsWith("Monster"));
|
||||||
X = playerPos.X + 250,
|
|
||||||
Y = playerPos.Y + 250,
|
|
||||||
Z = playerPos.Z
|
|
||||||
};
|
|
||||||
|
|
||||||
_entitySystem.Create(monster);
|
List<MonsterEntity> spawnMonsters = [];
|
||||||
monster.InitProps(_configManager.GetConfig<BasePropertyConfig>(600000100)!);
|
foreach (LevelEntityConfig levelEntity in entitiesToSpawn)
|
||||||
|
{
|
||||||
|
if (_entitySystem.HasDynamicEntity(levelEntity.EntityId)) continue;
|
||||||
|
|
||||||
|
MonsterEntity monster = _entityFactory.CreateMonster(levelEntity.EntityId);
|
||||||
|
monster.Pos = new()
|
||||||
|
{
|
||||||
|
X = levelEntity.Transform[0].X / 100,
|
||||||
|
Y = levelEntity.Transform[0].Y / 100,
|
||||||
|
Z = levelEntity.Transform[0].Z / 100
|
||||||
|
};
|
||||||
|
|
||||||
|
monster.InitProps(_configManager.GetConfig<BasePropertyConfig>(600000100)!);
|
||||||
|
spawnMonsters.Add(monster);
|
||||||
|
}
|
||||||
|
|
||||||
|
_entitySystem.Add(spawnMonsters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Models;
|
using GameServer.Models;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using GameServer.Systems.Entity;
|
|
||||||
using GameServer.Systems.Event;
|
using GameServer.Systems.Event;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -4,7 +4,6 @@ using GameServer.Extensions.Logic;
|
||||||
using GameServer.Models;
|
using GameServer.Models;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Systems.Entity;
|
using GameServer.Systems.Entity;
|
||||||
using GameServer.Systems.Entity.Component;
|
|
||||||
using GameServer.Systems.Event;
|
using GameServer.Systems.Event;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
|
@ -38,7 +37,7 @@ internal class InventoryController : Controller
|
||||||
public RpcResult OnItemExchangeInfoRequest() => Response(MessageId.ItemExchangeInfoResponse, new ItemExchangeInfoResponse());
|
public RpcResult OnItemExchangeInfoRequest() => Response(MessageId.ItemExchangeInfoResponse, new ItemExchangeInfoResponse());
|
||||||
|
|
||||||
[NetEvent(MessageId.EquipTakeOnRequest)]
|
[NetEvent(MessageId.EquipTakeOnRequest)]
|
||||||
public async Task<RpcResult> OnEquipTakeOnRequest(EquipTakeOnRequest request, ModelManager modelManager, CreatureController creatureController, ConfigManager configManager)
|
public RpcResult OnEquipTakeOnRequest(EquipTakeOnRequest request, ModelManager modelManager, CreatureController creatureController, RoleController roleController, ConfigManager configManager)
|
||||||
{
|
{
|
||||||
WeaponItem? weapon = modelManager.Inventory.GetWeaponById(request.Data.EquipIncId);
|
WeaponItem? weapon = modelManager.Inventory.GetWeaponById(request.Data.EquipIncId);
|
||||||
if (weapon == null) return Response(MessageId.EquipTakeOnResponse, new EquipTakeOnResponse
|
if (weapon == null) return Response(MessageId.EquipTakeOnResponse, new EquipTakeOnResponse
|
||||||
|
@ -60,39 +59,12 @@ internal class InventoryController : Controller
|
||||||
|
|
||||||
// Set new weapon
|
// Set new weapon
|
||||||
weapon.RoleId = role.RoleId;
|
weapon.RoleId = role.RoleId;
|
||||||
role.ApplyWeaponProperties(weaponConf);
|
roleController.ApplyWeaponPropertiesToRole(role.RoleId, weaponConf);
|
||||||
|
|
||||||
// Update role prop data on client
|
|
||||||
await Session.Push(MessageId.PbRolePropsNotify, new PbRolePropsNotify
|
|
||||||
{
|
|
||||||
RoleId = role.RoleId,
|
|
||||||
BaseProp = { role.BaseProp },
|
|
||||||
AddProp = { role.AddProp }
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// Update entity (if this role is currently active)
|
||||||
PlayerEntity? entity = creatureController.GetPlayerEntityByRoleId(request.Data.RoleId);
|
PlayerEntity? entity = creatureController.GetPlayerEntityByRoleId(request.Data.RoleId);
|
||||||
if (entity != null)
|
entity?.ChangeEquipment(weapon.Id);
|
||||||
{
|
entity?.ChangeGameplayAttributes(role.GetAttributeList());
|
||||||
// Update entity equipment
|
|
||||||
EntityEquipComponent equipComponent = entity.ComponentSystem.Get<EntityEquipComponent>();
|
|
||||||
equipComponent.WeaponId = weapon.Id;
|
|
||||||
|
|
||||||
await Session.Push(MessageId.EntityEquipChangeNotify, new EntityEquipChangeNotify
|
|
||||||
{
|
|
||||||
EntityId = entity.Id,
|
|
||||||
EquipComponent = equipComponent.Pb.EquipComponent
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update entity gameplay attributes
|
|
||||||
EntityAttributeComponent attrComponent = entity.ComponentSystem.Get<EntityAttributeComponent>();
|
|
||||||
attrComponent.SetAll(role.GetAttributeList());
|
|
||||||
|
|
||||||
await Session.Push(MessageId.AttributeChangedNotify, new AttributeChangedNotify
|
|
||||||
{
|
|
||||||
Id = entity.Id,
|
|
||||||
Attributes = { attrComponent.Pb.AttributeComponent.GameAttributes }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response
|
// Response
|
||||||
EquipTakeOnResponse response = new()
|
EquipTakeOnResponse response = new()
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -4,25 +4,38 @@ using GameServer.Extensions.Logic;
|
||||||
using GameServer.Models;
|
using GameServer.Models;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Systems.Event;
|
using GameServer.Systems.Event;
|
||||||
|
using GameServer.Systems.Notify;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
internal class RoleController : Controller
|
internal class RoleController : Controller
|
||||||
{
|
{
|
||||||
public RoleController(PlayerSession session) : base(session)
|
private readonly ModelManager _modelManager;
|
||||||
|
private readonly IGameActionListener _listener;
|
||||||
|
|
||||||
|
public RoleController(PlayerSession session, ModelManager modelManager, IGameActionListener listener) : base(session)
|
||||||
{
|
{
|
||||||
// RoleController.
|
_modelManager = modelManager;
|
||||||
|
_listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyWeaponPropertiesToRole(int roleId, WeaponConfig weaponConfiguration)
|
||||||
|
{
|
||||||
|
roleInfo? role = _modelManager.Roles.GetRoleById(roleId) ?? throw new ArgumentException($"Role with id {roleId} doesn't exist");
|
||||||
|
|
||||||
|
role.ApplyWeaponProperties(weaponConfiguration);
|
||||||
|
_ = _listener.OnRolePropertiesUpdated(roleId, role.BaseProp, role.AddProp);
|
||||||
}
|
}
|
||||||
|
|
||||||
[GameEvent(GameEventType.DebugUnlockAllRoles)]
|
[GameEvent(GameEventType.DebugUnlockAllRoles)]
|
||||||
public void UnlockAllRoles(ConfigManager configManager, ModelManager modelManager)
|
public void UnlockAllRoles(ConfigManager configManager)
|
||||||
{
|
{
|
||||||
foreach (RoleInfoConfig roleConfig in configManager.Enumerate<RoleInfoConfig>())
|
foreach (RoleInfoConfig roleConfig in configManager.Enumerate<RoleInfoConfig>())
|
||||||
{
|
{
|
||||||
roleInfo role = modelManager.Roles.Create(roleConfig.Id);
|
roleInfo role = _modelManager.Roles.Create(roleConfig.Id);
|
||||||
role.BaseProp.AddRange(CreateBasePropList(configManager.GetConfig<BasePropertyConfig>(roleConfig.Id)));
|
role.BaseProp.AddRange(CreateBasePropList(configManager.GetConfig<BasePropertyConfig>(roleConfig.Id)));
|
||||||
|
|
||||||
WeaponItem weapon = modelManager.Inventory.AddNewWeapon(roleConfig.InitWeaponItemId);
|
WeaponItem weapon = _modelManager.Inventory.AddNewWeapon(roleConfig.InitWeaponItemId);
|
||||||
weapon.RoleId = role.RoleId;
|
weapon.RoleId = role.RoleId;
|
||||||
|
|
||||||
role.ApplyWeaponProperties(configManager.GetConfig<WeaponConfig>(weapon.Id)!);
|
role.ApplyWeaponProperties(configManager.GetConfig<WeaponConfig>(weapon.Id)!);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Models;
|
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using GameServer.Systems.Entity;
|
using GameServer.Systems.Entity;
|
||||||
using GameServer.Systems.Entity.Component;
|
using GameServer.Systems.Entity.Component;
|
||||||
using GameServer.Systems.Event;
|
using GameServer.Systems.Event;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using GameServer.Systems.Event;
|
using GameServer.Systems.Event;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
using GameServer.Settings;
|
using GameServer.Settings;
|
||||||
using GameServer.Systems.Entity;
|
using GameServer.Systems.Entity;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
13
GameServer/Extensions/Logic/MathExtensions.cs
Normal file
13
GameServer/Extensions/Logic/MathExtensions.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Extensions.Logic;
|
||||||
|
internal static class MathExtensions
|
||||||
|
{
|
||||||
|
public static float GetDistance(this Vector self, Vector other)
|
||||||
|
{
|
||||||
|
float x = self.X - other.X;
|
||||||
|
float y = self.Y - other.Y;
|
||||||
|
|
||||||
|
return (float)Math.Sqrt(x * x + y * y);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
using Google.Protobuf;
|
using Protocol;
|
||||||
using Protocol;
|
|
||||||
|
|
||||||
namespace GameServer.Models.Chat;
|
namespace GameServer.Models.Chat;
|
||||||
internal class ChatRoom
|
internal class ChatRoom
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Core.Config;
|
using Protocol;
|
||||||
using Protocol;
|
|
||||||
|
|
||||||
namespace GameServer.Models;
|
namespace GameServer.Models;
|
||||||
internal class RoleModel
|
internal class RoleModel
|
||||||
|
|
|
@ -8,6 +8,7 @@ internal class KcpConnection : IConnection
|
||||||
{
|
{
|
||||||
private readonly byte[] _recvBuffer;
|
private readonly byte[] _recvBuffer;
|
||||||
private readonly KcpConversation _conv;
|
private readonly KcpConversation _conv;
|
||||||
|
private readonly ManualResetEvent _sendEvent;
|
||||||
private uint _upStreamSeqNo;
|
private uint _upStreamSeqNo;
|
||||||
private uint _downStreamSeqNo;
|
private uint _downStreamSeqNo;
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ internal class KcpConnection : IConnection
|
||||||
{
|
{
|
||||||
_conv = conv;
|
_conv = conv;
|
||||||
_recvBuffer = GC.AllocateUninitializedArray<byte>(8192);
|
_recvBuffer = GC.AllocateUninitializedArray<byte>(8192);
|
||||||
|
_sendEvent = new ManualResetEvent(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Active => !_conv.TransportClosed;
|
public bool Active => !_conv.TransportClosed;
|
||||||
|
@ -51,7 +53,16 @@ internal class KcpConnection : IConnection
|
||||||
MessageManager.EncodeMessage(memory[BaseMessage.LengthFieldSize..], message);
|
MessageManager.EncodeMessage(memory[BaseMessage.LengthFieldSize..], message);
|
||||||
|
|
||||||
if (_conv == null) throw new InvalidOperationException("Trying to send message when conv is null");
|
if (_conv == null) throw new InvalidOperationException("Trying to send message when conv is null");
|
||||||
|
|
||||||
|
if (!_sendEvent.WaitOne(0))
|
||||||
|
{
|
||||||
|
await Task.Yield();
|
||||||
|
_ = _sendEvent.WaitOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
_sendEvent.Reset();
|
||||||
await _conv.SendAsync(memoryOwner.Memory[..networkSize]);
|
await _conv.SendAsync(memoryOwner.Memory[..networkSize]);
|
||||||
|
_sendEvent.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint NextUpStreamSeqNo()
|
private uint NextUpStreamSeqNo()
|
||||||
|
|
|
@ -13,6 +13,7 @@ using GameServer.Network.Rpc;
|
||||||
using GameServer.Settings;
|
using GameServer.Settings;
|
||||||
using GameServer.Systems.Entity;
|
using GameServer.Systems.Entity;
|
||||||
using GameServer.Systems.Event;
|
using GameServer.Systems.Event;
|
||||||
|
using GameServer.Systems.Notify;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
@ -39,7 +40,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<EntitySystem>().AddScoped<EntityFactory>()
|
.AddScoped<EventSystem>().AddScoped<EntitySystem>().AddScoped<IGameActionListener, NotifySystem>()
|
||||||
|
.AddScoped<EntityFactory>()
|
||||||
.AddScoped<ModelManager>().AddScoped<ControllerManager>()
|
.AddScoped<ModelManager>().AddScoped<ControllerManager>()
|
||||||
.AddScoped<CombatManager>().AddScoped<ChatCommandManager>()
|
.AddScoped<CombatManager>().AddScoped<ChatCommandManager>()
|
||||||
.AddHostedService<WWGameServer>();
|
.AddHostedService<WWGameServer>();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Core.Config;
|
using Core.Config;
|
||||||
using GameServer.Systems.Entity.Component;
|
using GameServer.Systems.Entity.Component;
|
||||||
|
using GameServer.Systems.Notify;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Systems.Entity;
|
namespace GameServer.Systems.Entity;
|
||||||
|
@ -12,12 +13,15 @@ internal abstract class EntityBase
|
||||||
public Rotator Rot { get; set; }
|
public Rotator Rot { get; set; }
|
||||||
|
|
||||||
public bool Active { get; set; }
|
public bool Active { get; set; }
|
||||||
|
public int DynamicId { get; protected set; }
|
||||||
|
|
||||||
public EntityState State { get; protected set; }
|
public EntityState State { get; protected set; }
|
||||||
|
|
||||||
public bool IsConcomitant => ComponentSystem.TryGet<EntitySummonerComponent>(out _);
|
public bool IsConcomitant => ComponentSystem.TryGet<EntitySummonerComponent>(out _);
|
||||||
|
|
||||||
public EntityBase(long id)
|
protected IGameActionListener ActionListener { get; }
|
||||||
|
|
||||||
|
public EntityBase(long id, IGameActionListener listener)
|
||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
|
|
||||||
|
@ -25,6 +29,7 @@ internal abstract class EntityBase
|
||||||
Rot = new Rotator();
|
Rot = new Rotator();
|
||||||
|
|
||||||
ComponentSystem = new EntityComponentSystem();
|
ComponentSystem = new EntityComponentSystem();
|
||||||
|
ActionListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnCreate()
|
public virtual void OnCreate()
|
||||||
|
@ -40,6 +45,24 @@ internal abstract class EntityBase
|
||||||
// Activate.
|
// Activate.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ChangeEquipment(int weaponId)
|
||||||
|
{
|
||||||
|
if (ComponentSystem.TryGet(out EntityEquipComponent? equipComponent))
|
||||||
|
{
|
||||||
|
equipComponent.WeaponId = weaponId;
|
||||||
|
_ = ActionListener.OnEntityEquipmentChanged(Id, equipComponent.Pb.EquipComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeGameplayAttributes(IEnumerable<GameplayAttributeData> attributes)
|
||||||
|
{
|
||||||
|
if (ComponentSystem.TryGet(out EntityAttributeComponent? attrComponent))
|
||||||
|
{
|
||||||
|
attrComponent.SetAll(attributes);
|
||||||
|
_ = ActionListener.OnEntityAttributesChanged(Id, attrComponent.Pb.AttributeComponent.GameAttributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public virtual LivingStatus LivingStatus => LivingStatus.Alive;
|
public virtual LivingStatus LivingStatus => LivingStatus.Alive;
|
||||||
public virtual bool IsVisible => true;
|
public virtual bool IsVisible => true;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,40 @@
|
||||||
namespace GameServer.Systems.Entity;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Entity;
|
||||||
internal class EntityFactory
|
internal class EntityFactory
|
||||||
{
|
{
|
||||||
|
private static readonly ObjectFactory<PlayerEntity> s_createPlayerEntity;
|
||||||
|
private static readonly ObjectFactory<MonsterEntity> s_createMonsterEntity;
|
||||||
|
|
||||||
private long _entityIdCounter;
|
private long _entityIdCounter;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
|
static EntityFactory()
|
||||||
|
{
|
||||||
|
s_createPlayerEntity = ActivatorUtilities.CreateFactory<PlayerEntity>([typeof(long), typeof(int), typeof(int)]);
|
||||||
|
s_createMonsterEntity = ActivatorUtilities.CreateFactory<MonsterEntity>([typeof(long), typeof(int)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityFactory(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
public PlayerEntity CreatePlayer(int characterConfigId, int playerId)
|
public PlayerEntity CreatePlayer(int characterConfigId, int playerId)
|
||||||
=> new(NextId(), characterConfigId, playerId);
|
{
|
||||||
|
PlayerEntity entity = s_createPlayerEntity(_serviceProvider, [NextId(), characterConfigId, playerId]);
|
||||||
|
entity.OnCreate();
|
||||||
|
|
||||||
public MonsterEntity CreateMonster(int levelEntityId) => new(NextId(), levelEntityId);
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MonsterEntity CreateMonster(int levelEntityId)
|
||||||
|
{
|
||||||
|
MonsterEntity monsterEntity = s_createMonsterEntity(_serviceProvider, [NextId(), levelEntityId]);
|
||||||
|
monsterEntity.OnCreate();
|
||||||
|
|
||||||
|
return monsterEntity;
|
||||||
|
}
|
||||||
|
|
||||||
private long NextId() => Interlocked.Increment(ref _entityIdCounter);
|
private long NextId() => Interlocked.Increment(ref _entityIdCounter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
using Protocol;
|
using GameServer.Systems.Notify;
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Systems.Entity;
|
namespace GameServer.Systems.Entity;
|
||||||
internal class EntitySystem
|
internal class EntitySystem
|
||||||
{
|
{
|
||||||
private readonly List<EntityBase> _entities;
|
private readonly List<EntityBase> _entities;
|
||||||
|
private readonly List<int> _dynamicEntityIds;
|
||||||
|
|
||||||
public EntitySystem()
|
private readonly IGameActionListener _listener;
|
||||||
|
|
||||||
|
public EntitySystem(IGameActionListener listener)
|
||||||
{
|
{
|
||||||
_entities = [];
|
_entities = [];
|
||||||
|
_dynamicEntityIds = [];
|
||||||
|
_listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<EntityBase> EnumerateEntities()
|
public IEnumerable<EntityBase> EnumerateEntities()
|
||||||
|
@ -15,18 +21,36 @@ internal class EntitySystem
|
||||||
return _entities;
|
return _entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Create(EntityBase entity)
|
public void Add(IEnumerable<EntityBase> entities)
|
||||||
{
|
{
|
||||||
if (_entities.Any(e => e.Id == entity.Id))
|
foreach (EntityBase entity in entities)
|
||||||
throw new InvalidOperationException($"EntitySystem::Create - entity with id {entity.Id} already exists");
|
{
|
||||||
|
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);
|
||||||
_entities.Add(entity);
|
|
||||||
|
if (entity.DynamicId != 0)
|
||||||
|
_dynamicEntityIds.Add(entity.DynamicId);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = _listener.OnEntitiesAdded(entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Destroy(EntityBase entity)
|
public bool HasDynamicEntity(int dynamicId)
|
||||||
{
|
{
|
||||||
_ = _entities.Remove(entity);
|
return _dynamicEntityIds.Contains(dynamicId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Destroy(IEnumerable<EntityBase> entities)
|
||||||
|
{
|
||||||
|
foreach (EntityBase entity in entities)
|
||||||
|
{
|
||||||
|
_ = _entities.Remove(entity);
|
||||||
|
_ = _dynamicEntityIds.Remove(entity.DynamicId);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = _listener.OnEntitiesRemoved(entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Activate(EntityBase entity)
|
public void Activate(EntityBase entity)
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
using GameServer.Systems.Entity.Component;
|
using GameServer.Systems.Entity.Component;
|
||||||
|
using GameServer.Systems.Notify;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Systems.Entity;
|
namespace GameServer.Systems.Entity;
|
||||||
internal class MonsterEntity : EntityBase
|
internal class MonsterEntity : EntityBase
|
||||||
{
|
{
|
||||||
public MonsterEntity(long id, int configId) : base(id)
|
public MonsterEntity(long id, int configId, IGameActionListener listener) : base(id, listener)
|
||||||
{
|
{
|
||||||
ConfigId = configId;
|
ConfigId = configId;
|
||||||
|
DynamicId = configId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ConfigId { get; }
|
public int ConfigId { get; }
|
||||||
|
@ -32,17 +34,20 @@ internal class MonsterEntity : EntityBase
|
||||||
fsm.Fsms.Add(new DFsm
|
fsm.Fsms.Add(new DFsm
|
||||||
{
|
{
|
||||||
FsmId = 10007, // Main State Machine
|
FsmId = 10007, // Main State Machine
|
||||||
CurrentState = 10013, // Battle Branching
|
CurrentState = 10013 // Battle Branching
|
||||||
Status = 1, // ??
|
|
||||||
Flag = (int)EFsmStateFlag.Confirmed
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fsm.Fsms.Add(new DFsm
|
fsm.Fsms.Add(new DFsm
|
||||||
{
|
{
|
||||||
FsmId = 10007, // Main State Machine
|
FsmId = 10007, // Main State Machine
|
||||||
CurrentState = 10015, // Moving Combat
|
CurrentState = 10015 // Moving Combat
|
||||||
Status = 1, // ??
|
});
|
||||||
Flag = (int)EFsmStateFlag.Confirmed
|
|
||||||
|
// Some monsters need weapon
|
||||||
|
fsm.Fsms.Add(new DFsm
|
||||||
|
{
|
||||||
|
FsmId = 100,
|
||||||
|
CurrentState = 9 // [9 - Empty hand, 10 - Crowbar, 11 - flamethrower, 12 - chainsaw, 13 - electric blade, 14 - sniper rifle]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
using GameServer.Systems.Entity.Component;
|
using GameServer.Systems.Entity.Component;
|
||||||
|
using GameServer.Systems.Notify;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Systems.Entity;
|
namespace GameServer.Systems.Entity;
|
||||||
internal class PlayerEntity : EntityBase
|
internal class PlayerEntity : EntityBase
|
||||||
{
|
{
|
||||||
public PlayerEntity(long id, int configId, int playerId) : base(id)
|
public PlayerEntity(long id, int configId, int playerId, IGameActionListener listener) : base(id, listener)
|
||||||
{
|
{
|
||||||
ConfigId = configId;
|
ConfigId = configId;
|
||||||
PlayerId = playerId;
|
PlayerId = playerId;
|
||||||
|
|
14
GameServer/Systems/Notify/IGameActionListener.cs
Normal file
14
GameServer/Systems/Notify/IGameActionListener.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
using GameServer.Systems.Entity;
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Notify;
|
||||||
|
internal interface IGameActionListener
|
||||||
|
{
|
||||||
|
Task OnJoinedScene(SceneInformation sceneInformation, TransitionType transitionType);
|
||||||
|
Task OnEntitiesAdded(IEnumerable<EntityBase> entities);
|
||||||
|
Task OnEntitiesRemoved(IEnumerable<EntityBase> entities);
|
||||||
|
Task OnPlayerFightRoleInfoUpdated(int playerId, IEnumerable<FightRoleInformation> fightRoles);
|
||||||
|
Task OnRolePropertiesUpdated(int roleId, IEnumerable<ArrayIntInt> baseProp, IEnumerable<ArrayIntInt> addProp);
|
||||||
|
Task OnEntityEquipmentChanged(long entityId, EquipComponentPb componentPb);
|
||||||
|
Task OnEntityAttributesChanged(long entityId, IEnumerable<GameplayAttributeData> attributes);
|
||||||
|
}
|
97
GameServer/Systems/Notify/NotifySystem.cs
Normal file
97
GameServer/Systems/Notify/NotifySystem.cs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
using GameServer.Models;
|
||||||
|
using GameServer.Network;
|
||||||
|
using GameServer.Systems.Entity;
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Notify;
|
||||||
|
internal class NotifySystem : IGameActionListener
|
||||||
|
{
|
||||||
|
private readonly PlayerSession _session;
|
||||||
|
private readonly ModelManager _modelManager;
|
||||||
|
|
||||||
|
public NotifySystem(PlayerSession session, ModelManager modelManager)
|
||||||
|
{
|
||||||
|
_session = session;
|
||||||
|
_modelManager = modelManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task OnJoinedScene(SceneInformation sceneInformation, TransitionType transitionType)
|
||||||
|
{
|
||||||
|
return _session.Push(MessageId.JoinSceneNotify, new JoinSceneNotify
|
||||||
|
{
|
||||||
|
SceneInfo = sceneInformation,
|
||||||
|
TransitionOption = new TransitionOptionPb
|
||||||
|
{
|
||||||
|
TransitionType = (int)transitionType
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task OnEntitiesAdded(IEnumerable<EntityBase> entities)
|
||||||
|
{
|
||||||
|
if (_modelManager.Creature.LoadingWorld) return Task.CompletedTask;
|
||||||
|
|
||||||
|
return _session.Push(MessageId.EntityAddNotify, new EntityAddNotify
|
||||||
|
{
|
||||||
|
IsAdd = true,
|
||||||
|
EntityPbs = { entities.Select(e => e.Pb) }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task OnEntitiesRemoved(IEnumerable<EntityBase> entities)
|
||||||
|
{
|
||||||
|
if (_modelManager.Creature.LoadingWorld) return Task.CompletedTask;
|
||||||
|
|
||||||
|
return _session.Push(MessageId.EntityRemoveNotify, new EntityRemoveNotify
|
||||||
|
{
|
||||||
|
IsRemove = true,
|
||||||
|
RemoveInfos =
|
||||||
|
{
|
||||||
|
entities.Select(e => new EntityRemoveInfo
|
||||||
|
{
|
||||||
|
EntityId = e.Id,
|
||||||
|
Type = (int)ERemoveEntityType.RemoveTypeNormal
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task OnPlayerFightRoleInfoUpdated(int playerId, IEnumerable<FightRoleInformation> fightRoles)
|
||||||
|
{
|
||||||
|
return _session.Push(MessageId.UpdatePlayerAllFightRoleNotify, new UpdatePlayerAllFightRoleNotify
|
||||||
|
{
|
||||||
|
PlayerId = playerId,
|
||||||
|
FightRoleInfos = { fightRoles }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task OnRolePropertiesUpdated(int roleId, IEnumerable<ArrayIntInt> baseProp, IEnumerable<ArrayIntInt> addProp)
|
||||||
|
{
|
||||||
|
if (_modelManager.Creature.LoadingWorld) return Task.CompletedTask;
|
||||||
|
|
||||||
|
return _session.Push(MessageId.PbRolePropsNotify, new PbRolePropsNotify
|
||||||
|
{
|
||||||
|
RoleId = roleId,
|
||||||
|
BaseProp = { baseProp },
|
||||||
|
AddProp = { addProp }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task OnEntityEquipmentChanged(long entityId, EquipComponentPb componentPb)
|
||||||
|
{
|
||||||
|
return _session.Push(MessageId.EntityEquipChangeNotify, new EntityEquipChangeNotify
|
||||||
|
{
|
||||||
|
EntityId = entityId,
|
||||||
|
EquipComponent = componentPb
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task OnEntityAttributesChanged(long entityId, IEnumerable<GameplayAttributeData> attributes)
|
||||||
|
{
|
||||||
|
return _session.Push(MessageId.AttributeChangedNotify, new AttributeChangedNotify
|
||||||
|
{
|
||||||
|
Id = entityId,
|
||||||
|
Attributes = { attributes }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,13 +6,13 @@
|
||||||
"HeadFrame": 80060009,
|
"HeadFrame": 80060009,
|
||||||
"Characters": [ 1402, 1302, 1203 ],
|
"Characters": [ 1402, 1302, 1203 ],
|
||||||
"Position": {
|
"Position": {
|
||||||
"X": -35823,
|
"X": -45000,
|
||||||
"Y": 67132,
|
"Y": 67800,
|
||||||
"Z": 4067
|
"Z": 2600
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Features": {
|
"Features": {
|
||||||
"TeleportByMapMark": true,
|
"TeleportByMapMark": true,
|
||||||
"UnlimitedEnergy": true
|
"UnlimitedEnergy": false
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue