Compare commits
24 commits
Author | SHA1 | Date | |
---|---|---|---|
a1736317a1 | |||
5d58821be4 | |||
5fce82048f | |||
06692b4be9 | |||
3ecc265f4d | |||
d6d7ca6e76 | |||
e20c69f465 | |||
32b7c987bf | |||
832f4ab3eb | |||
|
97bbbbeae9 | ||
|
3cf22f41d9 | ||
|
32349137d3 | ||
934ef7d74a | |||
aa2bab9645 | |||
|
6fc374af32 | ||
|
c292baf580 | ||
|
e0cd311bfc | ||
|
092fd8df28 | ||
ec7db3384d | |||
a46dc434d8 | |||
3e7ec6f8ad | |||
1bd1931807 | |||
e70c6aa946 | |||
|
4e5f873003 |
59 changed files with 24225 additions and 392 deletions
|
@ -16,7 +16,12 @@ public class ConfigManager
|
||||||
logger.LogInformation("Loaded {count} config collections", _collectionsByEnum.Count);
|
logger.LogInformation("Loaded {count} config collections", _collectionsByEnum.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigCollection GetCollection<TConfigType>()
|
public IEnumerable<TConfig> Enumerate<TConfig>() where TConfig : IConfig
|
||||||
|
{
|
||||||
|
return GetCollection<TConfig>().Enumerate<TConfig>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigCollection GetCollection<TConfigType>() where TConfigType : IConfig
|
||||||
{
|
{
|
||||||
return _collectionsByType[typeof(TConfigType)];
|
return _collectionsByType[typeof(TConfigType)];
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,6 @@ public enum ConfigType
|
||||||
Weapon,
|
Weapon,
|
||||||
BaseProperty,
|
BaseProperty,
|
||||||
LevelEntity,
|
LevelEntity,
|
||||||
Blueprint
|
Blueprint,
|
||||||
|
ItemInfo
|
||||||
}
|
}
|
||||||
|
|
38
Core/Config/ItemInfoConfig.cs
Normal file
38
Core/Config/ItemInfoConfig.cs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
using Core.Config.Attributes;
|
||||||
|
|
||||||
|
namespace Core.Config;
|
||||||
|
|
||||||
|
[ConfigCollection("item/iteminfo.json")]
|
||||||
|
public class ItemInfoConfig : IConfig
|
||||||
|
{
|
||||||
|
public ConfigType Type => ConfigType.ItemInfo;
|
||||||
|
public int Identifier => Id;
|
||||||
|
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int ItemType { get; set; }
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
public List<int> ShowTypes { get; set; } = [];
|
||||||
|
public string AttributesDescription { get; set; } = string.Empty;
|
||||||
|
public string BgDescription { get; set; } = string.Empty;
|
||||||
|
public string Mesh { get; set; } = string.Empty;
|
||||||
|
public int QualityId { get; set; }
|
||||||
|
public int MainTypeId { get; set; }
|
||||||
|
public int RedDotDisableRule { get; set; }
|
||||||
|
public int UseCountLimit { get; set; }
|
||||||
|
public int SortIndex { get; set; }
|
||||||
|
public int MaxCapcity { get; set; }
|
||||||
|
public int MaxStackableNum { get; set; }
|
||||||
|
public int UseLevel { get; set; }
|
||||||
|
public int BeginTimeStamp { get; set; }
|
||||||
|
public int DurationStamp { get; set; }
|
||||||
|
public bool ShowUseButton { get; set; }
|
||||||
|
public int ObtainedShow { get; set; }
|
||||||
|
public string ObtainedShowDescription { get; set; } = string.Empty;
|
||||||
|
public int EntityConfig { get; set; }
|
||||||
|
public int NumLimit { get; set; }
|
||||||
|
public bool ShowInBag { get; set; }
|
||||||
|
public bool Destructible { get; set; }
|
||||||
|
public int ItemBuffType { get; set; }
|
||||||
|
public bool SpecialItem { get; set; }
|
||||||
|
public bool UiPlayItem { get; set; }
|
||||||
|
}
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="data\config\blueprint\blueprintconfig.json" />
|
<None Remove="data\config\blueprint\blueprintconfig.json" />
|
||||||
|
<None Remove="data\config\item\iteminfo.json" />
|
||||||
<None Remove="data\config\property\baseproperty.json" />
|
<None Remove="data\config\property\baseproperty.json" />
|
||||||
<None Remove="data\config\weapon\weaponconf.json" />
|
<None Remove="data\config\weapon\weaponconf.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
23002
Core/data/config/item/iteminfo.json
Normal file
23002
Core/data/config/item/iteminfo.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -10,14 +10,14 @@
|
||||||
"ResonLevelLimit": 5,
|
"ResonLevelLimit": 5,
|
||||||
"FirstPropId": {
|
"FirstPropId": {
|
||||||
"Id": 7,
|
"Id": 7,
|
||||||
"Value": 54,
|
"Value": 47,
|
||||||
"IsRatio": false
|
"IsRatio": false
|
||||||
},
|
},
|
||||||
"FirstCurve": 1,
|
"FirstCurve": 1,
|
||||||
"SecondPropId": {
|
"SecondPropId": {
|
||||||
"Id": 11,
|
"Id": 10007,
|
||||||
"Value": 432,
|
"Value": 0.08100000023841858,
|
||||||
"IsRatio": false
|
"IsRatio": true
|
||||||
},
|
},
|
||||||
"SecondCurve": 2,
|
"SecondCurve": 2,
|
||||||
"ResonId": 21010015,
|
"ResonId": 21010015,
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
"Desc": "WeaponConf_21010015_Desc",
|
"Desc": "WeaponConf_21010015_Desc",
|
||||||
"DescParams": [
|
"DescParams": [
|
||||||
{
|
{
|
||||||
"ArrayString": [ "12%", "15%", "18%", "21%", "24%" ]
|
"ArrayString": [ "12.8%", "16%", "19.2%", "22.4%", "25.6%" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "8%", "10%", "12%", "14%", "16%" ]
|
"ArrayString": [ "8%", "10%", "12%", "14%", "16%" ]
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
"ArrayString": [ "2", "2", "2", "2", "2" ]
|
"ArrayString": [ "2", "2", "2", "2", "2" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "8", "8", "8", "8", "8" ]
|
"ArrayString": [ "12", "12", "12", "12", "12" ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"TypeDescription": "WeaponConf_21010015_TypeDescription",
|
"TypeDescription": "WeaponConf_21010015_TypeDescription",
|
||||||
|
@ -84,16 +84,16 @@
|
||||||
"Desc": "WeaponConf_21020015_Desc",
|
"Desc": "WeaponConf_21020015_Desc",
|
||||||
"DescParams": [
|
"DescParams": [
|
||||||
{
|
{
|
||||||
"ArrayString": [ "16%", "20%", "24%", "28%", "32%" ]
|
"ArrayString": [ "12.8%", "16%", "19.2%", "22.4%", "25.6%" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "8%", "10%", "12%", "14%", "16%" ]
|
"ArrayString": [ "6%", "7.5%", "9%", "10.5%", "12%" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "2", "2", "2", "2", "2" ]
|
"ArrayString": [ "2", "2", "2", "2", "2" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "8", "8", "8", "8", "8" ]
|
"ArrayString": [ "10", "10", "10", "10", "10" ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"TypeDescription": "WeaponConf_21020015_TypeDescription",
|
"TypeDescription": "WeaponConf_21020015_TypeDescription",
|
||||||
|
@ -142,16 +142,16 @@
|
||||||
"Desc": "WeaponConf_21030015_Desc",
|
"Desc": "WeaponConf_21030015_Desc",
|
||||||
"DescParams": [
|
"DescParams": [
|
||||||
{
|
{
|
||||||
"ArrayString": [ "12%", "15%", "18%", "21%", "24%" ]
|
"ArrayString": [ "12.8%", "16%", "19.2%", "22.4%", "25.6%" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "2.4%", "3%", "3.6%", "4.2%", "4.8%" ]
|
"ArrayString": [ "10%", "12.5%", "15%", "17.5%", "20%" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "5", "5", "5", "5", "5" ]
|
"ArrayString": [ "1", "1", "1", "1", "1" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "8", "8", "8", "8", "8" ]
|
"ArrayString": [ "14", "14", "14", "14", "14" ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"TypeDescription": "WeaponConf_21030015_TypeDescription",
|
"TypeDescription": "WeaponConf_21030015_TypeDescription",
|
||||||
|
@ -189,9 +189,9 @@
|
||||||
},
|
},
|
||||||
"FirstCurve": 1,
|
"FirstCurve": 1,
|
||||||
"SecondPropId": {
|
"SecondPropId": {
|
||||||
"Id": 11,
|
"Id": 10007,
|
||||||
"Value": 864,
|
"Value": 0.08100000023841858,
|
||||||
"IsRatio": false
|
"IsRatio": true
|
||||||
},
|
},
|
||||||
"SecondCurve": 2,
|
"SecondCurve": 2,
|
||||||
"ResonId": 21040015,
|
"ResonId": 21040015,
|
||||||
|
@ -200,7 +200,7 @@
|
||||||
"Desc": "WeaponConf_21040015_Desc",
|
"Desc": "WeaponConf_21040015_Desc",
|
||||||
"DescParams": [
|
"DescParams": [
|
||||||
{
|
{
|
||||||
"ArrayString": [ "8%", "10%", "12%", "14%", "16%" ]
|
"ArrayString": [ "12.8%", "16%", "19.2%", "22.4%", "25.6%" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "10%", "12.5%", "15%", "17.5%", "20%" ]
|
"ArrayString": [ "10%", "12.5%", "15%", "17.5%", "20%" ]
|
||||||
|
@ -250,9 +250,9 @@
|
||||||
},
|
},
|
||||||
"FirstCurve": 1,
|
"FirstCurve": 1,
|
||||||
"SecondPropId": {
|
"SecondPropId": {
|
||||||
"Id": 11,
|
"Id": 10007,
|
||||||
"Value": 1280,
|
"Value": 0.11999999731779099,
|
||||||
"IsRatio": false
|
"IsRatio": true
|
||||||
},
|
},
|
||||||
"SecondCurve": 2,
|
"SecondCurve": 2,
|
||||||
"ResonId": 21050015,
|
"ResonId": 21050015,
|
||||||
|
@ -261,7 +261,7 @@
|
||||||
"Desc": "WeaponConf_21050015_Desc",
|
"Desc": "WeaponConf_21050015_Desc",
|
||||||
"DescParams": [
|
"DescParams": [
|
||||||
{
|
{
|
||||||
"ArrayString": [ "16%", "20%", "24%", "28%", "32%" ]
|
"ArrayString": [ "12.8%", "16%", "19.2%", "22.4%", "25.6%" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "3.2%", "4%", "4.8%", "5.6%", "6.4%" ]
|
"ArrayString": [ "3.2%", "4%", "4.8%", "5.6%", "6.4%" ]
|
||||||
|
@ -1670,13 +1670,13 @@
|
||||||
"ResonLevelLimit": 5,
|
"ResonLevelLimit": 5,
|
||||||
"FirstPropId": {
|
"FirstPropId": {
|
||||||
"Id": 7,
|
"Id": 7,
|
||||||
"Value": 31,
|
"Value": 27,
|
||||||
"IsRatio": false
|
"IsRatio": false
|
||||||
},
|
},
|
||||||
"FirstCurve": 1,
|
"FirstCurve": 1,
|
||||||
"SecondPropId": {
|
"SecondPropId": {
|
||||||
"Id": 10010,
|
"Id": 10010,
|
||||||
"Value": 0.10260000079870224,
|
"Value": 0.13680000603199005,
|
||||||
"IsRatio": true
|
"IsRatio": true
|
||||||
},
|
},
|
||||||
"SecondCurve": 2,
|
"SecondCurve": 2,
|
||||||
|
@ -1834,8 +1834,8 @@
|
||||||
},
|
},
|
||||||
"FirstCurve": 1,
|
"FirstCurve": 1,
|
||||||
"SecondPropId": {
|
"SecondPropId": {
|
||||||
"Id": 10007,
|
"Id": 10010,
|
||||||
"Value": 0.1080000028014183,
|
"Value": 0.13680000603199005,
|
||||||
"IsRatio": true
|
"IsRatio": true
|
||||||
},
|
},
|
||||||
"SecondCurve": 2,
|
"SecondCurve": 2,
|
||||||
|
@ -1886,7 +1886,7 @@
|
||||||
},
|
},
|
||||||
"FirstCurve": 1,
|
"FirstCurve": 1,
|
||||||
"SecondPropId": {
|
"SecondPropId": {
|
||||||
"Id": 10002,
|
"Id": 10007,
|
||||||
"Value": 0.08100000023841858,
|
"Value": 0.08100000023841858,
|
||||||
"IsRatio": true
|
"IsRatio": true
|
||||||
},
|
},
|
||||||
|
@ -2248,13 +2248,13 @@
|
||||||
"ResonLevelLimit": 5,
|
"ResonLevelLimit": 5,
|
||||||
"FirstPropId": {
|
"FirstPropId": {
|
||||||
"Id": 7,
|
"Id": 7,
|
||||||
"Value": 26,
|
"Value": 24,
|
||||||
"IsRatio": false
|
"IsRatio": false
|
||||||
},
|
},
|
||||||
"FirstCurve": 1,
|
"FirstCurve": 1,
|
||||||
"SecondPropId": {
|
"SecondPropId": {
|
||||||
"Id": 10010,
|
"Id": 10010,
|
||||||
"Value": 0.06840000301599503,
|
"Value": 0.08550000190734863,
|
||||||
"IsRatio": true
|
"IsRatio": true
|
||||||
},
|
},
|
||||||
"SecondCurve": 2,
|
"SecondCurve": 2,
|
||||||
|
@ -3128,7 +3128,7 @@
|
||||||
"ArrayString": [ "2", "2", "2", "2", "2" ]
|
"ArrayString": [ "2", "2", "2", "2", "2" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "10", "10", "10", "10", "10" ]
|
"ArrayString": [ "14", "14", "14", "14", "14" ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"TypeDescription": "WeaponConf_21010016_TypeDescription",
|
"TypeDescription": "WeaponConf_21010016_TypeDescription",
|
||||||
|
@ -3180,13 +3180,16 @@
|
||||||
"ArrayString": [ "12%", "15%", "18%", "21%", "24%" ]
|
"ArrayString": [ "12%", "15%", "18%", "21%", "24%" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "20%", "25%", "30%", "35%", "40%" ]
|
"ArrayString": [ "12%", "15%", "18%", "21%", "24%" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ArrayString": [ "12%", "15%", "18%", "21%", "24%" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "2", "2", "2", "2", "2" ]
|
"ArrayString": [ "2", "2", "2", "2", "2" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ArrayString": [ "18", "18", "18", "18", "18" ]
|
"ArrayString": [ "5", "5", "5", "5", "5" ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"TypeDescription": "WeaponConf_21050016_TypeDescription",
|
"TypeDescription": "WeaponConf_21050016_TypeDescription",
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
using GameServer.Controllers.Attributes;
|
||||||
|
using GameServer.Models;
|
||||||
|
using GameServer.Models.Chat;
|
||||||
|
using GameServer.Network;
|
||||||
|
using GameServer.Systems.Entity;
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Controllers.ChatCommands;
|
||||||
|
|
||||||
|
[ChatCommandCategory("player")]
|
||||||
|
internal class ChatPlayerCommandHandler
|
||||||
|
{
|
||||||
|
private readonly ChatRoom _helperRoom;
|
||||||
|
private readonly PlayerSession _session;
|
||||||
|
private readonly CreatureController _creatureController;
|
||||||
|
|
||||||
|
public ChatPlayerCommandHandler(ModelManager modelManager, PlayerSession session, CreatureController creatureController)
|
||||||
|
{
|
||||||
|
_helperRoom = modelManager.Chat.GetChatRoom(1338);
|
||||||
|
_session = session;
|
||||||
|
_creatureController = creatureController;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ChatCommand("getpos")]
|
||||||
|
[ChatCommandDesc("/player getpos - shows current player coordinates")]
|
||||||
|
public void OnPlayerGetPosCommand(string[] _)
|
||||||
|
{
|
||||||
|
PlayerEntity? entity = _creatureController.GetPlayerEntity();
|
||||||
|
if (entity == null) return;
|
||||||
|
|
||||||
|
_helperRoom.AddMessage(1338, 0, $"Your current position: ({entity.Pos.X / 100}, {entity.Pos.Y / 100}, {entity.Pos.Z / 100})");
|
||||||
|
}
|
||||||
|
|
||||||
|
[ChatCommand("teleport")]
|
||||||
|
[ChatCommandDesc("/player teleport [x] [y] [z] - performing fast travel to specified position")]
|
||||||
|
public async Task OnPlayerTeleportCommand(string[] args)
|
||||||
|
{
|
||||||
|
if (args.Length != 3 || !float.TryParse(args[0], out float x)
|
||||||
|
|| !float.TryParse(args[1], out float y)
|
||||||
|
|| !float.TryParse(args[2], out float z))
|
||||||
|
{
|
||||||
|
_helperRoom.AddMessage(1338, 0, $"Usage: /player teleport [x] [y] [z]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerEntity? entity = _creatureController.GetPlayerEntity();
|
||||||
|
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
await _session.Push(MessageId.TeleportNotify, new TeleportNotify
|
||||||
|
{
|
||||||
|
PosX = x * 100,
|
||||||
|
PosY = y * 100,
|
||||||
|
PosZ = z * 100,
|
||||||
|
PosA = 0,
|
||||||
|
MapId = 8,
|
||||||
|
Reason = (int)TeleportReason.Gm,
|
||||||
|
TransitionOption = new TransitionOptionPb
|
||||||
|
{
|
||||||
|
TransitionType = (int)TransitionType.Empty
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_helperRoom.AddMessage(1338, 0, $"Successfully performed fast travel to ({x}, {y}, {z})");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -34,9 +33,9 @@ internal class ChatSpawnCommandHandler
|
||||||
{
|
{
|
||||||
if (args.Length != 4 ||
|
if (args.Length != 4 ||
|
||||||
!(int.TryParse(args[0], out int levelEntityId) &&
|
!(int.TryParse(args[0], out int levelEntityId) &&
|
||||||
int.TryParse(args[1], out int x) &&
|
float.TryParse(args[1], out float x) &&
|
||||||
int.TryParse(args[2], out int y) &&
|
float.TryParse(args[2], out float y) &&
|
||||||
int.TryParse(args[3], out int z)))
|
float.TryParse(args[3], out float z)))
|
||||||
{
|
{
|
||||||
_helperRoom.AddMessage(1338, 0, "Usage: /spawn monster [id] [x] [y] [z]");
|
_helperRoom.AddMessage(1338, 0, "Usage: /spawn monster [id] [x] [y] [z]");
|
||||||
return;
|
return;
|
||||||
|
@ -45,19 +44,13 @@ internal class ChatSpawnCommandHandler
|
||||||
MonsterEntity monster = _entityFactory.CreateMonster(levelEntityId);
|
MonsterEntity monster = _entityFactory.CreateMonster(levelEntityId);
|
||||||
monster.Pos = new()
|
monster.Pos = new()
|
||||||
{
|
{
|
||||||
X = x,
|
X = x * 100,
|
||||||
Y = y,
|
Y = y * 100,
|
||||||
Z = z
|
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();
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Controllers.ChatCommands;
|
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;
|
||||||
internal class ChatController : Controller
|
internal partial class ChatController : Controller
|
||||||
{
|
{
|
||||||
private readonly ModelManager _modelManager;
|
private readonly ModelManager _modelManager;
|
||||||
|
|
||||||
|
@ -42,7 +42,8 @@ internal class ChatController : Controller
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string[] split = request.Content[1..].Split(' ');
|
string content = MultipleSpacesRegex().Replace(request.Content, " ");
|
||||||
|
string[] split = content[1..].Split(' ');
|
||||||
if (split.Length >= 2)
|
if (split.Length >= 2)
|
||||||
{
|
{
|
||||||
await chatCommandManager.InvokeCommandAsync(split[0], split[1], split[2..]);
|
await chatCommandManager.InvokeCommandAsync(split[0], split[1], split[2..]);
|
||||||
|
@ -85,4 +86,7 @@ internal class ChatController : Controller
|
||||||
|
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex(@"\s+")]
|
||||||
|
private static partial Regex MultipleSpacesRegex();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Systems.Entity;
|
using GameServer.Systems.Entity;
|
||||||
|
@ -33,8 +32,57 @@ internal class CombatManager
|
||||||
_creatureController = creatureController;
|
_creatureController = creatureController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CombatRequest(CombatRequestData.MessageOneofCase.RTimeStopRequest)]
|
||||||
|
public CombatResponseData OnRTimeStopRequest(CombatRequestContext context) => new()
|
||||||
|
{
|
||||||
|
CombatCommon = context.Request.CombatCommon,
|
||||||
|
RTimeStopResponse = new()
|
||||||
|
};
|
||||||
|
|
||||||
|
[CombatRequest(CombatRequestData.MessageOneofCase.ActivateBuffRequest)]
|
||||||
|
public CombatResponseData OnActivateBuffRequest(CombatRequestContext context) => new()
|
||||||
|
{
|
||||||
|
CombatCommon = context.Request.CombatCommon,
|
||||||
|
ActivateBuffResponse = new()
|
||||||
|
};
|
||||||
|
|
||||||
|
[CombatRequest(CombatRequestData.MessageOneofCase.UseSkillRequest)]
|
||||||
|
public CombatResponseData OnUseSkillRequest(CombatRequestContext context) => new()
|
||||||
|
{
|
||||||
|
CombatCommon = context.Request.CombatCommon,
|
||||||
|
UseSkillResponse = new()
|
||||||
|
{
|
||||||
|
SkillSingleId = context.Request.UseSkillRequest.SkillSingleId,
|
||||||
|
UseSkillInfo = context.Request.UseSkillRequest.UseSkillInfo
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
[CombatRequest(CombatRequestData.MessageOneofCase.ApplyGameplayEffectRequest)]
|
||||||
|
public CombatResponseData OnApplyGameplayEffectRequest(CombatRequestContext context) => new()
|
||||||
|
{
|
||||||
|
CombatCommon = context.Request.CombatCommon,
|
||||||
|
ApplyGameplayEffectResponse = new ApplyGameplayEffectResponse()
|
||||||
|
};
|
||||||
|
|
||||||
|
[CombatRequest(CombatRequestData.MessageOneofCase.RemoveGameplayEffectRequest)]
|
||||||
|
public CombatResponseData OnRemoveGameplayEffectRequest(CombatRequestContext context) => new()
|
||||||
|
{
|
||||||
|
CombatCommon = context.Request.CombatCommon,
|
||||||
|
RemoveGameplayEffectResponse = new RemoveGameplayEffectResponse()
|
||||||
|
};
|
||||||
|
|
||||||
|
[CombatRequest(CombatRequestData.MessageOneofCase.CreateBulletRequest)]
|
||||||
|
public CombatResponseData OnCreateBulletRequest(CombatRequestContext context)
|
||||||
|
{
|
||||||
|
return new CombatResponseData
|
||||||
|
{
|
||||||
|
CombatCommon = context.Request.CombatCommon,
|
||||||
|
CreateBulletResponse = new()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
[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;
|
||||||
|
|
||||||
|
@ -57,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
|
||||||
|
@ -199,13 +235,19 @@ internal class CombatManager
|
||||||
if (entity.ComponentSystem.TryGet(out EntityFsmComponent? fsmComponent))
|
if (entity.ComponentSystem.TryGet(out EntityFsmComponent? fsmComponent))
|
||||||
{
|
{
|
||||||
DFsm? dfsm = fsmComponent.Fsms.FirstOrDefault(fsm => fsm.FsmId == request.FsmId);
|
DFsm? dfsm = fsmComponent.Fsms.FirstOrDefault(fsm => fsm.FsmId == request.FsmId);
|
||||||
dfsm ??= new()
|
|
||||||
|
if (dfsm == null)
|
||||||
|
{
|
||||||
|
dfsm = new DFsm
|
||||||
{
|
{
|
||||||
FsmId = request.FsmId,
|
FsmId = request.FsmId,
|
||||||
Status = 1,
|
Status = 1,
|
||||||
Flag = (int)EFsmStateFlag.Confirmed
|
Flag = (int)EFsmStateFlag.Confirmed
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fsmComponent.Fsms.Add(dfsm);
|
||||||
|
}
|
||||||
|
|
||||||
dfsm.CurrentState = request.State;
|
dfsm.CurrentState = request.State;
|
||||||
context.Notifies.Add(new CombatNotifyData
|
context.Notifies.Add(new CombatNotifyData
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,18 +1,44 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Controllers.Combat;
|
using GameServer.Controllers.Combat;
|
||||||
|
using GameServer.Models;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
using GameServer.Systems.Entity;
|
||||||
|
using GameServer.Systems.Event;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
internal class CombatMessageController : Controller
|
internal class CombatMessageController : Controller
|
||||||
{
|
{
|
||||||
public CombatMessageController(PlayerSession session) : base(session)
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public CombatMessageController(PlayerSession session, ILogger<CombatMessageController> logger) : base(session)
|
||||||
{
|
{
|
||||||
// CombatMessageController.
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
[NetEvent(MessageId.CombatSendPackRequest)] // TODO: CombatSendPackRequest is important
|
[NetEvent(MessageId.MovePackagePush)]
|
||||||
|
public async Task OnMovePackagePush(MovePackagePush push, EntitySystem entitySystem, EventSystem eventSystem, ModelManager modelManager)
|
||||||
|
{
|
||||||
|
foreach (MovingEntityData movingEntityData in push.MovingEntities)
|
||||||
|
{
|
||||||
|
EntityBase? entity = entitySystem.Get<EntityBase>(movingEntityData.EntityId);
|
||||||
|
if (entity == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("OnMovePackagePush: moving entity not found! Id: {entityId}", movingEntityData.EntityId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MoveReplaySample lastMoveReplay = movingEntityData.MoveInfos.Last();
|
||||||
|
entity.Pos.MergeFrom(lastMoveReplay.Location);
|
||||||
|
entity.Rot.MergeFrom(lastMoveReplay.Rotation);
|
||||||
|
|
||||||
|
if (entity.Id == modelManager.Creature.PlayerEntityId)
|
||||||
|
await eventSystem.Emit(GameEventType.PlayerPositionChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[NetEvent(MessageId.CombatSendPackRequest)]
|
||||||
public async Task<RpcResult> OnCombatSendPackRequest(CombatSendPackRequest request, CombatManager combatManager)
|
public async Task<RpcResult> OnCombatSendPackRequest(CombatSendPackRequest request, CombatManager combatManager)
|
||||||
{
|
{
|
||||||
CombatReceivePackNotify combatPackNotify = new();
|
CombatReceivePackNotify combatPackNotify = new();
|
||||||
|
|
|
@ -1,27 +1,41 @@
|
||||||
using Core.Config;
|
using Core.Config;
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
|
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.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 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;
|
||||||
|
|
||||||
public CreatureController(PlayerSession session, EntitySystem entitySystem, EntityFactory entityFactory, ModelManager modelManager, ConfigManager configManager) : base(session)
|
private readonly GameplayFeatureSettings _gameplayFeatures;
|
||||||
|
private readonly Vector _lastDynamicSpawnPos;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
_lastDynamicSpawnPos = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task JoinScene(int instanceId)
|
public async Task JoinScene(int instanceId)
|
||||||
|
@ -30,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)]
|
||||||
|
@ -79,51 +85,29 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GameEvent(GameEventType.PlayerPositionChanged)]
|
||||||
|
public void OnPlayerPositionChanged()
|
||||||
|
{
|
||||||
|
_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)]
|
||||||
public async Task OnVisionSkillChanged()
|
public async Task OnVisionSkillChanged()
|
||||||
{
|
{
|
||||||
|
@ -168,6 +152,9 @@ internal class CreatureController : Controller
|
||||||
_modelManager.Creature.PlayerEntityId = newEntity.Id;
|
_modelManager.Creature.PlayerEntityId = newEntity.Id;
|
||||||
newEntity.IsCurrentRole = true;
|
newEntity.IsCurrentRole = true;
|
||||||
|
|
||||||
|
newEntity.Pos.MergeFrom(prevEntity.Pos);
|
||||||
|
newEntity.Rot.MergeFrom(prevEntity.Rot);
|
||||||
|
|
||||||
await UpdateAiHate();
|
await UpdateAiHate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,24 +228,37 @@ 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++)
|
||||||
{
|
{
|
||||||
PlayerEntity entity = _entityFactory.CreatePlayer(_modelManager.Formation.RoleIds[i], _modelManager.Player.Id);
|
int roleId = _modelManager.Formation.RoleIds[i];
|
||||||
|
|
||||||
|
PlayerEntity entity = _entityFactory.CreatePlayer(roleId, _modelManager.Player.Id);
|
||||||
entity.Pos = _modelManager.Player.Position.Clone();
|
entity.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.InitProps(_configManager.GetConfig<BasePropertyConfig>(entity.ConfigId)!);
|
|
||||||
|
|
||||||
CreateConcomitants(entity);
|
CreateConcomitants(entity);
|
||||||
|
entity.WeaponId = _modelManager.Inventory.GetEquippedWeapon(roleId)?.Id ?? 0;
|
||||||
// Give weapon to entity
|
|
||||||
RoleInfoConfig roleConfig = _configManager.GetConfig<RoleInfoConfig>(entity.ConfigId)!;
|
|
||||||
WeaponConfig weaponConfig = _configManager.GetConfig<WeaponConfig>(roleConfig.InitWeaponItemId)!;
|
|
||||||
entity.WeaponId = weaponConfig.ItemId;
|
|
||||||
|
|
||||||
if (i == 0) _modelManager.Creature.PlayerEntityId = entity.Id;
|
if (i == 0) _modelManager.Creature.PlayerEntityId = entity.Id;
|
||||||
|
|
||||||
|
if (_gameplayFeatures.UnlimitedEnergy)
|
||||||
|
{
|
||||||
|
EntityAttributeComponent attr = entity.ComponentSystem.Get<EntityAttributeComponent>();
|
||||||
|
attr.SetAttribute(EAttributeType.EnergyMax, 0);
|
||||||
|
attr.SetAttribute(EAttributeType.SpecialEnergy1Max, 0);
|
||||||
|
attr.SetAttribute(EAttributeType.SpecialEnergy2Max, 0);
|
||||||
|
attr.SetAttribute(EAttributeType.SpecialEnergy3Max, 0);
|
||||||
|
attr.SetAttribute(EAttributeType.SpecialEnergy4Max, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playerEntities[i] = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
_entitySystem.Add(playerEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateConcomitants(PlayerEntity entity)
|
private void CreateConcomitants(PlayerEntity entity)
|
||||||
|
@ -272,10 +272,10 @@ 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.Get<EntityConcomitantsComponent>();
|
EntityConcomitantsComponent concomitants = entity.ComponentSystem.Create<EntityConcomitantsComponent>();
|
||||||
concomitants.CustomEntityIds.Clear();
|
concomitants.CustomEntityIds.Clear();
|
||||||
|
concomitants.VisionEntityId = concomitant.Id;
|
||||||
concomitants.CustomEntityIds.Add(concomitant.Id);
|
concomitants.CustomEntityIds.Add(concomitant.Id);
|
||||||
|
|
||||||
EntitySummonerComponent summoner = concomitant.ComponentSystem.Create<EntitySummonerComponent>();
|
EntitySummonerComponent summoner = concomitant.ComponentSystem.Create<EntitySummonerComponent>();
|
||||||
|
@ -283,24 +283,51 @@ internal class CreatureController : Controller
|
||||||
summoner.SummonConfigId = summonConfigId;
|
summoner.SummonConfigId = summonConfigId;
|
||||||
summoner.SummonType = ESummonType.ConcomitantCustom;
|
summoner.SummonType = ESummonType.ConcomitantCustom;
|
||||||
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>()
|
||||||
|
.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"));
|
||||||
|
|
||||||
|
List<MonsterEntity> spawnMonsters = [];
|
||||||
|
foreach (LevelEntityConfig levelEntity in entitiesToSpawn)
|
||||||
|
{
|
||||||
|
if (_entitySystem.HasDynamicEntity(levelEntity.EntityId)) continue;
|
||||||
|
|
||||||
|
MonsterEntity monster = _entityFactory.CreateMonster(levelEntity.EntityId);
|
||||||
monster.Pos = new()
|
monster.Pos = new()
|
||||||
{
|
{
|
||||||
X = playerPos.X + 250,
|
X = levelEntity.Transform[0].X / 100,
|
||||||
Y = playerPos.Y + 250,
|
Y = levelEntity.Transform[0].Y / 100,
|
||||||
Z = playerPos.Z
|
Z = levelEntity.Transform[0].Z / 100
|
||||||
};
|
};
|
||||||
|
|
||||||
_entitySystem.Create(monster);
|
|
||||||
monster.InitProps(_configManager.GetConfig<BasePropertyConfig>(600000100)!);
|
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;
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using Core.Config;
|
||||||
|
using GameServer.Controllers.Attributes;
|
||||||
|
using GameServer.Extensions.Logic;
|
||||||
|
using GameServer.Models;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
using GameServer.Systems.Entity;
|
||||||
|
using GameServer.Systems.Event;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Controllers;
|
namespace GameServer.Controllers;
|
||||||
|
@ -12,14 +16,101 @@ internal class InventoryController : Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
[NetEvent(MessageId.NormalItemRequest)]
|
[NetEvent(MessageId.NormalItemRequest)]
|
||||||
public RpcResult OnNormalItemRequest() => Response(MessageId.NormalItemResponse, new NormalItemResponse());
|
public RpcResult OnNormalItemRequest(ModelManager modelManager) => Response(MessageId.NormalItemResponse, new NormalItemResponse
|
||||||
|
{
|
||||||
|
NormalItemList = { modelManager.Inventory.ItemList }
|
||||||
|
});
|
||||||
|
|
||||||
[NetEvent(MessageId.WeaponItemRequest)]
|
[NetEvent(MessageId.WeaponItemRequest)]
|
||||||
public RpcResult OnWeaponItemRequest() => Response(MessageId.WeaponItemResponse, new WeaponItemResponse());
|
public RpcResult OnWeaponItemRequest(ModelManager modelManager) => Response(MessageId.WeaponItemResponse, new WeaponItemResponse
|
||||||
|
{
|
||||||
|
WeaponItemList =
|
||||||
|
{
|
||||||
|
modelManager.Inventory.WeaponList
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
[NetEvent(MessageId.PhantomItemRequest)]
|
[NetEvent(MessageId.PhantomItemRequest)]
|
||||||
public RpcResult OnPhantomItemRequest() => Response(MessageId.PhantomItemResponse, new PhantomItemResponse());
|
public RpcResult OnPhantomItemRequest() => Response(MessageId.PhantomItemResponse, new PhantomItemResponse());
|
||||||
|
|
||||||
[NetEvent(MessageId.ItemExchangeInfoRequest)]
|
[NetEvent(MessageId.ItemExchangeInfoRequest)]
|
||||||
public RpcResult OnItemExchangeInfoRequest() => Response(MessageId.ItemExchangeInfoResponse, new ItemExchangeInfoResponse());
|
public RpcResult OnItemExchangeInfoRequest() => Response(MessageId.ItemExchangeInfoResponse, new ItemExchangeInfoResponse());
|
||||||
|
|
||||||
|
[NetEvent(MessageId.EquipTakeOnRequest)]
|
||||||
|
public RpcResult OnEquipTakeOnRequest(EquipTakeOnRequest request, ModelManager modelManager, CreatureController creatureController, RoleController roleController, ConfigManager configManager)
|
||||||
|
{
|
||||||
|
WeaponItem? weapon = modelManager.Inventory.GetWeaponById(request.Data.EquipIncId);
|
||||||
|
if (weapon == null) return Response(MessageId.EquipTakeOnResponse, new EquipTakeOnResponse
|
||||||
|
{
|
||||||
|
ErrorCode = (int)ErrorCode.ErrItemIdInvaild
|
||||||
|
});
|
||||||
|
|
||||||
|
WeaponConfig weaponConf = configManager.GetConfig<WeaponConfig>(weapon.Id)!;
|
||||||
|
|
||||||
|
roleInfo? role = modelManager.Roles.GetRoleById(request.Data.RoleId);
|
||||||
|
if (role == null) return Response(MessageId.EquipTakeOnResponse, new EquipTakeOnResponse
|
||||||
|
{
|
||||||
|
ErrorCode = (int)ErrorCode.NotValidRole
|
||||||
|
});
|
||||||
|
|
||||||
|
// Take off previous weapon
|
||||||
|
WeaponItem? prevWeapon = modelManager.Inventory.WeaponList.SingleOrDefault(weapon => weapon.RoleId == role.RoleId);
|
||||||
|
if (prevWeapon != null) prevWeapon.RoleId = 0;
|
||||||
|
|
||||||
|
// Set new weapon
|
||||||
|
weapon.RoleId = role.RoleId;
|
||||||
|
roleController.ApplyWeaponPropertiesToRole(role.RoleId, weaponConf);
|
||||||
|
|
||||||
|
// Update entity (if this role is currently active)
|
||||||
|
PlayerEntity? entity = creatureController.GetPlayerEntityByRoleId(request.Data.RoleId);
|
||||||
|
entity?.ChangeEquipment(weapon.Id);
|
||||||
|
entity?.ChangeGameplayAttributes(role.GetAttributeList());
|
||||||
|
|
||||||
|
// Response
|
||||||
|
EquipTakeOnResponse response = new()
|
||||||
|
{
|
||||||
|
DataList =
|
||||||
|
{
|
||||||
|
new RoleLoadEquipData
|
||||||
|
{
|
||||||
|
RoleId = request.Data.RoleId,
|
||||||
|
Pos = request.Data.Pos,
|
||||||
|
EquipIncId = request.Data.EquipIncId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (prevWeapon != null)
|
||||||
|
{
|
||||||
|
response.DataList.Add(new RoleLoadEquipData
|
||||||
|
{
|
||||||
|
EquipIncId = prevWeapon.IncrId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response(MessageId.EquipTakeOnResponse, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
[GameEvent(GameEventType.EnterGame)]
|
||||||
|
public async Task OnEnterGame()
|
||||||
|
{
|
||||||
|
await Session.Push(MessageId.ItemPkgOpenNotify, new ItemPkgOpenNotify
|
||||||
|
{
|
||||||
|
OpenPkg = { 0, 2, 1, 3, 4, 5, 6, 7 }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[GameEvent(GameEventType.DebugUnlockAllItems)]
|
||||||
|
public void DebugUnlockAllWeapons(ConfigManager configManager, ModelManager modelManager)
|
||||||
|
{
|
||||||
|
foreach (WeaponConfig weaponConf in configManager.Enumerate<WeaponConfig>())
|
||||||
|
{
|
||||||
|
modelManager.Inventory.AddNewWeapon(weaponConf.ItemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ItemInfoConfig itemInfo in configManager.Enumerate<ItemInfoConfig>())
|
||||||
|
{
|
||||||
|
modelManager.Inventory.AddItem(itemInfo.Id, itemInfo.MaxStackableNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,10 @@ internal class LoginController : Controller
|
||||||
{
|
{
|
||||||
await eventSystem.Emit(GameEventType.Login);
|
await eventSystem.Emit(GameEventType.Login);
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
await eventSystem.Emit(GameEventType.DebugUnlockAllRoles);
|
||||||
|
await eventSystem.Emit(GameEventType.DebugUnlockAllItems);
|
||||||
|
|
||||||
return Response(MessageId.LoginResponse, new LoginResponse
|
return Response(MessageId.LoginResponse, new LoginResponse
|
||||||
{
|
{
|
||||||
Code = 0,
|
Code = 0,
|
||||||
|
|
|
@ -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,7 +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.Event;
|
using GameServer.Systems.Event;
|
||||||
using Protocol;
|
using Protocol;
|
||||||
|
|
||||||
|
@ -22,34 +21,8 @@ internal class PlayerInfoController : Controller
|
||||||
{
|
{
|
||||||
RandomSeed = 1337,
|
RandomSeed = 1337,
|
||||||
Id = player.Id,
|
Id = player.Id,
|
||||||
Birthday = 0,
|
Birthday = player.BirthDay,
|
||||||
Attributes =
|
Attributes = { player.Attributes },
|
||||||
{
|
|
||||||
new PlayerAttr
|
|
||||||
{
|
|
||||||
Key = (int)PlayerAttrKey.Name,
|
|
||||||
ValueType = (int)PlayerAttrType.String,
|
|
||||||
StringValue = player.Name
|
|
||||||
},
|
|
||||||
new PlayerAttr
|
|
||||||
{
|
|
||||||
Key = (int)PlayerAttrKey.Level,
|
|
||||||
ValueType = (int)PlayerAttrType.Int32,
|
|
||||||
Int32Value = 10
|
|
||||||
},
|
|
||||||
new PlayerAttr
|
|
||||||
{
|
|
||||||
Key = (int)PlayerAttrKey.HeadPhoto,
|
|
||||||
ValueType = (int)PlayerAttrType.Int32,
|
|
||||||
Int32Value = 1402
|
|
||||||
},
|
|
||||||
new PlayerAttr
|
|
||||||
{
|
|
||||||
Key = (int)PlayerAttrKey.Sex,
|
|
||||||
ValueType = (int)PlayerAttrType.Int32,
|
|
||||||
Int32Value = 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
RoleShowList =
|
RoleShowList =
|
||||||
{
|
{
|
||||||
new RoleShowEntry
|
new RoleShowEntry
|
||||||
|
@ -72,6 +45,47 @@ internal class PlayerInfoController : Controller
|
||||||
await Session.Push(MessageId.BasicInfoNotify, basicInfo);
|
await Session.Push(MessageId.BasicInfoNotify, basicInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[NetEvent(MessageId.ChangeHeadPhotoRequest)]
|
||||||
|
public RpcResult OnChangeHeadPhotoRequest(ChangeHeadPhotoRequest request, ModelManager modelManager)
|
||||||
|
{
|
||||||
|
modelManager.Player.SetAttribute(PlayerAttrKey.HeadPhoto, request.HeadPhotoId);
|
||||||
|
|
||||||
|
return Response(MessageId.ChangeHeadPhotoResponse, new ChangeHeadPhotoResponse
|
||||||
|
{
|
||||||
|
HeadPhotoId = request.HeadPhotoId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[NetEvent(MessageId.BirthdayInitRequest)]
|
||||||
|
public RpcResult OnBirthdayInitRequest(BirthdayInitRequest request, ModelManager modelManager)
|
||||||
|
{
|
||||||
|
modelManager.Player.BirthDay = request.Birthday;
|
||||||
|
|
||||||
|
return Response(MessageId.BirthdayInitResponse, new BirthdayInitResponse());
|
||||||
|
}
|
||||||
|
|
||||||
|
[NetEvent(MessageId.ModifySignatureRequest)]
|
||||||
|
public RpcResult OnModifySignatureRequest(ModifySignatureRequest request, ModelManager modelManager)
|
||||||
|
{
|
||||||
|
modelManager.Player.SetAttribute(PlayerAttrKey.Sign, request.Signature);
|
||||||
|
|
||||||
|
return Response(MessageId.ModifySignatureResponse, new ModifySignatureResponse
|
||||||
|
{
|
||||||
|
Signature = request.Signature
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[NetEvent(MessageId.ModifyNameRequest)]
|
||||||
|
public RpcResult OnModifyNameRequest(ModifyNameRequest request, ModelManager modelManager)
|
||||||
|
{
|
||||||
|
modelManager.Player.SetAttribute(PlayerAttrKey.Name, request.Name);
|
||||||
|
|
||||||
|
return Response(MessageId.ModifyNameResponse, new ModifyNameResponse
|
||||||
|
{
|
||||||
|
Name = request.Name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[NetEvent(MessageId.PlayerBasicInfoGetRequest)]
|
[NetEvent(MessageId.PlayerBasicInfoGetRequest)]
|
||||||
public RpcResult OnPlayerBasicInfoGetRequest()
|
public RpcResult OnPlayerBasicInfoGetRequest()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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,36 +1,55 @@
|
||||||
using Core.Config;
|
using Core.Config;
|
||||||
using GameServer.Controllers.Attributes;
|
using GameServer.Controllers.Attributes;
|
||||||
|
using GameServer.Extensions.Logic;
|
||||||
using GameServer.Models;
|
using GameServer.Models;
|
||||||
using GameServer.Network;
|
using GameServer.Network;
|
||||||
using GameServer.Network.Messages;
|
|
||||||
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)]
|
||||||
|
public void UnlockAllRoles(ConfigManager configManager)
|
||||||
|
{
|
||||||
|
foreach (RoleInfoConfig roleConfig in configManager.Enumerate<RoleInfoConfig>())
|
||||||
|
{
|
||||||
|
roleInfo role = _modelManager.Roles.Create(roleConfig.Id);
|
||||||
|
role.BaseProp.AddRange(CreateBasePropList(configManager.GetConfig<BasePropertyConfig>(roleConfig.Id)));
|
||||||
|
|
||||||
|
WeaponItem weapon = _modelManager.Inventory.AddNewWeapon(roleConfig.InitWeaponItemId);
|
||||||
|
weapon.RoleId = role.RoleId;
|
||||||
|
|
||||||
|
role.ApplyWeaponProperties(configManager.GetConfig<WeaponConfig>(weapon.Id)!);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[GameEvent(GameEventType.EnterGame)]
|
[GameEvent(GameEventType.EnterGame)]
|
||||||
public async Task OnEnterGame(ModelManager modelManager, ConfigManager configManager)
|
public async Task OnEnterGame(ModelManager modelManager)
|
||||||
{
|
{
|
||||||
PlayerModel player = modelManager.Player;
|
|
||||||
|
|
||||||
await Session.Push(MessageId.PbGetRoleListNotify, new PbGetRoleListNotify
|
await Session.Push(MessageId.PbGetRoleListNotify, new PbGetRoleListNotify
|
||||||
{
|
{
|
||||||
RoleList =
|
RoleList =
|
||||||
{
|
{
|
||||||
configManager.GetCollection(ConfigType.RoleInfo)
|
modelManager.Roles.Roles
|
||||||
.Enumerate<RoleInfoConfig>()
|
|
||||||
.Select(config => new roleInfo
|
|
||||||
{
|
|
||||||
RoleId = config.Id,
|
|
||||||
Level = 1,
|
|
||||||
BaseProp = { CreateBasePropList(configManager.GetConfig<BasePropertyConfig>(config.Id)) }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -48,6 +67,36 @@ internal class RoleController : Controller
|
||||||
[NetEvent(MessageId.RoleFavorListRequest)]
|
[NetEvent(MessageId.RoleFavorListRequest)]
|
||||||
public RpcResult OnRoleFavorListRequest() => Response(MessageId.RoleFavorListResponse, new RoleFavorListResponse());
|
public RpcResult OnRoleFavorListRequest() => Response(MessageId.RoleFavorListResponse, new RoleFavorListResponse());
|
||||||
|
|
||||||
|
[NetEvent(MessageId.ResonantChainUnlockRequest)]
|
||||||
|
public RpcResult OnResonantChainUnlockRequest(ResonantChainUnlockRequest request, ModelManager modelManager, ConfigManager configManager)
|
||||||
|
{
|
||||||
|
roleInfo? role = modelManager.Roles.Roles.Find(r => r.RoleId == request.RoleId)!;
|
||||||
|
|
||||||
|
if (role != null)
|
||||||
|
{
|
||||||
|
RoleInfoConfig roleConfig = configManager.GetConfig<RoleInfoConfig>(request.RoleId)!;
|
||||||
|
|
||||||
|
int resonantChainGroupId = roleConfig.ResonantChainGroupId;
|
||||||
|
|
||||||
|
// Todo: add buff by _resonantChainGroupId
|
||||||
|
|
||||||
|
int curr = role.ResonantChainGroupIndex;
|
||||||
|
int next = Math.Min(curr + 1, 6);
|
||||||
|
role.ResonantChainGroupIndex = next;
|
||||||
|
|
||||||
|
return Response(MessageId.ResonantChainUnlockResponse, new ResonantChainUnlockResponse
|
||||||
|
{
|
||||||
|
RoleId = request.RoleId,
|
||||||
|
ResonantChainGroupIndex = next
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response(MessageId.ResonantChainUnlockResponse, new ResonantChainUnlockResponse
|
||||||
|
{
|
||||||
|
ErrCode = (int)ErrorCode.ErrRoleResonNotActive
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static List<ArrayIntInt> CreateBasePropList(BasePropertyConfig? config)
|
private static List<ArrayIntInt> CreateBasePropList(BasePropertyConfig? config)
|
||||||
{
|
{
|
||||||
List<ArrayIntInt> baseProp = [];
|
List<ArrayIntInt> baseProp = [];
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
39
GameServer/Extensions/Logic/RoleInfoExtensions.cs
Normal file
39
GameServer/Extensions/Logic/RoleInfoExtensions.cs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
using Core.Config;
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Extensions.Logic;
|
||||||
|
internal static class RoleInfoExtensions
|
||||||
|
{
|
||||||
|
public static IEnumerable<GameplayAttributeData> GetAttributeList(this roleInfo role)
|
||||||
|
{
|
||||||
|
return role.BaseProp.Select(prop => new GameplayAttributeData
|
||||||
|
{
|
||||||
|
AttributeType = prop.Key,
|
||||||
|
BaseValue = prop.Value,
|
||||||
|
CurrentValue = prop.Value + ((role.AddProp.SingleOrDefault(p => p.Key == prop.Key)?.Value) ?? 0),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ApplyWeaponProperties(this roleInfo role, WeaponConfig weaponConf)
|
||||||
|
{
|
||||||
|
role.AddProp.Clear();
|
||||||
|
|
||||||
|
if (weaponConf.FirstPropId != null)
|
||||||
|
{
|
||||||
|
role.AddProp.Add(new ArrayIntInt
|
||||||
|
{
|
||||||
|
Key = weaponConf.FirstPropId.Id,
|
||||||
|
Value = (int)weaponConf.FirstPropId.Value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weaponConf.SecondPropId != null)
|
||||||
|
{
|
||||||
|
role.AddProp.Add(new ArrayIntInt
|
||||||
|
{
|
||||||
|
Key = weaponConf.SecondPropId.Id,
|
||||||
|
Value = (int)weaponConf.SecondPropId.Value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -10,7 +10,7 @@ internal class FormationModel
|
||||||
|
|
||||||
public void Set(int[] roleIds)
|
public void Set(int[] roleIds)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < RoleIds.Length; i++)
|
for (int i = 0; i < roleIds.Length; i++)
|
||||||
{
|
{
|
||||||
RoleIds[i] = roleIds[i];
|
RoleIds[i] = roleIds[i];
|
||||||
}
|
}
|
||||||
|
|
55
GameServer/Models/InventoryModel.cs
Normal file
55
GameServer/Models/InventoryModel.cs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Models;
|
||||||
|
internal class InventoryModel
|
||||||
|
{
|
||||||
|
private int _itemIncrId;
|
||||||
|
|
||||||
|
public List<NormalItem> ItemList { get; } = [];
|
||||||
|
public List<WeaponItem> WeaponList { get; } = [];
|
||||||
|
|
||||||
|
public WeaponItem? GetEquippedWeapon(int roleId) => WeaponList.SingleOrDefault(weapon => weapon.RoleId == roleId);
|
||||||
|
|
||||||
|
public WeaponItem? GetWeaponById(int incrId) => WeaponList.SingleOrDefault(weapon => weapon.IncrId == incrId);
|
||||||
|
|
||||||
|
public int GetItemCount(int itemId) => ItemList.SingleOrDefault(item => item.Id == itemId)?.Count ?? 0;
|
||||||
|
|
||||||
|
public bool TryUseItem(int itemId, int amount)
|
||||||
|
{
|
||||||
|
int currentAmount = GetItemCount(itemId);
|
||||||
|
if (amount > currentAmount) return false;
|
||||||
|
|
||||||
|
AddItem(itemId, -amount);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddItem(int itemId, int amount)
|
||||||
|
{
|
||||||
|
NormalItem? item = ItemList.SingleOrDefault(item => item.Id == itemId);
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
item.Count += amount;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemList.Add(new NormalItem
|
||||||
|
{
|
||||||
|
Id = itemId,
|
||||||
|
Count = amount
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeaponItem AddNewWeapon(int weaponId)
|
||||||
|
{
|
||||||
|
WeaponItem weapon = new()
|
||||||
|
{
|
||||||
|
Id = weaponId,
|
||||||
|
IncrId = ++_itemIncrId,
|
||||||
|
WeaponLevel = 1,
|
||||||
|
WeaponResonLevel = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
WeaponList.Add(weapon);
|
||||||
|
return weapon;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using GameServer.Controllers.Attributes;
|
using Core.Config;
|
||||||
|
using GameServer.Controllers.Attributes;
|
||||||
using GameServer.Settings;
|
using GameServer.Settings;
|
||||||
using GameServer.Systems.Event;
|
using GameServer.Systems.Event;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
@ -7,13 +8,15 @@ namespace GameServer.Models;
|
||||||
internal class ModelManager
|
internal class ModelManager
|
||||||
{
|
{
|
||||||
private readonly IOptions<PlayerStartingValues> _playerStartingValues;
|
private readonly IOptions<PlayerStartingValues> _playerStartingValues;
|
||||||
|
private readonly ConfigManager _configManager;
|
||||||
|
|
||||||
private PlayerModel? _playerModel;
|
private PlayerModel? _playerModel;
|
||||||
private CreatureModel? _creatureModel;
|
private CreatureModel? _creatureModel;
|
||||||
|
|
||||||
public ModelManager(IOptions<PlayerStartingValues> playerStartingValues)
|
public ModelManager(IOptions<PlayerStartingValues> playerStartingValues, ConfigManager configManager)
|
||||||
{
|
{
|
||||||
_playerStartingValues = playerStartingValues;
|
_playerStartingValues = playerStartingValues;
|
||||||
|
_configManager = configManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
[GameEvent(GameEventType.Login)]
|
[GameEvent(GameEventType.Login)]
|
||||||
|
@ -29,6 +32,8 @@ internal class ModelManager
|
||||||
|
|
||||||
public CreatureModel Creature => _creatureModel ?? throw new InvalidOperationException($"Trying to access {nameof(CreatureModel)} instance before initialization!");
|
public CreatureModel Creature => _creatureModel ?? throw new InvalidOperationException($"Trying to access {nameof(CreatureModel)} instance before initialization!");
|
||||||
|
|
||||||
|
public RoleModel Roles { get; } = new();
|
||||||
public FormationModel Formation { get; } = new();
|
public FormationModel Formation { get; } = new();
|
||||||
|
public InventoryModel Inventory { get; } = new();
|
||||||
public ChatModel Chat { get; } = new();
|
public ChatModel Chat { get; } = new();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,103 @@
|
||||||
using Protocol;
|
using GameServer.Settings;
|
||||||
using GameServer.Settings;
|
using Protocol;
|
||||||
|
|
||||||
namespace GameServer.Models;
|
namespace GameServer.Models;
|
||||||
internal class PlayerModel
|
internal class PlayerModel
|
||||||
{
|
{
|
||||||
|
private const int MaxPlayerLevel = 80;
|
||||||
|
|
||||||
|
public List<PlayerAttr> Attributes { get; } = [];
|
||||||
|
|
||||||
public int Id { get; private set; }
|
public int Id { get; private set; }
|
||||||
public string Name { get; private set; }
|
public int BirthDay { get; set; }
|
||||||
public int[] Characters { get; private set; }
|
public int[] Characters { get; private set; }
|
||||||
public Vector Position { get; private set; }
|
public Vector Position { get; private set; }
|
||||||
|
|
||||||
|
public string Name => GetStringAttribute(PlayerAttrKey.Name);
|
||||||
|
|
||||||
public PlayerModel()
|
public PlayerModel()
|
||||||
{
|
{
|
||||||
Name = string.Empty;
|
|
||||||
Characters = [];
|
Characters = [];
|
||||||
Position = new Vector();
|
Position = new Vector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetAttribute(PlayerAttrKey key, int value)
|
||||||
|
{
|
||||||
|
SetAttribute(key, PlayerAttrType.Int32, value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAttribute(PlayerAttrKey key, string value)
|
||||||
|
{
|
||||||
|
SetAttribute(key, PlayerAttrType.String, 0, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetIntAttribute(PlayerAttrKey key)
|
||||||
|
{
|
||||||
|
return GetAttributeOfType(key, PlayerAttrType.Int32)?.Int32Value ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetStringAttribute(PlayerAttrKey key)
|
||||||
|
{
|
||||||
|
return GetAttributeOfType(key, PlayerAttrType.String)?.StringValue ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetAttribute(PlayerAttrKey key, PlayerAttrType type, int intValue, string? stringValue)
|
||||||
|
{
|
||||||
|
PlayerAttr? attr = GetAttributeOfType(key, type);
|
||||||
|
if (attr == null)
|
||||||
|
{
|
||||||
|
attr = new PlayerAttr
|
||||||
|
{
|
||||||
|
Key = (int)key,
|
||||||
|
ValueType = (int)type,
|
||||||
|
};
|
||||||
|
|
||||||
|
Attributes.Add(attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case PlayerAttrType.Int32:
|
||||||
|
attr.Int32Value = intValue; break;
|
||||||
|
case PlayerAttrType.String:
|
||||||
|
attr.StringValue = stringValue; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlayerAttr? GetAttributeOfType(PlayerAttrKey key, PlayerAttrType type)
|
||||||
|
{
|
||||||
|
PlayerAttr? attr = Attributes.SingleOrDefault(attr => attr.Key == (int)key);
|
||||||
|
if (attr != null)
|
||||||
|
{
|
||||||
|
if (attr.ValueType != (int)type)
|
||||||
|
throw new ArgumentException($"PlayerAttr type mismatch! Key: {key}, type: {(PlayerAttrType)attr.ValueType}, argument type: {type}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LevelUp()
|
||||||
|
{
|
||||||
|
int level = GetIntAttribute(PlayerAttrKey.Level);
|
||||||
|
|
||||||
|
if (level == MaxPlayerLevel) return;
|
||||||
|
SetAttribute(PlayerAttrKey.Level, level + 1);
|
||||||
|
}
|
||||||
|
|
||||||
public static PlayerModel CreateDefaultPlayer(PlayerStartingValues startingValues)
|
public static PlayerModel CreateDefaultPlayer(PlayerStartingValues startingValues)
|
||||||
{
|
{
|
||||||
return new PlayerModel
|
PlayerModel playerModel = new()
|
||||||
{
|
{
|
||||||
Id = 1337,
|
Id = 1337,
|
||||||
Name = startingValues.Name,
|
|
||||||
Characters = startingValues.Characters,
|
Characters = startingValues.Characters,
|
||||||
Position = startingValues.Position.Clone()
|
Position = startingValues.Position.Clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
playerModel.SetAttribute(PlayerAttrKey.Name, startingValues.Name);
|
||||||
|
playerModel.SetAttribute(PlayerAttrKey.Level, startingValues.PlayerLevel);
|
||||||
|
playerModel.SetAttribute(PlayerAttrKey.HeadPhoto, startingValues.HeadPhoto);
|
||||||
|
playerModel.SetAttribute(PlayerAttrKey.HeadFrame, startingValues.HeadFrame);
|
||||||
|
|
||||||
|
return playerModel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
24
GameServer/Models/RoleModel.cs
Normal file
24
GameServer/Models/RoleModel.cs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Models;
|
||||||
|
internal class RoleModel
|
||||||
|
{
|
||||||
|
public List<roleInfo> Roles { get; } = [];
|
||||||
|
|
||||||
|
public roleInfo Create(int id)
|
||||||
|
{
|
||||||
|
roleInfo info = new()
|
||||||
|
{
|
||||||
|
RoleId = id,
|
||||||
|
Level = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
Roles.Add(info);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public roleInfo? GetRoleById(int roleId)
|
||||||
|
{
|
||||||
|
return Roles.SingleOrDefault(role => role.RoleId == roleId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>();
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
internal class GameplayFeatureSettings
|
internal class GameplayFeatureSettings
|
||||||
{
|
{
|
||||||
public bool TeleportByMapMark { get; set; }
|
public bool TeleportByMapMark { get; set; }
|
||||||
|
public bool UnlimitedEnergy { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,9 @@ namespace GameServer.Settings;
|
||||||
internal class PlayerStartingValues
|
internal class PlayerStartingValues
|
||||||
{
|
{
|
||||||
public required string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
|
public required int PlayerLevel { get; set; }
|
||||||
|
public required int HeadPhoto { get; set; }
|
||||||
|
public required int HeadFrame { get; set; }
|
||||||
public required int[] Characters { get; set; }
|
public required int[] Characters { get; set; }
|
||||||
public required Vector Position { get; set; }
|
public required Vector Position { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,14 @@ internal class EntityAttributeComponent : EntityComponentBase
|
||||||
_gameplayAttributes = [];
|
_gameplayAttributes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetAll(IEnumerable<GameplayAttributeData> attributes)
|
||||||
|
{
|
||||||
|
foreach (GameplayAttributeData attr in attributes)
|
||||||
|
{
|
||||||
|
SetAttribute((EAttributeType)attr.AttributeType, attr.CurrentValue, attr.BaseValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void SetAttribute(EAttributeType type, int currentValue, int baseValue)
|
public void SetAttribute(EAttributeType type, int currentValue, int baseValue)
|
||||||
{
|
{
|
||||||
if (!_gameplayAttributes.TryGetValue(type, out GameplayAttributeData? attribute))
|
if (!_gameplayAttributes.TryGetValue(type, out GameplayAttributeData? attribute))
|
||||||
|
|
|
@ -4,6 +4,8 @@ namespace GameServer.Systems.Entity.Component;
|
||||||
internal class EntityConcomitantsComponent : EntityComponentBase
|
internal class EntityConcomitantsComponent : EntityComponentBase
|
||||||
{
|
{
|
||||||
public List<long> CustomEntityIds { get; }
|
public List<long> CustomEntityIds { get; }
|
||||||
|
public long PhantomRoleEntityId { get; set; }
|
||||||
|
public long VisionEntityId { get; set; }
|
||||||
|
|
||||||
public EntityConcomitantsComponent()
|
public EntityConcomitantsComponent()
|
||||||
{
|
{
|
||||||
|
@ -19,6 +21,10 @@ internal class EntityConcomitantsComponent : EntityComponentBase
|
||||||
EntityComponentPb pb = new()
|
EntityComponentPb pb = new()
|
||||||
{
|
{
|
||||||
ConcomitantsComponentPb = new()
|
ConcomitantsComponentPb = new()
|
||||||
|
{
|
||||||
|
PhantomRoleEid = PhantomRoleEntityId,
|
||||||
|
VisionEntityId = VisionEntityId
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pb.ConcomitantsComponentPb.CustomEntityIds.AddRange(CustomEntityIds);
|
pb.ConcomitantsComponentPb.CustomEntityIds.AddRange(CustomEntityIds);
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
using Protocol;
|
||||||
|
|
||||||
|
namespace GameServer.Systems.Entity.Component;
|
||||||
|
internal class EntityFightBuffComponent : EntityComponentBase
|
||||||
|
{
|
||||||
|
public List<FightBuffInformation> BuffInfoList { get; } = [];
|
||||||
|
|
||||||
|
public override EntityComponentType Type => EntityComponentType.FightBuff;
|
||||||
|
|
||||||
|
public override EntityComponentPb Pb => new()
|
||||||
|
{
|
||||||
|
FightBuffComponent = new()
|
||||||
|
{
|
||||||
|
FightBuffInfos =
|
||||||
|
{
|
||||||
|
BuffInfoList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ internal class EntitySummonerComponent : EntityComponentBase
|
||||||
Type = (int)SummonType,
|
Type = (int)SummonType,
|
||||||
SummonerId = SummonerId,
|
SummonerId = SummonerId,
|
||||||
PlayerId = PlayerId,
|
PlayerId = PlayerId,
|
||||||
SummonSkillId = SummonSkillId
|
SummonSkillId = SummonSkillId,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,10 +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 EntityBase(long id)
|
public bool IsConcomitant => ComponentSystem.TryGet<EntitySummonerComponent>(out _);
|
||||||
|
|
||||||
|
protected IGameActionListener ActionListener { get; }
|
||||||
|
|
||||||
|
public EntityBase(long id, IGameActionListener listener)
|
||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
|
|
||||||
|
@ -23,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()
|
||||||
|
@ -30,6 +37,7 @@ internal abstract class EntityBase
|
||||||
State = EntityState.Born;
|
State = EntityState.Born;
|
||||||
|
|
||||||
_ = ComponentSystem.Create<EntityLogicStateComponent>();
|
_ = ComponentSystem.Create<EntityLogicStateComponent>();
|
||||||
|
_ = ComponentSystem.Create<EntityFightBuffComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Activate()
|
public virtual void Activate()
|
||||||
|
@ -37,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)
|
||||||
|
{
|
||||||
|
foreach (EntityBase entity in entities)
|
||||||
{
|
{
|
||||||
if (_entities.Any(e => e.Id == entity.Id))
|
if (_entities.Any(e => e.Id == entity.Id))
|
||||||
throw new InvalidOperationException($"EntitySystem::Create - entity with id {entity.Id} already exists");
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Destroy(EntityBase entity)
|
_ = _listener.OnEntitiesAdded(entities);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasDynamicEntity(int dynamicId)
|
||||||
|
{
|
||||||
|
return _dynamicEntityIds.Contains(dynamicId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Destroy(IEnumerable<EntityBase> entities)
|
||||||
|
{
|
||||||
|
foreach (EntityBase entity in entities)
|
||||||
{
|
{
|
||||||
_ = _entities.Remove(entity);
|
_ = _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;
|
||||||
|
@ -37,15 +38,37 @@ internal class PlayerEntity : EntityBase
|
||||||
{
|
{
|
||||||
base.OnCreate();
|
base.OnCreate();
|
||||||
|
|
||||||
// Should be created immediately
|
|
||||||
EntityConcomitantsComponent concomitantsComponent = ComponentSystem.Create<EntityConcomitantsComponent>();
|
|
||||||
concomitantsComponent.CustomEntityIds.Add(Id);
|
|
||||||
|
|
||||||
EntityVisionSkillComponent visionSkillComponent = ComponentSystem.Create<EntityVisionSkillComponent>();
|
EntityVisionSkillComponent visionSkillComponent = ComponentSystem.Create<EntityVisionSkillComponent>();
|
||||||
visionSkillComponent.SetExploreTool(1001);
|
visionSkillComponent.SetExploreTool(1001);
|
||||||
|
|
||||||
_ = ComponentSystem.Create<EntityEquipComponent>();
|
_ = ComponentSystem.Create<EntityEquipComponent>();
|
||||||
_ = ComponentSystem.Create<EntityAttributeComponent>();
|
_ = ComponentSystem.Create<EntityAttributeComponent>();
|
||||||
|
|
||||||
|
// TODO: temporary solution to enable glider and wall run, should implement proper buff management.
|
||||||
|
EntityFightBuffComponent fightBuffComponent = ComponentSystem.Get<EntityFightBuffComponent>();
|
||||||
|
fightBuffComponent.BuffInfoList.Add(new FightBuffInformation
|
||||||
|
{
|
||||||
|
BuffId = 3004,
|
||||||
|
EntityId = Id,
|
||||||
|
InstigatorId = Id,
|
||||||
|
IsActive = true,
|
||||||
|
Duration = -1,
|
||||||
|
LeftDuration = -1,
|
||||||
|
Level = 1,
|
||||||
|
StackCount = 1
|
||||||
|
});
|
||||||
|
|
||||||
|
fightBuffComponent.BuffInfoList.Add(new FightBuffInformation
|
||||||
|
{
|
||||||
|
BuffId = 3003,
|
||||||
|
EntityId = Id,
|
||||||
|
InstigatorId = Id,
|
||||||
|
IsActive = true,
|
||||||
|
Duration = -1,
|
||||||
|
LeftDuration = -1,
|
||||||
|
Level = 1,
|
||||||
|
StackCount = 1
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Activate()
|
public override void Activate()
|
||||||
|
@ -56,7 +79,7 @@ internal class PlayerEntity : EntityBase
|
||||||
public override EEntityType Type => EEntityType.Player;
|
public override EEntityType Type => EEntityType.Player;
|
||||||
public override EntityConfigType ConfigType => EntityConfigType.Character;
|
public override EntityConfigType ConfigType => EntityConfigType.Character;
|
||||||
|
|
||||||
public override bool IsVisible => IsCurrentRole;
|
public override bool IsVisible => IsCurrentRole || IsConcomitant;
|
||||||
|
|
||||||
public override EntityPb Pb
|
public override EntityPb Pb
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,11 @@ internal enum GameEventType
|
||||||
PushDataDone,
|
PushDataDone,
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
|
PlayerPositionChanged,
|
||||||
FormationUpdated,
|
FormationUpdated,
|
||||||
VisionSkillChanged
|
VisionSkillChanged,
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
DebugUnlockAllRoles,
|
||||||
|
DebugUnlockAllItems
|
||||||
}
|
}
|
||||||
|
|
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 }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,18 @@
|
||||||
{
|
{
|
||||||
"StartingValues": {
|
"StartingValues": {
|
||||||
"Name": "ReversedRooms",
|
"Name": "ReversedRooms",
|
||||||
|
"PlayerLevel": 8,
|
||||||
|
"HeadPhoto": 1402,
|
||||||
|
"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": false
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue