combat actually works
This commit is contained in:
@@ -86,5 +86,8 @@ namespace OpenRa
|
|||||||
|
|
||||||
public static float2 Max(float2 a, float2 b) { return new float2(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
|
public static float2 Max(float2 a, float2 b) { return new float2(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
|
||||||
public static float2 Min(float2 a, float2 b) { return new float2(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
|
public static float2 Min(float2 a, float2 b) { return new float2(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
|
||||||
|
|
||||||
|
public float LengthSquared { get { return X * X + Y * Y; } }
|
||||||
|
public float Length { get { return (float)Math.Sqrt(LengthSquared); } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,5 +78,26 @@ namespace OpenRa.Game
|
|||||||
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
|
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InflictDamage(Actor attacker, Bullet inflictor, int damage)
|
||||||
|
{
|
||||||
|
/* todo: auto-retaliate, etc */
|
||||||
|
/* todo: death sequence for infantry based on inflictor */
|
||||||
|
/* todo: start smoking if < conditionYellow and took damage, and not already smoking
|
||||||
|
|
||||||
|
if (Health <= 0) return; /* overkill! */
|
||||||
|
|
||||||
|
Health -= damage;
|
||||||
|
if (Health <= 0)
|
||||||
|
{
|
||||||
|
Health = 0;
|
||||||
|
if (attacker.Owner != null)
|
||||||
|
attacker.Owner.Kills++;
|
||||||
|
|
||||||
|
Game.world.AddFrameEndTask(w => w.Remove(this));
|
||||||
|
|
||||||
|
/* todo: explosion */
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,12 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
Game.world.AddFrameEndTask(w => w.Remove(this));
|
Game.world.AddFrameEndTask(w => w.Remove(this));
|
||||||
Game.world.AddFrameEndTask(w => w.Add(new Explosion(Dest)));
|
Game.world.AddFrameEndTask(w => w.Add(new Explosion(Dest)));
|
||||||
|
|
||||||
|
var maxSpread = GetMaximumSpread();
|
||||||
|
var hitActors = Game.FindUnitsInCircle(Dest, GetMaximumSpread());
|
||||||
|
|
||||||
|
foreach (var victim in hitActors)
|
||||||
|
victim.InflictDamage(FiredBy, this, (int)GetDamageToInflict(victim));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,5 +76,20 @@ namespace OpenRa.Game
|
|||||||
Dest.ToFloat2(),
|
Dest.ToFloat2(),
|
||||||
(float)t / TotalTime()) - 0.5f * anim.Image.size);
|
(float)t / TotalTime()) - 0.5f * anim.Image.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float GetMaximumSpread()
|
||||||
|
{
|
||||||
|
return (int)(Warhead.Spread * Math.Log(Weapon.Damage, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetDamageToInflict(Actor target)
|
||||||
|
{
|
||||||
|
/* todo: some things can't be damaged AT ALL by certain weapons! */
|
||||||
|
var distance = (target.CenterLocation - Dest).Length;
|
||||||
|
var rawDamage = Weapon.Damage * (float)Math.Exp(-distance / Warhead.Spread);
|
||||||
|
var multiplier = Warhead.EffectivenessAgainst(target.unitInfo.Armor);
|
||||||
|
|
||||||
|
return rawDamage * multiplier;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,6 +144,12 @@ namespace OpenRa.Game
|
|||||||
.Where(x => x.Bounds.IntersectsWith(rect));
|
.Where(x => x.Bounds.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);
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<Actor> SelectUnitsInBox(float2 a, float2 b)
|
public static IEnumerable<Actor> SelectUnitsInBox(float2 a, float2 b)
|
||||||
{
|
{
|
||||||
return FindUnits(a, b).Where(x => x.Owner == LocalPlayer && x.traits.Contains<Traits.Mobile>());
|
return FindUnits(a, b).Where(x => x.Owner == LocalPlayer && x.traits.Contains<Traits.Mobile>());
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace OpenRa.Game.GameRules
|
|||||||
return int.Parse( x );
|
return int.Parse( x );
|
||||||
|
|
||||||
else if (fieldType == typeof(float))
|
else if (fieldType == typeof(float))
|
||||||
return float.Parse( x );
|
return float.Parse(x.Replace("%","")) * (x.Contains( '%' ) ? 0.01f : 1f);
|
||||||
|
|
||||||
else if (fieldType == typeof(string))
|
else if (fieldType == typeof(string))
|
||||||
return x;//.ToLowerInvariant();
|
return x;//.ToLowerInvariant();
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ using OpenRa.Game.Graphics;
|
|||||||
using IjwFramework.Types;
|
using IjwFramework.Types;
|
||||||
|
|
||||||
namespace OpenRa.Game.GameRules
|
namespace OpenRa.Game.GameRules
|
||||||
{
|
|
||||||
public class UnitInfo
|
|
||||||
{
|
{
|
||||||
public enum ArmorType
|
public enum ArmorType
|
||||||
{
|
{
|
||||||
@@ -18,6 +16,8 @@ namespace OpenRa.Game.GameRules
|
|||||||
concrete = 4,
|
concrete = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class UnitInfo
|
||||||
|
{
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
|
|
||||||
public readonly string Description = "";
|
public readonly string Description = "";
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ namespace OpenRa.Game.GameRules
|
|||||||
class WarheadInfo
|
class WarheadInfo
|
||||||
{
|
{
|
||||||
public readonly int Spread = 1;
|
public readonly int Spread = 1;
|
||||||
public readonly string Verses = "100%,100%,100%,100%,100%";
|
public readonly float[] Verses = { 1, 1, 1, 1, 1 };
|
||||||
public readonly bool Wall = false;
|
public readonly bool Wall = false;
|
||||||
public readonly bool Wood = false;
|
public readonly bool Wood = false;
|
||||||
public readonly bool Ore = false;
|
public readonly bool Ore = false;
|
||||||
public readonly int Explosion = 0;
|
public readonly int Explosion = 0;
|
||||||
public readonly int InfDeath = 0;
|
public readonly int InfDeath = 0;
|
||||||
|
|
||||||
|
public float EffectivenessAgainst(ArmorType at) { return Verses[ (int)at ]; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace OpenRa.Game
|
|||||||
Game.world.Add( new Actor( "mcv", new int2( 5, 5 ), Game.players[ 3 ]) );
|
Game.world.Add( new Actor( "mcv", new int2( 5, 5 ), Game.players[ 3 ]) );
|
||||||
Game.world.Add( new Actor( "mcv", new int2( 7, 5 ), Game.players[ 2 ] ) );
|
Game.world.Add( new Actor( "mcv", new int2( 7, 5 ), Game.players[ 2 ] ) );
|
||||||
Game.world.Add( new Actor( "mcv", new int2( 9, 5 ), Game.players[ 0 ] ) );
|
Game.world.Add( new Actor( "mcv", new int2( 9, 5 ), Game.players[ 0 ] ) );
|
||||||
var jeep = new Actor( "jeep", new int2( 9, 7 ), Game.players[ 1 ] );
|
var jeep = new Actor( "jeep", new int2( 9, 15 ), Game.players[ 1 ] );
|
||||||
Game.world.Add( jeep );
|
Game.world.Add( jeep );
|
||||||
var tank = new Actor( "3tnk", new int2( 12, 7 ), Game.players[ 1 ] );
|
var tank = new Actor( "3tnk", new int2( 12, 7 ), Game.players[ 1 ] );
|
||||||
Game.world.Add( tank );
|
Game.world.Add( tank );
|
||||||
@@ -77,10 +77,7 @@ namespace OpenRa.Game
|
|||||||
while (Created && Visible)
|
while (Created && Visible)
|
||||||
{
|
{
|
||||||
Game.Tick();
|
Game.Tick();
|
||||||
|
|
||||||
// rude hack
|
|
||||||
Game.viewport.cursor = Game.controller.ChooseCursor();
|
Game.viewport.cursor = Game.controller.ChooseCursor();
|
||||||
|
|
||||||
Application.DoEvents();
|
Application.DoEvents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace OpenRa.Game
|
|||||||
class Player
|
class Player
|
||||||
{
|
{
|
||||||
public int Palette;
|
public int Palette;
|
||||||
|
public int Kills;
|
||||||
public string PlayerName;
|
public string PlayerName;
|
||||||
public TechTree.TechTree TechTree = new OpenRa.TechTree.TechTree();
|
public TechTree.TechTree TechTree = new OpenRa.TechTree.TechTree();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user