Merge pull request #4855 from ScottNZ/phase-transport

Improve cloaking logic and add phase transport
This commit is contained in:
Matthias Mailänder
2014-03-14 11:40:18 +01:00
14 changed files with 136 additions and 39 deletions

View File

@@ -61,6 +61,11 @@ NEW:
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. Added new attack-move cursor artwork.
Added Phase Transport, an Allied high-tech infantry transport which can cloak.
Attack Dogs, Snipers, Mobile Radar Jammers, Camo Pillboxes, Phase Transports, Radar Domes, and Spy Planes can now detect cloaked units.
Removed the submarine detection ability from Cruiser and Transport.
Added the submarine detection ability to Submarines and Missile Subs.
Increased the submarine detection range of Gunboat from 3 to 4.
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.

View File

@@ -20,12 +20,14 @@ namespace OpenRA.Mods.RA.Activities
{ {
readonly Actor self; readonly Actor self;
readonly Cargo cargo; readonly Cargo cargo;
readonly Cloak cloak;
readonly bool unloadAll; readonly bool unloadAll;
public UnloadCargo(Actor self, bool unloadAll) public UnloadCargo(Actor self, bool unloadAll)
{ {
this.self = self; this.self = self;
cargo = self.Trait<Cargo>(); cargo = self.Trait<Cargo>();
cloak = self.TraitOrDefault<Cloak>();
this.unloadAll = unloadAll; this.unloadAll = unloadAll;
} }
@@ -52,6 +54,9 @@ namespace OpenRA.Mods.RA.Activities
if (IsCanceled || cargo.IsEmpty(self)) if (IsCanceled || cargo.IsEmpty(self))
return NextActivity; return NextActivity;
if (cloak != null && cloak.Info.UncloakOnUnload)
cloak.Uncloak();
var actor = cargo.Peek(self); var actor = cargo.Peek(self);
var exitCell = ChooseExitCell(actor); var exitCell = ChooseExitCell(actor);

View File

@@ -22,12 +22,15 @@ namespace OpenRA.Mods.RA
public readonly int InitialDelay = 10; // Ticks public readonly int InitialDelay = 10; // Ticks
public readonly int CloakDelay = 30; // Ticks public readonly int CloakDelay = 30; // Ticks
public readonly bool UncloakOnMove = false; public readonly bool UncloakOnMove = false;
public readonly bool UncloakOnUnload = false;
public readonly bool RequiresCrate = false; public readonly bool RequiresCrate = false;
public readonly string CloakSound = null; public readonly string CloakSound = null;
public readonly string UncloakSound = null; public readonly string UncloakSound = null;
public readonly string Palette = "cloak"; public readonly string Palette = "cloak";
public readonly string[] CloakTypes = { "Cloak" };
public object Create(ActorInitializer init) { return new Cloak(init.self, this); } public object Create(ActorInitializer init) { return new Cloak(init.self, this); }
} }
@@ -38,24 +41,24 @@ namespace OpenRA.Mods.RA
[Sync] bool crateDisabled; [Sync] bool crateDisabled;
Actor self; Actor self;
CloakInfo info; public readonly CloakInfo Info;
CPos? lastPos; CPos? lastPos;
public Cloak(Actor self, CloakInfo info) public Cloak(Actor self, CloakInfo info)
{ {
this.info = info;
this.self = self; this.self = self;
Info = info;
remainingTime = info.InitialDelay; remainingTime = info.InitialDelay;
crateDisabled = info.RequiresCrate; crateDisabled = info.RequiresCrate;
} }
public void Uncloak() { Uncloak(info.CloakDelay); } public void Uncloak() { Uncloak(Info.CloakDelay); }
public void Uncloak(int time) public void Uncloak(int time)
{ {
if (Cloaked) if (Cloaked)
Sound.Play(info.UncloakSound, self.CenterPosition); Sound.Play(Info.UncloakSound, self.CenterPosition);
remainingTime = Math.Max(remainingTime, time); remainingTime = Math.Max(remainingTime, time);
} }
@@ -77,10 +80,10 @@ namespace OpenRA.Mods.RA
return r; return r;
if (Cloaked && IsVisible(self, self.World.RenderPlayer)) if (Cloaked && IsVisible(self, self.World.RenderPlayer))
if (string.IsNullOrEmpty(info.Palette)) if (string.IsNullOrEmpty(Info.Palette))
return r; return r;
else else
return r.Select(a => a.WithPalette(wr.Palette(info.Palette))); return r.Select(a => a.WithPalette(wr.Palette(Info.Palette)));
else else
return SpriteRenderable.None; return SpriteRenderable.None;
} }
@@ -88,15 +91,12 @@ namespace OpenRA.Mods.RA
public void Tick(Actor self) public void Tick(Actor self)
{ {
if (remainingTime > 0 && !crateDisabled && !damageDisabled && --remainingTime <= 0) if (remainingTime > 0 && !crateDisabled && !damageDisabled && --remainingTime <= 0)
{ Sound.Play(Info.CloakSound, self.CenterPosition);
self.Generation++;
Sound.Play(info.CloakSound, self.CenterPosition);
}
if (self.IsDisabled()) if (self.IsDisabled())
Uncloak(); Uncloak();
if (info.UncloakOnMove && (lastPos == null || lastPos.Value != self.Location)) if (Info.UncloakOnMove && (lastPos == null || lastPos.Value != self.Location))
{ {
Uncloak(); Uncloak();
lastPos = self.Location; lastPos = self.Location;
@@ -108,9 +108,14 @@ namespace OpenRA.Mods.RA
if (!Cloaked || self.Owner.IsAlliedWith(viewer)) if (!Cloaked || self.Owner.IsAlliedWith(viewer))
return true; return true;
var centerPosition = self.CenterPosition; return self.World.ActorsWithTrait<DetectCloaked>().Any(a =>
return self.World.ActorsWithTrait<DetectCloaked>().Any(a => a.Actor.Owner.IsAlliedWith(viewer) && {
(centerPosition - a.Actor.CenterPosition).Length < WRange.FromCells(a.Actor.Info.Traits.Get<DetectCloakedInfo>().Range).Range); var dc = a.Actor.Info.Traits.Get<DetectCloakedInfo>();
return a.Actor.Owner.IsAlliedWith(viewer)
&& Info.CloakTypes.Intersect(dc.CloakTypes).Any()
&& (self.CenterPosition - a.Actor.CenterPosition).Length <= WRange.FromCells(dc.Range).Range;
});
} }
public Color RadarColorOverride(Actor self) public Color RadarColorOverride(Actor self)
@@ -121,7 +126,7 @@ namespace OpenRA.Mods.RA
return c; return c;
} }
public bool AcceptsCloakCrate { get { return info.RequiresCrate && crateDisabled; } } public bool AcceptsCloakCrate { get { return Info.RequiresCrate && crateDisabled; } }
public void ReceivedCloakCrate(Actor self) public void ReceivedCloakCrate(Actor self)
{ {

View File

@@ -14,6 +14,7 @@ namespace OpenRA.Mods.RA
{ {
class DetectCloakedInfo : TraitInfo<DetectCloaked> class DetectCloakedInfo : TraitInfo<DetectCloaked>
{ {
public readonly string[] CloakTypes = { "Cloak" };
public readonly int Range = 5; public readonly int Range = 5;
} }

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

Binary file not shown.

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

Binary file not shown.

View File

@@ -165,8 +165,6 @@
Voice: VehicleVoice Voice: VehicleVoice
TargetableUnit: TargetableUnit:
TargetTypes: Ground, Water TargetTypes: Ground, Water
DetectCloaked:
Range: 3
HiddenUnderFog: HiddenUnderFog:
AttackMove: AttackMove:
GainsExperience: GainsExperience:

View File

@@ -10,7 +10,7 @@ DOG:
Cost: 200 Cost: 200
Tooltip: Tooltip:
Name: Attack Dog Name: Attack Dog
Description: Anti-infantry unit. Not fooled by the \nSpy's disguise.\n Strong vs Infantry\n Weak vs Vehicles Description: Anti-infantry unit.\nCan detect cloaked units and spies.\n Strong vs Infantry\n Weak vs Vehicles
Selectable: Selectable:
Voice: DogVoice Voice: DogVoice
Bounds: 12,17,-1,-4 Bounds: 12,17,-1,-4
@@ -26,6 +26,8 @@ DOG:
RenderInfantry: RenderInfantry:
IdleAnimations: idle1,idle2 IdleAnimations: idle1,idle2
IgnoresDisguise: IgnoresDisguise:
DetectCloaked:
Range: 5
E1: E1:
Inherits: ^Infantry Inherits: ^Infantry
@@ -444,7 +446,7 @@ SNIPER:
Cost: 700 Cost: 700
Tooltip: Tooltip:
Name: Sniper Name: Sniper
Description: Elite sniper infantry unit.\n Strong vs Infantry\n Weak vs Vehicles Description: Elite sniper infantry unit.\nCan detect cloaked units.\n Strong vs Infantry\n Weak vs Vehicles
Buildable: Buildable:
Queue: Infantry Queue: Infantry
BuildPaletteOrder: 80 BuildPaletteOrder: 80
@@ -462,7 +464,7 @@ SNIPER:
RevealsShroud: RevealsShroud:
Range: 6c0 Range: 6c0
AutoTarget: AutoTarget:
InitialStance: HoldFire InitialStance: ReturnFire
Armament: Armament:
Weapon: Sniper Weapon: Sniper
AttackFrontal: AttackFrontal:
@@ -481,6 +483,8 @@ SNIPER:
CaptureTypes: CivilianBuilding CaptureTypes: CivilianBuilding
Sabotage: no Sabotage: no
SabotageHPRemoval: 0 SabotageHPRemoval: 0
DetectCloaked:
Range: 6
Zombie: Zombie:
Inherits: ^Infantry Inherits: ^Infantry

View File

@@ -10,7 +10,7 @@ SS:
Cost: 950 Cost: 950
Tooltip: Tooltip:
Name: Submarine Name: Submarine
Description: Submerged anti-ship unit armed with \ntorpedoes.\n Strong vs Ships\n Weak vs Everything\n Special Ability: Submerge Description: Submerged anti-ship unit armed with\ntorpedoes.\nCan detect other submarines.\n Strong vs Ships\n Weak vs Everything\n Special Ability: Submerge
Health: Health:
HP: 250 HP: 250
Armor: Armor:
@@ -26,6 +26,7 @@ SS:
CloakedTargetTypes: Underwater CloakedTargetTypes: Underwater
RenderUnit: RenderUnit:
Cloak: Cloak:
CloakTypes: Underwater
InitialDelay: 0 InitialDelay: 0
CloakDelay: 50 CloakDelay: 50
CloakSound: subshow1.aud CloakSound: subshow1.aud
@@ -40,9 +41,12 @@ SS:
Chronoshiftable: Chronoshiftable:
IronCurtainable: IronCurtainable:
RepairableNear: RepairableNear:
-DetectCloaked:
AutoTarget: AutoTarget:
InitialStance: HoldFire InitialStance: ReturnFire
DetectCloaked:
CloakTypes: Underwater
Range: 4
RenderDetectionCircle:
MSUB: MSUB:
Inherits: ^Ship Inherits: ^Ship
@@ -56,7 +60,7 @@ MSUB:
Cost: 2400 Cost: 2400
Tooltip: Tooltip:
Name: Missile Submarine Name: Missile Submarine
Description: Submerged anti-ground unit armed with \nlong-range ballistic missiles.\n Strong vs Buildings\n Weak vs Everything\n Special Ability: Submerge Description: Submerged anti-ground unit armed with\nlong-range ballistic missiles.\nCan detect other submarines.\n Strong vs Buildings\n Weak vs Everything\n Special Ability: Submerge
Health: Health:
HP: 400 HP: 400
Armor: Armor:
@@ -72,6 +76,7 @@ MSUB:
TargetTypes: Ground, Water TargetTypes: Ground, Water
CloakedTargetTypes: Underwater CloakedTargetTypes: Underwater
Cloak: Cloak:
CloakTypes: Underwater
InitialDelay: 0 InitialDelay: 0
CloakDelay: 100 CloakDelay: 100
CloakSound: subshow1.aud CloakSound: subshow1.aud
@@ -86,9 +91,12 @@ MSUB:
Chronoshiftable: Chronoshiftable:
IronCurtainable: IronCurtainable:
RepairableNear: RepairableNear:
-DetectCloaked:
AutoTarget: AutoTarget:
InitialStance: HoldFire InitialStance: ReturnFire
DetectCloaked:
CloakTypes: Underwater
Range: 4
RenderDetectionCircle:
DD: DD:
Inherits: ^Ship Inherits: ^Ship
@@ -102,7 +110,7 @@ DD:
Cost: 1000 Cost: 1000
Tooltip: Tooltip:
Name: Destroyer Name: Destroyer
Description: Fast multi-role ship. \n Strong vs Submarines, Aircraft\n Weak vs Infantry, Tanks Description: Fast multi-role ship.\nCan detect submarines.\n Strong vs Submarines, Aircraft\n Weak vs Infantry, Tanks
Health: Health:
HP: 400 HP: 400
Armor: Armor:
@@ -133,6 +141,7 @@ DD:
IronCurtainable: IronCurtainable:
RepairableNear: RepairableNear:
DetectCloaked: DetectCloaked:
CloakTypes: Underwater
Range: 4 Range: 4
RenderDetectionCircle: RenderDetectionCircle:
@@ -148,7 +157,7 @@ CA:
Cost: 2400 Cost: 2400
Tooltip: Tooltip:
Name: Cruiser Name: Cruiser
Description: Very slow long-range ship. \n Strong vs Buildings\n Weak vs Ships, Submarines Description: Very slow long-range ship.\n Strong vs Buildings\n Weak vs Ships, Submarines
Health: Health:
HP: 800 HP: 800
Armor: Armor:
@@ -237,7 +246,7 @@ PT:
Cost: 500 Cost: 500
Tooltip: Tooltip:
Name: Gunboat Name: Gunboat
Description: Light scout & support ship. \n Strong vs Ships, Submarines\n Weak vs Aircraft Description: Light scout & support ship.\nCan detect submarines.\n Strong vs Ships, Submarines\n Weak vs Aircraft
Health: Health:
HP: 200 HP: 200
Armor: Armor:
@@ -266,4 +275,8 @@ PT:
Chronoshiftable: Chronoshiftable:
IronCurtainable: IronCurtainable:
RepairableNear: RepairableNear:
DetectCloaked:
CloakTypes: Underwater
Range: 4
RenderDetectionCircle:

View File

@@ -373,7 +373,7 @@ DOME:
Cost: 1800 Cost: 1800
Tooltip: Tooltip:
Name: Radar Dome Name: Radar Dome
Description: Provides an overview of the battlefield.\n Requires power to operate. Description: Provides an overview of the battlefield.\nCan detect cloaked units.\n Requires power to operate.
Building: Building:
Power: -40 Power: -40
Footprint: xx xx Footprint: xx xx
@@ -393,6 +393,9 @@ DOME:
Infiltratable: Infiltratable:
Type: Exploration Type: Exploration
InfiltrateForExploration: InfiltrateForExploration:
DetectCloaked:
Range: 10
RenderDetectionCircle:
PBOX: PBOX:
Inherits: ^Building Inherits: ^Building
@@ -600,6 +603,8 @@ HBOX:
OnEnter: HBOX.sniper OnEnter: HBOX.sniper
OnExit: HBOX OnExit: HBOX
SkipMakeAnims: true SkipMakeAnims: true
DetectCloaked:
Range: 6
HBOX.E1: HBOX.E1:
Inherits: HBOX Inherits: HBOX
@@ -611,7 +616,7 @@ HBOX.E1:
Hotkey: l Hotkey: l
Tooltip: Tooltip:
Name: Camo Pillbox (Guns) Name: Camo Pillbox (Guns)
Description: Hidden defensive structure.\n Strong vs Infantry, Light Vehicles\n Weak vs Tanks, Aircraft Description: Hidden defensive structure.\nCan detect cloaked units.\n Strong vs Infantry, Light Vehicles\n Weak vs Tanks, Aircraft
RenderBuilding: RenderBuilding:
Image: HBOX Image: HBOX
RenderRangeCircle: RenderRangeCircle:
@@ -1062,7 +1067,7 @@ AFLD:
Icon: spyplane Icon: spyplane
ChargeTime: 180 ChargeTime: 180
Description: Spy Plane Description: Spy Plane
LongDesc: Reveals an area of the map. LongDesc: Reveals an area of the map\nand cloaked enemy units.
SelectTargetSound: slcttgt1.aud SelectTargetSound: slcttgt1.aud
EndChargeSound: spypln1.aud EndChargeSound: spypln1.aud
ParatroopersPower: ParatroopersPower:

View File

@@ -15,6 +15,7 @@ MINP:
CloakSound: CloakSound:
UncloakSound: UncloakSound:
Palette: Palette:
CloakTypes: Mine
Tooltip: Tooltip:
Name: Mine Name: Mine
ProximityCaptor: ProximityCaptor:
@@ -40,6 +41,7 @@ MINV:
CloakSound: CloakSound:
UncloakSound: UncloakSound:
Palette: Palette:
CloakTypes: Mine
Tooltip: Tooltip:
Name: Mine Name: Mine
ProximityCaptor: ProximityCaptor:
@@ -127,6 +129,8 @@ CAMERA:
ProximityCaptor: ProximityCaptor:
Types: Camera Types: Camera
BodyOrientation: BodyOrientation:
DetectCloaked:
Range: 10
FLARE: FLARE:
Immobile: Immobile:

View File

@@ -398,7 +398,7 @@ MNLY.AP:
Cost: 800 Cost: 800
Tooltip: Tooltip:
Name: Minelayer Name: Minelayer
Description: Lays mines to destroy unwary enemy units.\n Unarmed Description: Lays mines to destroy unwary enemy units.\nCan detect mines.\n Unarmed
Health: Health:
HP: 100 HP: 100
Armor: Armor:
@@ -416,6 +416,7 @@ MNLY.AP:
Ammo: 3 Ammo: 3
DetectCloaked: DetectCloaked:
Range: 5 Range: 5
CloakTypes: Mine
RenderDetectionCircle: RenderDetectionCircle:
MNLY.AT: MNLY.AT:
@@ -430,7 +431,7 @@ MNLY.AT:
Cost: 800 Cost: 800
Tooltip: Tooltip:
Name: Minelayer Name: Minelayer
Description: Lays mines to destroy unwary enemy units.\n Unarmed Description: Lays mines to destroy unwary enemy units.\nCan detect mines.\n Unarmed
Health: Health:
HP: 100 HP: 100
Armor: Armor:
@@ -448,6 +449,7 @@ MNLY.AT:
Ammo: 3 Ammo: 3
DetectCloaked: DetectCloaked:
Range: 5 Range: 5
CloakTypes: Mine
RenderDetectionCircle: RenderDetectionCircle:
TRUK: TRUK:
@@ -515,7 +517,7 @@ MRJ:
Cost: 1000 Cost: 1000
Tooltip: Tooltip:
Name: Mobile Radar Jammer Name: Mobile Radar Jammer
Description: Jams nearby enemy radar domes\nand deflects incoming missiles.\n Unarmed Description: Jams nearby enemy radar domes\nand deflects incoming missiles.\nCan detect cloaked units.\n Unarmed
Buildable: Buildable:
Queue: Vehicle Queue: Vehicle
BuildPaletteOrder: 150 BuildPaletteOrder: 150
@@ -542,6 +544,8 @@ MRJ:
JamsMissiles: JamsMissiles:
Range: 4 Range: 4
RenderJammerCircle: RenderJammerCircle:
DetectCloaked:
Range: 6
TTNK: TTNK:
Inherits: ^Tank Inherits: ^Tank
@@ -672,11 +676,11 @@ CTNK:
RenderUnit: RenderUnit:
AutoTarget: AutoTarget:
Armament@PRIMARY: Armament@PRIMARY:
Weapon: ChronoTusk Weapon: APTusk
LocalOffset: 0,-171,0 LocalOffset: 0,-171,0
LocalYaw: 100 LocalYaw: 100
Armament@SECONDARY: Armament@SECONDARY:
Weapon: ChronoTusk Weapon: APTusk
LocalOffset: 0,171,0 LocalOffset: 0,171,0
LocalYaw: -100 LocalYaw: -100
AttackFrontal: AttackFrontal:
@@ -713,4 +717,47 @@ QTNK:
-EjectOnDeath: -EjectOnDeath:
TargetableUnit: TargetableUnit:
TargetTypes: Ground, MADTank TargetTypes: Ground, MADTank
STNK:
Inherits: ^Vehicle
Buildable:
Queue: Vehicle
BuildPaletteOrder: 170
Prerequisites: atek
Owner: allies
Hotkey: p
Valued:
Cost: 1350
Tooltip:
Name: Phase Transport
Description: Lightly armored infantry transport\nwhich can cloak. Can detect cloaked units.\n Strong vs Light Vehicles\n Weak vs Aircraft
Selectable:
Bounds: 28,28
Health:
HP: 300
Armor:
Type: Light
Mobile:
Speed: 113
Crushes: wall, mine, crate, infantry
RevealsShroud:
Range: 6c0
RenderUnit:
AutoTarget:
InitialStance: ReturnFire
Armament:
Weapon: APTusk
LocalOffset: 400,0,0
Turreted:
ROT: 5
AttackTurreted:
WithTurret:
Cargo:
Types: Infantry
MaxWeight: 3
PipCount: 3
Cloak:
InitialDelay: 125
CloakDelay: 250
UncloakOnUnload: True
DetectCloaked:
Range: 6

View File

@@ -264,4 +264,14 @@ qtnk:
Facings: 8 Facings: 8
Length: 8 Length: 8
icon: qtnkicon icon: qtnkicon
Start: 0
stnk:
idle:
Start: 0
Facings: 32
turret:
Start: 38
Facings: 32
icon: stnkicon
Start: 0 Start: 0

View File

@@ -1241,7 +1241,7 @@ Sniper:
Concrete: 0% Concrete: 0%
InfDeath: 2 InfDeath: 2
ChronoTusk: APTusk:
ROF: 60 ROF: 60
Range: 6c0 Range: 6c0
Report: MISSILE6.AUD Report: MISSILE6.AUD