Merge pull request #7254 from penev92/bleed_moveFiles
Moving more files to Common
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Effects;
|
||||
using OpenRA.Traits;
|
||||
|
||||
|
||||
@@ -1,271 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
public abstract class Enter : Activity
|
||||
{
|
||||
public enum ReserveStatus { None, TooFar, Pending, Ready }
|
||||
enum State { ApproachingOrEntering, Inside, Exiting, Done }
|
||||
|
||||
readonly IMove move;
|
||||
readonly int maxTries = 0;
|
||||
readonly bool targetCenter;
|
||||
public Target Target { get { return target; } }
|
||||
Target target;
|
||||
State nextState = State.ApproachingOrEntering; // Hint/starting point for next state
|
||||
bool isEnteringOrInside = false; // Used to know if exiting should be used
|
||||
WPos savedPos; // Position just before entering
|
||||
Activity inner;
|
||||
bool firstApproach = true;
|
||||
|
||||
protected Enter(Actor self, Actor target, int maxTries = 1, bool targetCenter = false)
|
||||
{
|
||||
this.move = self.Trait<IMove>();
|
||||
this.target = Target.FromActor(target);
|
||||
this.maxTries = maxTries;
|
||||
this.targetCenter = targetCenter;
|
||||
}
|
||||
|
||||
// CanEnter(target) should to be true; othwise, Enter may abort.
|
||||
// Tries counter starts at 1 (reset every tick)
|
||||
protected virtual bool TryGetAlternateTarget(Actor self, int tries, ref Target target) { return false; }
|
||||
protected virtual bool CanReserve(Actor self) { return true; }
|
||||
protected virtual ReserveStatus Reserve(Actor self)
|
||||
{
|
||||
return !CanReserve(self) ? ReserveStatus.None : move.CanEnterTargetNow(self, target) ? ReserveStatus.Ready : ReserveStatus.TooFar;
|
||||
}
|
||||
|
||||
protected virtual void Unreserve(Actor self, bool abort) { }
|
||||
protected virtual void OnInside(Actor self) { }
|
||||
|
||||
protected bool TryGetAlternateTargetInCircle(Actor self, WRange radius, Action<Target> update, Func<Actor, bool> primaryFilter, Func<Actor, bool>[] preferenceFilters = null)
|
||||
{
|
||||
var radiusSquared = radius.Range * radius.Range;
|
||||
var diff = new WVec(radius, radius, WRange.Zero);
|
||||
var candidates = self.World.ActorMap.ActorsInBox(self.CenterPosition - diff, self.CenterPosition + diff)
|
||||
.Where(primaryFilter).Select(a => new { Actor = a, Ls = (self.CenterPosition - a.CenterPosition).HorizontalLengthSquared })
|
||||
.Where(p => p.Ls <= radiusSquared).OrderBy(p => p.Ls).Select(p => p.Actor);
|
||||
if (preferenceFilters != null)
|
||||
foreach (var filter in preferenceFilters)
|
||||
{
|
||||
var preferredCandidate = candidates.FirstOrDefault(filter);
|
||||
if (preferredCandidate == null)
|
||||
continue;
|
||||
target = Target.FromActor(preferredCandidate);
|
||||
update(target);
|
||||
return true;
|
||||
}
|
||||
|
||||
var candidate = candidates.FirstOrDefault();
|
||||
if (candidate == null)
|
||||
return false;
|
||||
target = Target.FromActor(candidate);
|
||||
update(target);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called when inner activity is this and returns inner activity for next tick.
|
||||
protected virtual Activity InsideTick(Actor self) { return null; }
|
||||
|
||||
// Abort entering and/or leave if necessary
|
||||
protected virtual void AbortOrExit(Actor self)
|
||||
{
|
||||
if (nextState == State.Done)
|
||||
return;
|
||||
nextState = isEnteringOrInside ? State.Exiting : State.Done;
|
||||
if (inner == this)
|
||||
inner = null;
|
||||
else if (inner != null)
|
||||
inner.Cancel(self);
|
||||
if (isEnteringOrInside)
|
||||
Unreserve(self, true);
|
||||
}
|
||||
|
||||
// Cancel inner activity and mark as done unless already leaving or done
|
||||
protected void Done(Actor self)
|
||||
{
|
||||
if (nextState == State.Done)
|
||||
return;
|
||||
nextState = State.Done;
|
||||
if (inner == this)
|
||||
inner = null;
|
||||
else if (inner != null)
|
||||
inner.Cancel(self);
|
||||
}
|
||||
|
||||
public override void Cancel(Actor self)
|
||||
{
|
||||
AbortOrExit(self);
|
||||
if (nextState < State.Exiting)
|
||||
base.Cancel(self);
|
||||
else
|
||||
NextActivity = null;
|
||||
}
|
||||
|
||||
ReserveStatus TryReserveElseTryAlternateReserve(Actor self)
|
||||
{
|
||||
for (var tries = 0;;)
|
||||
switch (Reserve(self))
|
||||
{
|
||||
case ReserveStatus.None:
|
||||
if (++tries > maxTries || !TryGetAlternateTarget(self, tries, ref target))
|
||||
return ReserveStatus.None;
|
||||
continue;
|
||||
case ReserveStatus.TooFar:
|
||||
// Always goto to transport on first approach
|
||||
if (firstApproach)
|
||||
{
|
||||
firstApproach = false;
|
||||
return ReserveStatus.TooFar;
|
||||
}
|
||||
|
||||
if (++tries > maxTries)
|
||||
return ReserveStatus.TooFar;
|
||||
Target t = target;
|
||||
if (!TryGetAlternateTarget(self, tries, ref t))
|
||||
return ReserveStatus.TooFar;
|
||||
if ((target.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= (t.CenterPosition - self.CenterPosition).HorizontalLengthSquared)
|
||||
return ReserveStatus.TooFar;
|
||||
target = t;
|
||||
continue;
|
||||
case ReserveStatus.Pending:
|
||||
return ReserveStatus.Pending;
|
||||
case ReserveStatus.Ready:
|
||||
return ReserveStatus.Ready;
|
||||
}
|
||||
}
|
||||
|
||||
State FindAndTransitionToNextState(Actor self)
|
||||
{
|
||||
switch (nextState)
|
||||
{
|
||||
case State.ApproachingOrEntering:
|
||||
|
||||
// Reserve to enter or approach
|
||||
isEnteringOrInside = false;
|
||||
switch (TryReserveElseTryAlternateReserve(self))
|
||||
{
|
||||
case ReserveStatus.None:
|
||||
return State.Done; // No available target -> abort to next activity
|
||||
case ReserveStatus.TooFar:
|
||||
inner = move.MoveToTarget(self, targetCenter ? Target.FromPos(target.CenterPosition) : target); // Approach
|
||||
return State.ApproachingOrEntering;
|
||||
case ReserveStatus.Pending:
|
||||
return State.ApproachingOrEntering; // Retry next tick
|
||||
case ReserveStatus.Ready:
|
||||
break; // Reserved target -> start entering target
|
||||
}
|
||||
|
||||
// Entering
|
||||
isEnteringOrInside = true;
|
||||
savedPos = self.CenterPosition; // Save position of self, before entering, for returning on exit
|
||||
|
||||
inner = move.MoveIntoTarget(self, target); // Enter
|
||||
|
||||
if (inner != null)
|
||||
{
|
||||
nextState = State.Inside; // Should be inside once inner activity is null
|
||||
return State.ApproachingOrEntering;
|
||||
}
|
||||
|
||||
// Can enter but there is no activity for it, so go inside without one
|
||||
goto case State.Inside;
|
||||
|
||||
case State.Inside:
|
||||
// Might as well teleport into target if there is no MoveIntoTarget activity
|
||||
if (nextState == State.ApproachingOrEntering)
|
||||
nextState = State.Inside;
|
||||
|
||||
// Otherwise, try to recover from moving target
|
||||
else if (target.CenterPosition != self.CenterPosition)
|
||||
{
|
||||
nextState = State.ApproachingOrEntering;
|
||||
Unreserve(self, false);
|
||||
if (Reserve(self) == ReserveStatus.Ready)
|
||||
{
|
||||
inner = move.MoveIntoTarget(self, target); // Enter
|
||||
if (inner != null)
|
||||
return State.ApproachingOrEntering;
|
||||
|
||||
nextState = State.ApproachingOrEntering;
|
||||
goto case State.ApproachingOrEntering;
|
||||
}
|
||||
|
||||
nextState = State.ApproachingOrEntering;
|
||||
isEnteringOrInside = false;
|
||||
inner = move.MoveIntoWorld(self, self.World.Map.CellContaining(savedPos));
|
||||
|
||||
return State.ApproachingOrEntering;
|
||||
}
|
||||
|
||||
OnInside(self);
|
||||
|
||||
// Return if Abort(Actor) or Done(self) was called from OnInside.
|
||||
if (nextState >= State.Exiting)
|
||||
return State.Inside;
|
||||
|
||||
inner = this; // Start inside activity
|
||||
nextState = State.Exiting; // Exit once inner activity is null (unless Done(self) is called)
|
||||
return State.Inside;
|
||||
|
||||
// TODO: Handle target moved while inside or always call done for movable targets and use a separate exit activity
|
||||
case State.Exiting:
|
||||
inner = move.MoveIntoWorld(self, self.World.Map.CellContaining(savedPos));
|
||||
|
||||
// If not successfully exiting, retry on next tick
|
||||
if (inner == null)
|
||||
return State.Exiting;
|
||||
isEnteringOrInside = false;
|
||||
nextState = State.Done;
|
||||
return State.Exiting;
|
||||
|
||||
case State.Done:
|
||||
return State.Done;
|
||||
}
|
||||
|
||||
return State.Done; // dummy to quiet dumb compiler
|
||||
}
|
||||
|
||||
Activity CanceledTick(Actor self)
|
||||
{
|
||||
if (inner == null)
|
||||
return Util.RunActivity(self, NextActivity);
|
||||
inner.Cancel(self);
|
||||
inner.Queue(NextActivity);
|
||||
return Util.RunActivity(self, inner);
|
||||
}
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
if (IsCanceled)
|
||||
return CanceledTick(self);
|
||||
|
||||
// Check target validity if not exiting or done
|
||||
if (nextState != State.Done && (target.Type != TargetType.Actor || !target.IsValidFor(self)))
|
||||
AbortOrExit(self);
|
||||
|
||||
// If no current activity, tick next activity
|
||||
if (inner == null && FindAndTransitionToNextState(self) == State.Done)
|
||||
return CanceledTick(self);
|
||||
|
||||
// Run inner activity/InsideTick
|
||||
inner = inner == this ? InsideTick(self) : Util.RunActivity(self, inner);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
class RepairBuilding : Enter
|
||||
{
|
||||
readonly Actor target;
|
||||
readonly Health health;
|
||||
|
||||
public RepairBuilding(Actor self, Actor target)
|
||||
: base(self, target)
|
||||
{
|
||||
this.target = target;
|
||||
health = target.Trait<Health>();
|
||||
}
|
||||
|
||||
protected override bool CanReserve(Actor self)
|
||||
{
|
||||
return health.DamageState != DamageState.Undamaged;
|
||||
}
|
||||
|
||||
protected override void OnInside(Actor self)
|
||||
{
|
||||
if (health.DamageState == DamageState.Undamaged)
|
||||
return;
|
||||
target.InflictDamage(self, -health.MaxHP, null);
|
||||
self.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Drawing;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Traits
|
||||
{
|
||||
public static class ActorExts
|
||||
{
|
||||
public static bool AppearsFriendlyTo(this Actor self, Actor toActor)
|
||||
{
|
||||
var stance = toActor.Owner.Stances[self.Owner];
|
||||
if (stance == Stance.Ally)
|
||||
return true;
|
||||
|
||||
if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.HasTrait<IgnoresDisguise>())
|
||||
return toActor.Owner.Stances[self.EffectiveOwner.Owner] == Stance.Ally;
|
||||
|
||||
return stance == Stance.Ally;
|
||||
}
|
||||
|
||||
public static bool AppearsHostileTo(this Actor self, Actor toActor)
|
||||
{
|
||||
var stance = toActor.Owner.Stances[self.Owner];
|
||||
if (stance == Stance.Ally)
|
||||
return false; /* otherwise, we'll hate friendly disguised spies */
|
||||
|
||||
if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.HasTrait<IgnoresDisguise>())
|
||||
return toActor.Owner.Stances[self.EffectiveOwner.Owner] == Stance.Enemy;
|
||||
|
||||
return stance == Stance.Enemy;
|
||||
}
|
||||
|
||||
public static Target ResolveFrozenActorOrder(this Actor self, Order order, Color targetLine)
|
||||
{
|
||||
// Not targeting a frozen actor
|
||||
if (order.ExtraData == 0)
|
||||
return Target.FromOrder(self.World, order);
|
||||
|
||||
// Targeted an actor under the fog
|
||||
var frozenLayer = self.Owner.PlayerActor.TraitOrDefault<FrozenActorLayer>();
|
||||
if (frozenLayer == null)
|
||||
return Target.Invalid;
|
||||
|
||||
var frozen = frozenLayer.FromID(order.ExtraData);
|
||||
if (frozen == null)
|
||||
return Target.Invalid;
|
||||
|
||||
// Flashes the frozen proxy
|
||||
self.SetTargetLine(frozen, targetLine, true);
|
||||
|
||||
// Target is still alive - resolve the real order
|
||||
if (frozen.Actor != null && frozen.Actor.IsInWorld)
|
||||
return Target.FromActor(frozen.Actor);
|
||||
|
||||
if (!order.Queued)
|
||||
self.CancelActivity();
|
||||
|
||||
var move = self.TraitOrDefault<IMove>();
|
||||
if (move != null)
|
||||
{
|
||||
// Move within sight range of the frozen actor
|
||||
var sight = self.TraitOrDefault<RevealsShroud>();
|
||||
var range = sight != null ? sight.Range : WRange.FromCells(2);
|
||||
|
||||
self.QueueActivity(move.MoveWithinRange(Target.FromPos(frozen.CenterPosition), range));
|
||||
}
|
||||
|
||||
return Target.Invalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Orders;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Orders;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[Desc("Actor can reveal Cloak actors in a specified range.")]
|
||||
class DetectCloakedInfo : TraitInfo<DetectCloaked>
|
||||
{
|
||||
[Desc("Specific cloak classifications I can reveal.")]
|
||||
public readonly string[] CloakTypes = { "Cloak" };
|
||||
|
||||
[Desc("Measured in cells.")]
|
||||
public readonly int Range = 5;
|
||||
}
|
||||
|
||||
class DetectCloaked { }
|
||||
}
|
||||
@@ -135,8 +135,4 @@ namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
public void Attacking(Actor self, Target target, Armament a, Barrel barrel) { DisguiseAs(self, null); }
|
||||
}
|
||||
|
||||
[Desc("Allows automatic targeting of disguised actors.")]
|
||||
class IgnoresDisguiseInfo : TraitInfo<IgnoresDisguise> { }
|
||||
class IgnoresDisguise { }
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
class Rank : IEffect
|
||||
{
|
||||
readonly Actor self;
|
||||
readonly Animation anim;
|
||||
readonly string paletteName;
|
||||
|
||||
public Rank(Actor self, string paletteName)
|
||||
{
|
||||
this.self = self;
|
||||
this.paletteName = paletteName;
|
||||
|
||||
var xp = self.Trait<GainsExperience>();
|
||||
anim = new Animation(self.World, "rank");
|
||||
anim.PlayRepeating("rank");
|
||||
anim.PlayFetchIndex("rank", () => xp.Level == 0 ? 0 : xp.Level - 1);
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
if (self.IsDead)
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
else
|
||||
anim.Tick();
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
if (!self.IsInWorld)
|
||||
yield break;
|
||||
|
||||
if (self.IsDead)
|
||||
yield break;
|
||||
|
||||
if (!self.Owner.IsAlliedWith(self.World.RenderPlayer))
|
||||
yield break;
|
||||
|
||||
if (wr.world.FogObscures(self))
|
||||
yield break;
|
||||
|
||||
var pos = wr.ScreenPxPosition(self.CenterPosition);
|
||||
var bounds = self.Bounds;
|
||||
bounds.Offset(pos.X, pos.Y);
|
||||
|
||||
var palette = wr.Palette(paletteName);
|
||||
var offset = (int)(4 / wr.Viewport.Zoom);
|
||||
var effectPos = wr.Position(new int2(bounds.Right - offset, bounds.Bottom - offset));
|
||||
yield return new SpriteRenderable(anim.Image, effectPos, WVec.Zero, 0, palette, 1f / wr.Viewport.Zoom, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Mods.Common.Orders;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Traits
|
||||
{
|
||||
[Desc("Can instantly repair other actors, but gets consumed afterwards.")]
|
||||
class EngineerRepairInfo : TraitInfo<EngineerRepair> { }
|
||||
|
||||
class EngineerRepair : IIssueOrder, IResolveOrder, IOrderVoice
|
||||
{
|
||||
public IEnumerable<IOrderTargeter> Orders
|
||||
{
|
||||
get { yield return new EngineerRepairOrderTargeter(); }
|
||||
}
|
||||
|
||||
public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)
|
||||
{
|
||||
if (order.OrderID != "EngineerRepair")
|
||||
return null;
|
||||
|
||||
if (target.Type == TargetType.FrozenActor)
|
||||
return new Order(order.OrderID, self, queued) { ExtraData = target.FrozenActor.ID };
|
||||
|
||||
return new Order(order.OrderID, self, queued) { TargetActor = target.Actor };
|
||||
}
|
||||
|
||||
static bool IsValidOrder(Actor self, Order order)
|
||||
{
|
||||
// Not targeting a frozen actor
|
||||
if (order.ExtraData == 0 && order.TargetActor == null)
|
||||
return false;
|
||||
|
||||
if (order.ExtraData != 0)
|
||||
{
|
||||
// Targeted an actor under the fog
|
||||
var frozenLayer = self.Owner.PlayerActor.TraitOrDefault<FrozenActorLayer>();
|
||||
if (frozenLayer == null)
|
||||
return false;
|
||||
|
||||
var frozen = frozenLayer.FromID(order.ExtraData);
|
||||
if (frozen == null)
|
||||
return false;
|
||||
|
||||
return frozen.DamageState > DamageState.Undamaged;
|
||||
}
|
||||
|
||||
return order.TargetActor.GetDamageState() > DamageState.Undamaged;
|
||||
}
|
||||
|
||||
public string VoicePhraseForOrder(Actor self, Order order)
|
||||
{
|
||||
return order.OrderString == "EngineerRepair" && IsValidOrder(self, order)
|
||||
? "Attack" : null;
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString != "EngineerRepair" || !IsValidOrder(self, order))
|
||||
return;
|
||||
|
||||
var target = self.ResolveFrozenActorOrder(order, Color.Yellow);
|
||||
if (target.Type != TargetType.Actor)
|
||||
return;
|
||||
|
||||
if (!order.Queued)
|
||||
self.CancelActivity();
|
||||
|
||||
self.SetTargetLine(target, Color.Yellow);
|
||||
self.QueueActivity(new RepairBuilding(self, target.Actor));
|
||||
}
|
||||
|
||||
class EngineerRepairOrderTargeter : UnitOrderTargeter
|
||||
{
|
||||
public EngineerRepairOrderTargeter()
|
||||
: base("EngineerRepair", 6, "goldwrench", false, true) { }
|
||||
|
||||
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
if (!target.HasTrait<EngineerRepairable>())
|
||||
return false;
|
||||
|
||||
if (self.Owner.Stances[target.Owner] != Stance.Ally)
|
||||
return false;
|
||||
|
||||
if (target.GetDamageState() == DamageState.Undamaged)
|
||||
cursor = "goldwrench-blocked";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
if (!target.Info.Traits.Contains<EngineerRepairable>())
|
||||
return false;
|
||||
|
||||
if (self.Owner.Stances[target.Owner] != Stance.Ally)
|
||||
return false;
|
||||
|
||||
if (target.DamageState == DamageState.Undamaged)
|
||||
cursor = "goldwrench-blocked";
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Desc("Eligible for instant repair.")]
|
||||
class EngineerRepairableInfo : TraitInfo<EngineerRepairable> { }
|
||||
|
||||
class EngineerRepairable { }
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Orders;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Effects;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[Desc("This actor's experience increases when it has killed a GivesExperience actor.")]
|
||||
public class GainsExperienceInfo : ITraitInfo, Requires<ValuedInfo>
|
||||
{
|
||||
[FieldLoader.LoadUsing("LoadUpgrades")]
|
||||
[Desc("Upgrades to grant at each level",
|
||||
"Key is the XP requirements for each level as a percentage of our own value.",
|
||||
"Value is a list of the upgrade types to grant")]
|
||||
public readonly Dictionary<int, string[]> Upgrades = null;
|
||||
|
||||
[Desc("Palette for the chevron glyph rendered in the selection box.")]
|
||||
public readonly string ChevronPalette = "effect";
|
||||
|
||||
[Desc("Palette for the level up sprite.")]
|
||||
public readonly string LevelUpPalette = "effect";
|
||||
|
||||
public object Create(ActorInitializer init) { return new GainsExperience(init, this); }
|
||||
|
||||
static object LoadUpgrades(MiniYaml y)
|
||||
{
|
||||
MiniYaml upgrades;
|
||||
|
||||
if (!y.ToDictionary().TryGetValue("Upgrades", out upgrades))
|
||||
{
|
||||
return new Dictionary<int, string[]>()
|
||||
{
|
||||
{ 200, new[] { "firepower", "damage", "speed", "reload", "inaccuracy" } },
|
||||
{ 400, new[] { "firepower", "damage", "speed", "reload", "inaccuracy" } },
|
||||
{ 800, new[] { "firepower", "damage", "speed", "reload", "inaccuracy" } },
|
||||
{ 1600, new[] { "firepower", "damage", "speed", "reload", "inaccuracy", "eliteweapon", "selfheal" } }
|
||||
};
|
||||
}
|
||||
|
||||
return upgrades.Nodes.ToDictionary(
|
||||
kv => FieldLoader.GetValue<int>("(key)", kv.Key),
|
||||
kv => FieldLoader.GetValue<string[]>("(value)", kv.Value.Value));
|
||||
}
|
||||
}
|
||||
|
||||
public class GainsExperience : ISync
|
||||
{
|
||||
readonly Actor self;
|
||||
readonly GainsExperienceInfo info;
|
||||
|
||||
readonly List<Pair<int, string[]>> nextLevel = new List<Pair<int, string[]>>();
|
||||
|
||||
// Stored as a percentage of our value
|
||||
[Sync] int experience = 0;
|
||||
|
||||
[Sync] public int Level { get; private set; }
|
||||
public readonly int MaxLevel;
|
||||
|
||||
public GainsExperience(ActorInitializer init, GainsExperienceInfo info)
|
||||
{
|
||||
self = init.self;
|
||||
this.info = info;
|
||||
|
||||
MaxLevel = info.Upgrades.Count;
|
||||
|
||||
var cost = self.Info.Traits.Get<ValuedInfo>().Cost;
|
||||
foreach (var kv in info.Upgrades)
|
||||
nextLevel.Add(Pair.New(kv.Key * cost, kv.Value));
|
||||
|
||||
if (init.Contains<ExperienceInit>())
|
||||
GiveExperience(init.Get<ExperienceInit, int>());
|
||||
}
|
||||
|
||||
public bool CanGainLevel { get { return Level < MaxLevel; } }
|
||||
|
||||
public void GiveLevels(int numLevels)
|
||||
{
|
||||
var newLevel = Math.Min(Level + numLevels, MaxLevel);
|
||||
GiveExperience(nextLevel[newLevel - 1].First - experience);
|
||||
}
|
||||
|
||||
public void GiveExperience(int amount)
|
||||
{
|
||||
experience += amount;
|
||||
|
||||
while (Level < MaxLevel && experience >= nextLevel[Level].First)
|
||||
{
|
||||
var upgrades = nextLevel[Level].Second;
|
||||
|
||||
Level++;
|
||||
|
||||
var um = self.TraitOrDefault<UpgradeManager>();
|
||||
if (um != null)
|
||||
foreach (var u in upgrades)
|
||||
um.GrantUpgrade(self, u, this);
|
||||
|
||||
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", "LevelUp", self.Owner.Country.Race);
|
||||
self.World.AddFrameEndTask(w => w.Add(new CrateEffect(self, "levelup", info.LevelUpPalette)));
|
||||
|
||||
if (Level == 1)
|
||||
{
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
if (!self.IsDead)
|
||||
w.Add(new Rank(self, info.ChevronPalette));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ExperienceInit : IActorInit<int>
|
||||
{
|
||||
[FieldFromYamlKey] public readonly int value = 0;
|
||||
public ExperienceInit() { }
|
||||
public ExperienceInit(int init) { value = init; }
|
||||
public int Value(World world) { return value; }
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Effects;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[Desc("You get money for playing this actor.")]
|
||||
class GivesBountyInfo : TraitInfo<GivesBounty>
|
||||
{
|
||||
[Desc("Calculated by Cost or CustomSellValue so they have to be set to avoid crashes.")]
|
||||
public readonly int Percentage = 10;
|
||||
[Desc("Higher ranked units give higher bounties.")]
|
||||
public readonly int LevelMod = 125;
|
||||
[Desc("Destroying creeps and enemies is rewarded.")]
|
||||
public readonly Stance[] Stances = { Stance.Neutral, Stance.Enemy };
|
||||
}
|
||||
|
||||
class GivesBounty : INotifyKilled
|
||||
{
|
||||
static int GetMultiplier(Actor self)
|
||||
{
|
||||
// returns 100's as 1, so as to keep accuracy for longer.
|
||||
var info = self.Info.Traits.Get<GivesBountyInfo>();
|
||||
var gainsExp = self.TraitOrDefault<GainsExperience>();
|
||||
if (gainsExp == null)
|
||||
return 100;
|
||||
|
||||
var slevel = gainsExp.Level;
|
||||
return (slevel > 0) ? slevel * info.LevelMod : 100;
|
||||
}
|
||||
|
||||
public void Killed(Actor self, AttackInfo e)
|
||||
{
|
||||
var info = self.Info.Traits.Get<GivesBountyInfo>();
|
||||
|
||||
if (e.Attacker == null || e.Attacker.Destroyed) return;
|
||||
|
||||
if (!info.Stances.Contains(e.Attacker.Owner.Stances[self.Owner])) return;
|
||||
|
||||
var cost = self.GetSellValue();
|
||||
|
||||
// 2 hundreds because of GetMultiplier and info.Percentage.
|
||||
var bounty = cost * GetMultiplier(self) * info.Percentage / 10000;
|
||||
|
||||
if (bounty > 0 && e.Attacker.Owner.IsAlliedWith(self.World.RenderPlayer))
|
||||
e.Attacker.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, e.Attacker.Owner.Color.RGB, FloatingText.FormatCashTick(bounty), 30)));
|
||||
|
||||
e.Attacker.Owner.PlayerActor.Trait<PlayerResources>().GiveCash(bounty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[Desc("This actor gives experience to a GainsExperience actor when they are killed.")]
|
||||
class GivesExperienceInfo : ITraitInfo
|
||||
{
|
||||
[Desc("If -1, use the value of the unit cost.")]
|
||||
public readonly int Experience = -1;
|
||||
|
||||
[Desc("Grant experience for team-kills.")]
|
||||
public readonly bool FriendlyFire = false;
|
||||
|
||||
public object Create(ActorInitializer init) { return new GivesExperience(init.self, this); }
|
||||
}
|
||||
|
||||
class GivesExperience : INotifyKilled
|
||||
{
|
||||
readonly GivesExperienceInfo info;
|
||||
|
||||
public GivesExperience(Actor self, GivesExperienceInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void Killed(Actor self, AttackInfo e)
|
||||
{
|
||||
// Prevent TK from giving exp
|
||||
if (e.Attacker == null || e.Attacker.Destroyed || (!info.FriendlyFire && e.Attacker.Owner.Stances[self.Owner] == Stance.Ally))
|
||||
return;
|
||||
|
||||
var valued = self.Info.Traits.GetOrDefault<ValuedInfo>();
|
||||
|
||||
// Default experience is 100 times our value
|
||||
var exp = info.Experience >= 0
|
||||
? info.Experience
|
||||
: valued != null ? valued.Cost * 100 : 0;
|
||||
|
||||
var killer = e.Attacker.TraitOrDefault<GainsExperience>();
|
||||
if (killer != null)
|
||||
killer.GiveExperience(exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Traits;
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
<Compile Include="AI\AttackOrFleeFuzzy.cs" />
|
||||
<Compile Include="AI\BaseBuilder.cs" />
|
||||
<Compile Include="AI\HackyAI.cs" />
|
||||
<Compile Include="Player\AllyRepair.cs" />
|
||||
<Compile Include="Render\WithIdleOverlay.cs" />
|
||||
<Compile Include="Traits\AcceptsSupplies.cs" />
|
||||
<Compile Include="Activities\Attack.cs" />
|
||||
@@ -106,7 +107,6 @@
|
||||
<Compile Include="Activities\DeliverResources.cs" />
|
||||
<Compile Include="Activities\Demolish.cs" />
|
||||
<Compile Include="Activities\DonateSupplies.cs" />
|
||||
<Compile Include="Activities\Enter.cs" />
|
||||
<Compile Include="Activities\EnterTransport.cs" />
|
||||
<Compile Include="Activities\FindResources.cs" />
|
||||
<Compile Include="Activities\Follow.cs" />
|
||||
@@ -118,22 +118,18 @@
|
||||
<Compile Include="Activities\RAHarvesterDockSequence.cs" />
|
||||
<Compile Include="Activities\Rearm.cs" />
|
||||
<Compile Include="Activities\Repair.cs" />
|
||||
<Compile Include="Activities\RepairBuilding.cs" />
|
||||
<Compile Include="Activities\Sell.cs" />
|
||||
<Compile Include="Activities\Teleport.cs" />
|
||||
<Compile Include="Activities\Transform.cs" />
|
||||
<Compile Include="Activities\UnloadCargo.cs" />
|
||||
<Compile Include="ActorExts.cs" />
|
||||
<Compile Include="AI\SupportPowerDecision.cs" />
|
||||
<Compile Include="Attack\AttackTurreted.cs" />
|
||||
<Compile Include="Crushable.cs" />
|
||||
<Compile Include="Effects\GpsSatellite.cs" />
|
||||
<Compile Include="Effects\Rank.cs" />
|
||||
<Compile Include="Effects\SatelliteLaunch.cs" />
|
||||
<Compile Include="Effects\TeslaZap.cs" />
|
||||
<Compile Include="Render\RenderUnitReload.cs" />
|
||||
<Compile Include="Graphics\TeslaZapRenderable.cs" />
|
||||
<Compile Include="GainsExperience.cs" />
|
||||
<Compile Include="EjectOnDeath.cs" />
|
||||
<Compile Include="AI\RushFuzzy.cs" />
|
||||
<Compile Include="AI\StateMachine.cs" />
|
||||
@@ -173,15 +169,11 @@
|
||||
<Compile Include="Traits\Crates\RevealMapCrateAction.cs" />
|
||||
<Compile Include="Traits\Crates\SupportPowerCrateAction.cs" />
|
||||
<Compile Include="Traits\DemoTruck.cs" />
|
||||
<Compile Include="DetectCloaked.cs" />
|
||||
<Compile Include="Effects\GpsDot.cs" />
|
||||
<Compile Include="Effects\Parachute.cs" />
|
||||
<Compile Include="Effects\RepairIndicator.cs" />
|
||||
<Compile Include="EmitInfantryOnSell.cs" />
|
||||
<Compile Include="EngineerRepair.cs" />
|
||||
<Compile Include="Explodes.cs" />
|
||||
<Compile Include="GivesBounty.cs" />
|
||||
<Compile Include="GivesExperience.cs" />
|
||||
<Compile Include="Guard.cs" />
|
||||
<Compile Include="Invulnerable.cs" />
|
||||
<Compile Include="Captures.cs" />
|
||||
@@ -203,8 +195,6 @@
|
||||
<Compile Include="Orders\RepairOrderGenerator.cs" />
|
||||
<Compile Include="ParaDrop.cs" />
|
||||
<Compile Include="Passenger.cs" />
|
||||
<Compile Include="Player\PlayerStatistics.cs" />
|
||||
<Compile Include="Player\AllyRepair.cs" />
|
||||
<Compile Include="Player\ClassicProductionQueue.cs" />
|
||||
<Compile Include="Player\PlaceBuilding.cs" />
|
||||
<Compile Include="Player\ProductionQueue.cs" />
|
||||
@@ -445,4 +435,4 @@ copy "FuzzyLogicLibrary.dll" "$(SolutionDir)"
|
||||
cd "$(SolutionDir)"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ItemGroup />
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -11,6 +11,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[Desc("Attach this to the player actor to collect observer stats.")]
|
||||
public class PlayerStatisticsInfo : ITraitInfo
|
||||
{
|
||||
public object Create(ActorInitializer init) { return new PlayerStatistics(init.self); }
|
||||
}
|
||||
|
||||
public class PlayerStatistics : ITick, IResolveOrder
|
||||
{
|
||||
World world;
|
||||
Player player;
|
||||
|
||||
public double MapControl;
|
||||
public int OrderCount;
|
||||
|
||||
public int EarnedThisMinute
|
||||
{
|
||||
get
|
||||
{
|
||||
return player.PlayerActor.Trait<PlayerResources>().Earned - earnedAtBeginningOfMinute;
|
||||
}
|
||||
}
|
||||
|
||||
public Queue<int> EarnedSamples = new Queue<int>(100);
|
||||
int earnedAtBeginningOfMinute;
|
||||
|
||||
public int KillsCost;
|
||||
public int DeathsCost;
|
||||
|
||||
public int UnitsKilled;
|
||||
public int UnitsDead;
|
||||
|
||||
public int BuildingsKilled;
|
||||
public int BuildingsDead;
|
||||
|
||||
public PlayerStatistics(Actor self)
|
||||
{
|
||||
world = self.World;
|
||||
player = self.Owner;
|
||||
}
|
||||
|
||||
void UpdateMapControl()
|
||||
{
|
||||
var total = (double)world.Map.Bounds.Width * world.Map.Bounds.Height;
|
||||
MapControl = world.Actors
|
||||
.Where(a => !a.IsDead && a.IsInWorld && a.Owner == player && a.HasTrait<RevealsShroud>())
|
||||
.SelectMany(a => world.Map.FindTilesInCircle(
|
||||
a.Location,
|
||||
a.Trait<RevealsShroud>().Range.Clamp(WRange.Zero, WRange.FromCells(Map.MaxTilesInCircleRange)).Range / 1024))
|
||||
.Distinct()
|
||||
.Count() / total;
|
||||
}
|
||||
|
||||
void UpdateEarnedThisMinute()
|
||||
{
|
||||
EarnedSamples.Enqueue(EarnedThisMinute);
|
||||
earnedAtBeginningOfMinute = player.PlayerActor.Trait<PlayerResources>().Earned;
|
||||
if (EarnedSamples.Count > 100)
|
||||
EarnedSamples.Dequeue();
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (self.World.WorldTick % 1500 == 1)
|
||||
UpdateEarnedThisMinute();
|
||||
if (self.World.WorldTick % 250 == 0)
|
||||
UpdateMapControl();
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
switch (order.OrderString)
|
||||
{
|
||||
case "Chat":
|
||||
case "TeamChat":
|
||||
case "HandshakeResponse":
|
||||
case "PauseGame":
|
||||
case "StartGame":
|
||||
case "Disconnected":
|
||||
case "ServerError":
|
||||
case "AuthenticationError":
|
||||
case "SyncLobbyInfo":
|
||||
case "SyncClientInfo":
|
||||
case "SyncLobbySlots":
|
||||
case "SyncLobbyGlobalSettings":
|
||||
case "SyncClientPing":
|
||||
case "Ping":
|
||||
case "Pong":
|
||||
return;
|
||||
}
|
||||
|
||||
if (order.OrderString.StartsWith("Dev"))
|
||||
return;
|
||||
OrderCount++;
|
||||
}
|
||||
}
|
||||
|
||||
[Desc("Attach this to a unit to update observer stats.")]
|
||||
public class UpdatesPlayerStatisticsInfo : TraitInfo<UpdatesPlayerStatistics> { }
|
||||
|
||||
public class UpdatesPlayerStatistics : INotifyKilled
|
||||
{
|
||||
public void Killed(Actor self, AttackInfo e)
|
||||
{
|
||||
if (self.Owner.WinState != WinState.Undefined)
|
||||
return;
|
||||
|
||||
var attackerStats = e.Attacker.Owner.PlayerActor.Trait<PlayerStatistics>();
|
||||
var defenderStats = self.Owner.PlayerActor.Trait<PlayerStatistics>();
|
||||
if (self.HasTrait<Building>())
|
||||
{
|
||||
attackerStats.BuildingsKilled++;
|
||||
defenderStats.BuildingsDead++;
|
||||
}
|
||||
else if (self.HasTrait<IPositionable>())
|
||||
{
|
||||
attackerStats.UnitsKilled++;
|
||||
defenderStats.UnitsDead++;
|
||||
}
|
||||
|
||||
if (self.HasTrait<Valued>())
|
||||
{
|
||||
var cost = self.Info.Traits.Get<ValuedInfo>().Cost;
|
||||
attackerStats.KillsCost += cost;
|
||||
defenderStats.DeathsCost += cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Graphics;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
@@ -12,6 +12,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Orders;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Traits
|
||||
{
|
||||
|
||||
@@ -11,10 +11,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Orders;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Orders;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Orders;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -12,6 +12,7 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Orders;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
|
||||
@@ -13,6 +13,7 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Orders;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -8,11 +8,9 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
|
||||
Reference in New Issue
Block a user