mirror of
https://github.com/Campofinale/CampofinaleBackup.git
synced 2025-12-13 00:04:36 +00:00
another try to improve entity spawning and fix loading but still loading issues
This commit is contained in:
parent
f47ec48073
commit
35f8fbb2b2
@ -4,10 +4,12 @@ using Campofinale.Packets.Sc;
|
|||||||
using Campofinale.Resource;
|
using Campofinale.Resource;
|
||||||
using Campofinale.Resource.Dynamic;
|
using Campofinale.Resource.Dynamic;
|
||||||
using MongoDB.Bson.Serialization.Attributes;
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using System;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using static Campofinale.Resource.Dynamic.SpawnerConfig;
|
using static Campofinale.Resource.Dynamic.SpawnerConfig;
|
||||||
using static Campofinale.Resource.ResourceManager;
|
using static Campofinale.Resource.ResourceManager;
|
||||||
using static Campofinale.Resource.ResourceManager.LevelScene.LevelData;
|
using static Campofinale.Resource.ResourceManager.LevelScene.LevelData;
|
||||||
|
using static Campofinale.Resource.ResourceManager.LevelScene.LevelData.LevelFunctionAreaData;
|
||||||
|
|
||||||
namespace Campofinale.Game
|
namespace Campofinale.Game
|
||||||
{
|
{
|
||||||
@ -235,7 +237,6 @@ namespace Campofinale.Game
|
|||||||
{
|
{
|
||||||
if (scene != null)
|
if (scene != null)
|
||||||
{
|
{
|
||||||
scene.alreadyLoaded = false;
|
|
||||||
scene.Unload();
|
scene.Unload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,11 +257,11 @@ namespace Campofinale.Game
|
|||||||
[BsonIgnore,JsonIgnore]
|
[BsonIgnore,JsonIgnore]
|
||||||
public List<Entity> entities = new();
|
public List<Entity> entities = new();
|
||||||
[BsonIgnore, JsonIgnore]
|
[BsonIgnore, JsonIgnore]
|
||||||
public bool alreadyLoaded = false;
|
|
||||||
[BsonIgnore, JsonIgnore]
|
|
||||||
public List<ulong> activeScripts = new();
|
public List<ulong> activeScripts = new();
|
||||||
|
|
||||||
public List<LevelScript> scripts = new();
|
public List<LevelScript> scripts = new();
|
||||||
|
[BsonIgnore, JsonIgnore]
|
||||||
|
private LevelFunctionRangeData currentAreaRange = new();
|
||||||
public int GetCollection(string id)
|
public int GetCollection(string id)
|
||||||
{
|
{
|
||||||
if (collections.ContainsKey(id))
|
if (collections.ContainsKey(id))
|
||||||
@ -367,17 +368,12 @@ namespace Campofinale.Game
|
|||||||
entities.Add(entity);
|
entities.Add(entity);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UpdateShowEntities();
|
UpdateShowEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SpawnEntity(Entity en,bool spawnedCheck=true)
|
public void SpawnEntity(Entity en,bool spawnedCheck=true)
|
||||||
{
|
{
|
||||||
|
|
||||||
en.spawned = true;
|
en.spawned = true;
|
||||||
|
|
||||||
GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List<Entity>() { en }));
|
GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List<Entity>() { en }));
|
||||||
}
|
}
|
||||||
public bool GetActiveScript(ulong id)
|
public bool GetActiveScript(ulong id)
|
||||||
@ -392,10 +388,22 @@ namespace Campofinale.Game
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateArea()
|
||||||
|
{
|
||||||
|
LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId);
|
||||||
|
lv_scene.levelData.functionArea.ranges.ForEach(range =>
|
||||||
|
{
|
||||||
|
if (range.IsObjectInside(GetOwner().position))
|
||||||
|
{
|
||||||
|
currentAreaRange=range;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
//Bug on scene 101: spawning entities in this way make the game break if you try to load another scene from scene 101
|
//Bug on scene 101: spawning entities in this way make the game break if you try to load another scene from scene 101
|
||||||
public async void UpdateShowEntities()
|
public async void UpdateShowEntities()
|
||||||
{
|
{
|
||||||
|
UpdateArea();
|
||||||
List<Entity> toSpawn = new();
|
List<Entity> toSpawn = new();
|
||||||
List<Entity> toCheck = GetEntityExcludingChar().FindAll(e => e.spawned == false);
|
List<Entity> toCheck = GetEntityExcludingChar().FindAll(e => e.spawned == false);
|
||||||
toCheck.Sort((a, b) => a.Position.Distance(GetOwner().position).CompareTo(b.Position.Distance(GetOwner().position)));
|
toCheck.Sort((a, b) => a.Position.Distance(GetOwner().position).CompareTo(b.Position.Distance(GetOwner().position)));
|
||||||
@ -404,6 +412,7 @@ namespace Campofinale.Game
|
|||||||
|
|
||||||
if(e.spawned==false && (GetActiveScript(e.belongLevelScriptId) || e.belongLevelScriptId==0))
|
if(e.spawned==false && (GetActiveScript(e.belongLevelScriptId) || e.belongLevelScriptId==0))
|
||||||
{
|
{
|
||||||
|
if(currentAreaRange.IsObjectInside(e.Position))
|
||||||
if (!e.defaultHide)
|
if (!e.defaultHide)
|
||||||
{
|
{
|
||||||
toSpawn.Add(e);
|
toSpawn.Add(e);
|
||||||
@ -423,34 +432,18 @@ namespace Campofinale.Game
|
|||||||
GetOwner().Send(new PacketScObjectEnterView(GetOwner(), chunk));
|
GetOwner().Send(new PacketScObjectEnterView(GetOwner(), chunk));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
List<ulong> toDespawn=new();
|
||||||
|
foreach(Entity en in GetEntityExcludingChar().FindAll(e=> e.spawned==true))
|
||||||
|
{
|
||||||
|
if (!currentAreaRange.IsObjectInside(en.Position))
|
||||||
|
{
|
||||||
|
toDespawn.Add(en.guid);
|
||||||
|
en.spawned = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* foreach(Entity en in GetEntityExcludingChar())
|
}
|
||||||
{
|
if(toDespawn.Count > 0)
|
||||||
float minDis = 100;
|
GetOwner().Send(new PacketScObjectLeaveView(GetOwner(), toDespawn));
|
||||||
|
|
||||||
//todo new system
|
|
||||||
if (en.Position.DistanceXZ(GetOwner().position) < minDis)
|
|
||||||
{
|
|
||||||
if (!en.spawned)
|
|
||||||
{
|
|
||||||
SpawnEntity(en);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
/*if (en.spawned)
|
|
||||||
{
|
|
||||||
|
|
||||||
en.spawned = false;
|
|
||||||
GetOwner().Send(new PacketScObjectLeaveView(GetOwner(), new List<ulong>() { en.guid }));
|
|
||||||
en.Position=en.BornPos;
|
|
||||||
en.Rotation = en.Rotation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player GetOwner()
|
public Player GetOwner()
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Campofinale.Packets.Cs
|
|||||||
{
|
{
|
||||||
CsSceneMoveStateSet req = packet.DecodeBody<CsSceneMoveStateSet>();
|
CsSceneMoveStateSet req = packet.DecodeBody<CsSceneMoveStateSet>();
|
||||||
//req.
|
//req.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using Campofinale.Network;
|
using Campofinale.Network;
|
||||||
using Campofinale.Protocol;
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Utils;
|
||||||
|
|
||||||
namespace Campofinale.Packets.Cs
|
namespace Campofinale.Packets.Cs
|
||||||
{
|
{
|
||||||
@ -26,6 +27,9 @@ namespace Campofinale.Packets.Cs
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
uint unixTimestamp = (uint)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||||
|
var generator = new SnowflakeIdGenerator(machineId: 1);
|
||||||
|
long id = generator.GenerateId();
|
||||||
ScSceneTeleport t = new()
|
ScSceneTeleport t = new()
|
||||||
{
|
{
|
||||||
TeleportReason = req.TeleportReason,
|
TeleportReason = req.TeleportReason,
|
||||||
@ -33,6 +37,8 @@ namespace Campofinale.Packets.Cs
|
|||||||
Position = req.Position,
|
Position = req.Position,
|
||||||
Rotation = req.Rotation,
|
Rotation = req.Rotation,
|
||||||
SceneNumId = req.SceneNumId,
|
SceneNumId = req.SceneNumId,
|
||||||
|
ServerTime = unixTimestamp,
|
||||||
|
TpUuid= (ulong)id
|
||||||
};
|
};
|
||||||
session.curSceneNumId = t.SceneNumId;
|
session.curSceneNumId = t.SceneNumId;
|
||||||
session.Send(ScMsgId.ScSceneTeleport, t);
|
session.Send(ScMsgId.ScSceneTeleport, t);
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
using Campofinale.Resource.Json;
|
using Campofinale.Resource.Json;
|
||||||
using Campofinale.Resource.Table;
|
using Campofinale.Resource.Table;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System.Numerics;
|
||||||
|
using System;
|
||||||
using static Campofinale.Resource.ResourceManager.LevelScene;
|
using static Campofinale.Resource.ResourceManager.LevelScene;
|
||||||
|
|
||||||
namespace Campofinale.Resource
|
namespace Campofinale.Resource
|
||||||
@ -549,6 +551,7 @@ namespace Campofinale.Resource
|
|||||||
public List<WorldWayPointSets> worldWayPointSets = new();
|
public List<WorldWayPointSets> worldWayPointSets = new();
|
||||||
public List<LevelFactoryRegionData> factoryRegions = new();
|
public List<LevelFactoryRegionData> factoryRegions = new();
|
||||||
public List<LevelSpawnerData> spawners = new();
|
public List<LevelSpawnerData> spawners = new();
|
||||||
|
public LevelFunctionAreaData functionArea = new();
|
||||||
public void Merge(LevelData other)
|
public void Merge(LevelData other)
|
||||||
{
|
{
|
||||||
this.sceneId = other.sceneId;
|
this.sceneId = other.sceneId;
|
||||||
@ -560,6 +563,7 @@ namespace Campofinale.Resource
|
|||||||
this.worldWayPointSets.AddRange(other.worldWayPointSets);
|
this.worldWayPointSets.AddRange(other.worldWayPointSets);
|
||||||
this.factoryRegions.AddRange(other.factoryRegions);
|
this.factoryRegions.AddRange(other.factoryRegions);
|
||||||
this.spawners.AddRange(other.spawners);
|
this.spawners.AddRange(other.spawners);
|
||||||
|
this.functionArea.ranges.AddRange(other.functionArea.ranges);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WorldWayPointSets
|
public class WorldWayPointSets
|
||||||
@ -567,6 +571,26 @@ namespace Campofinale.Resource
|
|||||||
public int id;
|
public int id;
|
||||||
public Dictionary<string, int> pointIdToIndex = new();
|
public Dictionary<string, int> pointIdToIndex = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class LevelFunctionAreaData
|
||||||
|
{
|
||||||
|
public List<LevelFunctionRangeData> ranges = new();
|
||||||
|
|
||||||
|
public class LevelFunctionRangeData
|
||||||
|
{
|
||||||
|
public Vector3f m_center = new();
|
||||||
|
public Vector3f m_size = new();
|
||||||
|
|
||||||
|
public bool IsObjectInside(Vector3f position)
|
||||||
|
{
|
||||||
|
Vector3f halfSize = m_size * 0.5f;
|
||||||
|
|
||||||
|
return Math.Abs(position.x - m_center.x) <= halfSize.x &&
|
||||||
|
Math.Abs(position.y - m_center.y) <= halfSize.y &&
|
||||||
|
Math.Abs(position.z - m_center.z) <= halfSize.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public class LevelSpawnerData
|
public class LevelSpawnerData
|
||||||
{
|
{
|
||||||
public ulong spawnerId;
|
public ulong spawnerId;
|
||||||
@ -949,6 +973,10 @@ namespace Campofinale.Resource
|
|||||||
public Vector3f()
|
public Vector3f()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public static Vector3f operator *(Vector3f v, float scalar)
|
||||||
|
{
|
||||||
|
return new Vector3f(v.x * scalar, v.y * scalar, v.z * scalar);
|
||||||
}
|
}
|
||||||
public Vector3f(float x, float y, float z)
|
public Vector3f(float x, float y, float z)
|
||||||
{
|
{
|
||||||
|
|||||||
56
Campofinale/Utils/SnowflakeIdGenerator.cs
Normal file
56
Campofinale/Utils/SnowflakeIdGenerator.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Utils
|
||||||
|
{
|
||||||
|
public class SnowflakeIdGenerator
|
||||||
|
{
|
||||||
|
private static readonly DateTime Epoch = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||||
|
|
||||||
|
private readonly int _machineId; // es. 0–31 (5 bit)
|
||||||
|
private int _sequence = 0;
|
||||||
|
private long _lastTimestamp = -1L;
|
||||||
|
|
||||||
|
private readonly object _lock = new object();
|
||||||
|
|
||||||
|
public SnowflakeIdGenerator(int machineId)
|
||||||
|
{
|
||||||
|
_machineId = machineId & 0x1F; // 5 bit
|
||||||
|
}
|
||||||
|
|
||||||
|
public long GenerateId()
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
long timestamp = GetCurrentTimestamp();
|
||||||
|
|
||||||
|
if (timestamp == _lastTimestamp)
|
||||||
|
{
|
||||||
|
_sequence = (_sequence + 1) & 0xFFF; // 12 bit
|
||||||
|
if (_sequence == 0)
|
||||||
|
{
|
||||||
|
// Attendi il prossimo millisecondo
|
||||||
|
while ((timestamp = GetCurrentTimestamp()) <= _lastTimestamp) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_sequence = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastTimestamp = timestamp;
|
||||||
|
|
||||||
|
return ((timestamp << 22) | ((long)_machineId << 12) | (long)_sequence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long GetCurrentTimestamp()
|
||||||
|
{
|
||||||
|
return (long)(DateTime.UtcNow - Epoch).TotalMilliseconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user