mirror of
https://git.muiegratis.online/suikoakari/Campofinale
synced 2025-12-12 17:44:37 +01:00
spawners, todo: saving levelscript states and properties
This commit is contained in:
@@ -7,6 +7,7 @@ namespace Campofinale.Game.Entities
|
|||||||
public class EntityMonster : Entity
|
public class EntityMonster : Entity
|
||||||
{
|
{
|
||||||
public string templateId;
|
public string templateId;
|
||||||
|
public ulong originId;
|
||||||
public EntityMonster()
|
public EntityMonster()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -83,7 +84,7 @@ namespace Campofinale.Game.Entities
|
|||||||
|
|
||||||
Type =(int) ObjectTypeIndex.Enemy,
|
Type =(int) ObjectTypeIndex.Enemy,
|
||||||
},
|
},
|
||||||
|
OriginId= originId,
|
||||||
Attrs =
|
Attrs =
|
||||||
{
|
{
|
||||||
GetAttributes()
|
GetAttributes()
|
||||||
|
|||||||
@@ -3,10 +3,14 @@ using Campofinale.Game.Inventory;
|
|||||||
using Campofinale.Game.Spawners;
|
using Campofinale.Game.Spawners;
|
||||||
using Campofinale.Packets.Sc;
|
using Campofinale.Packets.Sc;
|
||||||
using Campofinale.Resource;
|
using Campofinale.Resource;
|
||||||
|
using Campofinale.Resource.Dynamic;
|
||||||
using MongoDB.Bson.Serialization.Attributes;
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using System.Numerics;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
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 System.Formats.Asn1.AsnWriter;
|
||||||
|
|
||||||
namespace Campofinale.Game
|
namespace Campofinale.Game
|
||||||
{
|
{
|
||||||
@@ -256,8 +260,6 @@ namespace Campofinale.Game
|
|||||||
public bool alreadyLoaded = false;
|
public bool alreadyLoaded = false;
|
||||||
[BsonIgnore, JsonIgnore]
|
[BsonIgnore, JsonIgnore]
|
||||||
public List<ulong> activeScripts = new();
|
public List<ulong> activeScripts = new();
|
||||||
[BsonIgnore, JsonIgnore]
|
|
||||||
public List<GameSpawner> gameSpawners = new();
|
|
||||||
public int GetCollection(string id)
|
public int GetCollection(string id)
|
||||||
{
|
{
|
||||||
if (collections.ContainsKey(id))
|
if (collections.ContainsKey(id))
|
||||||
@@ -354,7 +356,7 @@ namespace Campofinale.Game
|
|||||||
lv_scene.levelData.npcs.ForEach(en =>
|
lv_scene.levelData.npcs.ForEach(en =>
|
||||||
{
|
{
|
||||||
|
|
||||||
if (en.npcGroupId.Contains("chr") && sceneNumId== 99) return;
|
if (en.npcGroupId.Contains("chr")) return;
|
||||||
EntityNpc entity = new(en.entityDataIdKey,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId)
|
EntityNpc entity = new(en.entityDataIdKey,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId)
|
||||||
{
|
{
|
||||||
belongLevelScriptId = en.belongLevelScriptId,
|
belongLevelScriptId = en.belongLevelScriptId,
|
||||||
@@ -365,23 +367,8 @@ namespace Campofinale.Game
|
|||||||
entity.defaultHide = en.defaultHide;
|
entity.defaultHide = en.defaultHide;
|
||||||
entities.Add(entity);
|
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();
|
UpdateShowEntities();
|
||||||
|
|
||||||
|
|
||||||
@@ -389,31 +376,13 @@ namespace Campofinale.Game
|
|||||||
|
|
||||||
public void SpawnEntity(Entity en,bool spawnedCheck=true)
|
public void SpawnEntity(Entity en,bool spawnedCheck=true)
|
||||||
{
|
{
|
||||||
if (!activeScripts.Contains(en.belongLevelScriptId) && en.defaultHide && en.belongLevelScriptId != 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
en.spawned = true;
|
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 }));
|
GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List<Entity>() { en }));
|
||||||
}
|
}
|
||||||
public void UpdateShowEntities()
|
public void UpdateShowEntities()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < gameSpawners.Count; i++)
|
|
||||||
{
|
|
||||||
GameSpawner spawner = gameSpawners[i];
|
|
||||||
if(spawner != null)
|
|
||||||
{
|
|
||||||
spawner.Update(GetOwner());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Entity> toSpawn = new();
|
List<Entity> toSpawn = new();
|
||||||
foreach(Entity e in GetEntityExcludingChar())
|
foreach(Entity e in GetEntityExcludingChar())
|
||||||
{
|
{
|
||||||
@@ -489,6 +458,34 @@ namespace Campofinale.Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SpawnWaveEnemy(ulong spawnerId, int waveId)
|
||||||
|
{
|
||||||
|
LevelSpawnerData data=info().levelData.spawners.Find(s => s.spawnerId == spawnerId);
|
||||||
|
if (data!=null)
|
||||||
|
{
|
||||||
|
SpawnerConfig config = spawnerConfigs.Find(s => s.configId == data.configId);
|
||||||
|
if (config != null)
|
||||||
|
{
|
||||||
|
foreach(var group in config.waveMap[$"{waveId}"].groupMap.Values)
|
||||||
|
{
|
||||||
|
foreach (var act in group.actionMap.Values)
|
||||||
|
{
|
||||||
|
EnemyLibraryData enemyData = config.enemyLibrary.Find(e=>e.key==act.libraryKey);
|
||||||
|
if (enemyData != null)
|
||||||
|
{
|
||||||
|
entities.Add(new EntityMonster(enemyData.enemyId, enemyData.enemyLevel, ownerId, act.position, act.rotation, sceneNumId)
|
||||||
|
{
|
||||||
|
|
||||||
|
defaultHide = false,
|
||||||
|
spawned = false,
|
||||||
|
belongLevelScriptId = data.belongLevelScriptId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
using Campofinale.Game.Entities;
|
|
||||||
using Campofinale.Resource;
|
|
||||||
using Campofinale.Resource.Dynamic;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Campofinale.Game.Spawners
|
|
||||||
{
|
|
||||||
public class GameSpawner
|
|
||||||
{
|
|
||||||
public Scene scene;
|
|
||||||
public int curWave = 1;
|
|
||||||
public int curGroup = 1;
|
|
||||||
public string configId;
|
|
||||||
public bool spawned;
|
|
||||||
|
|
||||||
public SpawnerConfig GetConfig()
|
|
||||||
{
|
|
||||||
return ResourceManager.spawnerConfigs.Find(s => s.configId == configId);
|
|
||||||
}
|
|
||||||
public SpawnerConfig.WaveGroup GetCurrentWaveGroup()
|
|
||||||
{
|
|
||||||
return GetConfig().waveMap[$"{curWave}"].groupMap[$"{curGroup}"];
|
|
||||||
}
|
|
||||||
public int GetEnemiesOfCurrentWave()
|
|
||||||
{
|
|
||||||
return scene.entities.FindAll(e => e.dependencyGroupId == GetCurrentWaveGroup().groupId).Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update(Player player)
|
|
||||||
{
|
|
||||||
if (spawned)
|
|
||||||
{
|
|
||||||
if (GetEnemiesOfCurrentWave() < 1)
|
|
||||||
{
|
|
||||||
if (GetConfig().waveMap.ContainsKey($"{curWave + 1}"))
|
|
||||||
{
|
|
||||||
curWave++;
|
|
||||||
spawned = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
foreach (var item in GetCurrentWaveGroup().actionMap.Values)
|
|
||||||
{
|
|
||||||
Logger.Print($"Debug: Spawning {item.libraryKey}");
|
|
||||||
scene.entities.Add(new EntityMonster(item.libraryKey, 1, player.roleId, item.position, item.rotation, scene.sceneNumId)
|
|
||||||
{
|
|
||||||
dependencyGroupId = GetCurrentWaveGroup().groupId,
|
|
||||||
defaultHide = false,
|
|
||||||
spawned = false
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
spawned = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsSceneMonsterSpawnerBeginWave
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsSceneMonsterSpawnerBeginWave)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsSceneMonsterSpawnerBeginWave req = packet.DecodeBody<CsSceneMonsterSpawnerBeginWave>();
|
||||||
|
session.sceneManager.GetCurScene().SpawnWaveEnemy(req.SpawnerId, req.WaveId);
|
||||||
|
session.Send(ScMsgId.ScSceneMonsterSpawnerBeginWave, new ScSceneMonsterSpawnerBeginWave()
|
||||||
|
{
|
||||||
|
SceneNumId=req.SceneNumId,
|
||||||
|
SpawnerId=req.SpawnerId,
|
||||||
|
WaveId=req.WaveId,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -122,11 +122,13 @@ namespace Campofinale.Packets.Cs
|
|||||||
break;
|
break;
|
||||||
case ScriptActionType.StartSpawner:
|
case ScriptActionType.StartSpawner:
|
||||||
|
|
||||||
player.sceneManager.GetCurScene().gameSpawners.Add(new Game.Spawners.GameSpawner()
|
ScSceneMonsterSpawnerStart start = new()
|
||||||
{
|
{
|
||||||
configId = action.valueStr[0],
|
SceneNumId = player.curSceneNumId,
|
||||||
scene= player.sceneManager.GetCurScene()
|
SpawnerId = action.valueUlong[0],
|
||||||
});
|
|
||||||
|
};
|
||||||
|
player.Send(ScMsgId.ScSceneMonsterSpawnerStart,start);
|
||||||
break;
|
break;
|
||||||
case ScriptActionType.AddCharacter:
|
case ScriptActionType.AddCharacter:
|
||||||
Character chara =player.AddCharacter(action.valueStr[0],(int) action.valueUlong[0],true);
|
Character chara =player.AddCharacter(action.valueStr[0],(int) action.valueUlong[0],true);
|
||||||
|
|||||||
@@ -12,11 +12,17 @@ namespace Campofinale.Resource.Dynamic
|
|||||||
{
|
{
|
||||||
public string configId;
|
public string configId;
|
||||||
public Dictionary<string, SpawnerWave> waveMap = new();
|
public Dictionary<string, SpawnerWave> waveMap = new();
|
||||||
|
public List<EnemyLibraryData> enemyLibrary = new();
|
||||||
|
|
||||||
|
|
||||||
public SpawnerConfig() { }
|
public SpawnerConfig() { }
|
||||||
|
public class EnemyLibraryData
|
||||||
|
{
|
||||||
|
public string key;
|
||||||
|
public string enemyId;
|
||||||
|
public int enemyLevel;
|
||||||
|
|
||||||
|
}
|
||||||
public class SpawnerWave
|
public class SpawnerWave
|
||||||
{
|
{
|
||||||
public int waveId;
|
public int waveId;
|
||||||
|
|||||||
@@ -534,6 +534,7 @@ namespace Campofinale.Resource
|
|||||||
public List<LevelScriptData> levelScripts = new();
|
public List<LevelScriptData> levelScripts = new();
|
||||||
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 void Merge(LevelData other)
|
public void Merge(LevelData other)
|
||||||
{
|
{
|
||||||
this.sceneId = other.sceneId;
|
this.sceneId = other.sceneId;
|
||||||
@@ -544,6 +545,7 @@ namespace Campofinale.Resource
|
|||||||
this.levelScripts.AddRange(other.levelScripts);
|
this.levelScripts.AddRange(other.levelScripts);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WorldWayPointSets
|
public class WorldWayPointSets
|
||||||
@@ -551,6 +553,12 @@ namespace Campofinale.Resource
|
|||||||
public int id;
|
public int id;
|
||||||
public Dictionary<string, int> pointIdToIndex = new();
|
public Dictionary<string, int> pointIdToIndex = new();
|
||||||
}
|
}
|
||||||
|
public class LevelSpawnerData
|
||||||
|
{
|
||||||
|
public ulong spawnerId;
|
||||||
|
public string configId;
|
||||||
|
public ulong belongLevelScriptId;
|
||||||
|
}
|
||||||
public class LevelScriptData
|
public class LevelScriptData
|
||||||
{
|
{
|
||||||
public ulong scriptId;
|
public ulong scriptId;
|
||||||
|
|||||||
Reference in New Issue
Block a user