mirror of
https://git.muiegratis.online/suikoakari/Campofinale
synced 2025-12-13 10:04:34 +01:00
453 lines
15 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|