Files
Campofinale/Campofinale/Game/SceneManager.cs
AlessandroCH 7c0a512ad6 test
2025-05-28 12:12:04 +02:00

453 lines
15 KiB
C#

using Campofinale.Game.Entities;
using Campofinale.Game.Inventory;
using Campofinale.Packets.Sc;
using Campofinale.Resource;
using MongoDB.Bson.Serialization.Attributes;
using System.Text.Json.Serialization;
using static Campofinale.Resource.ResourceManager;
using static Campofinale.Resource.ResourceManager.LevelScene.LevelData;
namespace Campofinale.Game
{
public class SceneManager
{
public List<Scene> scenes = new List<Scene>();
public Player player;
public List<Entity> globalEntities = new List<Entity>();
public SceneManager(Player player) {
this.player = player;
}
public void Update()
{
if (GetCurScene()!=null)
GetCurScene().UpdateShowEntities();
}
public Entity GetEntity(ulong guid)
{
Scene scene = scenes.Find(s => s.sceneNumId == player.curSceneNumId);
Entity en = globalEntities.Find(e => e.guid == guid);
if (en != null)
{
return en;
}
if (scene != null)
{
return scene.entities.Find(e => e.guid == guid);
}
return null;
}
public void LoadCurrentTeamEntities()
{
globalEntities.RemoveAll(e => e is EntityCharacter);
foreach (Character.Character chara in player.GetCurTeam())
{
EntityCharacter ch = new(chara.guid, player.roleId);
globalEntities.Add(ch);
}
}
public void LoadCurrent()
{
Scene curscene = GetCurScene();
string sceneConfigPath = curscene.info().defaultState.exportedSceneConfigPath;
foreach(Scene scene in scenes.FindAll(s => s.info().defaultState.exportedSceneConfigPath == sceneConfigPath))
{
if (scene != null)
{
scene.Load();
}
}
}
public Scene GetScene(int sceneId)
{
return scenes.Find(s=>s.sceneNumId==sceneId);
}
public Scene GetCurScene()
{
return scenes.Find(s => s.sceneNumId == player.curSceneNumId);
}
public void SpawnEntity(Entity entity)
{
Scene scene = GetCurScene();
if (scene != null)
{
scene.entities.Add(entity);
//Spawn packet
player.Send(new PacketScObjectEnterView(player,new List<Entity>{ entity }));
}
}
public void KillEntity(ulong guid, bool killClient=false, int reason=1)
{
Scene scene = GetCurScene();
if (scene != null)
{
if(GetEntity(guid) is EntityMonster)
{
EntityMonster monster = (EntityMonster)GetEntity(guid);
CreateDrop(monster.Position, new RewardTable.ItemBundle()
{
id = "item_gem_rarity_3",
count=1
});
LevelScene lv_scene = ResourceManager.GetLevelData(GetEntity(guid).sceneNumId);
LevelEnemyData d = lv_scene.levelData.enemies.Find(l => l.levelLogicId == monster.guid);
if (d != null)
{
if (!d.respawnable)
{
player.noSpawnAnymore.Add(monster.guid);
}
}
}
if (killClient)
{
ScSceneDestroyEntity destroy = new()
{
Id = guid,
Reason = reason,
SceneNumId = GetEntity(guid).sceneNumId,
};
player.Send(Protocol.ScMsgId.ScSceneDestroyEntity, destroy);
}
if (GetEntity(guid) != null)
{
if(scenes.Find(s => s.sceneNumId == GetEntity(guid).sceneNumId) != null)
{
scenes.Find(s => s.sceneNumId == GetEntity(guid).sceneNumId).entities.Remove(GetEntity(guid));
}
}
}
}
public void CreateDrop(Vector3f pos,ResourceManager.RewardTable.ItemBundle bundle)
{
ItemTable info = ResourceManager.itemTable[bundle.id];
Item item = new Item(player.roleId, info.id, bundle.count);
EntityInteractive drop = new(info.modelKey, player.roleId, pos, new Vector3f(), GetCurScene().sceneNumId)
{
type = (ObjectType)5,
curHp = 100,
properties =
{
new ParamKeyValue()
{
key="is_collected",
value = new()
{
type=ParamRealType.Bool,
valueArray=new ParamKeyValue.ParamValueAtom[1]
{
new ParamKeyValue.ParamValueAtom()
{
}
}
}
},
new ParamKeyValue()
{
key="item_id",
value = new()
{
type=ParamRealType.String,
valueArray=new ParamKeyValue.ParamValueAtom[1]
{
new ParamKeyValue.ParamValueAtom()
{
valueString=info.id,
}
}
}
},
}
};
drop.properties.Add(new ParamKeyValue()
{
key = "count",
value = new()
{
type = ParamRealType.Int,
valueArray = new ParamKeyValue.ParamValueAtom[1]
{
new ParamKeyValue.ParamValueAtom()
{
valueBit64=bundle.count
}
}
}
});
if (item.InstanceType())
{
drop.properties.Add(new ParamKeyValue()
{
key = "item_inst",
value = new()
{
type = ParamRealType.String,
valueArray = new ParamKeyValue.ParamValueAtom[1]
{
new ParamKeyValue.ParamValueAtom()
{
valueString=Newtonsoft.Json.JsonConvert.SerializeObject(item.ToProto().Inst)
}
}
}
});
}
SpawnEntity(drop);
}
public ulong GetSceneGuid(int sceneNumId)
{
return scenes.Find(s=>s.sceneNumId == sceneNumId).guid;
}
public void Load()
{
foreach (var level in ResourceManager.levelDatas)
{
if(scenes.Find(s=>s.sceneNumId==level.idNum) == null)
scenes.Add(new Scene()
{
guid = (ulong)player.random.Next(),
ownerId=player.roleId,
sceneNumId=level.idNum,
});
}
}
public void UnloadAllByConfigPath(string sceneConfigPath)
{
foreach (Scene scene in scenes.FindAll(s => s.info().defaultState.exportedSceneConfigPath == sceneConfigPath))
{
if (scene != null)
{
scene.alreadyLoaded = false;
scene.Unload();
}
}
}
}
public class Scene
{
public ulong ownerId;
public ulong guid;
public int sceneNumId;
public Dictionary<string, int> collections = new();
[BsonIgnore,JsonIgnore]
public List<Entity> entities = new();
[BsonIgnore, JsonIgnore]
public bool alreadyLoaded = false;
[BsonIgnore, JsonIgnore]
public List<ulong> activeScripts = new();
public int GetCollection(string id)
{
if (collections.ContainsKey(id))
{
return collections[id];
}
return 0;
}
public void AddCollection(string id,int amt)
{
if (collections.ContainsKey(id))
{
collections[id] += amt;
}
else
{
collections.Add(id, amt);
}
}
public List<Entity> GetEntityExcludingChar()
{
return entities.FindAll(c => c is not EntityCharacter);
}
public void Unload()
{
List<ulong> guids = new();
foreach(Entity e in entities)
{
guids.Add(e.guid);
}
entities.Clear();
GetOwner().Send(new PacketScObjectLeaveView(GetOwner(), guids));
}
public LevelScene info()
{
return levelDatas.Find(l => l.idNum == sceneNumId);
}
public void Load()
{
if (info().isSeamless && alreadyLoaded) return;
alreadyLoaded = true;
Unload();
LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId);
lv_scene.levelData.interactives.ForEach(en =>
{
if (GetOwner().noSpawnAnymore.Contains(en.levelLogicId) && sceneNumId != 87)
{
return;
}
EntityInteractive entity = new(en.entityDataIdKey, ownerId, en.position, en.rotation, sceneNumId, en.levelLogicId)
{
belongLevelScriptId=en.belongLevelScriptId,
dependencyGroupId=en.dependencyGroupId,
levelLogicId= en.levelLogicId,
type = en.entityType,
properties= en.properties,
componentProperties=en.componentProperties,
};
entities.Add(entity);
});
lv_scene.levelData.factoryRegions.ForEach(en =>
{
if (GetOwner().noSpawnAnymore.Contains(en.levelLogicId) && sceneNumId!=87)
{
return;
}
EntityInteractive entity = new(en.entityDataIdKey, ownerId, en.position, en.rotation, sceneNumId, en.levelLogicId)
{
belongLevelScriptId = en.belongLevelScriptId,
dependencyGroupId = 0,
levelLogicId = en.levelLogicId,
type = en.entityType,
};
entities.Add(entity);
});
lv_scene.levelData.enemies.ForEach(en =>
{
if(GetOwner().noSpawnAnymore.Contains(en.levelLogicId) && sceneNumId != 87) return;
EntityMonster entity = new(en.entityDataIdKey,en.level,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId)
{
type=en.entityType,
belongLevelScriptId=en.belongLevelScriptId,
levelLogicId = en.levelLogicId,
};
entities.Add(entity);
});
lv_scene.levelData.npcs.ForEach(en =>
{
if (en.npcGroupId.Contains("chr") && sceneNumId== 99) return;
EntityNpc entity = new(en.entityDataIdKey,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId)
{
belongLevelScriptId = en.belongLevelScriptId,
levelLogicId = en.levelLogicId,
type = en.entityType,
};
entities.Add(entity);
});
GetEntityExcludingChar().ForEach(e =>
{
if(e is EntityInteractive)
{
// e.spawned = true;
// GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List<Entity>() { e }));
}
});
GetEntityExcludingChar().FindAll(e=> e is not EntityInteractive).ForEach(e =>
{
// e.spawned = true;
// GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List<Entity>() { e }));
});
UpdateShowEntities();
}
public void SpawnEntity(Entity en,bool spawnedCheck=true)
{
if (!activeScripts.Contains(en.belongLevelScriptId) && en.defaultHide && en.belongLevelScriptId != 0)
{
return;
}
en.spawned = true;
ParamKeyValue targetList=en.properties.Find(p => p.key == "target_list");
if(targetList!=null)
foreach (Entity e in GetEntityExcludingChar().FindAll(e=>e.spawned == false && targetList.value.valueArray.Any(v=>v.valueBit64== (long)e.levelLogicId)))
{
SpawnEntity(e);
}
GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List<Entity>() { en}));
}
public void UpdateShowEntities()
{
foreach(Entity en in GetEntityExcludingChar())
{
float minDis = 100;
//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()
{
return Server.clients.Find(c => c.roleId == ownerId);
}
public void SpawnEnemy(ulong v)
{
LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId);
LevelEnemyData en = lv_scene.levelData.enemies.Find(e=>e.levelLogicId == v);
if(en!=null)
{
EntityMonster entity = new(en.entityDataIdKey, en.level, ownerId, en.position, en.rotation, sceneNumId, en.levelLogicId)
{
type = en.entityType,
belongLevelScriptId = en.belongLevelScriptId,
levelLogicId = en.levelLogicId
};
entities.Add(entity);
SpawnEntity(entity);
}
}
}
}