public void SetScreenEffect(ActionArguments args, WarUnit doer, Point2 center, IEnumerable<Point2> areaPoints, IEnumerable<Point2> validAreaPoints, int times, Action<int, int> callbackFunc) { args.Model.SetFrameAnimationOnScreen(_surfaces, 150, () => { for (int i = 1; i <= times; i++) callbackFunc(i, times); }); }
public UniformMotionSprite( Surface surface, Point2 startLocation, Point2 endLocation, float totalTime) : this(new StaticAnimation(surface), startLocation, endLocation, totalTime) { }
public SurfaceSprite(Surface surface, Point2 location) { Contract.Requires(surface != null); _surface = surface; _location = location; }
public UnmovingSprite( AnimationSurface animationSurface, Point2 location) { Contract.Requires(animationSurface != null); _animationSurface = animationSurface; _location = location; }
public UniformMotionSprite( Surface surface, Point2 startLocation, Vector2F velocity, float totalTime) : this(new StaticAnimation(surface), startLocation, startLocation + (Vector2)(velocity * totalTime), totalTime) { }
public UniformMotionSprite( AnimationSurface animationSurface, Point2 startLocation, Vector2 velocity, float totalTime) : this(animationSurface, startLocation, startLocation + (Vector2)(velocity * totalTime), totalTime) { }
public override IEnumerable<Point2> GetAreaScope(Situation situation, WarUnit doer, Point2 center) { var v = ScopeUtil.GetDirectionalVector(center - doer.Location); var p = doer.Location; for (int i = 0; i < _range; i++) { p += v; yield return p; } }
public UniformMotionSprite( AnimationSurface animationSurface, Point2 startLocation, Point2 endLocation, float totalTime) { Contract.Requires(animationSurface != null); _animationSurface = animationSurface; StartLocation = startLocation; _location = startLocation; _diffVector = endLocation - startLocation; _totalTime = totalTime; }
protected override IEnumerable<int> GetCoroutine(ActionArguments args, WarUnit doer, Point2 center, Action finished, Action doCoroutine) { // 行為のキャンセルの不許可 args.Model.CancelCommandStack.Clear(); // コストの消費 _cost.Expend(args.Situation, doer); // 攻撃アニメーションとその後の処理を予約する IEnumerable<Point2> areaPoints; var validPoints = _scope.GetValidAreaScope(args.Situation, doer, center, out areaPoints); _screenEffect.SetScreenEffect(args, doer, center, areaPoints, validPoints, doCoroutine); yield return 0; // エフェクト表示 // 洪水処理 var map = args.Situation.Map; var width = map.Width; var height = map.Height; var enableDamageAnimation = false; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { var land = map[x, y]; if (land.Height <= TARGET_HEIGHT) { var taker = land.Unit; if (taker != null && _attackType != AttackType.なし) { AdditionalEffect cond; var damage = BattleActionUtil.GetMagicDamage(doer, taker, _power, _attackType, out cond); BattleActionUtil.RunAttackRoutine(args, doer, taker, damage, cond, doCoroutine); enableDamageAnimation = true; } // マップの更新 if (brinkNames.Contains(land.Info.Name)) { map[x, y] = new Land(land.Height - TARGET_HEIGHT, land.Landform, null); } else { map[x, y] = new Land(land.Height - TARGET_HEIGHT, _brinkLandform, null); } } } } if (enableDamageAnimation) yield return 0; // ダメージ表示 finished(); }
public static List<Point2> GetStraightScopePoints(Point2 originPoint, int range) { var points = new List<Point2>(range * 6); for (int j = 1; j <= range; j++) { points.Add(new Point2(originPoint.X - j, originPoint.Y + 0)); points.Add(new Point2(originPoint.X - j, originPoint.Y - j)); points.Add(new Point2(originPoint.X + 0, originPoint.Y - j)); points.Add(new Point2(originPoint.X + j, originPoint.Y + 0)); points.Add(new Point2(originPoint.X + j, originPoint.Y + j)); points.Add(new Point2(originPoint.X + 0, originPoint.Y + j)); } return points; }
public virtual IEnumerable<Point2> GetValidAreaScope(Situation situation, WarUnit doer, Point2 center, out IEnumerable<Point2> areaScope) { var validAreaPoints = new List<Point2>(); areaScope = GetAreaScope(situation, doer, center); foreach (var p in areaScope) { if (IsValidPoint(situation, doer, p)) { validAreaPoints.Add(p); } } return validAreaPoints; }
public void SetScreenEffect(ActionArguments args, WarUnit doer, Point2 center, IEnumerable<Point2> areaPoints, IEnumerable<Point2> validAreaPoints, int times, Action<int, int> callbackFunc) { var model = args.Model; int delay = 0; for (int i = 1; i <= times; i++) { foreach (var p in areaPoints) { var anime = model.CreateDirectedUniformMotionAnimationOnMap(_surfaces, doer.Location, p, 0.125f); anime = new ExtendTimeAnimationSprite(anime, delay, 0); model.ChipAnimations.Add(anime, callbackFunc.GetCurrying(i, times)); delay += 300; } } }
public static List<Point2> GetScopePoints(Point2 originPoint, int range) { var points = new List<Point2>(range * (3 * range + 3) + 1); for (int j = -range; j <= range; j++) { points.Add(new Point2(originPoint.X + j, originPoint.Y)); } for (int i = 1; i <= range; i++) { for (int j = -range; j <= range - i; j++) { points.Add(new Point2(originPoint.X + j, originPoint.Y - i)); points.Add(new Point2(originPoint.X + j + i, originPoint.Y + i)); } } return points; }
protected override IEnumerable<int> GetCoroutine(ActionArguments args, WarUnit doer, Point2 center, Action finished, Action doCoroutine) { // 行為のキャンセルの不許可 args.Model.CancelCommandStack.Clear(); // コストの消費 _cost.Expend(args.Situation, doer); // 攻撃アニメーションとその後の処理を予約する IEnumerable<Point2> areaPoints; var validPoints = _scope.GetValidAreaScope(args.Situation, doer, center, out areaPoints); _screenEffect.SetScreenEffect(args, doer, center, areaPoints, validPoints, doCoroutine); yield return 0; // エフェクト表示 foreach (var p in validPoints) { var taker = args.Situation.Map[p].Unit; taker.Conditions.Add(_cond, args.Situation); } finished(); }
protected virtual bool IsValidPoint(Situation situation, WarUnit doer, Point2 p) { var unit = situation.Map[p].Unit; // チップの情報からターゲットタイプの値を算出 TargetType type; if (unit == null) { type = TargetType.NONE; } else { if (doer.IsOpponent(unit)) type = TargetType.ENEMY; else type = TargetType.FRIEND; } // スコープのターゲットタイプに内包されるかチェック return (_targetType & type) != 0; }
protected override IEnumerable<int> GetCoroutine(ActionArguments args, WarUnit doer, Point2 center, Action finished, Action doCoroutine) { // 行為のキャンセルの不許可 args.Model.CancelCommandStack.Clear(); Debug.Assert(args.Situation.Map[center].Unit != null, "選択位置にユニットが存在しません."); var taker = args.Situation.Map[center].Unit; var doerAttack = doer.Status.DefaultAttacks.Select(atk => new { Doer = doer, Taker = taker, atk.Type, atk.Power }); var takerAttack = taker.Status.DefaultAttacks.Select(atk => new { Doer = taker, Taker = doer, atk.Type, atk.Power }); var source = doerAttack.AlternatelyConcat(takerAttack) .Where(info => info.Type != AttackType.なし); foreach (var info in source) { // ローカル変数にも代入しておく(ごっちゃにならないように) doer = info.Doer; taker = info.Taker; // アニメーション中は、マップ上のユニット表示をオフにする doer.Visible = false; // 攻撃アニメーションとその後の処理を予約する args.Model.SetContinuouslyMovingAnimationOnMap( doer.ChipImage, new[] { doer.Location, taker.Location, doer.Location }, args.Model.ATTACK_EFFECT_TIME, 0, doCoroutine); yield return 0; // エフェクト表示 doer.Visible = true; AdditionalEffect cond; var damage = BattleActionUtil.GetDamage(doer, taker, info.Power, info.Type, out cond); BattleActionUtil.RunAttackRoutine(args, doer, taker, damage, cond, doCoroutine); yield return 0; // ダメージ表示 // どちらかが死亡したら処理を中断 if (!doer.Alive || !taker.Alive) break; } finished(); }
protected override IEnumerable<int> GetCoroutine(ActionArguments args, WarUnit doer, Point2 center, Action finished, Action doCoroutine) { // 行為のキャンセルの不許可 args.Model.CancelCommandStack.Clear(); // コストの消費 _cost.Expend(args.Situation, doer); IEnumerable<Point2> areaPoints; var validPoints = _scope.GetValidAreaScope(args.Situation, doer, center, out areaPoints); var times = XMath.Center(doer.SkillTimes, 1, _maxTimes); _screenEffect.SetScreenEffect(args, doer, center, areaPoints, validPoints, times, (times_, maxTimes_) => { foreach (var p in validPoints) { var taker = args.Situation.Map[p].Unit; AdditionalEffect cond; var value = BattleActionUtil.GetSkillValue(doer, taker, _power, _attackType, _atkDependency, _defDependency, out cond); var action = times_ < maxTimes_ ? doCoroutine.GetNOP() : doCoroutine; if (_attackType != AttackType.体力回復 && _attackType != AttackType.魔力回復) { BattleActionUtil.RunAttackRoutine(args, doer, taker, value, cond, action); } else { if (_attackType == AttackType.体力回復) taker.HealHP(args.Situation, doer, value); else taker.HealMP(args.Situation, doer, value); // 回復値の表示 args.Model.SetHealAnimationOnMap(value, doer.Location, action); } } }); yield return 0; // 最後のダメージ表示 finished(); }
protected override IEnumerable<int> GetCoroutine(ActionArguments args, WarUnit doer, Point2 center, Action finished, Action doCoroutine) { // 行為のキャンセルの不許可 args.Model.CancelCommandStack.Clear(); // コストの消費 _cost.Expend(args.Situation, doer); // 攻撃アニメーションとその後の処理を予約する IEnumerable<Point2> areaPoints; var validPoints = _scope.GetValidAreaScope(args.Situation, doer, center, out areaPoints); _screenEffect.SetScreenEffect(args, doer, center, areaPoints, validPoints, doCoroutine); yield return 0; // エフェクト表示 foreach (var p in validPoints) { Debug.Assert(args.Situation.Map[p].Unit == null); var unit = WarGlobal.UnitBuilder.Create(new Unit(_unit), doer.Side, null); args.Situation.Units.AddUnit(unit); args.Situation.Map.Deploy(unit, p); } finished(); }
protected override IEnumerable<int> GetCoroutine(ActionArguments args, WarUnit doer, Point2 center, Action finished, Action doCoroutine) { // 行為のキャンセルの不許可 args.Model.CancelCommandStack.Clear(); // コストの消費 _cost.Expend(args.Situation, doer); // 攻撃アニメーションとその後の処理を予約する IEnumerable<Point2> areaPoints; var validPoints = _scope.GetValidAreaScope(args.Situation, doer, center, out areaPoints); _screenEffect.SetScreenEffect(args, doer, center, areaPoints, validPoints, doCoroutine); yield return 0; // エフェクト表示 foreach (var p in validPoints) { var taker = args.Situation.Map[p].Unit; if (!AttackTypes.Heal.Contains(_attackType)) { AdditionalEffect cond; var damage = BattleActionUtil.GetMagicDamage(doer, taker, _power, _attackType, out cond); BattleActionUtil.RunAttackRoutine(args, doer, taker, damage, cond, doCoroutine); } else { var value = BattleActionUtil.GetMagicHeal(doer, taker, _power); if (_attackType == AttackType.体力回復) taker.HealHP(args.Situation, doer, value); else taker.HealMP(args.Situation, doer, value); // 回復値の表示 args.Model.SetHealAnimationOnMap(value, doer.Location, doCoroutine); } } yield return 0; // ダメージ表示 finished(); }
protected override IEnumerable<int> GetCoroutine(ActionArguments args, WarUnit doer, Point2 center, Action finished, Action doCoroutine) { // 行為のキャンセルの不許可 args.Model.CancelCommandStack.Clear(); // コストの消費 _cost.Expend(args.Situation, doer); // 攻撃アニメーションとその後の処理を予約する IEnumerable<Point2> areaPoints; var validPoints = _scope.GetValidAreaScope(args.Situation, doer, center, out areaPoints); _screenEffect.SetScreenEffect(args, doer, center, areaPoints, validPoints, doCoroutine); yield return 0; // エフェクト表示 // 対象内の壁を破壊 var map = args.Situation.Map; var enableDamageAnimation = false; foreach (var p in areaPoints) { var land = map[p]; if (land.Construct != null && land.Construct.Info.Name == "壁") { map[p] = new Land(land.Height, land.Landform, null); if (land.Unit != null && _attackType != AttackType.なし) { var taker = land.Unit; AdditionalEffect cond; var damage = BattleActionUtil.GetMagicDamage(doer, taker, _power, _attackType, out cond); BattleActionUtil.RunAttackRoutine(args, doer, taker, damage, cond, doCoroutine); enableDamageAnimation = true; } } } if (enableDamageAnimation) yield return 0; // ダメージ表示 finished(); }
protected override IEnumerable<int> GetCoroutine(ActionArguments args, WarUnit doer, Point2 center, Action finished, Action doCoroutine) { // キャンセル処理のために記憶する var oldLocation = doer.Location; var resetCommandState = doer.SaveCommandState(); // 移動アニメーション用に経路を生成する var movePoints = new Stack<Point2>(); var movePoint = _scope.CurrentMovableArea.Find(p => p.Point == center); while (movePoint != null) { movePoints.Push(movePoint.Point); movePoint = movePoint.From; } // アニメーション中は、マップ上のユニット表示をオフにする doer.Visible = false; // 移動アニメーションのセット args.Model.SetContinuouslyMovingAnimationOnMap(doer.ChipImage, movePoints, 150, 20, doCoroutine); yield return 0; // 移動アニメーションの表示 // アニメーション後に元に戻す doer.Visible = true; args.Situation.Map.MoveUnit(doer, center); // アクション終了の通知 finished(); // 移動前に戻すキャンセル処理の追加 args.Model.CancelCommandStack.Push( () => { args.Situation.Map.MoveUnit(doer, oldLocation); resetCommandState(); return false; // キャンセル処理の続行 }); }
protected abstract IEnumerable<int> GetCoroutine(ActionArguments args, WarUnit doer, Point2 center, Action finished, Action doCoroutine);
/// <summary> /// マップチップ上に指定した開始位置から指定した終了位置まで指定した速度で等速直線移動するアニメーションを配置します。 /// なお、サーフェイスは指定したサーフェイス郡の中から移動方向に合わせて適切に選択されます。 /// </summary> /// <param name="surfaces"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="speed"></param> /// <param name="endAnimationEvent"></param> public void SetDirectedUniformMotionAnimationOnMap( IList<Surface> surfaces, Point2 from, Point2 to, float speed, Action endAnimationEvent) { var anime = _mapWindow.CreateDirectedUniformMotionAnimationOnMap(surfaces, from, to, speed); _chipAnimations.Add(anime, endAnimationEvent); }
public IEnumerable<Point2> GetAreaScope(Situation situation, WarUnit doer, Point2 center) { return new[] { center }; }
public IEnumerable<Point2> GetValidAreaScope(Situation situation, WarUnit doer, Point2 center, out IEnumerable<Point2> areaScope) { areaScope = ((IScope)this).GetAreaScope(situation, doer, center); return areaScope; }
/// <summary> /// マップチップ上に指定した複数のサーフェイスを一定時間ごとに切り替わるアニメーションを配置します。 /// </summary> /// <param name="surfaces"></param> /// <param name="chipPoint"></param> /// <param name="endAnimationEvent"></param> public void SetFrameAnimationOnMap(IList<Surface> surfaces, Point2 chipPoint, Action endAnimationEvent) { var anime = _mapWindow.CreateFrameAnimationOnMap(surfaces, chipPoint, 150); _chipAnimations.Add(anime, endAnimationEvent); }
/// <summary> /// マップチップ上に指定した回復値を表示するアニメーションを配置します。 /// </summary> /// <param name="value"></param> /// <param name="point"></param> /// <param name="endAnimationEvent"></param> public void SetHealAnimationOnMap(int value, Point2 point, Action endAnimationEvent) { var str = value != 0 ? value.ToString() : "ミス"; var anime = _mapWindow.CreateStringAnimationOnMap(str, point, Color.Blue, 500); _chipAnimations.Add(anime, endAnimationEvent); }
public override IEnumerable<Point2> GetAreaScope(Situation situation, WarUnit doer, Point2 center) { return ScopeUtil.GetScopePoints(center, _area - 1); // 範囲は1で1マス }
public abstract void Execute(ActionArguments args, WarUnit doer, Point2 center, Action finished);
public override void Execute(ActionArguments args, WarUnit doer, Point2 center, Action finished) { IEnumerator<int> enumerator = null; enumerator = GetCoroutine(args, doer, center, finished, () => enumerator.MoveNext()).GetEnumerator(); enumerator.MoveNext(); }