diff --git a/OpenRa.Game/Traits/Infantry.cs b/OpenRa.Game/Traits/Infantry.cs index d1122aa7b2..9697605c55 100644 --- a/OpenRa.Game/Traits/Infantry.cs +++ b/OpenRa.Game/Traits/Infantry.cs @@ -28,7 +28,7 @@ namespace OpenRa.Game.Traits public IEnumerable CrushableBy() { yield return UnitMovementType.Track; - yield return UnitMovementType.Wheel; + //yield return UnitMovementType.Wheel; // Can infantry be crushed by wheel? } } } diff --git a/OpenRa.Game/Traits/Mobile.cs b/OpenRa.Game/Traits/Mobile.cs index dcc29f4ff5..c009ab0a1c 100644 --- a/OpenRa.Game/Traits/Mobile.cs +++ b/OpenRa.Game/Traits/Mobile.cs @@ -84,31 +84,16 @@ namespace OpenRa.Game.Traits { if (Game.BuildingInfluence.GetBuildingAt(a) != null) return false; - var actors = Game.UnitInfluence.GetUnitsAt(a); var crushable = true; - foreach (Actor actor in actors) + foreach (Actor actor in Game.UnitInfluence.GetUnitsAt(a)) { if (actor == self) continue; - var c = actor.traits.WithInterface(); - if (c == null) + if (!Game.IsActorCrushableByActor(actor, self)) { crushable = false; break; } - - foreach (var crush in c) - { - // TODO: Unhack this. I can't wrap my head around this right now... - if (!(((crush.IsCrushableByEnemy() && actor.Owner != Game.LocalPlayer) || (crush.IsCrushableByFriend() && actor.Owner == Game.LocalPlayer)) - && crush.CrushableBy().Contains(GetMovementType()))) - { - crushable = false; - Log.Write("{0} is NOT crushable by {1} (mobile)", actor.Info.Name, self.Info.Name); - break; - } - } - Log.Write("{0} is crushable by {1} (mobile)", actor.Info.Name, self.Info.Name); } if (!crushable) return false; diff --git a/OpenRa.Game/Traits/Production.cs b/OpenRa.Game/Traits/Production.cs index a3cc336c15..640f9143d1 100755 --- a/OpenRa.Game/Traits/Production.cs +++ b/OpenRa.Game/Traits/Production.cs @@ -21,7 +21,7 @@ namespace OpenRa.Game.Traits public bool Produce( Actor self, UnitInfo producee ) { var location = CreationLocation( self, producee ); - if( location == null || !Game.UnitInfluence.GetUnitsAt( location.Value ).Any() ) + if( location == null || Game.UnitInfluence.GetUnitsAt( location.Value ).Any() ) return false; var newUnit = new Actor( producee, location.Value, self.Owner ); diff --git a/OpenRa.Game/UnitInfluenceMap.cs b/OpenRa.Game/UnitInfluenceMap.cs index ee2b6beaea..6d5e5975ff 100644 --- a/OpenRa.Game/UnitInfluenceMap.cs +++ b/OpenRa.Game/UnitInfluenceMap.cs @@ -46,9 +46,11 @@ namespace OpenRa.Game [Conditional( "SANITY_CHECKS" )] void SanityCheckAdd( IOccupySpace a ) { + /* This check is too strict now that we can have multiple units in a cell foreach( var c in a.OccupiedCells() ) if( influence[c.X, c.Y].Any()) throw new InvalidOperationException( "UIM: Sanity check failed (Add)" ); + */ } public IEnumerable GetUnitsAt( int2 a ) diff --git a/units.ini b/units.ini index 0078c01ace..3e806737d3 100755 --- a/units.ini +++ b/units.ini @@ -522,52 +522,52 @@ MEDI Description=Attack Dog BuiltAt=KENN Voice=DogVoice -Traits=Unit, Mobile, RenderInfantry +Traits=Unit, Mobile, RenderInfantry, Infantry LongDesc=Anti-infantry unit. Not fooled by the \nSpy's disguise.\n Strong vs Infantry\n Weak vs Vehicles [E1] Description=Rifle Infantry -Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover +Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover, Infantry LongDesc=General-purpose infantry. Strong vs Infantry\n Weak vs Vehicles [E2] Description=Grenadier -Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover +Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover, Infantry FireDelay=15 PrimaryOffset=0,0,0,-13 LongDesc=Infantry armed with grenades. \n Strong vs Buildings, Infantry\n Weak vs Vehicles [E3] Description=Rocket Soldier -Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover +Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover, Infantry PrimaryOffset=0,0,0,-13 LongDesc=Anti-tank/Anti-aircraft infantry.\n Strong vs Tanks, Aircraft\n Weak vs Infantry [E4] Description=Flamethrower -Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover +Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover, Infantry FireDelay=8 LongDesc=Advanced Anti-infantry unit.\n Strong vs Infantry, Buildings\n Weak vs Vehicles [E6] Description=Engineer -Traits=Unit, Mobile, RenderInfantry, TakeCover +Traits=Unit, Mobile, RenderInfantry, TakeCover, Infantry Voice=EngineerVoice LongDesc=Infiltrates and captures enemy structures.\n Strong vs Nothing\n Weak vs Everything [SPY] Description=Spy Voice=SpyVoice -Traits=Unit, Mobile, RenderInfantry, TakeCover +Traits=Unit, Mobile, RenderInfantry, TakeCover, Infantry LongDesc=Infiltrates enemy structures to gather \nintelligence. Exact effect depends on the \nbuilding infiltrated.\n Strong vs Nothing\n Weak vs Everything\n Special Ability: Disguised [THF] Description=Thief Voice=ThiefVoice -Traits=Unit, Mobile, RenderInfantry, TakeCover +Traits=Unit, Mobile, RenderInfantry, TakeCover, Infantry LongDesc=Infiltrates enemy refineries & \nsilos, and steals money stored there.\n Unarmed [E7] Description=Tanya Voice=TanyaVoice -Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover +Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover, Infantry LongDesc=Elite commando infantry, armed with \ndual pistols and C4.\n Strong vs Infantry, Buildings\n Weak vs Vehicles\n Special Ability: Destroy Building with C4 [MEDI] Description=Medic Voice=MedicVoice -Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover +Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover, Infantry LongDesc=Heals nearby infantry.\n Strong vs Nothing\n Weak vs Everything