Merge pull request #4828 from pchote/cursors

Cursor improvements
This commit is contained in:
Matthias Mailänder
2014-03-12 12:52:01 +01:00
26 changed files with 201 additions and 140 deletions

View File

@@ -24,6 +24,7 @@ NEW:
Fixed chat synchronization in replays. Fixed chat synchronization in replays.
Fixed the game sometimes crashing when deploying and activating the guard cursor at the same time. Fixed the game sometimes crashing when deploying and activating the guard cursor at the same time.
Build time is now set when an item reaches the front of a queue, instead of immediately when queued. Build time is now set when an item reaches the front of a queue, instead of immediately when queued.
The attack cursor now changes if the target is out of range.
Dune 2000: Dune 2000:
Added the Atreides grenadier from the 1.06 patch. Added the Atreides grenadier from the 1.06 patch.
Added randomized tiles for Sand and Rock terrain. Added randomized tiles for Sand and Rock terrain.
@@ -56,6 +57,7 @@ NEW:
Fixed spies staying on the minimap after infiltration. Fixed spies staying on the minimap after infiltration.
Added maps: Blitzkrieg and Burlesca by s1w. Added maps: Blitzkrieg and Burlesca by s1w.
Both Allied and Soviet factions now build general-purpose mines instead of AT and AP mines respectively. Both Allied and Soviet factions now build general-purpose mines instead of AT and AP mines respectively.
Added new attack-move cursor artwork.
Tiberian Dawn: Tiberian Dawn:
Chinook rotors now counter-rotate. Chinook rotors now counter-rotate.
Commando can now plant C4 on bridges. Commando can now plant C4 on bridges.
@@ -83,6 +85,7 @@ NEW:
Increased the chance of Tiberium or chemical deaths spawning a Visceroid from 2% to 10%. Increased the chance of Tiberium or chemical deaths spawning a Visceroid from 2% to 10%.
Increased Obelisk of Light laser damage from 200 to 360. Increased Obelisk of Light laser damage from 200 to 360.
Fixed Obelisk of Light charge animation and sound not playing. Fixed Obelisk of Light charge animation and sound not playing.
Replaced or improved several mouse cursors.
Engine: Engine:
Converted Aircraft CruiseAltitude to world coordinates. Converted Aircraft CruiseAltitude to world coordinates.
Converted Health Radius to world coordinates. Converted Health Radius to world coordinates.

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -19,11 +19,12 @@ namespace OpenRA.Mods.RA.Air
class AttackHeli : AttackFrontal class AttackHeli : AttackFrontal
{ {
public AttackHeli(Actor self, AttackHeliInfo info) : base(self, info) { } public AttackHeli(Actor self, AttackHeliInfo info)
: base(self, info) { }
public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove)
{ {
return new HeliAttack( newTarget ); return new HeliAttack(newTarget);
} }
} }
} }

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -19,7 +19,8 @@ namespace OpenRA.Mods.RA.Air
class AttackPlane : AttackFrontal class AttackPlane : AttackFrontal
{ {
public AttackPlane(Actor self, AttackPlaneInfo info) : base(self, info) { } public AttackPlane(Actor self, AttackPlaneInfo info)
: base(self, info) { }
public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove)
{ {

View File

@@ -20,6 +20,7 @@ namespace OpenRA.Mods.RA
public abstract class AttackBaseInfo : ITraitInfo public abstract class AttackBaseInfo : ITraitInfo
{ {
public readonly string Cursor = "attack"; public readonly string Cursor = "attack";
public readonly string OutsideRangeCursor = "attackoutsiderange";
public abstract object Create(ActorInitializer init); public abstract object Create(ActorInitializer init);
} }
@@ -29,14 +30,20 @@ namespace OpenRA.Mods.RA
[Sync] public bool IsAttacking { get; internal set; } [Sync] public bool IsAttacking { get; internal set; }
readonly Actor self; readonly Actor self;
readonly AttackBaseInfo info;
protected Lazy<IFacing> facing;
Lazy<IEnumerable<Armament>> armaments; Lazy<IEnumerable<Armament>> armaments;
protected IEnumerable<Armament> Armaments { get { return armaments.Value; } } protected IEnumerable<Armament> Armaments { get { return armaments.Value; } }
List<Pair<int, Action>> delayedActions = new List<Pair<int, Action>>();
public AttackBase(Actor self) public AttackBase(Actor self, AttackBaseInfo info)
{ {
this.self = self; this.self = self;
this.info = info;
armaments = Lazy.New(() => self.TraitsImplementing<Armament>()); armaments = Lazy.New(() => self.TraitsImplementing<Armament>());
facing = Lazy.New(() => self.TraitOrDefault<IFacing>());
} }
protected virtual bool CanAttack(Actor self, Target target) protected virtual bool CanAttack(Actor self, Target target)
@@ -60,8 +67,6 @@ namespace OpenRA.Mods.RA
public bool IsReloading() { return Armaments.Any(a => a.IsReloading); } public bool IsReloading() { return Armaments.Any(a => a.IsReloading); }
List<Pair<int, Action>> delayedActions = new List<Pair<int, Action>>();
public virtual void Tick(Actor self) public virtual void Tick(Actor self)
{ {
for (var i = 0; i < delayedActions.Count; i++) for (var i = 0; i < delayedActions.Count; i++)
@@ -88,9 +93,8 @@ namespace OpenRA.Mods.RA
if (!CanAttack(self, target)) if (!CanAttack(self, target))
return; return;
var facing = self.TraitOrDefault<IFacing>();
foreach (var a in Armaments) foreach (var a in Armaments)
a.CheckFire(self, this, facing, target); a.CheckFire(self, this, facing.Value, target);
} }
public IEnumerable<IOrderTargeter> Orders public IEnumerable<IOrderTargeter> Orders
@@ -101,7 +105,7 @@ namespace OpenRA.Mods.RA
yield break; yield break;
var negativeDamage = Armaments.First().Weapon.Warheads[0].Damage < 0; var negativeDamage = Armaments.First().Weapon.Warheads[0].Damage < 0;
yield return new AttackOrderTargeter("Attack", 6, negativeDamage); yield return new AttackOrderTargeter(this, "Attack", 6, negativeDamage);
} }
} }
@@ -168,9 +172,11 @@ namespace OpenRA.Mods.RA
class AttackOrderTargeter : IOrderTargeter class AttackOrderTargeter : IOrderTargeter
{ {
readonly bool negativeDamage; readonly bool negativeDamage;
readonly AttackBase ab;
public AttackOrderTargeter(string order, int priority, bool negativeDamage) public AttackOrderTargeter(AttackBase ab, string order, int priority, bool negativeDamage)
{ {
this.ab = ab;
this.OrderID = order; this.OrderID = order;
this.OrderPriority = priority; this.OrderPriority = priority;
this.negativeDamage = negativeDamage; this.negativeDamage = negativeDamage;
@@ -183,12 +189,15 @@ namespace OpenRA.Mods.RA
{ {
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
cursor = self.Info.Traits.Get<AttackBaseInfo>().Cursor; var a = ab.ChooseArmamentForTarget(target);
cursor = a != null && !target.IsInRange(self.CenterPosition, a.Weapon.Range)
? ab.info.OutsideRangeCursor
: ab.info.Cursor;
if (target.Type == TargetType.Actor && target.Actor == self) if (target.Type == TargetType.Actor && target.Actor == self)
return false; return false;
if (!self.Trait<AttackBase>().HasAnyValidWeapons(target)) if (!ab.HasAnyValidWeapons(target))
return false; return false;
if (modifiers.HasModifier(TargetModifiers.ForceAttack)) if (modifiers.HasModifier(TargetModifiers.ForceAttack))
@@ -210,16 +219,23 @@ namespace OpenRA.Mods.RA
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
cursor = self.Info.Traits.Get<AttackBaseInfo>().Cursor; cursor = ab.info.Cursor;
if (negativeDamage) if (negativeDamage)
return false; return false;
if (!self.Trait<AttackBase>().HasAnyValidWeapons(Target.FromCell(location))) if (!ab.HasAnyValidWeapons(Target.FromCell(location)))
return false; return false;
if (modifiers.HasModifier(TargetModifiers.ForceAttack)) if (modifiers.HasModifier(TargetModifiers.ForceAttack))
{
var maxRange = ab.GetMaximumRange().Range;
var targetRange = (location.CenterPosition - self.CenterPosition).HorizontalLengthSquared;
if (targetRange > maxRange * maxRange)
cursor = ab.info.OutsideRangeCursor;
return true; return true;
}
return false; return false;
} }

View File

@@ -8,8 +8,8 @@
*/ */
#endregion #endregion
using OpenRA.Mods.RA.Activities;
using OpenRA.FileFormats; using OpenRA.FileFormats;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Render; using OpenRA.Mods.RA.Render;
using OpenRA.Traits; using OpenRA.Traits;
@@ -24,32 +24,35 @@ namespace OpenRA.Mods.RA
public readonly int InitialChargeDelay = 22; public readonly int InitialChargeDelay = 22;
[Desc("Delay for additional charges if MaxCharge is larger than 1.")] [Desc("Delay for additional charges if MaxCharge is larger than 1.")]
public readonly int ChargeDelay = 3; public readonly int ChargeDelay = 3;
public override object Create(ActorInitializer init) { return new AttackCharge(init.self); } public override object Create(ActorInitializer init) { return new AttackCharge(init.self, this); }
} }
class AttackCharge : AttackOmni, ITick, INotifyAttack, ISync class AttackCharge : AttackOmni, ITick, INotifyAttack, ISync
{ {
readonly AttackChargeInfo aci;
[Sync] int charges; [Sync] int charges;
[Sync] int timeToRecharge; [Sync] int timeToRecharge;
public AttackCharge(Actor self) public AttackCharge(Actor self, AttackChargeInfo info)
: base(self) : base(self, info)
{ {
charges = self.Info.Traits.Get<AttackChargeInfo>().MaxCharges; aci = self.Info.Traits.Get<AttackChargeInfo>();
charges = aci.MaxCharges;
} }
public override void Tick( Actor self ) public override void Tick(Actor self)
{ {
if( --timeToRecharge <= 0 ) if (--timeToRecharge <= 0)
charges = self.Info.Traits.Get<AttackChargeInfo>().MaxCharges; charges = aci.MaxCharges;
base.Tick( self ); base.Tick(self);
} }
public void Attacking(Actor self, Target target, Armament a, Barrel barrel) public void Attacking(Actor self, Target target, Armament a, Barrel barrel)
{ {
--charges; --charges;
timeToRecharge = self.Info.Traits.Get<AttackChargeInfo>().ReloadTime; timeToRecharge = aci.ReloadTime;
} }
public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove)
@@ -57,7 +60,6 @@ namespace OpenRA.Mods.RA
return new ChargeAttack(newTarget); return new ChargeAttack(newTarget);
} }
public override void ResolveOrder(Actor self, Order order) public override void ResolveOrder(Actor self, Order order)
{ {
base.ResolveOrder(self, order); base.ResolveOrder(self, order);
@@ -82,7 +84,7 @@ namespace OpenRA.Mods.RA
var initDelay = self.Info.Traits.Get<AttackChargeInfo>().InitialChargeDelay; var initDelay = self.Info.Traits.Get<AttackChargeInfo>().InitialChargeDelay;
var attack = self.Trait<AttackCharge>(); var attack = self.Trait<AttackCharge>();
if(attack.charges == 0 || !attack.CanAttack(self, target)) if (attack.charges == 0 || !attack.CanAttack(self, target))
return this; return this;
self.Trait<RenderBuildingCharge>().PlayCharge(self); self.Trait<RenderBuildingCharge>().PlayCharge(self);
@@ -106,7 +108,7 @@ namespace OpenRA.Mods.RA
var chargeDelay = self.Info.Traits.Get<AttackChargeInfo>().ChargeDelay; var chargeDelay = self.Info.Traits.Get<AttackChargeInfo>().ChargeDelay;
var attack = self.Trait<AttackCharge>(); var attack = self.Trait<AttackCharge>();
if(attack.charges == 0) if (attack.charges == 0)
return NextActivity; return NextActivity;
attack.DoAttack(self, target); attack.DoAttack(self, target);

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -15,7 +15,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA namespace OpenRA.Mods.RA
{ {
[Desc("Unit got to face the target")] [Desc("Unit got to face the target")]
public class AttackFrontalInfo : AttackBaseInfo public class AttackFrontalInfo : AttackBaseInfo, Requires<IFacingInfo>
{ {
public readonly int FacingTolerance = 1; public readonly int FacingTolerance = 1;
@@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA
readonly AttackFrontalInfo info; readonly AttackFrontalInfo info;
public AttackFrontal(Actor self, AttackFrontalInfo info) public AttackFrontal(Actor self, AttackFrontalInfo info)
: base(self) : base(self, info)
{ {
this.info = info; this.info = info;
} }
@@ -37,10 +37,10 @@ namespace OpenRA.Mods.RA
if (!base.CanAttack(self, target)) if (!base.CanAttack(self, target))
return false; return false;
var facing = self.Trait<IFacing>().Facing; var f = facing.Value.Facing;
var facingToTarget = Util.GetFacing(target.CenterPosition - self.CenterPosition, facing); var facingToTarget = Util.GetFacing(target.CenterPosition - self.CenterPosition, f);
if (Math.Abs(facingToTarget - facing) % 256 > info.FacingTolerance) if (Math.Abs(facingToTarget - f) % 256 > info.FacingTolerance)
return false; return false;
return true; return true;

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA
public class AttackLoyalty : AttackFrontal public class AttackLoyalty : AttackFrontal
{ {
public AttackLoyalty(Actor self, AttackLoyaltyInfo info) public AttackLoyalty(Actor self, AttackLoyaltyInfo info)
: base( self, info ) {} : base(self, info) { }
public override void DoAttack(Actor self, Target target) public override void DoAttack(Actor self, Target target)
{ {

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -15,7 +15,7 @@ namespace OpenRA.Mods.RA
{ {
class AttackOmniInfo : AttackBaseInfo class AttackOmniInfo : AttackBaseInfo
{ {
public override object Create(ActorInitializer init) { return new AttackOmni(init.self); } public override object Create(ActorInitializer init) { return new AttackOmni(init.self, this); }
} }
class AttackOmni : AttackBase, INotifyBuildComplete, ISync class AttackOmni : AttackBase, INotifyBuildComplete, ISync
@@ -23,30 +23,37 @@ namespace OpenRA.Mods.RA
[Sync] bool buildComplete = false; [Sync] bool buildComplete = false;
public void BuildingComplete(Actor self) { buildComplete = true; } public void BuildingComplete(Actor self) { buildComplete = true; }
public AttackOmni(Actor self) : base(self) { } public AttackOmni(Actor self, AttackOmniInfo info)
: base(self, info) { }
protected override bool CanAttack( Actor self, Target target ) protected override bool CanAttack(Actor self, Target target)
{ {
var isBuilding = ( self.HasTrait<Building>() && !buildComplete ); var isBuilding = self.HasTrait<Building>() && !buildComplete;
return base.CanAttack( self, target ) && !isBuilding; return base.CanAttack(self, target) && !isBuilding;
} }
public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove)
{ {
return new SetTarget( newTarget ); return new SetTarget(newTarget, this);
} }
class SetTarget : Activity class SetTarget : Activity
{ {
readonly Target target; readonly Target target;
public SetTarget( Target target ) { this.target = target; } readonly AttackOmni ao;
public override Activity Tick( Actor self ) public SetTarget(Target target, AttackOmni ao)
{
this.target = target;
this.ao = ao;
}
public override Activity Tick(Actor self)
{ {
if (IsCanceled || !target.IsValidFor(self)) if (IsCanceled || !target.IsValidFor(self))
return NextActivity; return NextActivity;
self.Trait<AttackOmni>().DoAttack(self, target); ao.DoAttack(self, target);
return this; return this;
} }
} }

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -16,73 +16,74 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA namespace OpenRA.Mods.RA
{ {
class AttackPopupTurretedInfo : AttackTurretedInfo class AttackPopupTurretedInfo : AttackTurretedInfo, Requires<BuildingInfo>, Requires<RenderBuildingInfo>
{ {
public int CloseDelay = 125; public int CloseDelay = 125;
public int DefaultFacing = 0; public int DefaultFacing = 0;
public float ClosedDamageMultiplier = 0.5f; public float ClosedDamageMultiplier = 0.5f;
public override object Create(ActorInitializer init) { return new AttackPopupTurreted( init, this ); }
public override object Create(ActorInitializer init) { return new AttackPopupTurreted(init, this); }
} }
class AttackPopupTurreted : AttackTurreted, INotifyBuildComplete, INotifyIdle, IDamageModifier class AttackPopupTurreted : AttackTurreted, INotifyBuildComplete, INotifyIdle, IDamageModifier
{ {
enum PopupState { Open, Rotating, Transitioning, Closed }; enum PopupState { Open, Rotating, Transitioning, Closed }
AttackPopupTurretedInfo Info; AttackPopupTurretedInfo info;
int IdleTicks = 0; RenderBuilding rb;
PopupState State = PopupState.Open;
int idleTicks = 0;
PopupState state = PopupState.Open;
Turreted turret; Turreted turret;
public AttackPopupTurreted(ActorInitializer init, AttackPopupTurretedInfo info) : base(init.self) public AttackPopupTurreted(ActorInitializer init, AttackPopupTurretedInfo info)
: base(init.self, info)
{ {
Info = info; this.info = info;
buildComplete = init.Contains<SkipMakeAnimsInit>(); buildComplete = init.Contains<SkipMakeAnimsInit>();
turret = turrets.FirstOrDefault(); turret = turrets.FirstOrDefault();
rb = init.self.Trait<RenderBuilding>();
} }
protected override bool CanAttack( Actor self, Target target ) protected override bool CanAttack(Actor self, Target target)
{ {
if (State == PopupState.Transitioning) if (state == PopupState.Transitioning || !buildComplete)
return false; return false;
if( self.HasTrait<Building>() && !buildComplete ) if (!base.CanAttack(self, target))
return false; return false;
if (!base.CanAttack( self, target )) idleTicks = 0;
return false; if (state == PopupState.Closed)
IdleTicks = 0;
if (State == PopupState.Closed)
{ {
State = PopupState.Transitioning; state = PopupState.Transitioning;
var rb = self.Trait<RenderBuilding>();
rb.PlayCustomAnimThen(self, "opening", () => rb.PlayCustomAnimThen(self, "opening", () =>
{ {
State = PopupState.Open; state = PopupState.Open;
rb.PlayCustomAnimRepeating(self, "idle"); rb.PlayCustomAnimRepeating(self, "idle");
}); });
return false; return false;
} }
if (!turret.FaceTarget(self,target)) return false; if (!turret.FaceTarget(self, target))
return false;
return true; return true;
} }
public void TickIdle(Actor self) public void TickIdle(Actor self)
{ {
if (State == PopupState.Open && IdleTicks++ > Info.CloseDelay) if (state == PopupState.Open && idleTicks++ > info.CloseDelay)
{ {
turret.desiredFacing = Info.DefaultFacing; turret.desiredFacing = info.DefaultFacing;
State = PopupState.Rotating; state = PopupState.Rotating;
} }
else if (State == PopupState.Rotating && turret.turretFacing == Info.DefaultFacing) else if (state == PopupState.Rotating && turret.turretFacing == info.DefaultFacing)
{ {
State = PopupState.Transitioning; state = PopupState.Transitioning;
var rb = self.Trait<RenderBuilding>();
rb.PlayCustomAnimThen(self, "closing", () => rb.PlayCustomAnimThen(self, "closing", () =>
{ {
State = PopupState.Closed; state = PopupState.Closed;
rb.PlayCustomAnimRepeating(self, "closed-idle"); rb.PlayCustomAnimRepeating(self, "closed-idle");
turret.desiredFacing = null; turret.desiredFacing = null;
}); });
@@ -94,17 +95,17 @@ namespace OpenRA.Mods.RA
// Set true for SkipMakeAnimsInit // Set true for SkipMakeAnimsInit
if (buildComplete) if (buildComplete)
{ {
State = PopupState.Closed; state = PopupState.Closed;
self.Trait<RenderBuilding>() rb.PlayCustomAnimRepeating(self, "closed-idle");
.PlayCustomAnimRepeating(self, "closed-idle");
turret.desiredFacing = null; turret.desiredFacing = null;
} }
buildComplete = true; buildComplete = true;
} }
public float GetDamageModifier(Actor attacker, WarheadInfo warhead) public float GetDamageModifier(Actor attacker, WarheadInfo warhead)
{ {
return State == PopupState.Closed ? Info.ClosedDamageMultiplier : 1f; return state == PopupState.Closed ? info.ClosedDamageMultiplier : 1f;
} }
} }
} }

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -19,7 +19,7 @@ namespace OpenRA.Mods.RA
{ {
class AttackTurretedInfo : AttackBaseInfo, Requires<TurretedInfo> class AttackTurretedInfo : AttackBaseInfo, Requires<TurretedInfo>
{ {
public override object Create(ActorInitializer init) { return new AttackTurreted(init.self); } public override object Create(ActorInitializer init) { return new AttackTurreted(init.self, this); }
} }
class AttackTurreted : AttackBase, INotifyBuildComplete, ISync class AttackTurreted : AttackBase, INotifyBuildComplete, ISync
@@ -28,7 +28,8 @@ namespace OpenRA.Mods.RA
protected IEnumerable<Turreted> turrets; protected IEnumerable<Turreted> turrets;
[Sync] protected bool buildComplete; [Sync] protected bool buildComplete;
public AttackTurreted(Actor self) : base(self) public AttackTurreted(Actor self, AttackTurretedInfo info)
: base(self, info)
{ {
turrets = self.TraitsImplementing<Turreted>(); turrets = self.TraitsImplementing<Turreted>();
} }
@@ -41,11 +42,13 @@ namespace OpenRA.Mods.RA
if (!target.IsValidFor(self)) if (!target.IsValidFor(self))
return false; return false;
bool canAttack = false; var canAttack = false;
foreach (var t in turrets) foreach (var t in turrets)
if (t.FaceTarget(self, target)) if (t.FaceTarget(self, target))
canAttack = true; canAttack = true;
if (!canAttack) return false;
if (!canAttack)
return false;
return base.CanAttack(self, target); return base.CanAttack(self, target);
} }
@@ -88,7 +91,8 @@ namespace OpenRA.Mods.RA
if (IsCanceled || !target.IsValidFor(self)) if (IsCanceled || !target.IsValidFor(self))
return NextActivity; return NextActivity;
if (self.IsDisabled()) return this; if (self.IsDisabled())
return this;
var attack = self.Trait<AttackTurreted>(); var attack = self.Trait<AttackTurreted>();
const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */ const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * 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 * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.RA
[Sync] Target target; [Sync] Target target;
public AttackBomber(Actor self, AttackBomberInfo info) public AttackBomber(Actor self, AttackBomberInfo info)
: base(self) : base(self, info)
{ {
this.info = info; this.info = info;
this.camera = null; this.camera = null;

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
mods/cnc/bits/mouse5.shp Normal file

Binary file not shown.

BIN
mods/cnc/bits/mouse6.shp Normal file

Binary file not shown.

BIN
mods/cnc/bits/mouse7.shp Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,7 +1,5 @@
Palettes: Palettes:
cursor: cursor.pal cursor: cursor.pal
cursor2: racursor.pal
Cursors: Cursors:
mouse2.shp: cursor mouse2.shp: cursor
@@ -40,11 +38,6 @@ Cursors:
select: select:
start:12 start:12
length:6 length:6
default:
start:0
x: -16
y: -12
default-minimap: default-minimap:
start:86 start:86
length:1 length:1
@@ -78,12 +71,6 @@ Cursors:
c4-minimap: c4-minimap:
start:127 start:127
length:3 length:3
guard:
start:153
length:1
guard-minimap:
start:152
length:1
# Cursors that need minimap variants # Cursors that need minimap variants
deploy: deploy:
@@ -114,66 +101,81 @@ Cursors:
start:154 start:154
length:24 length:24
mouse3.shp: cursor
default:
start:0
x: -16
y: -12
deploy-blocked:
start:1
length:1
mouse4.shp:cursor mouse4.shp:cursor
move: move:
start:0 start:0
length:8 length:8
move-minimap: move-minimap:
start:9 start:8
length:4 length:4
move-rough: move-rough:
start:0 start:0
length: 8 length: 8
attackmove.shp:cursor
attackmove: attackmove:
start:0 start:12
length:8 length:8
attackmove-minimap: attackmove-minimap:
start:9 start:20
length:4 length:4
move-blocked: move-blocked:
start:8 start:24
length:1
move-blocked-minimap: move-blocked-minimap:
start:13 start:25
length:1 length:1
mouse3.shp: cursor2 mouse5.shp: cursor
enter-blocked: guard:
start:212 start:0
length:8
guard-minimap:
start:8
length:8
mouse6.shp: cursor
goldwrench:
start:0
length:3
goldwrench-minimap:
start:3
length:3
goldwrench-blocked:
start:6
length:1 length:1
enter-blocked-minimap: goldwrench-blocked-minimap:
start:33 start:7
length:1 length:1
capture: capture:
start:164 start:8
length:3 length:3
capture-minimap: capture-minimap:
start:167 start:11
length:3 length:3
heal: capture-blocked:
start:160 start:14
length:4
heal-minimap:
start:194
length:1 length:1
ability-minimap: capture-blocked-minimap:
start:214 start:15
length:8
deploy-blocked:
start:211
length:1 length:1
goldwrench: enter-blocked:
start:170 start:16
length:24 length:1
goldwrench-blocked: enter-blocked-minimap:
start:213 start:17
length:1 length:1
nopower.shp: cursor mouse7.shp: cursor
powerdown-blocked: attackoutsiderange:
start:0 start:0
length: 1 length:8
powerdown: attackoutsiderange-minimap:
start:1 start:8
length: 3

View File

@@ -119,6 +119,16 @@ Cursors:
length: 8 length: 8
x: 24 x: 24
y: 24 y: 24
attackoutsiderange:
start:16
length: 8
x: 24
y: 24
attackoutsiderange-minimap:
start:16
length: 8
x: 24
y: 24
attackmove: attackmove:
start:16 start:16
length: 8 length: 8

BIN
mods/ra/bits/attackmove.shp Normal file

Binary file not shown.

View File

@@ -70,10 +70,10 @@ Cursors:
attack-minimap: attack-minimap:
start:203 start:203
length: 8 length: 8
attackmove: attackoutsiderange:
start:21 start:21
length: 8 length: 8
attackmove-minimap: attackoutsiderange-minimap:
start:134 start:134
length: 8 length: 8
harvest: harvest:
@@ -170,3 +170,11 @@ Cursors:
powerdown: powerdown:
start:1 start:1
length: 3 length: 3
attackmove.shp: cursor
attackmove:
start:0
length: 4
attackmove-minimap:
start:4
length: 4

View File

@@ -72,6 +72,12 @@ Cursors:
attack-minimap: attack-minimap:
start: 63 start: 63
length: 5 length: 5
attackoutsiderange:
start: 58
length: 5
attackoutsiderange-minimap:
start: 63
length: 5
attackmove: #TODO attackmove: #TODO
start: 58 start: 58
length: 5 length: 5