|
楼主 |
发表于 2018-1-7 12:40:56
|
显示全部楼层
本帖最后由 zt0616 于 2018-1-16 10:38 编辑
第二部分 模拟效果树
1. 观察效果历史
下面来实现一下效果树。在开始之前,我们需要先找个参照。
星际2里有EffectHistory(效果历史),创建后的效果实例会被注册进施法者,可以通过索引查询各种相关信息,返回条目数也可以自定义。
索引从1开始,索引越小时间上越近。
若要给一个施法者实例注册效果,得先增加该单位条目的字段EffectHistoryLimit(效果历史限制)每个分类的值。要被注册的效果条目下CasterHistory(施法者历史)字段也需要做相应设置。
这里有演示。
效果历史条目信息可以通过触发器查询。下面是触发器中有关效果历史的(包括虚空之遗新增的),我们先来观察一下。
首先是枚举类型:
- enum e_effectHistory { Damage, Death, Modifier, Healing };
- enum e_effectUnit { Caster, Origin, Outer, Source, Target };
- enum e_effectHistoryAmount { Absorbed, Damaged, Dodged, EnergyChanged, EnergyLeeched, Found, Healed, Killed, LifeChanged, LifeLeeched, ShieldsChanged, ShieldsLeeched, Splashed };
- enum e_effectHistoryEffect { Current, Root };
复制代码
下面是所有相关的方法(函数):
- interface Trigger {
- /**
- * Returns an Effect History object that can be used to inspect the history of effects for a unit.
- * 返回一个可以用来检索一个单位的效果历史的的效果历史对象。
- * In order for a unit to register effects to its history, the unit must specify an Effect History Limit value,
- * 一个单位若想要在它的历史中注册效果,就必须指定一个“效果历史限制”值,
- * and any effects you want to track must specify a Caster History value.
- * 此外,所有想要追踪的效果都必须指定一个“施法者历史”值。
- * The Caster History value specifies the category under which you want to track the effect.
- * 施法者历史值决定你想要将该效果追踪于哪个分类中。
- * You can use Effect History Entry Type to query the category for an Effect History entry.
- * 你可以使用“效果历史条目类型”来查询一个效果历史条目的类型。
- * A max count of 0 (the default) will get all available entries.
- * 将最大计数设为0(默认)则会获得所有可用的条目。
- */
- UnitEffectHistory(unit: Unit, maxCount: int): EffectHistory
- /**
- * Returns the number of entries in the specified Effect History.
- * 返回指定效果历史中的条目数量。
- * Use Effect History Of Unit to get an Effect History.
- * 使用“单位的效果历史”来获取效果历史。
- */
- EffectHistoryCount(history: EffectHistory): int
- /**
- * Returns the type of effect that was logged in the Effect History at the specified Index.
- * 返回记录在效果历史中指定索引的效果类型。
- * The type for the effect is set in the effect data in the Caster History field.
- * 这一效果类型由效果数据的“施法者历史”字段决定。
- */
- EffectHistoryGetType(history: EffectHistory, index: int): e_effectHistory
- /**
- * Returns the game time (in seconds) when the effect that was logged in the Effect History at the specified Index occurred.
- * 返回记录在效果历史中指定索引的效果发生时的游戏时间(以秒为单位)。
- */
- EffectHistoryGetTime(history: EffectHistory, index: int): fixed
- EffectHistoryGetAmountInt(history: EffectHistory, index: int, amount: e_effectHistoryAmount, total: boolean): int
- EffectHistoryGetAmountFixed(history: EffectHistory, index: int, amount: e_effectHistoryAmount, total: boolean): fixed
- EffectHistoryGetUnitByLocation(history: EffectHistory, index: int, unit: e_effectUnit): Unit
- /**
- * If the Effect parameter is set to Root, this will return the effect that was at the root of the effect tree for the effect that was logged in the Effect History at the specified Index.
- * 假如效果参数设为根,会返回记录在效果历史中指定索引处的效果的效果树的根效果。
- * If the Effect parameter is set to Current, then this will return the effect that was logged in the Effect History at the specified Index.
- * 假如效果参数设为当前,则会返回记录在效果历史中指定索引处的效果。
- */
- EffectHistoryGetEffect(history: EffectHistory, index: int, effect: e_effectHistoryEffect): CEffect
- /**
- * Returns the weapon that originated the effect that was logged in the Effect History at the specified Index.
- * 返回引发记录在效果历史中指定索引的效果的武器。
- * If the effect came from an ability rather than a weapon, this will return No Game Link.
- * 假如效果由技能而非武器引发,则会返回“无游戏链接”。
- */
- EffectHistoryGetWeapon(history: EffectHistory, index: int): CWeapon
- /**
- * Returns the ability that originated the effect that was logged in the Effect History at the specified Index.
- * 返回引发记录在效果历史中指定索引的效果的技能。
- * If the effect came from a weapon rather than an ability, this will return No Game Link.
- * 假如效果由武器而非技能引发,则会返回“无游戏链接”。
- */
- EffectHistoryGetAbil(history: EffectHistory, index: int): CAbil
- }
复制代码
根据上面的信息可以看出,效果历史由多个条目构成,各个条目至少记录了如下这些信息:
1. 效果链接及其根效果
2. 起源武器
3. 起源技能
4. 各个位置的单位(e_effectUnit:目标单位、施法者、源单位等)
5. 效果伤害类型(e_effectHistoryAmount,吸收、击杀等)
6. 效果发生时间
7. 分类(e_effectHistory:伤害、死亡、治疗、修改四个类)
看到这里相信大家可以想象,效果条目里平时制作技能时非常重要的两个字段:轰击位置/发射位置,大概是怎么运作的。
但是真正的效果树并不是被记录在施法单位上的,而且效果历史条目信息还缺乏“目标点、施法者点”这个重要信息。可效果历史无疑为我们提供了一个重要参考。
2. 设置条目
在第一部分,我们成功地让武器能筛选出可攻击单位来,还得让武器能对单位施放效果,才是一把真正的武器。下面将模拟武器对目标发射飞弹并对其造成伤害。
首先申明抽象类CEffect,并让CEffectLaunchMissile和CEffectDamage成为其子类。
- public abstract class CEffect : CatalogScope { }
- public class CEffectLaunchMissile : CEffect { }
- public class CEffectDamage : CEffect { }
复制代码
给这些类及先前的武器新增字段。
- public class CWeapon : CatalogScope
- {
- private CTargetFilters targetFilters;
- public CTargetFilters TargetFilters => targetFilters;
- private CEffect effect;
- public CEffect Effect => effect;
- }
复制代码- public class CEffectLaunchMissile : CEffect
- {
- private CUnit ammoUnit;
- public CUnit AmmoUnit => ammoUnit;
- private CEffect impactEffect;
- public CEffect ImpactEffect => impactEffect;
- private SEffectWhichLocation launchLocaction;
- public SEffectWhichLocation LaunchLocaction { get { return launchLocaction; } }
- private SEffectWhichLocation impactLocation;
- public SEffectWhichLocation ImpactLocation { get { return impactLocation; } }
- }
- public class CEffectDamage : CEffect
- {
- private float amount;
- public float Amount => amount;
- private SEffectWhichLocation launchLocaction;
- public SEffectWhichLocation LaunchLocaction { get { return launchLocaction; } }
- private SEffectWhichLocation impactLocation;
- public SEffectWhichLocation ImpactLocation { get { return impactLocation; } }
- }
复制代码
注:这里使用float作为伤害量的类型,只是为了文章简洁性。考虑到ABE框架适合用确定性(deterministic)同步方式,浮点数运算在不同中央处理器架构下不具有确定性,因此这里应该用FixedPoint描述amount。具体实现这里不做叙述,有兴趣的话可以了解下.NET下的FixedMath库。
下面申明位置字段。CEffectDamage和CEffectLaunchMissile都具有发射位置和轰击位置字段。这种表明位置字段有4个类:
SEffectWhichUnit——哪个单位,用于CEffectApplyBehavior、CEffectIssueOrder、CEffectModifyUnit等;
枚举类型:
- enum EffectUnit { Caster, Source, Target, Outer, Origin, CasterOuter, TargetOuter };
复制代码
SEffectWhichLocation——哪个单位和点,用于CEffectCreatePersistent、EffectDamage、CEffectEnumArea、CEffectLaunchMissile等;
枚举类型:
- enum EffectLocation {
- CasterUnit, SourceUnit, TargetUnit, OuterUnit, OriginUnit, CasterOuterUnit, TargetOuterUnit,
- CasterPoint, SourcePoint, TargetPoint, OuterPoint, OriginPoint, CasterOuterPoint, TargetOuterPoint
- };
复制代码
SEffectWhichPlayer——哪个玩家,用于CEffectModifyPlayer、CEffectCreateUnit、CEffectIssueOrder等;
枚举类型:
- enum EffectPlayer { Caster, Source, Target, Outer, Origin, CasterOuter, TargetOuter, Creator, Hostile, Neutral };
复制代码
SEffectWhichTimeScale——哪个时间刻度,用于CEffectCreatePersistent、CEffectApplyForce。
枚举类型:
- enum EffectTimeScale { Caster, Target, Global };
复制代码
这些结构共有effect字段,所以将他们继承于抽象类CEffectWhich。
- public abstract class CEffectWhich
- {
- private CEffect effect;
- public CEffect Effect { get { return effect; } }
- }
- public class SEffectWhichLocation : CEffectWhich
- {
- private CEffectLocation value;
- public CEffectLocation Value { get { return value; } }
- }
- public class SEffectWhichUnit : CEffectWhich
- {
- private CEffectLocationUnit value;
- public CEffectLocationUnit Value { get { return value; } }
- }
复制代码
然后是位置类型的类,用于手动引用到效果条目。这里并没直接套用星际2的格式EffectLocation,而是将EffectLocation分为EffectLocationUnit和EffectLocationPoint,这样代码会清晰得多。
- public abstract class CEffectLocation : CatalogScope { }
- public enum EffectUnit
- {
- Caster, Source, Target, Outer, Origin, CasterOuter, TargetOuter
- };
- public class CEffectLocationUnit : CEffectLocation
- {
- private EffectUnit type;
- public EffectUnit Type { get { return type; } }
- }
- public enum EffectPoint
- {
- Caster, Source, Target, Outer, Origin, CasterOuter, TargetOuter
- };
- public class CEffectLocationPoint : CEffectLocation
- {
- private EffectPoint type;
- public EffectPoint Type { get { return type; } }
- }
复制代码 |
|