Merge branch 'master' into minelayer

This commit is contained in:
Chris Forbes
2009-12-28 13:21:21 +13:00
13 changed files with 105 additions and 30 deletions

View File

@@ -50,7 +50,6 @@ namespace OpenRa.Game
public void Tick()
{
while (currentActivity != null)
{
var a = currentActivity;
@@ -93,11 +92,8 @@ namespace OpenRa.Game
if (!Rules.Map.IsInMap(xy.X, xy.Y))
return null;
// HACK: Get the first unit in the cell
// This will need to be updated for multiple-infantry-in-a-cell
// HACK: this doesn't work for targeting air units either
var underCursor = Game.UnitInfluence.GetUnitsAt( xy ).FirstOrDefault()
?? Game.BuildingInfluence.GetBuildingAt( xy );
var loc = mi.Location + Game.viewport.Location;
var underCursor = Game.FindUnits(loc, loc).FirstOrDefault();
if (underCursor != null && !underCursor.Info.Selectable)
underCursor = null;
@@ -107,19 +103,18 @@ namespace OpenRa.Game
.FirstOrDefault( x => x != null );
}
public RectangleF Bounds
public RectangleF GetBounds(bool useAltitude)
{
get
var size = SelectedSize;
var loc = CenterLocation - 0.5f * size;
if (useAltitude)
{
var size = SelectedSize;
var loc = CenterLocation - 0.5f * size;
var unit = traits.GetOrDefault<Unit>();
if (unit != null)
loc -= new float2(0, unit.Altitude);
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
if (unit != null) loc -= new float2(0, unit.Altitude);
}
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
}
public bool IsDead { get { return Health <= 0; } }
@@ -150,6 +145,8 @@ namespace OpenRa.Game
Game.world.AddFrameEndTask(w => w.Remove(this));
}
if (Health > Info.Strength)
Health = Info.Strength;
var newState = GetDamageState();

View File

@@ -39,7 +39,7 @@ namespace OpenRa.Game
static float GetMaximumSpread(WeaponInfo weapon, WarheadInfo warhead)
{
return (int)(warhead.Spread * Math.Log(weapon.Damage, 2));
return (int)(warhead.Spread * Math.Log(Math.Abs(weapon.Damage), 2));
}
static float GetDamageToInflict(Actor target, int2 loc, WeaponInfo weapon, WarheadInfo warhead)

View File

@@ -124,7 +124,7 @@ namespace OpenRa.Game
{
var mods = GetModifierKeys();
var c = (orderGenerator is UnitOrderGenerator) ? orderGenerator.Order(dragEnd.ToInt2(),
new MouseInput { Button = MouseButton.Right, Modifiers = mods })
new MouseInput { Location = (Game.CellSize * dragEnd - Game.viewport.Location).ToInt2(), Button = MouseButton.Right, Modifiers = mods })
.Where(o => o.Validate())
.Select(o => CursorForOrderString(o.OrderString, o.Subject, o.TargetLocation))
.FirstOrDefault(a => a != null) : null;

View File

@@ -269,13 +269,19 @@ namespace OpenRa.Game
var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y);
return world.Actors
.Where(x => x.Bounds.IntersectsWith(rect));
.Where(x => x.GetBounds(true).IntersectsWith(rect));
}
public static IEnumerable<Actor> FindUnitsInCircle(float2 a, float r)
{
return FindUnits(a - new float2(r, r), a + new float2(r, r))
.Where(x => (x.CenterLocation - a).LengthSquared < r * r);
var min = a - new float2(r, r);
var max = a + new float2(r, r);
var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y);
var inBox = world.Actors.Where(x => x.GetBounds(false).IntersectsWith(rect));
return inBox.Where(x => (x.CenterLocation - a).LengthSquared < r * r);
}
public static IEnumerable<int2> FindTilesInCircle(int2 a, int r)

View File

@@ -111,7 +111,7 @@ namespace OpenRa.Game.Graphics
public void DrawSelectionBox(Actor selectedUnit, Color c, bool drawHealthBar)
{
var bounds = selectedUnit.Bounds;
var bounds = selectedUnit.GetBounds(true);
var xy = new float2(bounds.Left, bounds.Top);
var Xy = new float2(bounds.Right, bounds.Top);

View File

@@ -172,6 +172,7 @@
<Compile Include="Traits\AttackBase.cs" />
<Compile Include="Traits\AttackInfo.cs" />
<Compile Include="Traits\AttackTurreted.cs" />
<Compile Include="Traits\AutoHeal.cs" />
<Compile Include="Traits\AutoTarget.cs" />
<Compile Include="Traits\BelowUnits.cs" />
<Compile Include="Traits\Building.cs" />

View File

@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OpenRa.Game.Traits
{
class AutoHeal : ITick
{
public AutoHeal(Actor self) { }
void AttackTarget(Actor self, Actor target)
{
var attack = self.traits.WithInterface<AttackBase>().First();
if (target != null)
attack.ResolveOrder(self, new Order("Attack", self, target, int2.Zero, null));
else
self.CancelActivity();
}
float GetMaximumRange(Actor self)
{
return new[] { self.Info.Primary, self.Info.Secondary }
.Where(w => w != null)
.Max(w => Rules.WeaponInfo[w].Range);
}
bool NeedsNewTarget(Actor self)
{
var attack = self.traits.WithInterface<AttackBase>().First();
var range = GetMaximumRange(self);
if (attack.target == null)
return true; // he's dead.
if ((attack.target.Location - self.Location).LengthSquared > range * range + 2)
return true; // wandered off faster than we could follow
if (attack.target.Health == attack.target.Info.Strength)
return true; // fully healed
return false;
}
public void Tick(Actor self)
{
var attack = self.traits.WithInterface<AttackBase>().First();
var range = GetMaximumRange(self);
if (NeedsNewTarget(self))
AttackTarget(self, ChooseTarget(self, range));
}
Actor ChooseTarget(Actor self, float range)
{
var inRange = Game.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
return inRange
.Where(a => a.Owner == self.Owner) /* todo: one day deal with friendly players */
.Where(a => Combat.HasAnyValidWeapons(self, a))
.Where(a => a.Health < a.Info.Strength)
.OrderBy(a => (a.Location - self.Location).LengthSquared)
.FirstOrDefault();
}
}
}

View File

@@ -16,16 +16,23 @@ namespace OpenRa.Game.Traits
attack.ResolveOrder(self, new Order("Attack", self, target, int2.Zero, null));
}
float GetMaximumRange(Actor self)
{
return new[] { self.Info.Primary, self.Info.Secondary }
.Where(w => w != null)
.Max(w => Rules.WeaponInfo[w].Range);
}
public void Tick(Actor self)
{
if (!self.IsIdle) return;
var attack = self.traits.WithInterface<AttackBase>().First();
var range = Rules.WeaponInfo[self.Info.Primary].Range;
var range = GetMaximumRange(self);
if (attack.target == null ||
(attack.target.Location - self.Location).LengthSquared > range * range + 2)
attack.target = ChooseTarget(self, range);
AttackTarget(self, ChooseTarget(self, range));
}
Actor ChooseTarget(Actor self, float range)

View File

@@ -35,7 +35,7 @@ namespace OpenRa.Game.Traits
{
if (doneBuilding) roof.Tick();
var b = self.Bounds;
var b = self.GetBounds(false);
if (isOpen && !Game.UnitInfluence.GetUnitsAt(((1/24f) * self.CenterLocation).ToInt2()).Any())
{
isOpen = false;

View File

@@ -4,11 +4,11 @@ Ground Units:
All Infantry No idle animations
E1 Range is wrong.
E2 Grenades are too accurate.
E3 AA weapon doesn't work.
E3 Works
E4 Flamer origin is wrong
E6 Capture action missing, repair action missing
E7 C4 action missing
MEDI Heal doesn't work
MEDI Heal targeting is wrong
SPY Infiltrate action missing
THF Steal action missing
C1,C2,Einstein,Kosygin Not implemented
@@ -33,7 +33,6 @@ ARTY Works
Helicopters
- Weapons don't work,
- hover while attacking doesn't work,
- render is broken (altitude) -- less broken, but there are Z-order issues.
- Repair/rearm doesn't work
TRAN Cargo doesn't work

View File

@@ -2411,7 +2411,7 @@ InfDeath=5
; special case to only affect infantry (do not use for regular weapons)
[Organic]
Spread=0
Spread=5
Verses=100%,0%,0%,0%,0%
InfDeath=0

View File

@@ -7,4 +7,5 @@
s0=Multi0,mcv,600,2841,0,Guard,None
s1=Multi2,mcv,600,12445,0,Guard,None
s2=Multi1,mcv,600,12505,0,Guard,None
;s2=Multi1,e3,600,12505,0,Guard,None
s3=Multi3,mcv,600,2910,0,Guard,None

View File

@@ -249,7 +249,7 @@ InitialFacing=224
LongDesc=Anti-Air base defense.\n Strong vs Aircraft\n Weak vs Infantry, Tanks
[FTUR]
Description=Flame Turret
Traits=Building, RenderBuilding, AttackTurreted, AutoTarget
Traits=Turreted, Building, RenderBuilding, AttackTurreted, AutoTarget
Dimensions=1,1
Footprint=x
SelectionPriority=3
@@ -578,7 +578,7 @@ LongDesc=Elite commando infantry, armed with \ndual pistols and C4.\n Strong vs
[MEDI]
Description=Medic
Voice=MedicVoice
Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover, Infantry, AutoTarget
Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover, Infantry, AutoHeal
LongDesc=Heals nearby infantry.\n Strong vs Nothing\n Weak vs Everything