From 2c58b0722309f0ae57dccc0bd82facdd36661084 Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Thu, 9 Jun 2011 19:44:40 +0000 Subject: [PATCH] # Add experimental fighter planes. This was SVN commit r9605. --- .../_test.sim/simulation/templates/unit.xml | 1 + .../simulation/templates/unitobstruct.xml | 1 + .../public/maps/scenarios/Flight_demo.pmp | 3 + .../public/maps/scenarios/Flight_demo.xml | 3 + .../public/simulation/components/UnitAI.js | 4 +- .../simulation/components/UnitMotionFlying.js | 196 ++++++++++++++++++ .../simulation/templates/other/plane.xml | 36 ++++ .../simulation/templates/special/actor.xml | 1 + .../templates/special/formation.xml | 1 + .../templates/template_entity_full.xml | 1 + .../templates/template_entity_quasi.xml | 1 + source/simulation2/TypeList.h | 1 + .../simulation2/components/CCmpPosition.cpp | 57 +++-- .../simulation2/components/CCmpUnitMotion.cpp | 24 ++- .../simulation2/components/ICmpPosition.cpp | 3 +- source/simulation2/components/ICmpPosition.h | 8 +- .../simulation2/components/ICmpUnitMotion.cpp | 68 +++++- .../simulation2/components/ICmpUnitMotion.h | 5 + .../tests/test_CmpTemplateManager.h | 4 +- 19 files changed, 386 insertions(+), 32 deletions(-) create mode 100644 binaries/data/mods/public/maps/scenarios/Flight_demo.pmp create mode 100644 binaries/data/mods/public/maps/scenarios/Flight_demo.xml create mode 100644 binaries/data/mods/public/simulation/components/UnitMotionFlying.js create mode 100644 binaries/data/mods/public/simulation/templates/other/plane.xml diff --git a/binaries/data/mods/_test.sim/simulation/templates/unit.xml b/binaries/data/mods/_test.sim/simulation/templates/unit.xml index f3066ac95f..43bcab103d 100644 --- a/binaries/data/mods/_test.sim/simulation/templates/unit.xml +++ b/binaries/data/mods/_test.sim/simulation/templates/unit.xml @@ -10,6 +10,7 @@ 0 upright false + 6.0 diff --git a/binaries/data/mods/_test.sim/simulation/templates/unitobstruct.xml b/binaries/data/mods/_test.sim/simulation/templates/unitobstruct.xml index d06e0018cf..5b3943ad07 100644 --- a/binaries/data/mods/_test.sim/simulation/templates/unitobstruct.xml +++ b/binaries/data/mods/_test.sim/simulation/templates/unitobstruct.xml @@ -10,6 +10,7 @@ 0 upright false + 6.0 diff --git a/binaries/data/mods/public/maps/scenarios/Flight_demo.pmp b/binaries/data/mods/public/maps/scenarios/Flight_demo.pmp new file mode 100644 index 0000000000..965280b8f1 --- /dev/null +++ b/binaries/data/mods/public/maps/scenarios/Flight_demo.pmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:798c4237a9a9d17ed14e5413c0c6b62cb520e2de95fdc64acea11cfff4dee9d9 +size 656466 diff --git a/binaries/data/mods/public/maps/scenarios/Flight_demo.xml b/binaries/data/mods/public/maps/scenarios/Flight_demo.xml new file mode 100644 index 0000000000..92403f2aed --- /dev/null +++ b/binaries/data/mods/public/maps/scenarios/Flight_demo.xml @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:132cd0d3ac1052b453a950a4827e46948e67d0f1a196b24dfc663db1c0ae0bda +size 3732 diff --git a/binaries/data/mods/public/simulation/components/UnitAI.js b/binaries/data/mods/public/simulation/components/UnitAI.js index a7fee3d37c..4b104d411b 100644 --- a/binaries/data/mods/public/simulation/components/UnitAI.js +++ b/binaries/data/mods/public/simulation/components/UnitAI.js @@ -1829,9 +1829,7 @@ UnitAI.prototype.FaceTowardsTarget = function(target) { var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); if (cmpUnitMotion) - { - cmpPosition.TurnTo(angle); - } + cmpUnitMotion.FaceTowardsPoint(pos.x, pos.z); } } diff --git a/binaries/data/mods/public/simulation/components/UnitMotionFlying.js b/binaries/data/mods/public/simulation/components/UnitMotionFlying.js new file mode 100644 index 0000000000..70c556b6d2 --- /dev/null +++ b/binaries/data/mods/public/simulation/components/UnitMotionFlying.js @@ -0,0 +1,196 @@ +// (A serious implementation of this might want to use C++ instead of JS +// for performance; this is just for fun.) + +function UnitMotionFlying() {} + +UnitMotionFlying.prototype.Schema = + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + ""; + +UnitMotionFlying.prototype.Init = function() +{ + this.hasTarget = false; + this.reachedTarget = false; + this.targetX = 0; + this.targetZ = 0; + this.targetMinRange = 0; + this.targetMaxRange = 0; + this.speed = 0; +}; + +UnitMotionFlying.prototype.OnUpdate = function(msg) +{ + var turnLength = msg.turnLength; + + if (!this.hasTarget) + return; + + var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); + var pos = cmpPosition.GetPosition(); + var angle = cmpPosition.GetRotation().y; + + var canTurn = true; + + // If we haven't reached max speed yet then we're still on the ground; + // otherwise we're taking off or flying + if (this.speed < this.template.MaxSpeed) + { + // Accelerate forwards + this.speed = Math.min(this.template.MaxSpeed, this.speed + turnLength*this.template.AccelRate); + canTurn = false; + + // Clamp to ground if below it, or descend if above + + var cmpTerrain = Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain); + var ground = cmpTerrain.GetGroundLevel(pos.x, pos.z); + + if (pos.y < ground) + pos.y = ground; + else if (pos.y > ground) + pos.y = Math.max(ground, pos.y - turnLength*this.template.ClimbRate); + + cmpPosition.SetHeightFixed(pos.y); + } + else + { + // Climb/sink to max height above ground + + var cmpTerrain = Engine.QueryInterface(SYSTEM_ENTITY, IID_Terrain); + var ground = cmpTerrain.GetGroundLevel(pos.x, pos.z); + + var targetHeight = ground + (+this.template.FlyingHeight); + if (pos.y < targetHeight) + pos.y = Math.min(targetHeight, pos.y + turnLength*this.template.ClimbRate); + else if (pos.y > targetHeight) + pos.y = Math.max(targetHeight, pos.y - turnLength*this.template.ClimbRate); + + cmpPosition.SetHeightFixed(pos.y); + } + + // If we're in range of the target then tell people that we've reached it + // (TODO: quantisation breaks this) + var distFromTarget = Math.sqrt(Math.pow(this.targetX - pos.x, 2) + Math.pow(this.targetZ - pos.z, 2)); + if (!this.reachedTarget && this.targetMinRange <= distFromTarget && distFromTarget <= this.targetMaxRange) + { + this.reachedTarget = true; + Engine.PostMessage(this.entity, MT_MotionChanged, { "starting": false, "error": false }); + } + + // If we're facing away from the target, and are still fairly close to it, + // then carry on going straight so we overshoot in a straight line + var isBehindTarget = ((this.targetX - pos.x)*Math.sin(angle) + (this.targetZ - pos.z)*Math.cos(angle) < 0); + if (isBehindTarget && distFromTarget < this.template.MaxSpeed*this.template.OvershootTime) + { + // Overshoot the target: carry on straight + canTurn = false; + } + + if (canTurn) + { + // Turn towards the target + + var targetAngle = Math.atan2(this.targetX - pos.x, this.targetZ - pos.z); + + var delta = targetAngle - angle; + // Wrap delta to -pi..pi + delta = (delta + Math.PI) % (2*Math.PI); // range -2pi..2pi + if (delta < 0) delta += 2*Math.PI; // range 0..2pi + delta -= Math.PI; // range -pi..pi + // Clamp to max rate + var deltaClamped = Math.min(Math.max(delta, -this.template.TurnRate*turnLength), this.template.TurnRate*turnLength); + // Calculate new orientation, in a peculiar way in order to make sure the + // result gets close to targetAngle (rather than being n*2*pi out) + angle = targetAngle + deltaClamped - delta; + } + + pos.x += this.speed * turnLength * Math.sin(angle); + pos.z += this.speed * turnLength * Math.cos(angle); + + cmpPosition.TurnTo(angle); + cmpPosition.MoveTo(pos.x, pos.z); +}; + +UnitMotionFlying.prototype.MoveToPointRange = function(x, z, minRange, maxRange) +{ + this.hasTarget = true; + this.reachedTarget = false; + this.targetX = x; + this.targetZ = z; + this.targetMinRange = minRange; + this.targetMaxRange = maxRange; + + return true; +}; + +UnitMotionFlying.prototype.MoveToTargetRange = function(target, minRange, maxRange) +{ + var cmpTargetPosition = Engine.QueryInterface(target, IID_Position); + if (!cmpTargetPosition || !cmpTargetPosition.IsInWorld()) + return false; + + var targetPos = cmpTargetPosition.GetPosition2D(); + + this.hasTarget = true; + this.reachedTarget = false; + this.targetX = targetPos.x; + this.targetZ = targetPos.y; + this.targetMinRange = minRange; + this.targetMaxRange = maxRange; + + return true; +}; + +UnitMotionFlying.prototype.IsInTargetRange = function(target, minRange, maxRange) +{ + var cmpTargetPosition = Engine.QueryInterface(target, IID_Position); + if (!cmpTargetPosition || !cmpTargetPosition.IsInWorld()) + return false; + + var targetPos = cmpTargetPosition.GetPosition2D(); + + var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); + var pos = cmpPosition.GetPosition2D(); + + var distFromTarget = Math.sqrt(Math.pow(targetPos.x - pos.x, 2) + Math.pow(targetPos.y - pos.y, 2)); + if (minRange <= distFromTarget && distFromTarget <= maxRange) + return true; + + return false; +}; + +UnitMotionFlying.prototype.GetWalkSpeed = function() +{ + return +this.template.MaxSpeed; +}; + +UnitMotionFlying.prototype.GetRunSpeed = function() +{ + return this.GetWalkSpeed(); +}; + +UnitMotionFlying.prototype.FaceTowardsPoint = function(x, z) +{ + // Ignore this - angle is controlled by the target-seeking code instead +}; + +UnitMotionFlying.prototype.SetDebugOverlay = function(enabled) +{ +}; + +Engine.RegisterComponentType(IID_UnitMotion, "UnitMotionFlying", UnitMotionFlying); diff --git a/binaries/data/mods/public/simulation/templates/other/plane.xml b/binaries/data/mods/public/simulation/templates/other/plane.xml new file mode 100644 index 0000000000..a12c1aaa2a --- /dev/null +++ b/binaries/data/mods/public/simulation/templates/other/plane.xml @@ -0,0 +1,36 @@ + + + + hele + Aeroplane + This may be anachronistic. + + + units/hellenes/siege_rock.xml + + + + + 1.57 + + + 24.0 + 8.0 + 1.57 + 2.0 + 16.0 + 3.0 + + + + 0.0 + 100.0 + 25.0 + 48 + 24 + 50.0 + 0 + 1000 + + + diff --git a/binaries/data/mods/public/simulation/templates/special/actor.xml b/binaries/data/mods/public/simulation/templates/special/actor.xml index 4b87cd5c8c..ac3732ad3f 100644 --- a/binaries/data/mods/public/simulation/templates/special/actor.xml +++ b/binaries/data/mods/public/simulation/templates/special/actor.xml @@ -4,6 +4,7 @@ 0 upright false + 6.0 (should be overridden) diff --git a/binaries/data/mods/public/simulation/templates/special/formation.xml b/binaries/data/mods/public/simulation/templates/special/formation.xml index 98434a62eb..24484d2572 100644 --- a/binaries/data/mods/public/simulation/templates/special/formation.xml +++ b/binaries/data/mods/public/simulation/templates/special/formation.xml @@ -4,6 +4,7 @@ 0 upright false + 6.0 diff --git a/binaries/data/mods/public/simulation/templates/template_entity_full.xml b/binaries/data/mods/public/simulation/templates/template_entity_full.xml index 52cc4797fe..10d6626870 100644 --- a/binaries/data/mods/public/simulation/templates/template_entity_full.xml +++ b/binaries/data/mods/public/simulation/templates/template_entity_full.xml @@ -6,6 +6,7 @@ 0 upright false + 6.0 diff --git a/binaries/data/mods/public/simulation/templates/template_entity_quasi.xml b/binaries/data/mods/public/simulation/templates/template_entity_quasi.xml index fcf0a7d16d..f85ed76bae 100644 --- a/binaries/data/mods/public/simulation/templates/template_entity_quasi.xml +++ b/binaries/data/mods/public/simulation/templates/template_entity_quasi.xml @@ -6,5 +6,6 @@ 0 upright false + 6.0 diff --git a/source/simulation2/TypeList.h b/source/simulation2/TypeList.h index ea3b3c045c..b86fb46128 100644 --- a/source/simulation2/TypeList.h +++ b/source/simulation2/TypeList.h @@ -127,6 +127,7 @@ COMPONENT(Terrain) INTERFACE(UnitMotion) COMPONENT(UnitMotion) // must be after Obstruction +COMPONENT(UnitMotionScripted) INTERFACE(Vision) COMPONENT(Vision) diff --git a/source/simulation2/components/CCmpPosition.cpp b/source/simulation2/components/CCmpPosition.cpp index 6b01feabd7..ca63383536 100644 --- a/source/simulation2/components/CCmpPosition.cpp +++ b/source/simulation2/components/CCmpPosition.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -68,6 +68,7 @@ public: bool m_InWorld; entity_pos_t m_X, m_Z, m_LastX, m_LastZ; // these values contain undefined junk if !InWorld entity_pos_t m_YOffset; + bool m_RelativeToGround; // whether m_YOffset is relative to terrain/water plane, or an absolute height entity_angle_t m_RotX, m_RotY, m_RotZ; float m_InterpolatedRotY; // not serialized @@ -80,6 +81,7 @@ public: "upright" "0.0" "false" + "6.0" "" "" "" @@ -93,6 +95,9 @@ public: "" "" "" + "" + "" + "" ""; } @@ -109,9 +114,10 @@ public: m_InWorld = false; m_YOffset = paramNode.GetChild("Altitude").ToFixed(); + m_RelativeToGround = true; m_Floating = paramNode.GetChild("Floating").ToBool(); - m_RotYSpeed = 6.f; // TODO: should get from template + m_RotYSpeed = paramNode.GetChild("TurnRate").ToFixed().ToFloat(); m_RotX = m_RotY = m_RotZ = entity_angle_t::FromInt(0); m_InterpolatedRotY = 0; @@ -137,6 +143,7 @@ public: serialize.NumberFixed_Unbounded("rot y", m_RotY); serialize.NumberFixed_Unbounded("rot z", m_RotZ); serialize.NumberFixed_Unbounded("altitude", m_YOffset); + serialize.Bool("relative", m_RelativeToGround); if (serialize.IsDebug()) { @@ -168,6 +175,7 @@ public: deserialize.NumberFixed_Unbounded("rot y", m_RotY); deserialize.NumberFixed_Unbounded("rot z", m_RotZ); deserialize.NumberFixed_Unbounded("altitude", m_YOffset); + deserialize.Bool("relative", m_RelativeToGround); // TODO: should there be range checks on all these values? m_InterpolatedRotY = m_RotY.ToFloat(); @@ -212,6 +220,7 @@ public: virtual void SetHeightOffset(entity_pos_t dy) { m_YOffset = dy; + m_RelativeToGround = true; AdvertisePositionChanges(); } @@ -221,6 +230,12 @@ public: return m_YOffset; } + virtual void SetHeightFixed(entity_pos_t y) + { + m_YOffset = y; + m_RelativeToGround = false; + } + virtual bool IsFloating() { return m_Floating; @@ -235,15 +250,18 @@ public: } entity_pos_t baseY; - CmpPtr cmpTerrain(GetSimContext(), SYSTEM_ENTITY); - if (!cmpTerrain.null()) - baseY = cmpTerrain->GetGroundLevel(m_X, m_Z); - - if (m_Floating) + if (m_RelativeToGround) { - CmpPtr cmpWaterMan(GetSimContext(), SYSTEM_ENTITY); - if (!cmpWaterMan.null()) - baseY = std::max(baseY, cmpWaterMan->GetWaterLevel(m_X, m_Z)); + CmpPtr cmpTerrain(GetSimContext(), SYSTEM_ENTITY); + if (!cmpTerrain.null()) + baseY = cmpTerrain->GetGroundLevel(m_X, m_Z); + + if (m_Floating) + { + CmpPtr cmpWaterMan(GetSimContext(), SYSTEM_ENTITY); + if (!cmpWaterMan.null()) + baseY = std::max(baseY, cmpWaterMan->GetWaterLevel(m_X, m_Z)); + } } return CFixedVector3D(m_X, baseY + m_YOffset, m_Z); @@ -327,15 +345,18 @@ public: GetInterpolatedPosition2D(frameOffset, x, z, rotY); float baseY = 0; - CmpPtr cmpTerrain(GetSimContext(), SYSTEM_ENTITY); - if (!cmpTerrain.null()) - baseY = cmpTerrain->GetExactGroundLevel(x, z); - - if (m_Floating || forceFloating) + if (m_RelativeToGround) { - CmpPtr cmpWaterMan(GetSimContext(), SYSTEM_ENTITY); - if (!cmpWaterMan.null()) - baseY = std::max(baseY, cmpWaterMan->GetExactWaterLevel(x, z)); + CmpPtr cmpTerrain(GetSimContext(), SYSTEM_ENTITY); + if (!cmpTerrain.null()) + baseY = cmpTerrain->GetExactGroundLevel(x, z); + + if (m_Floating || forceFloating) + { + CmpPtr cmpWaterMan(GetSimContext(), SYSTEM_ENTITY); + if (!cmpWaterMan.null()) + baseY = std::max(baseY, cmpWaterMan->GetExactWaterLevel(x, z)); + } } float y = baseY + m_YOffset.ToFloat(); diff --git a/source/simulation2/components/CCmpUnitMotion.cpp b/source/simulation2/components/CCmpUnitMotion.cpp index 5980f4ea90..f1b82a6d9f 100644 --- a/source/simulation2/components/CCmpUnitMotion.cpp +++ b/source/simulation2/components/CCmpUnitMotion.cpp @@ -413,6 +413,8 @@ public: virtual bool IsInTargetRange(entity_id_t target, entity_pos_t minRange, entity_pos_t maxRange); virtual void MoveToFormationOffset(entity_id_t target, entity_pos_t x, entity_pos_t z); + virtual void FaceTowardsPoint(entity_pos_t x, entity_pos_t z); + virtual void StopMoving() { m_ExpectedPathTicket = 0; @@ -522,7 +524,7 @@ private: /** * Rotate to face towards the target point, given the current pos */ - void FaceTowardsPoint(CFixedVector2D pos, entity_pos_t x, entity_pos_t z); + void FaceTowardsPointFromPos(CFixedVector2D pos, entity_pos_t x, entity_pos_t z); /** * Returns an appropriate obstruction filter for use with path requests. @@ -901,7 +903,7 @@ void CCmpUnitMotion::Move(fixed dt) StopMoving(); - FaceTowardsPoint(pos, m_FinalGoal.x, m_FinalGoal.z); + FaceTowardsPointFromPos(pos, m_FinalGoal.x, m_FinalGoal.z); // TODO: if the goal was a square building, we ought to point towards the // nearest point on the square, not towards its center } @@ -1033,7 +1035,17 @@ bool CCmpUnitMotion::PathIsShort(const ICmpPathfinder::Path& path, CFixedVector2 return true; } -void CCmpUnitMotion::FaceTowardsPoint(CFixedVector2D pos, entity_pos_t x, entity_pos_t z) +void CCmpUnitMotion::FaceTowardsPoint(entity_pos_t x, entity_pos_t z) +{ + CmpPtr cmpPosition(GetSimContext(), GetEntityId()); + if (cmpPosition.null() || !cmpPosition->IsInWorld()) + return; + + CFixedVector2D pos = cmpPosition->GetPosition2D(); + FaceTowardsPointFromPos(pos, x, z); +} + +void CCmpUnitMotion::FaceTowardsPointFromPos(CFixedVector2D pos, entity_pos_t x, entity_pos_t z) { CFixedVector2D target(x, z); CFixedVector2D offset = target - pos; @@ -1223,7 +1235,7 @@ bool CCmpUnitMotion::MoveToPointRange(entity_pos_t x, entity_pos_t z, entity_pos else { // We're already in range - no need to move anywhere - FaceTowardsPoint(pos, x, z); + FaceTowardsPointFromPos(pos, x, z); return false; } @@ -1334,7 +1346,7 @@ bool CCmpUnitMotion::MoveToTargetRange(entity_id_t target, entity_pos_t minRange else if (maxRange < entity_pos_t::Zero() || distance < maxRange) { // We're already in range - no need to move anywhere - FaceTowardsPoint(pos, goal.x, goal.z); + FaceTowardsPointFromPos(pos, goal.x, goal.z); return false; } else @@ -1356,7 +1368,7 @@ bool CCmpUnitMotion::MoveToTargetRange(entity_id_t target, entity_pos_t minRange if (circleDistance < maxRange) { // We're already in range - no need to move anywhere - FaceTowardsPoint(pos, goal.x, goal.z); + FaceTowardsPointFromPos(pos, goal.x, goal.z); return false; } diff --git a/source/simulation2/components/ICmpPosition.cpp b/source/simulation2/components/ICmpPosition.cpp index d1f2217018..1e3c8b0efb 100644 --- a/source/simulation2/components/ICmpPosition.cpp +++ b/source/simulation2/components/ICmpPosition.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -28,6 +28,7 @@ DEFINE_INTERFACE_METHOD_2("MoveTo", void, ICmpPosition, MoveTo, entity_pos_t, en DEFINE_INTERFACE_METHOD_2("JumpTo", void, ICmpPosition, JumpTo, entity_pos_t, entity_pos_t) DEFINE_INTERFACE_METHOD_1("SetHeightOffset", void, ICmpPosition, SetHeightOffset, entity_pos_t) DEFINE_INTERFACE_METHOD_0("GetHeightOffset", entity_pos_t, ICmpPosition, GetHeightOffset) +DEFINE_INTERFACE_METHOD_1("SetHeightFixed", void, ICmpPosition, SetHeightFixed, entity_pos_t) DEFINE_INTERFACE_METHOD_0("IsFloating", bool, ICmpPosition, IsFloating) DEFINE_INTERFACE_METHOD_0("GetPosition", CFixedVector3D, ICmpPosition, GetPosition) DEFINE_INTERFACE_METHOD_0("GetPosition2D", CFixedVector2D, ICmpPosition, GetPosition2D) diff --git a/source/simulation2/components/ICmpPosition.h b/source/simulation2/components/ICmpPosition.h index 19f00d48d5..4a4b274534 100644 --- a/source/simulation2/components/ICmpPosition.h +++ b/source/simulation2/components/ICmpPosition.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -84,6 +84,12 @@ public: */ virtual entity_pos_t GetHeightOffset() = 0; + /** + * Set the vertical position as a fixed, absolute value. + * Will stay at this height until the next call to SetHeightFixed or SetHeightOffset. + */ + virtual void SetHeightFixed(entity_pos_t y) = 0; + /** * Returns whether the entity floats on water. */ diff --git a/source/simulation2/components/ICmpUnitMotion.cpp b/source/simulation2/components/ICmpUnitMotion.cpp index 431f205e99..ee9cad68f0 100644 --- a/source/simulation2/components/ICmpUnitMotion.cpp +++ b/source/simulation2/components/ICmpUnitMotion.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -20,12 +20,14 @@ #include "ICmpUnitMotion.h" #include "simulation2/system/InterfaceScripted.h" +#include "simulation2/scripting/ScriptComponent.h" BEGIN_INTERFACE_WRAPPER(UnitMotion) DEFINE_INTERFACE_METHOD_4("MoveToPointRange", bool, ICmpUnitMotion, MoveToPointRange, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t) DEFINE_INTERFACE_METHOD_3("IsInTargetRange", bool, ICmpUnitMotion, IsInTargetRange, entity_id_t, entity_pos_t, entity_pos_t) DEFINE_INTERFACE_METHOD_3("MoveToTargetRange", bool, ICmpUnitMotion, MoveToTargetRange, entity_id_t, entity_pos_t, entity_pos_t) DEFINE_INTERFACE_METHOD_3("MoveToFormationOffset", void, ICmpUnitMotion, MoveToFormationOffset, entity_id_t, entity_pos_t, entity_pos_t) +DEFINE_INTERFACE_METHOD_2("FaceTowardsPoint", void, ICmpUnitMotion, FaceTowardsPoint, entity_pos_t, entity_pos_t) DEFINE_INTERFACE_METHOD_0("StopMoving", void, ICmpUnitMotion, StopMoving) DEFINE_INTERFACE_METHOD_1("SetSpeed", void, ICmpUnitMotion, SetSpeed, fixed) DEFINE_INTERFACE_METHOD_0("GetWalkSpeed", fixed, ICmpUnitMotion, GetWalkSpeed) @@ -33,3 +35,67 @@ DEFINE_INTERFACE_METHOD_0("GetRunSpeed", fixed, ICmpUnitMotion, GetRunSpeed) DEFINE_INTERFACE_METHOD_1("SetUnitRadius", void, ICmpUnitMotion, SetUnitRadius, fixed) DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpUnitMotion, SetDebugOverlay, bool) END_INTERFACE_WRAPPER(UnitMotion) + +class CCmpUnitMotionScripted : public ICmpUnitMotion +{ +public: + DEFAULT_SCRIPT_WRAPPER(UnitMotionScripted) + + virtual bool MoveToPointRange(entity_pos_t x, entity_pos_t z, entity_pos_t minRange, entity_pos_t maxRange) + { + return m_Script.Call("MoveToPointRange", x, z, minRange, maxRange); + } + + virtual bool IsInTargetRange(entity_id_t target, entity_pos_t minRange, entity_pos_t maxRange) + { + return m_Script.Call("IsInTargetRange", target, minRange, maxRange); + } + + virtual bool MoveToTargetRange(entity_id_t target, entity_pos_t minRange, entity_pos_t maxRange) + { + return m_Script.Call("MoveToTargetRange", target, minRange, maxRange); + } + + virtual void MoveToFormationOffset(entity_id_t target, entity_pos_t x, entity_pos_t z) + { + m_Script.CallVoid("MoveToFormationOffset", target, x, z); + } + + virtual void FaceTowardsPoint(entity_pos_t x, entity_pos_t z) + { + m_Script.CallVoid("FaceTowardsPoint", x, z); + } + + virtual void StopMoving() + { + m_Script.CallVoid("StopMoving"); + } + + virtual void SetSpeed(fixed speed) + { + m_Script.CallVoid("SetSpeed", speed); + } + + virtual fixed GetWalkSpeed() + { + return m_Script.Call("GetWalkSpeed"); + } + + virtual fixed GetRunSpeed() + { + return m_Script.Call("GetRunSpeed"); + } + + virtual void SetUnitRadius(fixed radius) + { + m_Script.CallVoid("SetUnitRadius", radius); + } + + virtual void SetDebugOverlay(bool enabled) + { + m_Script.CallVoid("SetDebugOverlay", enabled); + } + +}; + +REGISTER_COMPONENT_SCRIPT_WRAPPER(UnitMotionScripted) diff --git a/source/simulation2/components/ICmpUnitMotion.h b/source/simulation2/components/ICmpUnitMotion.h index ce86efb91c..fa8c609779 100644 --- a/source/simulation2/components/ICmpUnitMotion.h +++ b/source/simulation2/components/ICmpUnitMotion.h @@ -67,6 +67,11 @@ public: */ virtual void MoveToFormationOffset(entity_id_t target, entity_pos_t x, entity_pos_t z) = 0; + /** + * Turn to look towards the given point. + */ + virtual void FaceTowardsPoint(entity_pos_t x, entity_pos_t z) = 0; + /** * Stop moving immediately. */ diff --git a/source/simulation2/tests/test_CmpTemplateManager.h b/source/simulation2/tests/test_CmpTemplateManager.h index f1d77d3684..7581b73fc0 100644 --- a/source/simulation2/tests/test_CmpTemplateManager.h +++ b/source/simulation2/tests/test_CmpTemplateManager.h @@ -83,7 +83,7 @@ public: const CParamNode* preview = tempMan->LoadTemplate(ent2, "preview|unit", -1); TS_ASSERT(preview != NULL); TS_ASSERT_WSTR_EQUALS(preview->ToXML(), - L"0uprightfalse" + L"0uprightfalse6.0" L"true0false" L"examplefalsefalse"); @@ -97,7 +97,7 @@ public: L"falsefalse" L"" L"" - L"0uprightfalse" + L"0uprightfalse6.0" L"true0false" L"examplefalsefalse");