public void Run() { Random random = new Random(); var world = Origin.GetWorld(); var alive = Target.GetBehavior <BehaviorAlive>(); var sword = Origin.GetBehavior <BehaviorSword>(); Target.GetFlashHelper()?.AddFlash(ColorMatrix.Flat(Color.White), 20); Target.GetShakeHelper()?.AddShakeRandom(3, LerpHelper.QuadraticOut, 30); if (!Target.IsHeartless()) { alive.SetDamage(alive.HP); SkillUtil.CreateSpatter(world, Target.GetVisualTarget(), 5, Util.AngleToVector(sword.Angle) * 24, 2, Random); if (sword != null) { sword.HasBlood = true; sword.HasHeart = true; } if (Origin == world.PlayerCurio) { world.RunStats.HeartsRipped += 1; } Blood.Play(1, 0.5f, 0); Behavior.Apply(new BehaviorHeartless(Target)); } }
public override void SetupAttributes() { base.SetupAttributes(); var captainSD = LegacyResourcesAPI.Load <SkillDef>("SkillDefs/CaptainBody/CaptainSkillUsedUp"); disabledSkillDef = SkillUtil.CloneSkillDef(captainSD); disabledSkillDef.skillNameToken = "TKSAT_DISABLED_SKILL_NAME"; disabledSkillDef.skillDescriptionToken = "TKSAT_DISABLED_SKILL_DESCRIPTION"; disabledSkillDef.dontAllowPastMaxStocks = false; disabledSkillDef.beginSkillCooldownOnSkillEnd = true; ContentAddition.AddSkillDef(disabledSkillDef); tauntDebuff = ScriptableObject.CreateInstance <BuffDef>(); tauntDebuff.buffColor = Color.white; tauntDebuff.canStack = false; tauntDebuff.isDebuff = true; tauntDebuff.name = "TKSATTaunt"; tauntDebuff.iconSprite = Addressables.LoadAssetAsync <Sprite>("RoR2/Base/Common/MiscIcons/texAttackIcon.png") .WaitForCompletion(); ContentAddition.AddBuffDef(tauntDebuff); R2API.Networking.NetworkingAPI.RegisterMessageType <ServerTimedSkillDisable.MsgApply>(); R2API.Networking.NetworkingAPI.RegisterMessageType <ServerTimedSkillDisable.MsgRemove>(); }
public override IEnumerable <Wait> RoutineUse(Creature user, object target) { Consume(); ShowSkill(user); user.VisualPose = user.FlickPose(CreaturePose.Cast, CreaturePose.Stand, 70); yield return(user.WaitSome(50)); //var userTiles = user.Mask.Select(o => user.Tile.GetNeighbor(o.X, o.Y)).ToList(); var targetTiles = SkillUtil.GetFrontierTiles(user).Shuffle(Random); int currentCount = 0; foreach (var targetTile in targetTiles) { if (!targetTile.Solid && !targetTile.Creatures.Any() && currentCount < Count) { //var userTile = userTiles.Pick(Random); var bomb = new AutoBomb(targetTile.World); bomb.MoveTo(targetTile, 0); bomb.VisualPosition = bomb.SlideJump(user.VisualTarget - bomb.CenterOffset, bomb.ActualPosition, 10, LerpHelper.Quadratic, 10); bomb.AddControlTurn(); Effect.Apply(new EffectSummon(user, bomb)); currentCount++; yield return(user.WaitSome(3)); } } yield return(user.WaitSome(20)); }
public void Draw(SceneGame scene, DrawPass pass) { if (Origin.IsDeadOrDestroyed()) { return; } var tile = Origin.GetMainTile(); var target = GetTarget(); var mace = Origin.GetBehavior <BehaviorMace>(); if (pass == DrawPass.EffectLowAdditive) { if (!mace.Upswing.Done) { SkillUtil.DrawArea(scene, GetUpswingArea(), ColorStart, ColorEnd, FrameUpswingSlash.Slide); } SkillUtil.DrawArea(scene, new[] { target }, ColorStart, ColorEnd, mace.Upswing.Slide); SkillUtil.DrawImpact(scene, target, ColorStart, ColorEnd, mace.Upswing.Slide); } if (pass == DrawPass.EffectAdditive) { SkillUtil.DrawImpactLine(scene, AoEVisual.GetStraight(Origin.GetVisualTarget(), target.GetVisualTarget()), ColorStart, ColorEnd, mace.Upswing.Slide); if (mace.Upswing.Done && !Frame.Done) { SkillUtil.DrawStrike(scene, Origin.GetVisualTarget(), target.GetVisualTarget(), Frame.Slide, Color.White); } } }
/// <summary> /// 弹射单次完成 /// </summary> /// <param name="identifyId"></param> public virtual void OnBounceNodeEnd(int identifyId, int activeId) { CommonParam param = GetParam(identifyId, false); if (param == null) { return; } if (param.IsBounce) //弹射 { SkillActionData bounceData = SkillUtil.GetSkillActionData(param.BounceParam.BounceActionId); int maxBounceTime = int.Parse(bounceData.Para1); //最大允许的弹射次数 float.TryParse(bounceData.Para2, out float interval); //弹射间隔 if (param.BounceParam.BounceTime < maxBounceTime) //开始下一次弹射 { object[] actionParam = { activeId, bounceData.Id, identifyId }; if (interval > 0) { var timerService = ServiceLocate.Instance.GetService <TimerService>(); timerService.CreateTimer(TryDoNextBounce, 0.1f, interval, actionParam); } else { TryDoNextBounce(true, actionParam); } } else //超过弹射次数 { SkillUtil.LogWarning("超过最大弹射次数 弹射取消 Max Time->" + maxBounceTime); RemoveSkillAction(activeId, param); } } }
public void Run() { Random random = new Random(); var world = Target.GetWorld(); var lastSeen = Target.GetBehavior <BehaviorLastSeen>(); var canBeSeen = lastSeen.CanSee(Origin); SkillUtil.CreateBloodCircle(world, Target.GetVisualTarget(), 60, 64, Random); if (canBeSeen) { SoundRat.Play(1, Random.NextFloat(-0.5f, +0.5f), 0); SkillUtil.CreateSpatter(world, Target.GetVisualTarget(), 5, Vector2.Zero, 1, Random); if (Score > 0) { world.AddWorldScore(Score, Target.GetVisualTarget(), ScoreType.Small); } if (Origin == world.PlayerCurio) { world.RunStats.Gibs += 1; world.RunStats.RatsHunted += 1; } } Splat.Play(1.0f, Random.NextFloat(-0.5f, +0.5f), 0); Behavior.Apply(new BehaviorGib(Target)); }
private ISkill GetSkill(int skillId) { if (skills == null) { return(null); } for (int i = 0; i < skills.Count; i++) { if (skills[i] != null && skills[i].GetSkillId() == skillId) { return(skills[i]); } } #if UNITY_EDITOR System.Text.StringBuilder sb = new System.Text.StringBuilder(); for (int i = 0; i < this.skills.Count; i++) { sb.Append(this.skills[i].GetSkillId()); sb.Append("|"); } SkillUtil.LogError($"已经装配的Skill {sb}"); #endif SkillUtil.LogError($"SkillId-> {skillId.ToString()} 不存在"); return(null); }
public virtual void CastSkill(CommonParam commonParam) { if (!isInit) { SkillUtil.LogError("SKill is not Init"); return; } if (context.CanCastSkill(id)) { return; } identifyId++; AddSkillParam(identifyId, commonParam); SkillUtil.LogWarning($"{SkillUtil.GetSkillDebugDes(this)} 开始释放"); PlayAnimation(); float castPointTime = SkillUtil.GetSkillCastPoint(GetSkillLevel(), data); void CastSkill(bool isEnd, object[] param) { CommonParam actionParam = (CommonParam)param[0]; if (isEnd) { OnCastSkillStart(actionParam.IdentifyId); } } var timerService = ServiceLocate.Instance.GetService <TimerService>(); timerService.CreateTimer(CastSkill, 0.1f, castPointTime, new object[] { commonParam }); }
private IEnumerable <Wait> RoutineExplode(Creature attacker, Tile explosionTarget, int radius, int reactionLevel) { yield return(new WaitTime(5 + Random.Next(5))); new FireExplosion(attacker.World, explosionTarget.VisualTarget, Vector2.Zero, 0, 15); new ScreenShakeRandom(attacker.World, 6, 30, LerpHelper.Linear); var waitForDamage = new List <Wait>(); foreach (var explosionTile in SkillUtil.GetCircularArea(explosionTarget, radius)) { foreach (var targetCreature in explosionTile.Creatures) { waitForDamage.Add(attacker.Attack(targetCreature, SkillUtil.SafeNormalize(targetCreature.VisualTarget - explosionTarget.VisualTarget), (a, b) => ExplosionAttack(a, b, reactionLevel + 1))); } if (explosionTile is IMineable mineable) { MineEvent fracture = new MineEvent(attacker, null, 100) { Fault = this, ReactionLevel = reactionLevel + 1 }; waitForDamage.Add(mineable.Mine(fracture)); } } yield return(new WaitAll(waitForDamage)); }
public IEnumerable <Wait> RoutineExplosion(Creature creature, double force, int reactionLevel) { new AcidExplosion(creature.World, creature.VisualTarget, Vector2.Zero, 0, 20); yield return(creature.WaitSome(10)); new ScreenShakeRandom(creature.World, 5, 20, LerpHelper.Linear); new RingExplosion(creature.World, creature.VisualTarget, (pos, vel, angle, time) => new SteamExplosion(creature.World, pos, vel, angle, time), 12, 24, 10); int radius = 2; int dryRadius = 1; IEnumerable <Tile> dryArea = SkillUtil.GetCircularArea(creature, dryRadius); IEnumerable <Tile> explosionArea = SkillUtil.GetCircularArea(creature, radius); foreach (var tile in dryArea) { if (tile is Water) { tile.Replace(new FloorCave()); } } var explosion = new Skills.Explosion(creature, explosionArea, creature.VisualTarget); explosion.Fault = this; explosion.ReactionLevel = reactionLevel; explosion.Attack = (a, b) => ExplosionAttack(a, b, force, reactionLevel); yield return(explosion.Run()); }
public IEnumerable <Wait> Splinter(Attack attack) { int traitLvl = attack.Attacker.GetTrait(this); if (attack.Defender is Creature targetCreature && attack.ReactionLevel == 0) { var boneShards = SpriteLoader.Instance.AddSprite("content/shards"); IEnumerable <Tile> targetTiles = SkillUtil.GetFrontierTiles(new[] { attack.Attacker, targetCreature }); HashSet <Creature> targets = new HashSet <Creature>(); yield return(attack.Attacker.WaitSome(10)); foreach (Tile tile in targetTiles) { targets.AddRange(tile.Creatures.Where(creature => creature != attack.Attacker && creature != attack.Defender)); new Shards(attack.Attacker.World, boneShards, Vector2.Lerp(attack.Attacker.VisualTarget, targetCreature.VisualTarget, 0.5f), tile.VisualTarget, LerpHelper.CubicOut, 10); } List <Wait> waitForDamage = new List <Wait>(); foreach (var target in targets) { double splinterDamage = traitLvl * 0.2 * attack.FinalDamage.Sum(x => x.Value); var wait = attack.Attacker.Attack(target, SkillUtil.SafeNormalize(target.VisualTarget - attack.Attacker.VisualTarget), (a, b) => SplinterAttack(a, b, splinterDamage)); waitForDamage.Add(wait); } yield return(new WaitAll(waitForDamage)); } yield return(Wait.NoWait); }
private bool Internal_TriggerAction(ISkill skill, int actionId, int identifyId, bool isBuff, bool addSkillAction = true) { SkillActionData data = null; if (!IsValid(skill, actionId, identifyId, isBuff, ref data)) { return(false); } var param = skill.GetParam(identifyId, isBuff); if (map.ContainsKey(data.ActionType)) { // SkillUtil.Log(string.Format(" Trigger Type-> {0}", (SkillActionType) data.ActionType)); if (addSkillAction && !isBuff) { skill.AddSkillAction(actionId, identifyId); } map[data.ActionType].Action(skill, data, param); } else { SkillUtil.LogError(SkillUtil.GetSkillDebugDes(skill) + " Ation Type" + data.ActionType + " 未注册"); } return(true); }
public void Run() { Random random = new Random(); var world = Origin.GetWorld(); var alive = Target.GetBehavior <BehaviorAlive>(); var grapple = Origin.GetBehavior <BehaviorGrapplingHook>(); Target.GetFlashHelper()?.AddFlash(ColorMatrix.Flat(Color.White), 20); Target.GetShakeHelper()?.AddShakeRandom(3, LerpHelper.QuadraticOut, 30); if (!Target.IsHeartless()) { var delta = Vector2.Normalize(Origin.GetVisualTarget() - Target.GetVisualTarget()); alive.SetDamage(alive.HP); SkillUtil.CreateSpatter(world, Target.GetVisualTarget(), 5, delta * 24, 2, Random); if (grapple != null) { grapple.HasHeart = true; } if (Origin == world.PlayerCurio) { world.RunStats.HeartsRipped += 1; } Blood.Play(1, 0, 0); new TimeFade(world, 0.01f, LerpHelper.ExponentialIn, 60); Behavior.Apply(new BehaviorHeartless(Target)); } }
public void ShowMaskAfterCombo() { if (character.isDead) { return; } ShowCommonCDImage(true); switch (Fight.Controller.FightController.instance.fightStatus) { case FightStatus.FloatComboing: if (character.characterInfo.skillInfo1 != null) { if (SkillUtil.AttackableFloat(character.characterInfo.skillInfo1)) { if (character.characterInfo.skillInfo1.skillData.attackableType == AttackableType.Float) { skillItemView1.ShowMask(true); } skillItemView1.ShowFloatParticle(false); } } if (character.characterInfo.skillInfo2 != null) { if (SkillUtil.AttackableFloat(character.characterInfo.skillInfo2)) { if (character.characterInfo.skillInfo2.skillData.attackableType == AttackableType.Float) { skillItemView2.ShowMask(true); } skillItemView2.ShowFloatParticle(false); } } break; case FightStatus.TumbleComboing: if (character.characterInfo.skillInfo1 != null) { if (SkillUtil.AttackableTumble(character.characterInfo.skillInfo1)) { if (character.characterInfo.skillInfo1.skillData.attackableType == AttackableType.Tumble) { skillItemView1.ShowMask(true); } skillItemView1.ShowTumbleParticle(false); } } if (character.characterInfo.skillInfo2 != null) { if (SkillUtil.AttackableTumble(character.characterInfo.skillInfo2)) { if (character.characterInfo.skillInfo2.skillData.attackableType == AttackableType.Tumble) { skillItemView2.ShowMask(true); } skillItemView2.ShowTumbleParticle(false); } } break; } }
public override IEnumerable <Wait> RoutineUse(Creature user, object target) { Consume(); ShowSkill(user); user.VisualPose = user.FlickPose(CreaturePose.Cast, CreaturePose.Stand, 70); yield return(user.WaitSome(50)); var targetTiles = SkillUtil.GetFrontierTiles(user).Shuffle(Random); int maxCount = targetTiles.Count(); var currentCount = user.GetEffects <EffectSummon>().Count(x => x.Slave is AbyssalTendril); if (currentCount < maxCount) { foreach (var targetTile in targetTiles) { if (!targetTile.Solid && !targetTile.Creatures.Any() && currentCount < maxCount) { var tentacle = new AbyssalTendril(targetTile.World); tentacle.MoveTo(targetTile, 0); tentacle.AddControlTurn(); tentacle.VisualPose = tentacle.FlickPose(CreaturePose.Walk, CreaturePose.Stand, 5); Effect.Apply(new EffectSummon(user, tentacle)); currentCount++; yield return(user.WaitSome(10)); } } } yield return(user.WaitSome(20)); }
private ISkill GetSkill(int skillId) { if (skills == null) { return(null); } foreach (var t in skills) { if (t != null && t.GetSkillId() == skillId) { return(t); } } #if UNITY_EDITOR System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (var t in skills) { sb.Append(t.GetSkillId()); sb.Append("|"); } SkillUtil.LogError($"已经装配的Skill {sb}"); #endif SkillUtil.LogError($"SkillId-> {skillId.ToString()} 不存在"); return(null); }
public override IEnumerable <Wait> RoutineUse(Creature user, object target) { if (target is Creature targetCreature) { Consume(); ShowSkill(user); user.VisualPose = user.FlickPose(CreaturePose.Cast, CreaturePose.Stand, 70); yield return(user.WaitSome(50)); var effect = new FlareCharge(user.World, SpriteLoader.Instance.AddSprite("content/cinder_ender"), user, () => targetCreature.VisualTarget, 200); yield return(user.WaitSome(50)); new ScreenShakeRandom(user.World, 2, 150, LerpHelper.Invert(LerpHelper.Linear)); yield return(new WaitEffect(effect)); new ScreenFlashLocal(user.World, () => ColorMatrix.Ender(), targetCreature.VisualTarget, 60, 150, 80, 50); new EnderNuke(user.World, SpriteLoader.Instance.AddSprite("content/nuke_ender"), targetCreature.VisualTarget, 0.6f, 80); new ScreenShakeRandom(user.World, 8, 80, LerpHelper.QuarticIn); //new BigExplosion(user.World, () => target.VisualTarget, (pos, time) => new EnderExplosion(user.World, pos, Vector2.Zero, time)); yield return(user.WaitSome(10)); var wait = user.Attack(targetCreature, SkillUtil.SafeNormalize(targetCreature.VisualTarget - user.VisualTarget), FlareAttack); yield return(wait); yield return(user.WaitSome(20)); } }
public override Wait Impact(Projectile projectile, Tile tile) { Explosion explosion = new Explosion(projectile.Shooter, SkillUtil.GetCircularArea(tile, Radius), tile.VisualTarget); explosion.Attack = AttackGenerator; return(explosion.Run()); }
//todo 这个触发结构不好 后期优化重构 public bool TriggerMultiple(ISkill skill, List <int> actionIds, int identifyId) { if (skill == null) { SkillUtil.LogError("skill is nullptr"); return(false); } var result = true; foreach (var actionId in actionIds) { skill.AddSkillAction(actionId, identifyId); } foreach (var actionId in actionIds) { if (!Internal_TriggerAction(skill, actionId, identifyId, false, false)) { result = false; } } return(result); }
//连击技能预约超时,显示为不可点击 public void ShowMaskStartCombo() { if (character.isDead) { return; } switch (Fight.Controller.FightController.instance.fightStatus) { case FightStatus.FloatComboing: if (character.characterInfo.skillInfo1 != null) { if (SkillUtil.AttackableFloat(character.characterInfo.skillInfo1)) { if (skillItemView1.canOrder) { skillItemView1.ShowMask(true); } skillItemView1.ShowFloatParticle(false); } } if (character.characterInfo.skillInfo2 != null) { if (SkillUtil.AttackableFloat(character.characterInfo.skillInfo2)) { if (skillItemView1.canOrder) { skillItemView2.ShowMask(true); } skillItemView2.ShowFloatParticle(false); } } break; case FightStatus.TumbleComboing: if (character.characterInfo.skillInfo1 != null) { if (SkillUtil.AttackableTumble(character.characterInfo.skillInfo1)) { if (skillItemView1.canOrder) { skillItemView1.ShowMask(true); } skillItemView1.ShowTumbleParticle(false); } } if (character.characterInfo.skillInfo2 != null) { if (SkillUtil.AttackableTumble(character.characterInfo.skillInfo2)) { if (skillItemView1.canOrder) { skillItemView2.ShowMask(true); } skillItemView2.ShowTumbleParticle(false); } } break; } }
public void Action(ISkill skill, SkillActionData data, CommonParam param) { if (SkillUtil.GetSkillActionDamage(skill.GetSkillLevel(), data, out int damage)) { Damage(skill, param, damage); } skill.RemoveSkillAction(data.Id, param); }
public float GetDuringTime() { if (Math.Abs(duration - SkillDefine.NONE) < 0.01) { duration = SkillUtil.GetBuffDurationTime(this.GetOwner().GetSkillLevel(), data.Duration); } return(duration); }
public void Action(ISkill skill, SkillActionData data, CommonParam param) { if (SkillUtil.TryParseWithDebug(data.Para1, out int removeBuffId, "remove BuffID")) { RemoveBuff(param, removeBuffId); } skill.RemoveSkillAction(data.Id, param); }
public void Action(ISkill skill, SkillActionData data, CommonParam param) { if (SkillUtil.GetSkillActionHeal(skill.GetSkillLevel(), data, out int heal)) { Heal(skill, param, heal); } skill.RemoveSkillAction(data.Id, param); }
void Internal_OnOwnedSkill() { SkillUtil.LogWarning(string.Format("{0} 被动技能初始化", SkillUtil.GetSkillDebugDes(this))); identifyId++; var param = new CommonParam(); AddSkillParam(identifyId, param); }
public void Draw(SceneGame scene, DrawPass pass) { var lich = Origin.GetBehavior <BehaviorLich>(); if (!SlashTime.Done) { SkillUtil.DrawArea(scene, lich.GetImpactArea(), ColorStart, ColorEnd, StartTime.Slide); } }
public void TryTriggerAction(ISkill skill, SkillData data, SkillActionTriggerTime triggerTime, int identifyId, Action confirmCb = null) { SkillUtil.Log(string.Format(" TriggerTime-> {0}", triggerTime)); if (HasAction(data, triggerTime, ref cacheActions)) { confirmCb?.Invoke(); TriggerMultiple(skill, cacheActions, identifyId); } }
void UpdateCd(bool isEnd, object param) { leftCDTime -= cdInterval; if (isEnd) { this.leftCDTime = 0; SkillUtil.LogWarning(string.Format("{0} 冷却完毕 ", SkillUtil.GetSkillDebugDes(this))); } }
public void Action(ISkill skill, SkillActionData data, CommonParam param) { SkillUtil.TryParseWithDebug(data.Para1, out float delayTime, "Delay Time"); SkillUtil.TryParseWithDebug(data.Para1, out int actionId, "Action Id"); object[] actionParam = { skill, data, param, actionId }; var timer = ServiceLocate.Instance.GetService <TimerService>(); timer?.CreateTimer(DelayedCall, 0.1f, delayTime, actionParam); }
public static bool TryParseWithDebug(string param, out float intParam, string error) { if (float.TryParse(param, out intParam)) { return(true); } SkillUtil.LogError(string.Format("{0} [策划配置错误 {1}]", param, error)); return(false); }