This commit is contained in:
daixiawu 2025-07-02 01:17:02 +08:00
commit df80c8b3cb
36 changed files with 497 additions and 225 deletions

View File

@ -9,6 +9,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using Logic;
using Logic.Action;
using Logic.AI;
using UnityEditor.Experimental.GraphView;
@ -897,21 +898,12 @@ namespace RuntimeData
}
}
// 当场上有小兵攻击时
public void OnUnitAttack(UnitData origin, UnitData target)
{
foreach (var idBase in GetAllIdentifierBase())
{
foreach (var skill in idBase.Skills) skill.OnUnitAttack(idBase, origin, target, this);
}
}
// 当场上有小兵受伤时
public void OnUnitDamage(UnitData origin, UnitData target)
public void OnUnitDamaged(SettlementInfo info)
{
foreach (var idBase in GetAllIdentifierBase())
{
foreach (var skill in idBase.Skills) skill.OnUnitDamage(idBase, origin, target, this);
foreach (var skill in idBase.Skills) skill.OnUnitDamaged(idBase, this, info);
}
}

View File

@ -452,6 +452,16 @@ namespace RuntimeData
}
return false;
}
// 是否可以被伤害结算
public bool CanBeDamaged(MapData map, int dmg)
{
foreach (var skill in Skills)
{
if (skill.IsCanBeDamaged(this, map, dmg)) return true;
}
return false;
}
// 是否经验锁定
public bool IsExpLock(MapData map)
@ -524,23 +534,6 @@ namespace RuntimeData
foreach (var skill in Skills)
skill.OnMove(this, target, map,moveType);
}
public void BeforeAttack(MapData map,UnitData target)
{
foreach (var skill in Skills)
skill.BeforeAttack(this,target,map);
}
public void OnAttack(MapData map,UnitData target,int dmg)
{
foreach (var skill in Skills)
skill.OnAttack(this,target,map,dmg);
}
public void OnKill(UnitData target ,MapData map)
{
foreach (var skill in Skills)
skill.OnKill(this, target, map);
}
}
}

View File

@ -2032,13 +2032,13 @@ namespace Logic.Action
if (dis == 1)
{
//var damage = Table.Instance.CalcDamage(actionParams.MapData, unitA, unitB);
Main.UnitLogic.SpecialDamage(actionParams.MapData,unitA, unitB,6);
Main.UnitLogic.DamageSettlement(actionParams.MapData,unitA, unitB,6, DamageType.Splash);
}
//处理外圈伤害
if (dis == 2)
{
//var damage = Table.Instance.CalcDamage(actionParams.MapData, unitA, unitB,damagePara:0.5f);
Main.UnitLogic.SpecialDamage(actionParams.MapData,unitA, unitB,3);
Main.UnitLogic.DamageSettlement(actionParams.MapData,unitA, unitB,3, DamageType.Splash);
}
}
else

View File

@ -7,11 +7,12 @@
using System;
using Logic.Audio;
using Logic.Multilingual;
using NodeCanvas.BehaviourTrees;
using Logic.Timeline;
using UnityEngine;
using RuntimeData;
using TH1Renderer;
namespace Logic
{
public class Main : MonoBehaviour
@ -156,6 +157,7 @@ namespace Logic
UIManager.Update(MapData);
Timer.Instance.Update();
AudioManager.Instance.Update();
TimelineManager.Instance.Update();
}
public bool HasArchive()

View File

@ -28,23 +28,26 @@ namespace Logic.Skill
return SkillType.ALLYCOUNTER;
}
public override void OnUnitAttack(IdentifierBase identifier, UnitData origin, UnitData target, MapData mapData)
public override void OnEvent(IdentifierBase identifier, SkillDamageEvent skillEvent, MapData mapData, SettlementInfo info)
{
if (skillEvent != SkillDamageEvent.ActiveAttackFinished) return;
if (info == null) return;
if (info.DamageType != DamageType.ActiveAttack) return;
if (info.DamageOrigin == null || info.DamageTarget == null) return;
if (identifier is not UnitData self) return;
if (!mapData.GetGridDataByUnitId(self.Id, out var selfGrid)) return;
var selfUnitList = new HashSet<UnitData>();
mapData.GetUnitDataListByPlayerId(mapData.PlayerMap.SelfPlayerId, selfUnitList);
if (selfUnitList.Contains(origin)) return;
if (!selfUnitList.Contains(target)) return;
if (selfUnitList.Contains(info.DamageOrigin)) return;
if (!selfUnitList.Contains(info.DamageTarget)) return;
if (!mapData.GetGridDataByUnitId(origin.Id, out var originGrid)) return;
if (!mapData.GetGridDataByUnitId(target.Id, out var targetGrid)) return;
if (!mapData.GetGridDataByUnitId(info.DamageOrigin.Id, out var originGrid)) return;
if (!mapData.GetGridDataByUnitId(info.DamageTarget.Id, out var targetGrid)) return;
var roundGrids = mapData.GridMap.GetAroundGridDataSet(2, 2, selfGrid);
if (!roundGrids.Contains(originGrid) || !roundGrids.Contains(targetGrid)) return;
if (Main.UnitLogic.TryKillUnit(mapData, self, self, 3)) return;
Main.UnitLogic.TryDamageUnit(mapData, self, self, 3);
Main.UnitLogic.DamageSettlement(mapData, self, self, 3, DamageType.FollowAttack);
}
}
}

View File

@ -28,21 +28,25 @@ namespace Logic.Skill
}
// 攻击一名单位后,将该单位变成己方单位
public override void OnAttack(UnitData self, UnitData target, MapData mapData, int dmg)
public override void OnDamageOther(MapData mapData, SettlementInfo info)
{
if (!mapData.GetPlayerIdByUnitId(self.Id, out var playerId)) return;
if (info == null) return;
if (info.DamageType != DamageType.ActiveAttack) return;
if (info.DamageOrigin == null || info.DamageTarget == null) return;
if (!mapData.GetPlayerIdByUnitId(info.DamageOrigin.Id, out var playerId)) return;
var citySet = mapData.GetCityDataSetByPlayerId(playerId);
foreach (var city in citySet)
{
if (mapData.GetUnitCount(city.Id) >= city.Level) continue;
mapData.SetUnitIdToCityId(target.Id, city.Id);
mapData.SetUnitIdToCityId(info.DamageTarget.Id, city.Id);
return;
}
foreach (var city in citySet)
{
if (!city.IsCapital) continue;
mapData.SetUnitIdToCityId(target.Id, city.Id);
mapData.SetUnitIdToCityId(info.DamageTarget.Id, city.Id);
return;
}
}

View File

@ -26,10 +26,14 @@ namespace Logic.Skill
{
return SkillType.ESCAPE;
}
public override void OnAttack(UnitData self, UnitData target, MapData mapData, int dmg)
public override void OnDamageOther(MapData mapData, SettlementInfo info)
{
self.MP = 1;
if (info == null) return;
if (info.DamageType != DamageType.ActiveAttack) return;
if (info.DamageOrigin == null || info.DamageTarget == null) return;
info.DamageOrigin.MP = 1;
}
}
}

View File

@ -46,7 +46,7 @@ namespace Logic.Skill
return SkillType.ETERNITY;
}
public override bool IsCanBeDamage(UnitData self, MapData mapData, int dmg)
public override bool IsCanBeDamaged(UnitData self, MapData mapData, int dmg)
{
_recordDmg += dmg;
return false;
@ -54,8 +54,7 @@ namespace Logic.Skill
public override void OnTurnEnd(UnitData self, MapData mapData)
{
if (Main.UnitLogic.TryKillUnit(mapData, self, self, _recordDmg)) return;
Main.UnitLogic.TryDamageUnit(mapData, self, self, _recordDmg);
Main.UnitLogic.DamageSettlement(mapData, self, self, _recordDmg, DamageType.True);
}
}
}

View File

@ -27,9 +27,9 @@ namespace Logic.Skill
return SkillType.ILLUSION;
}
public override void OnKill(UnitData self, UnitData target, MapData mapData)
public override void OnDamageOther(MapData mapData, SettlementInfo info)
{
base.OnDamageOther(mapData, info);
}
}
}

View File

@ -27,18 +27,21 @@ namespace Logic.Skill
return SkillType.NUCLEARFUSION;
}
public override void OnDeath(UnitData self, UnitData origin, MapData mapData)
public override void OnDamaged(MapData mapData, SettlementInfo info)
{
if (origin == self) return;
if (info?.DamageTarget == null) return;
if (info.DamageOrigin == info.DamageTarget) return;
if (!info.IsKill) return;
if (!mapData.GetGridDataByUnitId(self.Id, out var targetGrid)) return;
if (!mapData.GetGridDataByUnitId(info.DamageTarget.Id, out var targetGrid)) return;
var roundGrid = mapData.GridMap.GetAroundGridData(1, 1, targetGrid);
foreach (var grid in roundGrid)
{
if (!mapData.GetUnitDataByGid(grid.Id, out var unit)) continue;
var damage = Table.Instance.CalcDamage(mapData, self, unit);
Main.UnitLogic.SpecialDamage(mapData, self, unit, damage);
if (unit == info.DamageTarget) continue;
var damage = Table.Instance.CalcDamage(mapData, info.DamageTarget, unit);
Main.UnitLogic.DamageSettlement(mapData, info.DamageTarget, unit, damage, DamageType.Splash);
}
}
@ -51,12 +54,12 @@ namespace Logic.Skill
foreach (var grid in roundGrid)
{
if (!mapData.GetUnitDataByGid(grid.Id, out var unit)) continue;
if (unit == self) continue;
var damage = Table.Instance.CalcDamage(mapData, self, unit);
Main.UnitLogic.SpecialDamage(mapData, self, unit, damage);
Main.UnitLogic.DamageSettlement(mapData, self, unit, damage, DamageType.Splash);
}
self.Health = 0;
Main.UnitLogic.Die(mapData, self);
Main.UnitLogic.DamageSettlement(mapData, self, self, 0, DamageType.KillSelf);
}
}
}

View File

@ -28,10 +28,11 @@ namespace Logic.Skill
return SkillType.PERSIST;
}
public override void OnKill(UnitData self, UnitData target, MapData mapData)
public override void OnDamageOther(MapData mapData, SettlementInfo info)
{
base.OnKill(self, target, mapData);
self.AP = 1;
if (info == null) return;
if (info.DamageOrigin == null || info.DamageTarget == null) return;
info.DamageOrigin.AP = 1;
}
}
}

View File

@ -32,11 +32,13 @@ namespace Logic.Skill
return false;
}
public override void OnDamage(UnitData self, UnitData origin, MapData mapData, int dmg)
public override void OnDamaged(MapData mapData, SettlementInfo info)
{
if (self.Health > 0) return;
self.Health = 1;
self.Skills.Add(SkillFactory.GetSkillBySkillType(SkillType.PHOENIXEGG));
if (info?.DamageTarget == null) return;
if (!info.IsKill) return;
info.DamageTarget.Health = 1;
info.DamageTarget.Skills.Add(SkillFactory.GetSkillBySkillType(SkillType.PHOENIXEGG));
IsPermanent = false;
TurnsLimit = 0;
}

View File

@ -43,8 +43,11 @@ namespace Logic.Skill
_attackMark = false;
}
public override void OnAttack(UnitData self, UnitData target, MapData mapData, int dmg)
public override void OnDamageOther(MapData mapData, SettlementInfo info)
{
if (info == null) return;
if (info.DamageType != DamageType.ActiveAttack) return;
if (info.DamageOrigin == null || info.DamageTarget == null) return;
_attackMark = true;
}

View File

@ -27,9 +27,9 @@ namespace Logic.Skill
return SkillType.RECYCLE;
}
public override void OnDeath(UnitData self, UnitData origin, MapData mapData)
public override void OnDamaged(MapData mapData, SettlementInfo info)
{
base.OnDamaged(mapData, info);
}
}
}

View File

@ -28,21 +28,26 @@ namespace Logic.Skill
return SkillType.SPLASH;
}
// 造成伤害时对目标单位周围1圈造成伤害
public override void OnDamageOther(UnitData self, UnitData target, MapData mapData, int dmg)
public override void OnDamageOther(MapData mapData, SettlementInfo info)
{
if (info == null) return;
if (info.DamageType != DamageType.ActiveAttack) return;
if (info.DamageOrigin == null || info.DamageTarget == null) return;
if (!mapData.GetPlayerDataByUnitId(info.DamageOrigin.Id, out var player)) return;
var selfUnitList = new HashSet<UnitData>();
mapData.GetUnitDataListByPlayerId(mapData.PlayerMap.SelfPlayerId, selfUnitList);
mapData.GetUnitDataListByPlayerId(player.Id, selfUnitList);
if (!mapData.GetGridDataByUnitId(target.Id, out var targetGrid)) return;
if (!mapData.GetGridDataByUnitId(info.DamageTarget.Id, out var targetGrid)) return;
var roundGrid = mapData.GridMap.GetAroundGridData(1, 1, targetGrid);
foreach (var grid in roundGrid)
{
if (!mapData.GetUnitDataByGid(grid.Id, out var unit)) continue;
if (unit == info.DamageTarget) continue;
if (selfUnitList.Contains(unit)) continue;
// 计算攻击伤害
var damage = Table.Instance.CalcDamage(mapData, self, unit, damagePara:0.5f);
Main.UnitLogic.SpecialDamage(mapData, self, unit, damage);
var damage = Table.Instance.CalcDamage(mapData, info.DamageOrigin, unit, damagePara:0.5f);
Main.UnitLogic.DamageSettlement(mapData, info.DamageOrigin, unit, damage, DamageType.Splash);
}
}
}

View File

@ -48,7 +48,7 @@ namespace Logic.Skill
// 计算攻击伤害
var damage = Table.Instance.CalcDamage(mapData, self, unit, damagePara:0.5f);
Main.UnitLogic.SpecialDamage(mapData, self, unit, damage, needRandomWait:true);
Main.UnitLogic.DamageSettlement(mapData, self, unit, damage, DamageType.Splash);
}
}

View File

@ -47,17 +47,16 @@ namespace Logic.Skill
{
self.AP = 1;
}
}
}
}
public override void OnKill(UnitData self, UnitData target, MapData mapData)
public override void OnDamaged(MapData mapData, SettlementInfo info)
{
self.MP = 1;
if (info?.DamageTarget == null) return;
if (!info.IsKill) return;
info.DamageTarget.MP = 1;
}
}
}

View File

@ -37,18 +37,9 @@ namespace Logic.Skill
_isDamaged = false;
}
public override void OnDamage(UnitData self, UnitData origin, MapData mapData, int dmg)
{
_isDamaged = true;
}
public override void OnAttacked(UnitData self, UnitData origin, MapData mapData, int dmg)
{
_isDamaged = true;
}
public override void OnCounterAttacked(UnitData self, UnitData origin, MapData mapData, int dmg)
public override void OnDamaged(MapData mapData, SettlementInfo info)
{
if (info == null) return;
_isDamaged = true;
}

View File

@ -27,12 +27,16 @@ namespace Logic.Skill
return SkillType.SWAP;
}
public override void BeforeAttack(UnitData self, UnitData target, MapData mapData)
public override void OnEvent(IdentifierBase identifier, SkillDamageEvent skillEvent, MapData mapData, SettlementInfo info)
{
if (!mapData.GetGridDataByUnitId(self.Id, out var selfGrid)) return;
if (!mapData.GetGridDataByUnitId(target.Id, out var targetGrid)) return;
mapData.SetUnitIdToGridId(self.Id, targetGrid.Id);
mapData.SetUnitIdToGridId(target.Id, selfGrid.Id);
if (skillEvent != SkillDamageEvent.ActiveAttackBeforeStarted) return;
if (info == null) return;
if (info.DamageOrigin == null || info.DamageTarget == null) return;
if (!mapData.GetGridDataByUnitId(info.DamageOrigin.Id, out var selfGrid)) return;
if (!mapData.GetGridDataByUnitId(info.DamageTarget.Id, out var targetGrid)) return;
mapData.SetUnitIdToGridId(info.DamageOrigin.Id, targetGrid.Id);
mapData.SetUnitIdToGridId(info.DamageTarget.Id, selfGrid.Id);
}
}
}

View File

@ -27,10 +27,14 @@ namespace Logic.Skill
return SkillType.TAICHI;
}
public override void OnAttacked(UnitData self, UnitData origin, MapData mapData, int dmg)
public override void OnDamaged(MapData mapData, SettlementInfo info)
{
if (origin.GetAttackRange() >= 2) return;
Main.UnitLogic.SpecialDamage(mapData, self, origin, dmg);
if (info == null) return;
if (info.DamageType != DamageType.ActiveAttack) return;
if (info.DamageOrigin == null || info.DamageTarget == null) return;
if (info.DamageOrigin.GetAttackRange() >= 2) return;
Main.UnitLogic.DamageSettlement(mapData, info.DamageTarget, info.DamageOrigin, info.DamageValue, DamageType.FollowAttack);
}
}
}

View File

@ -27,11 +27,15 @@ namespace Logic.Skill
return SkillType.VAMPIRE;
}
public override void OnDamageOther(UnitData self, UnitData target, MapData mapData, int dmg)
public override void OnDamageOther(MapData mapData, SettlementInfo info)
{
self.Health += (int)Math.Round(dmg * 0.3f);
if (self.Health > self.GetMaxHealth()) self.Health = self.GetMaxHealth();
self.RenderMark = true;
if (info == null) return;
if (info.DamageOrigin == null || info.DamageTarget == null) return;
info.DamageOrigin.Health += (int)Math.Round(info.DamageValue * 0.3f);
if (info.DamageOrigin.Health > info.DamageOrigin.GetMaxHealth())
info.DamageOrigin.Health = info.DamageOrigin.GetMaxHealth();
info.DamageOrigin.RenderMark = true;
}
}
}

View File

@ -12,33 +12,23 @@ using UnityEngine;
namespace Logic.Skill
{
public enum SkillDamageEvent
{
ActiveAttackBeforeStarted,
ActiveAttackFinished,
}
public interface ISkill
{
public SkillType GetSkillType();
// 事件触发生命周期 (事件已发生)
// 攻击别人
public void OnAttack(UnitData self, UnitData target, MapData mapData, int dmg);
// 被攻击
public void OnAttacked(UnitData self, UnitData origin, MapData mapData, int dmg);
public void OnMove(UnitData self, GridData grid, MapData mapData, MoveType moveType);
// 反击别人
public void OnCounterAttack(UnitData self, UnitData target, MapData mapData, int dmg);
// 被反击
public void OnCounterAttacked(UnitData self, UnitData origin, MapData mapData, int dmg);
public void OnDeath(UnitData self, UnitData origin, MapData mapData);
public void OnKill(UnitData self, UnitData target, MapData mapData);
// 受伤时
public void OnDamage(UnitData self, UnitData origin, MapData mapData, int dmg);
// 对他人造成伤害时
public void OnDamageOther(UnitData self, UnitData target, MapData mapData, int dmg);
// 伤害结算时
public void OnDamaged(MapData mapData, SettlementInfo info);
// 对他人伤害结算时
public void OnDamageOther(MapData mapData, SettlementInfo info);
// 事件触发生命周期 (时刻)
public void OnTurnStart(UnitData self, MapData mapData);
@ -96,7 +86,7 @@ namespace Logic.Skill
public bool IsCanBeKill(UnitData self, MapData mapData);
// 能否被伤害
public bool IsCanBeDamage(UnitData self, MapData mapData, int dmg);
public bool IsCanBeDamaged(UnitData self, MapData mapData, int dmg);
// 能否制造矿山
public bool IsCanBuildMine(UnitData self, MapData mapData);
@ -117,13 +107,17 @@ namespace Logic.Skill
// 获取暴击率
public float GetCriticalHitRate(UnitData self, MapData mapData);
// 伤害相关事件触发
public void OnEvent(SkillDamageEvent skillEvent, MapData mapData, SettlementInfo info);
// 全局技能
// 当有单位受伤时
public void OnUnitDamage(IdentifierBase identifier, UnitData origin, UnitData target, MapData mapData);
// 当有单位受伤结算
public void OnUnitDamaged(IdentifierBase identifier, MapData mapData, SettlementInfo info);
// 当有单位攻击时
public void OnUnitAttack(IdentifierBase identifier, UnitData origin, UnitData target, MapData mapData);
// 伤害相关事件触发
public void OnEvent(IdentifierBase identifier, SkillDamageEvent skillEvent, MapData mapData,
SettlementInfo info);
// 当有单位移动时
public void OnUnitMove(IdentifierBase identifier, UnitData moveUnit, GridData target, MapData mapData);
@ -177,53 +171,17 @@ namespace Logic.Skill
TurnsLimit = copySkill.TurnsLimit;
}
public virtual void BeforeAttack(UnitData self, UnitData target, MapData mapData)
{
}
public virtual void OnAttack(UnitData self, UnitData target, MapData mapData, int dmg)
{
}
public virtual void OnAttacked(UnitData self, UnitData origin, MapData mapData, int dmg)
{
}
public virtual void OnMove(UnitData self, GridData grid, MapData mapData,MoveType moveType)
{
}
public virtual void OnCounterAttack(UnitData self, UnitData target, MapData mapData, int dmg)
public virtual void OnDamaged(MapData mapData, SettlementInfo info)
{
}
public virtual void OnCounterAttacked(UnitData self, UnitData origin, MapData mapData, int dmg)
{
}
public virtual void OnDeath(UnitData self, UnitData origin, MapData mapData)
{
}
public virtual void OnKill(UnitData self, UnitData target, MapData mapData)
{
}
public virtual void OnDamage(UnitData self, UnitData origin, MapData mapData, int dmg)
{
}
public virtual void OnDamageOther(UnitData self, UnitData target, MapData mapData, int dmg)
public virtual void OnDamageOther(MapData mapData, SettlementInfo info)
{
}
@ -344,7 +302,7 @@ namespace Logic.Skill
return true;
}
public virtual bool IsCanBeDamage(UnitData self, MapData mapData, int dmg)
public virtual bool IsCanBeDamaged(UnitData self, MapData mapData, int dmg)
{
return true;
}
@ -379,20 +337,24 @@ namespace Logic.Skill
return 0;
}
public virtual void OnUnitDamage(IdentifierBase identifier, UnitData origin, UnitData target, MapData mapData)
public virtual void OnEvent(SkillDamageEvent skillEvent, MapData mapData, SettlementInfo info)
{
}
public virtual void OnUnitDamaged(IdentifierBase identifier, MapData mapData, SettlementInfo info)
{
}
public virtual void OnUnitAttack(IdentifierBase identifier, UnitData origin, UnitData target, MapData mapData)
public virtual void OnEvent(IdentifierBase identifier, SkillDamageEvent skillEvent, MapData mapData, SettlementInfo info)
{
}
public virtual void OnUnitMove(IdentifierBase identifier, UnitData moveUnit, GridData target, MapData mapData)
{
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d302e647340b49f68187f74271e26686
timeCreated: 1751340272

View File

@ -0,0 +1,35 @@
/*
* @Author:
* @Description:
* @Date: 20250701 14:07:05
* @Modify:
*/
namespace Logic.Timeline
{
public enum FragmentType
{
Move,
ActiveAttack,
CounterAttack,
AttackBack,
Kill,
ActionEvent,
}
public enum FragmentState
{
Prepare,
Playing,
Finished,
}
public interface IFragment
{
public void OnStart();
public void OnFinished();
public void OnUpdate(float time);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e992c5e394f1422f918b5f936a3824db
timeCreated: 1751350920

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c35df220d5c2428b9e46c33733f2945f
timeCreated: 1751340751

View File

@ -0,0 +1,83 @@
/*
* @Author:
* @Description:
* @Date: 20250701 11:07:18
* @Modify:
*/
using RuntimeData;
namespace Logic.Timeline
{
public abstract class LogicFragmentBase : IFragment
{
public TimeParam Param;
public FragmentType Type;
public FragmentState State;
public float StartTime;
public float Duration;
public abstract bool Check();
public abstract void OnStart();
public abstract void OnFinished();
public abstract void OnUpdate(float time);
}
public class ActiveAttackFragment : LogicFragmentBase
{
public override bool Check()
{
if (Param?.Map == null) return false;
if (Param.Origin == null || Param.Target == null) return false;
return true;
}
public override void OnStart()
{
}
public override void OnFinished()
{
var dmg = Table.Instance.CalcDamage(Param.Map, Param.Origin, Param.Target);
Main.UnitLogic.DamageSettlement(Param.Map, Param.Origin, Param.Target, 0, DamageType.ActiveAttack);
}
public override void OnUpdate(float time)
{
}
}
public class MoveFragment : LogicFragmentBase
{
public override bool Check()
{
if (Param?.Map == null) return false;
if (Param.Origin == null) return false;
if (Param.Grid == null) return false;
return true;
}
public override void OnStart()
{
}
public override void OnFinished()
{
}
public override void OnUpdate(float time)
{
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6cbd0fe4b554489d9d2d9a840ea3cc4e
timeCreated: 1751340289

View File

@ -0,0 +1,55 @@
/*
* @Author:
* @Description:
* @Date: 20250701 11:07:44
* @Modify:
*/
using System.Collections.Generic;
using RuntimeData;
namespace Logic.Timeline
{
public enum TimeGroupState
{
Prepare,
Playing,
Finished,
}
public class TimeParam
{
public MapData Map;
public UnitData Origin;
public UnitData Target;
public GridData Grid;
public DamageType DamageType;
public SettlementInfo Info;
}
public class TimeGroup
{
public TimeGroupState State;
public List<IFragment> Fragments;
public TimeGroup()
{
State = TimeGroupState.Prepare;
Fragments = new List<IFragment>();
}
public void Update()
{
if (Fragments.Count == 0)
{
State = TimeGroupState.Finished;
return;
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8b96044a07cb457f8a0b397218b46d89
timeCreated: 1751340341

View File

@ -0,0 +1,42 @@
/*
* @Author:
* @Description:
* @Date: 20250701 11:07:48
* @Modify:
*/
using System.Collections.Generic;
namespace Logic.Timeline
{
public class TimelineManager
{
public static TimelineManager Instance = new TimelineManager();
private TimelineManager() { }
private List<TimeGroup> _groups;
public TimeGroup CreateTimeGroup()
{
var group = new TimeGroup();
_groups.Add(group);
return group;
}
public void Update()
{
foreach (var group in _groups)
{
group.Update();
}
for (int i = _groups.Count - 1; i >= 0; i--)
{
if (_groups[i].State != TimeGroupState.Finished) continue;
_groups.RemoveAt(i);
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 825d293f02b34c28ade88901bb31843b
timeCreated: 1751340279

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 990036c664354e82aec2526199dc3839
timeCreated: 1751340798

View File

@ -0,0 +1,40 @@
/*
* @Author:
* @Description:
* @Date: 20250701 11:07:18
* @Modify:
*/
namespace Logic.Timeline
{
public abstract class ViewFragmentBase : IFragment
{
public LogicFragmentBase LogicFragment;
public FragmentType Type;
public FragmentState State;
public abstract void OnStart();
public abstract void OnFinished();
public abstract void OnUpdate(float time);
}
public class ActiveAttackFragmentView : ViewFragmentBase
{
public override void OnStart()
{
}
public override void OnFinished()
{
}
public override void OnUpdate(float time)
{
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 08ed9b107bb543289e1b28f2f8a2cc76
timeCreated: 1751341003

View File

@ -17,6 +17,31 @@ using TH1Renderer;
namespace Logic
{
public enum DamageType
{
ActiveAttack,
PassiveAttack,
FollowAttack,
Splash,
True,
KillSelf,
}
public class SettlementInfo
{
//伤害类型
public DamageType DamageType;
//伤害来源的unitId
public UnitData DamageOrigin;
//伤害目标的unitId
public UnitData DamageTarget;
//伤害值
public int DamageValue;
//是否击杀
public bool IsKill;
}
public class UnitLogic : IUnitLogic
{
@ -180,8 +205,6 @@ namespace Logic
if (!mapData.GetGridDataByUnitId(unit2.Id, out var grid2)) return false;
player1.CurAttackPlayers.Add(player2.Id);
player2.CurAttackPlayers.Add(player1.Id);
mapData.OnUnitAttack(unit1, unit2);
unit1.BeforeAttack(mapData, unit2);
player1.TurnNoAttack = 0;
// 计算攻击伤害
@ -228,7 +251,8 @@ namespace Logic
{
//立刻死亡并播放受伤动画,必须先处理死亡再处理移动不然gridToUnit的dict会出错
TryKillUnit(mapData,unit1,unit2,dmg1);
unit2.Health = 0;
Main.UnitLogic.Die(mapData, unit2);
//unit2.Health -= dmg1;
//RunDamageSkillGroup(mapData,unit1,unit2,dmg1);
//Main.UnitLogic.Die(mapData, unit2);
@ -403,28 +427,54 @@ namespace Logic
},
counterAttackBack);
}
//处理 ESCAPE 和 SPLASH 技能 OnAttack
unit1.OnAttack(mapData, unit2, dmg1);
var settlement = new SettlementInfo();
settlement.DamageType = DamageType.ActiveAttack;
settlement.DamageOrigin = unit1;
settlement.DamageTarget = unit2;
settlement.DamageValue = dmg1;
foreach (var skill in unit1.Skills) skill.OnDamageOther(mapData, settlement);
return true;
}
// SpecialDamage和Attack同等级
public void SpecialDamage(MapData mapData, UnitData unit1, UnitData unit2, int dmg, bool needRandomWait = false)
// 伤害新结算方法所有的掉血都要走此方法不允许直接修改UnitData.Health
// TODO 自杀或者杀队友要不要加 player.TotalKill
// TODO 死亡动画标记移除了,最好用新系统实现
public SettlementInfo DamageSettlement(MapData mapData, UnitData origin, UnitData target, int dmg, DamageType type)
{
if (!mapData.GetPlayerDataByUnitId(unit1.Id, out var player1)) return;
// 尝试击杀
if (TryKillUnit(mapData, unit1, unit2, dmg,needRandomWait))
if (!target.CanBeDamaged(mapData, dmg)) return null;
var settlement = new SettlementInfo();
settlement.DamageType = type;
settlement.DamageOrigin = origin;
settlement.DamageTarget = target;
settlement.DamageValue = dmg;
target.Health -= dmg;
if (type == DamageType.KillSelf)
{
// 权力奇观记录
player1.TotalKill++;
// 尝试增加小兵经验
if (!unit1.IsExpLock(mapData))unit1.Exp++;
return;
target.Health = 0;
settlement.IsKill = true;
Main.UnitLogic.Die(mapData, target);
}
else if (target.CanBeKilled(mapData) && target.Health <= 0)
{
target.Health = 0;
settlement.IsKill = true;
Main.UnitLogic.Die(mapData, target);
if (!origin.IsExpLock(mapData)) origin.Exp++;
mapData.GetPlayerDataByUnitId(origin.Id, out var player);
if (player != null) player.TotalKill++;
}
else
{
settlement.IsKill = false;
}
// 尝试伤害
TryDamageUnit(mapData, unit1, unit2, dmg, needRandomWait);
foreach (var skill in target.Skills) skill.OnDamaged(mapData, settlement);
foreach (var skill in origin.Skills) skill.OnDamageOther(mapData, settlement);
mapData.OnUnitDamaged(settlement);
return settlement;
}
public void DieAnimRenderMarkUpadate(GridData grid2,UnitData unit2,int dmg,bool needRandomWait = false)
@ -468,38 +518,6 @@ namespace Logic
if (!target.CanBeKilled(mapData)) return false;
return true;
}
public bool TryKillUnit(MapData mapData, UnitData origin, UnitData target, int dmg,bool needRandomWait = false)
{
if (dmg < target.Health) return false;
if (!target.CanBeKilled(mapData)) return false;
// 伤害超过血量时会溢出,伤害 = 总掉血量
dmg = target.Health;
target.Health = 0;
foreach (var skill in target.Skills) skill.OnDamage(target, origin, mapData, dmg);
foreach (var skill in target.Skills) skill.OnDeath(target, origin, mapData);
foreach (var skill in origin.Skills) skill.OnDamageOther(origin, target, mapData, dmg);
foreach (var skill in origin.Skills) skill.OnKill(origin, target, mapData);
mapData.OnUnitDamage(origin, target);
Main.UnitLogic.Die(mapData, target);
//更新死亡动画相关rendermark
if(mapData.GetGridDataByUnitId(target.Id,out var targetGrid))
DieAnimRenderMarkUpadate(targetGrid,target,dmg,needRandomWait);
return true;
}
public bool TryDamageUnit(MapData mapData, UnitData origin, UnitData target, int dmg,bool needRandomWait = false)
{
target.Health -= dmg;
foreach (var skill in target.Skills) skill.OnDamage(target, origin, mapData, dmg);
foreach (var skill in origin.Skills) skill.OnDamageOther(origin, target, mapData, dmg);
mapData.OnUnitDamage(origin, target);
if(mapData.GetGridDataByUnitId(target.Id,out var targetGrid))
DamageAnimRenderMarkUpdate(targetGrid,target,dmg,needRandomWait);
return true;
}
public void DebugOutputMoveInfo(MapData mapData)
{