2
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
8.4 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Collections.Generic;
using Game;
using UnityEngine;
using Articy.Touhou.Features;
using Ludiq;
public class LevelPoolItem : ObjectPoolItemBase
{
public string CfgId;
public LevelFeature Cfg;
public LevelNodeMonsterWave CurWave; //当前波次配置
private GameObject _gameObject;
private Vector3 _playerBorn = GameConst.NoneDir; //玩家出生点
private int _waveMax = 0; //最大波数
private int _waveNow = 0; //当前波数
private int _monsterCount = 0; //场景内怪物数
private readonly List<LevelNode> _levelData = new List<LevelNode>();
private readonly List<LevelNodeDoor> _doorList = new List<LevelNodeDoor>();
private readonly List<LevelNodePlayerBorn> _playerBornList = new List<LevelNodePlayerBorn>();
private readonly List<int> _interactList = new List<int>(); //通关后打开的交互物
private readonly List<Material> _wallMaterialList = new List<Material>();
private static readonly int WorldPos = Shader.PropertyToID("_WorldPos");
protected override void OnCreate()
{
base.OnCreate();
_gameObject.SetActive(true);
EventManager.Instance.AddEvent<PEntityAlive>(EEvent.EntityAlive, OnEntityAlive);
}
protected override void OnDestroy()
{
EventManager.Instance.RemoveEvent<PEntityAlive>(EEvent.EntityAlive, OnEntityAlive);
base.OnDestroy();
DestroyLevel();
_gameObject.SetActive(false);
}
protected override void OnCreateBind()
{
var master = Util.GetMaster();
BindData(master.view.PosView, ((pre, now) =>
{
foreach (var item in _wallMaterialList)
{
item.SetVector(WorldPos, now);
}
}));
}
public void Init()
{
//关卡配置解析
var prefabPath = Cfg.Prefab;
//关卡go创建
_gameObject = LevelPoolManager.Instance.CreateLevelGo(prefabPath);
//位置分布
var nodes = _gameObject.GetComponentsInChildren<LevelNode>();
foreach (var item in nodes)
{
item.SetPos(item.transform.position);
item.OnInit();
switch (item)
{
case LevelNodePlayerBorn born:
_playerBornList.Add(born);
continue;
case LevelNodeMonster itemLevelNodeMonster:
var monsterId = Cfg.MonsterList[itemLevelNodeMonster.monsterIndex].TechnicalName;
itemLevelNodeMonster.SetCfgId(monsterId);
continue;
case LevelNodeMonsterWave itemLevelNodeMonsterWave:
if (itemLevelNodeMonsterWave.transform.childCount == 0)
continue;
itemLevelNodeMonsterWave.SetWaveIndex(_waveMax);
_waveMax++;
break;
case LevelNodeDoor door:
door.SetCfgId(Cfg.Door.TechnicalName);
door.SetTargetLevel(Cfg);
_doorList.Add(door);
break;
case LevelNodeNpc npc:
npc.SetCfgId(npc.npcId);
npc.SetTargetId(npc.dialogId);
break;
}
_levelData.Add(item);
}
//开启阴影
var sprites = _gameObject.GetComponentsInChildren<SpriteRenderer>();
foreach (var item in sprites)
{
item.receiveShadows = false;
item.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
}
//墙壁
var levelRect = new Vector2(Cfg.LevelSizeX, Cfg.LevelSizeY) * 12.81f;
var walls = _gameObject.GetComponentsInChildren<LevelMarkAirWall>();
foreach (var item in walls)
{
if (!item.TryGetComponent<MeshRenderer>(out var meshRenderer)) continue;
var material = meshRenderer.material;
var mainTexture = (Texture2D)material.mainTexture;
var textureSize = mainTexture.Size() / 64f;
_wallMaterialList.Add(material);
if (item.transform.localScale.z > 1f)
{
//竖向墙
material.mainTextureScale = new Vector2(levelRect.x / textureSize.x, 20 / textureSize.y) * 2;
}
else
{
//横向墙
material.mainTextureScale = new Vector2(levelRect.y / textureSize.x, 20 / textureSize.y) * 2;
}
}
}
public void SetPlayerBorn(string preLevelId)
{
//出生点选取规则优先选择关卡连接关系对应否则从playerBorn中随机
_playerBorn = GameConst.NoneDir;
if (!string.IsNullOrEmpty(preLevelId))
{
foreach (var item in _doorList)
{
if (item.IsFromPreLevel(preLevelId))
{
_playerBorn = item.GetPos();
return;
}
}
}
if (_playerBornList.Count > 0)
{
_playerBorn = GameRandom.Pick(_playerBornList).GetPos();
return;
}
Util.Print("关卡配置错误,没有出生点");
}
public void CreateLevel()
{
Util.GetMaster().SetFixedPos(_playerBorn);
foreach (var item in _levelData)
{
if (item is LevelNodeMonsterWave)
{
continue; //进入关卡时不刷怪
}
Util.CreateEntity(item.GetCfgId(), (entity) =>
{
entity.SetPos(item.GetPos());
if (item is LevelNodeDoor)
{
entity.interact.TargetId = item.GetTargetId();
entity.interact.IsActive.Value = _waveMax == 0;
_interactList.Add(entity.ID());
}
if (item is LevelNodeNpc)
{
entity.interact.TargetId = item.GetTargetId();
}
});
}
NextWave();
}
private void NextWave()
{
_monsterCount = 0;
var isOk = false;
if (_waveNow > _waveMax)
{
Util.Print("通关");
//通关
foreach (var interact in _interactList)
{
var entity = Util.GetEntity(interact);
if (entity != null)
{
entity.interact.IsActive.Value = true;
}
}
isOk = true;
//TODO
}
else
{
foreach (var item in _levelData)
{
if (!(item is LevelNodeMonsterWave itemLevelNodeMonsterWave)) continue;
if (itemLevelNodeMonsterWave.GetWaveIndex() != _waveNow) continue;
foreach (var monster in itemLevelNodeMonsterWave.GetMonsters())
{
Util.CreateEntity(monster.GetCfgId(), (entity) => { entity.SetPos(monster.GetPos()); });
}
isOk = true;
CurWave = itemLevelNodeMonsterWave;
break;
}
if (isOk)
{
Util.Print("创建怪物实体 波数:", _waveNow);
}
}
_waveNow++;
if (!isOk)
{
NextWave();
}
}
private void DestroyLevel()
{
//TODO 销毁实体、特效等
var entities = Util.GetGroup(GameMatcher.ID);
foreach (var item in entities)
{
if (item.IsMaster() || item.IsMasterSoul())
{
continue;
}
item.OnDie();
item.iD.Data.IsDestroy = true;
}
//销毁残影和尸体
Util.DestroyCastShadowAll();
_waveNow = 0;
CurWave = null;
_interactList.Clear();
}
private void OnEntityAlive(PEntityAlive param)
{
var entity = param.Entity;
if (entity == Util.GetMasterID())
{
return;
}
_monsterCount += (param.IsAlive ? 1 : -1);
if (_monsterCount == 0)
{
NextWave();
}
}
}