mirror of
https://git.muiegratis.online/suikoakari/Campofinale
synced 2025-12-12 09:34:34 +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 string templateId;
|
||||
public ulong originId;
|
||||
public EntityMonster()
|
||||
{
|
||||
|
||||
@@ -83,7 +84,7 @@ namespace Campofinale.Game.Entities
|
||||
|
||||
Type =(int) ObjectTypeIndex.Enemy,
|
||||
},
|
||||
|
||||
OriginId= originId,
|
||||
Attrs =
|
||||
{
|
||||
GetAttributes()
|
||||
|
||||
@@ -3,10 +3,14 @@ using Campofinale.Game.Inventory;
|
||||
using Campofinale.Game.Spawners;
|
||||
using Campofinale.Packets.Sc;
|
||||
using Campofinale.Resource;
|
||||
using Campofinale.Resource.Dynamic;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using System.Numerics;
|
||||
using System.Text.Json.Serialization;
|
||||
using static Campofinale.Resource.Dynamic.SpawnerConfig;
|
||||
using static Campofinale.Resource.ResourceManager;
|
||||
using static Campofinale.Resource.ResourceManager.LevelScene.LevelData;
|
||||
using static System.Formats.Asn1.AsnWriter;
|
||||
|
||||
namespace Campofinale.Game
|
||||
{
|
||||
@@ -256,8 +260,6 @@ namespace Campofinale.Game
|
||||
public bool alreadyLoaded = false;
|
||||
[BsonIgnore, JsonIgnore]
|
||||
public List<ulong> activeScripts = new();
|
||||
[BsonIgnore, JsonIgnore]
|
||||
public List<GameSpawner> gameSpawners = new();
|
||||
public int GetCollection(string id)
|
||||
{
|
||||
if (collections.ContainsKey(id))
|
||||
@@ -354,7 +356,7 @@ namespace Campofinale.Game
|
||||
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)
|
||||
{
|
||||
belongLevelScriptId = en.belongLevelScriptId,
|
||||
@@ -365,22 +367,7 @@ namespace Campofinale.Game
|
||||
entity.defaultHide = en.defaultHide;
|
||||
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();
|
||||
|
||||
@@ -389,31 +376,13 @@ namespace Campofinale.Game
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
en.spawned = true;
|
||||
|
||||
GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List<Entity>() { en }));
|
||||
}
|
||||
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();
|
||||
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,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ namespace Campofinale.Packets.Cs
|
||||
|
||||
State = 4
|
||||
};
|
||||
|
||||
|
||||
session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp);
|
||||
}
|
||||
|
||||
@@ -122,11 +122,13 @@ namespace Campofinale.Packets.Cs
|
||||
break;
|
||||
case ScriptActionType.StartSpawner:
|
||||
|
||||
player.sceneManager.GetCurScene().gameSpawners.Add(new Game.Spawners.GameSpawner()
|
||||
ScSceneMonsterSpawnerStart start = new()
|
||||
{
|
||||
configId = action.valueStr[0],
|
||||
scene= player.sceneManager.GetCurScene()
|
||||
});
|
||||
SceneNumId = player.curSceneNumId,
|
||||
SpawnerId = action.valueUlong[0],
|
||||
|
||||
};
|
||||
player.Send(ScMsgId.ScSceneMonsterSpawnerStart,start);
|
||||
break;
|
||||
case ScriptActionType.AddCharacter:
|
||||
Character chara =player.AddCharacter(action.valueStr[0],(int) action.valueUlong[0],true);
|
||||
|
||||
@@ -12,11 +12,17 @@ namespace Campofinale.Resource.Dynamic
|
||||
{
|
||||
public string configId;
|
||||
public Dictionary<string, SpawnerWave> waveMap = new();
|
||||
public List<EnemyLibraryData> enemyLibrary = new();
|
||||
|
||||
|
||||
|
||||
|
||||
public SpawnerConfig() { }
|
||||
public class EnemyLibraryData
|
||||
{
|
||||
public string key;
|
||||
public string enemyId;
|
||||
public int enemyLevel;
|
||||
|
||||
}
|
||||
public class SpawnerWave
|
||||
{
|
||||
public int waveId;
|
||||
|
||||
@@ -534,6 +534,7 @@ namespace Campofinale.Resource
|
||||
public List<LevelScriptData> levelScripts = new();
|
||||
public List<WorldWayPointSets> worldWayPointSets = new();
|
||||
public List<LevelFactoryRegionData> factoryRegions = new();
|
||||
public List<LevelSpawnerData> spawners = new();
|
||||
public void Merge(LevelData other)
|
||||
{
|
||||
this.sceneId = other.sceneId;
|
||||
@@ -544,6 +545,7 @@ namespace Campofinale.Resource
|
||||
this.levelScripts.AddRange(other.levelScripts);
|
||||
this.worldWayPointSets.AddRange(other.worldWayPointSets);
|
||||
this.factoryRegions.AddRange(other.factoryRegions);
|
||||
this.spawners.AddRange(other.spawners);
|
||||
}
|
||||
|
||||
public class WorldWayPointSets
|
||||
@@ -551,6 +553,12 @@ namespace Campofinale.Resource
|
||||
public int id;
|
||||
public Dictionary<string, int> pointIdToIndex = new();
|
||||
}
|
||||
public class LevelSpawnerData
|
||||
{
|
||||
public ulong spawnerId;
|
||||
public string configId;
|
||||
public ulong belongLevelScriptId;
|
||||
}
|
||||
public class LevelScriptData
|
||||
{
|
||||
public ulong scriptId;
|
||||
|
||||
Reference in New Issue
Block a user