Add the Engine code for turrets + use them to get units on walls. The scripted TurretHolder isn't included due to lack of usability for now. Refs #2577
This was SVN commit r15246.
This commit is contained in:
parent
d05bd656e7
commit
cfec28e553
@ -227,6 +227,16 @@ Attack.prototype.CanAttack = function(target)
|
||||
if (cmpFormation)
|
||||
return true;
|
||||
|
||||
var cmpThisPosition = Engine.QueryInterface(this.entity, IID_Position);
|
||||
var cmpTargetPosition = Engine.QueryInterface(target, IID_Position);
|
||||
if (!cmpThisPosition || !cmpTargetPosition || !cmpThisPosition.IsInWorld() || !cmpTargetPosition.IsInWorld())
|
||||
return false;
|
||||
|
||||
// Check if the relative height difference is larger than the attack range
|
||||
// If the relative height is bigger, it means they will never be able to
|
||||
// reach each other, no matter how close they come.
|
||||
var heightDiff = Math.abs(cmpThisPosition.GetHeightOffset() - cmpTargetPosition.GetHeightOffset());
|
||||
|
||||
const cmpIdentity = Engine.QueryInterface(target, IID_Identity);
|
||||
if (!cmpIdentity)
|
||||
return undefined;
|
||||
@ -235,6 +245,9 @@ Attack.prototype.CanAttack = function(target)
|
||||
|
||||
for each (var type in this.GetAttackTypes())
|
||||
{
|
||||
if (heightDiff > this.GetRange(type).max)
|
||||
continue;
|
||||
|
||||
var canAttack = true;
|
||||
var restrictedClasses = this.GetRestrictedClasses(type);
|
||||
|
||||
|
@ -29,6 +29,26 @@ GarrisonHolder.prototype.Schema =
|
||||
"<element name='Pickup' a:help='This garrisonHolder will move to pick up units to be garrisoned'>" +
|
||||
"<data type='boolean'/>" +
|
||||
"</element>" +
|
||||
"</optional>" +
|
||||
"<optional>" +
|
||||
"<element name='VisibleGarrisonPoints' a:help='Points that will be used to visibly garrison a unit'>" +
|
||||
"<zeroOrMore>" +
|
||||
"<element a:help='Element containing the offset coordinates'>" +
|
||||
"<anyName/>" +
|
||||
"<interleave>" +
|
||||
"<element name='X'>" +
|
||||
"<data type='decimal'/>" +
|
||||
"</element>" +
|
||||
"<element name='Y'>" +
|
||||
"<data type='decimal'/>" +
|
||||
"</element>" +
|
||||
"<element name='Z'>" +
|
||||
"<data type='decimal'/>" +
|
||||
"</element>" +
|
||||
"</interleave>" +
|
||||
"</element>" +
|
||||
"</zeroOrMore>" +
|
||||
"</element>" +
|
||||
"</optional>";
|
||||
|
||||
/**
|
||||
@ -40,6 +60,18 @@ GarrisonHolder.prototype.Init = function()
|
||||
this.entities = [];
|
||||
this.timer = undefined;
|
||||
this.allowGarrisoning = {};
|
||||
this.visibleGarrisonPoints = [];
|
||||
if (this.template.VisibleGarrisonPoints)
|
||||
{
|
||||
for each (var offset in this.template.VisibleGarrisonPoints)
|
||||
{
|
||||
var o = {};
|
||||
o.x = +offset.X;
|
||||
o.y = +offset.Y;
|
||||
o.z = +offset.Z;
|
||||
this.visibleGarrisonPoints.push({"offset":o, "entity": null});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -206,7 +238,21 @@ GarrisonHolder.prototype.Garrison = function(entity)
|
||||
if (!this.PerformGarrison(entity))
|
||||
return false;
|
||||
|
||||
cmpPosition.MoveOutOfWorld();
|
||||
var visiblyGarrisoned = false;
|
||||
for (var vgp of this.visibleGarrisonPoints)
|
||||
{
|
||||
if (vgp.entity)
|
||||
continue;
|
||||
vgp.entity = entity;
|
||||
cmpPosition.SetTurretParent(this.entity, vgp.offset);
|
||||
var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI)
|
||||
if (cmpUnitAI)
|
||||
cmpUnitAI.SetTurret(true);
|
||||
visiblyGarrisoned = true;
|
||||
break;
|
||||
}
|
||||
if (!visiblyGarrisoned)
|
||||
cmpPosition.MoveOutOfWorld();
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -291,8 +337,21 @@ GarrisonHolder.prototype.Eject = function(entity, forced)
|
||||
}
|
||||
}
|
||||
|
||||
var cmpNewPosition = Engine.QueryInterface(entity, IID_Position);
|
||||
this.entities.splice(entityIndex, 1);
|
||||
|
||||
for (var vgp of this.visibleGarrisonPoints)
|
||||
{
|
||||
if (vgp.entity != entity)
|
||||
continue;
|
||||
cmpNewPosition.SetTurretParent(INVALID_ENTITY, new Vector3D());
|
||||
vgp.entity = null;
|
||||
var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI)
|
||||
if (cmpUnitAI)
|
||||
cmpUnitAI.SetTurret(false);
|
||||
break;
|
||||
}
|
||||
|
||||
var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
|
||||
if (cmpUnitAI)
|
||||
cmpUnitAI.Ungarrison();
|
||||
@ -306,8 +365,8 @@ GarrisonHolder.prototype.Eject = function(entity, forced)
|
||||
cmpAura.RemoveGarrisonBonus(this.entity);
|
||||
|
||||
|
||||
var cmpNewPosition = Engine.QueryInterface(entity, IID_Position);
|
||||
cmpNewPosition.JumpTo(pos.x, pos.z);
|
||||
cmpNewPosition.SetHeightOffset(0);
|
||||
// TODO: what direction should they face in?
|
||||
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [entity] });
|
||||
@ -579,8 +638,8 @@ GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg)
|
||||
var entityIndex = this.entities.indexOf(msg.entity);
|
||||
if (entityIndex != -1)
|
||||
{
|
||||
this.entities[entityIndex] = msg.newentity;
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [msg.newentity], "removed": [msg.entity] });
|
||||
this.Eject(msg.entity);
|
||||
this.Garrison(msg.newentity);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -179,7 +179,7 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
// Called when being told to walk as part of a formation
|
||||
"Order.FormationWalk": function(msg) {
|
||||
// Let players move captured domestic animals around
|
||||
if (this.IsAnimal() && !this.IsDomestic())
|
||||
if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret())
|
||||
{
|
||||
this.FinishOrder();
|
||||
return;
|
||||
@ -207,7 +207,7 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
"Order.LeaveFoundation": function(msg) {
|
||||
// If foundation is not ally of entity, or if entity is unpacked siege,
|
||||
// ignore the order
|
||||
if (!IsOwnedByAllyOfEntity(this.entity, msg.data.target) || this.IsPacking() || this.CanPack())
|
||||
if (!IsOwnedByAllyOfEntity(this.entity, msg.data.target) || this.IsPacking() || this.CanPack() || this.IsTurret())
|
||||
{
|
||||
this.FinishOrder();
|
||||
return;
|
||||
@ -252,7 +252,7 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
|
||||
"Order.Walk": function(msg) {
|
||||
// Let players move captured domestic animals around
|
||||
if (this.IsAnimal() && !this.IsDomestic())
|
||||
if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret())
|
||||
{
|
||||
this.FinishOrder();
|
||||
return;
|
||||
@ -281,7 +281,7 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
|
||||
"Order.WalkAndFight": function(msg) {
|
||||
// Let players move captured domestic animals around
|
||||
if (this.IsAnimal() && !this.IsDomestic())
|
||||
if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret())
|
||||
{
|
||||
this.FinishOrder();
|
||||
return;
|
||||
@ -308,7 +308,7 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
|
||||
"Order.WalkToTarget": function(msg) {
|
||||
// Let players move captured domestic animals around
|
||||
if (this.IsAnimal() && !this.IsDomestic())
|
||||
if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret())
|
||||
{
|
||||
this.FinishOrder();
|
||||
return;
|
||||
@ -489,7 +489,7 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
|
||||
// If we can't reach the target, but are standing ground, then abandon this attack order.
|
||||
// Unless we're hunting, that's a special case where we should continue attacking our target.
|
||||
if (this.GetStance().respondStandGround && !this.order.data.force && !this.order.data.hunting)
|
||||
if (this.GetStance().respondStandGround && !this.order.data.force && !this.order.data.hunting || this.IsTurret())
|
||||
{
|
||||
this.FinishOrder();
|
||||
return;
|
||||
@ -688,6 +688,11 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
},
|
||||
|
||||
"Order.Garrison": function(msg) {
|
||||
if (this.IsTurret())
|
||||
{
|
||||
this.FinishOrder();
|
||||
return;
|
||||
}
|
||||
// For packable units:
|
||||
// 1. If packed, we can move to the garrison target.
|
||||
// 2. If unpacked, we first need to pack, then follow case 1.
|
||||
@ -1245,7 +1250,7 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
"Order.LeaveFoundation": function(msg) {
|
||||
// If foundation is not ally of entity, or if entity is unpacked siege,
|
||||
// ignore the order
|
||||
if (!IsOwnedByAllyOfEntity(this.entity, msg.data.target) || this.IsPacking() || this.CanPack())
|
||||
if (!IsOwnedByAllyOfEntity(this.entity, msg.data.target) || this.IsPacking() || this.CanPack() || this.IsTurret())
|
||||
{
|
||||
this.FinishOrder();
|
||||
return;
|
||||
@ -2836,6 +2841,9 @@ UnitAI.prototype.UnitFsmSpec = {
|
||||
delete this.pickup;
|
||||
}
|
||||
|
||||
if (this.IsTurret())
|
||||
this.SetNextState("IDLE");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -3135,6 +3143,28 @@ UnitAI.prototype.Init = function()
|
||||
this.lastHealed = undefined;
|
||||
|
||||
this.SetStance(this.template.DefaultStance);
|
||||
this.SetTurret(false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the flag to true to use this unit as a turret
|
||||
* This means no moving is allowed, only turning
|
||||
*/
|
||||
UnitAI.prototype.SetTurret = function(flag)
|
||||
{
|
||||
this.isTurret = flag;
|
||||
if (flag == false && this.oldStance)
|
||||
this.SetStance(this.oldStance);
|
||||
else if (flag == true)
|
||||
{
|
||||
this.OldStance = this.GetStance();
|
||||
this.SetStance("standground");
|
||||
}
|
||||
};
|
||||
|
||||
UnitAI.prototype.IsTurret = function()
|
||||
{
|
||||
return this.isTurret;
|
||||
};
|
||||
|
||||
UnitAI.prototype.ReactsToAlert = function(level)
|
||||
@ -4168,7 +4198,7 @@ UnitAI.prototype.MoveToTarget = function(target)
|
||||
|
||||
UnitAI.prototype.MoveToTargetRange = function(target, iid, type)
|
||||
{
|
||||
if (!this.CheckTargetVisible(target))
|
||||
if (!this.CheckTargetVisible(target) || this.IsTurret())
|
||||
return false;
|
||||
|
||||
var cmpRanged = Engine.QueryInterface(this.entity, iid);
|
||||
@ -4599,6 +4629,9 @@ UnitAI.prototype.ShouldAbandonChase = function(target, force, iid, type)
|
||||
*/
|
||||
UnitAI.prototype.ShouldChaseTargetedEntity = function(target, force)
|
||||
{
|
||||
if (this.IsTurret())
|
||||
return false;
|
||||
|
||||
// TODO: use special stances instead?
|
||||
var cmpPack = Engine.QueryInterface(this.entity, IID_Pack);
|
||||
if (cmpPack)
|
||||
@ -5530,6 +5563,8 @@ UnitAI.prototype.CanGarrison = function(target)
|
||||
|
||||
UnitAI.prototype.CanGather = function(target)
|
||||
{
|
||||
if (this.IsTurret())
|
||||
return false;
|
||||
// The target must be a valid resource supply.
|
||||
var cmpResourceSupply = Engine.QueryInterface(target, IID_ResourceSupply);
|
||||
if (!cmpResourceSupply)
|
||||
@ -5602,6 +5637,8 @@ UnitAI.prototype.CanHeal = function(target)
|
||||
|
||||
UnitAI.prototype.CanReturnResource = function(target, checkCarriedResource)
|
||||
{
|
||||
if (this.IsTurret())
|
||||
return false;
|
||||
// Formation controllers should always respond to commands
|
||||
// (then the individual units can make up their own minds)
|
||||
if (this.IsFormationController())
|
||||
@ -5636,6 +5673,8 @@ UnitAI.prototype.CanReturnResource = function(target, checkCarriedResource)
|
||||
|
||||
UnitAI.prototype.CanTrade = function(target)
|
||||
{
|
||||
if (this.IsTurret())
|
||||
return false;
|
||||
// Formation controllers should always respond to commands
|
||||
// (then the individual units can make up their own minds)
|
||||
if (this.IsFormationController())
|
||||
@ -5651,6 +5690,8 @@ UnitAI.prototype.CanTrade = function(target)
|
||||
|
||||
UnitAI.prototype.CanRepair = function(target)
|
||||
{
|
||||
if (this.IsTurret())
|
||||
return false;
|
||||
// Formation controllers should always respond to commands
|
||||
// (then the individual units can make up their own minds)
|
||||
if (this.IsFormationController())
|
||||
|
@ -4,6 +4,25 @@
|
||||
<Square width="38.5" depth="8.5"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>8</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-8</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
<Archer4>
|
||||
<X>4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer4>
|
||||
<Archer5>
|
||||
<X>-4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer5>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>brit</Civ>
|
||||
<SelectionGroupName>structures/celt_wallset_stone</SelectionGroupName>
|
||||
|
@ -4,6 +4,19 @@
|
||||
<Square width="26.5" depth="8.5"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Health>
|
||||
<Max>3000</Max>
|
||||
</Health>
|
||||
|
@ -4,6 +4,25 @@
|
||||
<Square width="45.0" depth="11.0"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>12.5</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>8</X><Y>12.5</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-8</X><Y>12.5</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
<Archer4>
|
||||
<X>4</X><Y>12.5</Y><Z>0</Z>
|
||||
</Archer4>
|
||||
<Archer5>
|
||||
<X>-4</X><Y>12.5</Y><Z>0</Z>
|
||||
</Archer5>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>cart</Civ>
|
||||
<SelectionGroupName>structures/cart_wallset_stone</SelectionGroupName>
|
||||
|
@ -4,6 +4,19 @@
|
||||
<Square width="31.0" depth="11.0"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>12.5</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>4</X><Y>12.5</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-4</X><Y>12.5</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>cart</Civ>
|
||||
<SelectionGroupName>structures/cart_wallset_stone</SelectionGroupName>
|
||||
|
@ -4,6 +4,25 @@
|
||||
<Square width="38.5" depth="8.5"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>8</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-8</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
<Archer4>
|
||||
<X>4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer4>
|
||||
<Archer5>
|
||||
<X>-4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer5>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>celt</Civ>
|
||||
<SelectionGroupName>structures/celt_wallset_stone</SelectionGroupName>
|
||||
|
@ -7,6 +7,19 @@
|
||||
<Health>
|
||||
<Max>3000</Max>
|
||||
</Health>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>celt</Civ>
|
||||
<SelectionGroupName>structures/celt_wallset_stone</SelectionGroupName>
|
||||
|
@ -4,6 +4,25 @@
|
||||
<Square width="38.5" depth="8.5"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>8</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-8</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
<Archer4>
|
||||
<X>4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer4>
|
||||
<Archer5>
|
||||
<X>-4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer5>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>gaul</Civ>
|
||||
<SelectionGroupName>structures/celt_wallset_stone</SelectionGroupName>
|
||||
|
@ -7,6 +7,19 @@
|
||||
<Health>
|
||||
<Max>3000</Max>
|
||||
</Health>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-4</X><Y>9.3</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>gaul</Civ>
|
||||
<SelectionGroupName>structures/celt_wallset_stone</SelectionGroupName>
|
||||
|
@ -4,6 +4,25 @@
|
||||
<Square width="37" depth="9"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.0</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>8</X><Y>9.0</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-8</X><Y>9.0</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
<Archer4>
|
||||
<X>4</X><Y>9.0</Y><Z>0</Z>
|
||||
</Archer4>
|
||||
<Archer5>
|
||||
<X>-4</X><Y>9.0</Y><Z>0</Z>
|
||||
</Archer5>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>iber</Civ>
|
||||
<SelectionGroupName>structures/iber_wallset_stone</SelectionGroupName>
|
||||
|
@ -4,6 +4,19 @@
|
||||
<Square width="25" depth="9"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.0</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>4</X><Y>9.0</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-4</X><Y>9.0</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Health>
|
||||
<Max>3000</Max>
|
||||
</Health>
|
||||
|
@ -10,6 +10,25 @@
|
||||
<Square width="36.5" depth="9.0"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.5</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>8</X><Y>9.5</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-8</X><Y>9.5</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
<Archer4>
|
||||
<X>4</X><Y>9.5</Y><Z>0</Z>
|
||||
</Archer4>
|
||||
<Archer5>
|
||||
<X>-4</X><Y>9.5</Y><Z>0</Z>
|
||||
</Archer5>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>maur</Civ>
|
||||
<SelectionGroupName>structures/maur_wallset_stone</SelectionGroupName>
|
||||
|
@ -10,6 +10,19 @@
|
||||
<Square width="26.5" depth="9.0"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.5</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>4</X><Y>9.5</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-4</X><Y>9.5</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>maur</Civ>
|
||||
<SelectionGroupName>structures/maur_wallset_stone</SelectionGroupName>
|
||||
|
@ -4,6 +4,25 @@
|
||||
<Square width="38.5" depth="9.0"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>10.6</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>8</X><Y>10.6</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-8</X><Y>10.6</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
<Archer4>
|
||||
<X>4</X><Y>10.6</Y><Z>0</Z>
|
||||
</Archer4>
|
||||
<Archer5>
|
||||
<X>-4</X><Y>10.6</Y><Z>0</Z>
|
||||
</Archer5>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>pers</Civ>
|
||||
<SelectionGroupName>structures/pers_wallset_stone</SelectionGroupName>
|
||||
@ -19,4 +38,4 @@
|
||||
<WallPiece>
|
||||
<Length>37.0</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
||||
</Entity>
|
||||
|
@ -4,6 +4,19 @@
|
||||
<Square width="26.0" depth="9.0"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>10.6</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>4</X><Y>10.6</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-4</X><Y>10.6</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>pers</Civ>
|
||||
<SelectionGroupName>structures/pers_wallset_stone</SelectionGroupName>
|
||||
|
@ -4,6 +4,25 @@
|
||||
<Square width="40" depth="10.0"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.7</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>8</X><Y>9.7</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-8</X><Y>9.7</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
<Archer4>
|
||||
<X>4</X><Y>9.7</Y><Z>0</Z>
|
||||
</Archer4>
|
||||
<Archer5>
|
||||
<X>-4</X><Y>9.7</Y><Z>0</Z>
|
||||
</Archer5>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>ptol</Civ>
|
||||
<SelectionGroupName>structures/ptol_wallset_stone</SelectionGroupName>
|
||||
@ -19,4 +38,4 @@
|
||||
<WallPiece>
|
||||
<Length>38.0</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
||||
</Entity>
|
||||
|
@ -4,6 +4,19 @@
|
||||
<Square width="28.0" depth="10.0"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>9.7</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>4</X><Y>9.7</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-4</X><Y>9.7</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>ptol</Civ>
|
||||
<SelectionGroupName>structures/mace_wallset_stone</SelectionGroupName>
|
||||
|
@ -23,6 +23,25 @@
|
||||
<Square width="40.0" depth="8.0"/>
|
||||
<Height>7.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>5.7</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>8</X><Y>5.7</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-8</X><Y>5.7</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
<Archer4>
|
||||
<X>4</X><Y>5.7</Y><Z>0</Z>
|
||||
</Archer4>
|
||||
<Archer5>
|
||||
<X>-4</X><Y>5.7</Y><Z>0</Z>
|
||||
</Archer5>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Health>
|
||||
<Max>2000</Max>
|
||||
</Health>
|
||||
|
@ -26,6 +26,19 @@
|
||||
<Health>
|
||||
<Max>1500</Max>
|
||||
</Health>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>5.7</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>4</X><Y>5.7</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-4</X><Y>5.7</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>rome</Civ>
|
||||
<SelectionGroupName>structures/rome_wallset_siege</SelectionGroupName>
|
||||
|
@ -4,6 +4,25 @@
|
||||
<Square width="38.5" depth="9.0"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>8.9</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>8</X><Y>8.9</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-8</X><Y>8.9</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
<Archer4>
|
||||
<X>4</X><Y>8.9</Y><Z>0</Z>
|
||||
</Archer4>
|
||||
<Archer5>
|
||||
<X>-4</X><Y>8.9</Y><Z>0</Z>
|
||||
</Archer5>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Civ>rome</Civ>
|
||||
<SelectionGroupName>structures/rome_wallset_stone</SelectionGroupName>
|
||||
|
@ -4,6 +4,19 @@
|
||||
<Square width="26.5" depth="9.0"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>8.9</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>4</X><Y>8.9</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-4</X><Y>8.9</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Health>
|
||||
<Max>3000</Max>
|
||||
</Health>
|
||||
|
@ -9,6 +9,31 @@
|
||||
<Health>
|
||||
<SpawnEntityOnDeath>rubble/rubble_stone_wall_long</SpawnEntityOnDeath>
|
||||
</Health>
|
||||
<GarrisonHolder>
|
||||
<Max>5</Max>
|
||||
<List datatype="tokens">Infantry</List>
|
||||
<EjectHealth>0.1</EjectHealth>
|
||||
<EjectClassesOnDestroy datatype="tokens">Infantry</EjectClassesOnDestroy>
|
||||
<BuffHeal>0</BuffHeal>
|
||||
<LoadingRange>2</LoadingRange>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>11.5</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>8</X><Y>11.5</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-8</X><Y>11.5</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
<Archer4>
|
||||
<X>4</X><Y>11.5</Y><Z>0</Z>
|
||||
</Archer4>
|
||||
<Archer5>
|
||||
<X>-4</X><Y>11.5</Y><Z>0</Z>
|
||||
</Archer5>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Identity>
|
||||
<Classes datatype="tokens">LongWall</Classes>
|
||||
<Tooltip>Long wall segments can be converted to gates.</Tooltip>
|
||||
|
@ -6,6 +6,25 @@
|
||||
<stone>20</stone>
|
||||
</Resources>
|
||||
</Cost>
|
||||
<GarrisonHolder>
|
||||
<Max>3</Max>
|
||||
<List datatype="tokens">Infantry</List>
|
||||
<EjectHealth>0.1</EjectHealth>
|
||||
<EjectClassesOnDestroy datatype="tokens">Infantry</EjectClassesOnDestroy>
|
||||
<BuffHeal>0</BuffHeal>
|
||||
<LoadingRange>2</LoadingRange>
|
||||
<VisibleGarrisonPoints>
|
||||
<Archer1>
|
||||
<X>0</X><Y>11.5</Y><Z>0</Z>
|
||||
</Archer1>
|
||||
<Archer2>
|
||||
<X>4</X><Y>11.5</Y><Z>0</Z>
|
||||
</Archer2>
|
||||
<Archer3>
|
||||
<X>-4</X><Y>11.5</Y><Z>0</Z>
|
||||
</Archer3>
|
||||
</VisibleGarrisonPoints>
|
||||
</GarrisonHolder>
|
||||
<Health>
|
||||
<Max>3000</Max>
|
||||
<SpawnEntityOnDeath>rubble/rubble_stone_wall_medium</SpawnEntityOnDeath>
|
||||
|
@ -40,7 +40,7 @@
|
||||
<Height>8.0</Height>
|
||||
</Footprint>
|
||||
<GarrisonHolder>
|
||||
<Max>5</Max>
|
||||
<Max>2</Max>
|
||||
<EjectHealth>0.1</EjectHealth>
|
||||
<EjectClassesOnDestroy datatype="tokens">Unit</EjectClassesOnDestroy>
|
||||
<List datatype="tokens">Support Infantry</List>
|
||||
|
@ -76,10 +76,16 @@ public:
|
||||
entity_pos_t m_Y, m_LastYDifference; // either the relative or the absolute Y coordinate
|
||||
bool m_RelativeToGround; // whether m_Y is relative to terrain/water plane, or an absolute height
|
||||
|
||||
// when the entity is a turret, only m_RotY is used, and this is the rotation
|
||||
// relative to the parent entity
|
||||
entity_angle_t m_RotX, m_RotY, m_RotZ;
|
||||
|
||||
player_id_t m_Territory;
|
||||
|
||||
entity_id_t m_TurretParent;
|
||||
CFixedVector3D m_TurretPosition;
|
||||
std::set<entity_id_t> m_Turrets;
|
||||
|
||||
// not serialized:
|
||||
float m_InterpolatedRotX, m_InterpolatedRotY, m_InterpolatedRotZ;
|
||||
float m_LastInterpolatedRotX, m_LastInterpolatedRotZ; // not serialized
|
||||
@ -142,6 +148,8 @@ public:
|
||||
m_Territory = INVALID_PLAYER;
|
||||
|
||||
m_NeedInitialXZRotation = false;
|
||||
m_TurretParent = INVALID_ENTITY;
|
||||
m_TurretPosition = CFixedVector3D();
|
||||
}
|
||||
|
||||
virtual void Deinit()
|
||||
@ -223,6 +231,60 @@ public:
|
||||
UpdateXZRotation();
|
||||
}
|
||||
|
||||
virtual void UpdateTurretPosition()
|
||||
{
|
||||
if (m_TurretParent == INVALID_ENTITY)
|
||||
return;
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent);
|
||||
if (!cmpPosition)
|
||||
{
|
||||
LOGERROR(L"Turret with parent without position component");
|
||||
return;
|
||||
}
|
||||
if (!cmpPosition->IsInWorld())
|
||||
MoveOutOfWorld();
|
||||
else
|
||||
{
|
||||
CFixedVector2D rotatedPosition = CFixedVector2D(m_TurretPosition.X, m_TurretPosition.Z);
|
||||
rotatedPosition = rotatedPosition.Rotate(cmpPosition->GetRotation().Y);
|
||||
CFixedVector2D rootPosition = cmpPosition->GetPosition2D();
|
||||
entity_pos_t x = rootPosition.X + rotatedPosition.X;
|
||||
entity_pos_t z = rootPosition.Y + rotatedPosition.Y;
|
||||
if (!m_InWorld || m_X != x || m_Z != z)
|
||||
MoveTo(x, z);
|
||||
entity_pos_t y = cmpPosition->GetHeightOffset() + m_TurretPosition.Y;
|
||||
if (!m_InWorld || GetHeightOffset() != y)
|
||||
SetHeightOffset(y);
|
||||
m_InWorld = true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::set<entity_id_t>* GetTurrets()
|
||||
{
|
||||
return &m_Turrets;
|
||||
}
|
||||
|
||||
virtual void SetTurretParent(entity_id_t id, CFixedVector3D offset)
|
||||
{
|
||||
if (m_TurretParent != INVALID_ENTITY)
|
||||
{
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent);
|
||||
if (cmpPosition)
|
||||
cmpPosition->GetTurrets()->erase(GetEntityId());
|
||||
}
|
||||
|
||||
m_TurretParent = id;
|
||||
m_TurretPosition = offset;
|
||||
|
||||
if (m_TurretParent != INVALID_ENTITY)
|
||||
{
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent);
|
||||
if (cmpPosition)
|
||||
cmpPosition->GetTurrets()->insert(GetEntityId());
|
||||
}
|
||||
UpdateTurretPosition();
|
||||
}
|
||||
|
||||
virtual bool IsInWorld()
|
||||
{
|
||||
return m_InWorld;
|
||||
@ -255,7 +317,6 @@ public:
|
||||
{
|
||||
m_X = x;
|
||||
m_Z = z;
|
||||
m_RotY = ry;
|
||||
|
||||
if (!m_InWorld)
|
||||
{
|
||||
@ -265,7 +326,8 @@ public:
|
||||
m_LastYDifference = entity_pos_t::Zero();
|
||||
}
|
||||
|
||||
AdvertisePositionChanges();
|
||||
// TurnTo will advertise the position changes
|
||||
TurnTo(ry);
|
||||
}
|
||||
|
||||
virtual void JumpTo(entity_pos_t x, entity_pos_t z)
|
||||
@ -405,6 +467,12 @@ public:
|
||||
|
||||
virtual void TurnTo(entity_angle_t y)
|
||||
{
|
||||
if (m_TurretParent != INVALID_ENTITY)
|
||||
{
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent);
|
||||
if (cmpPosition)
|
||||
y -= cmpPosition->GetRotation().Y;
|
||||
}
|
||||
m_RotY = y;
|
||||
|
||||
AdvertisePositionChanges();
|
||||
@ -412,6 +480,12 @@ public:
|
||||
|
||||
virtual void SetYRotation(entity_angle_t y)
|
||||
{
|
||||
if (m_TurretParent != INVALID_ENTITY)
|
||||
{
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent);
|
||||
if (cmpPosition)
|
||||
y -= cmpPosition->GetRotation().Y;
|
||||
}
|
||||
m_RotY = y;
|
||||
m_InterpolatedRotY = m_RotY.ToFloat();
|
||||
|
||||
@ -444,6 +518,13 @@ public:
|
||||
|
||||
virtual CFixedVector3D GetRotation()
|
||||
{
|
||||
entity_angle_t y = m_RotY;
|
||||
if (m_TurretParent != INVALID_ENTITY)
|
||||
{
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent);
|
||||
if (cmpPosition)
|
||||
y += cmpPosition->GetRotation().Y;
|
||||
}
|
||||
return CFixedVector3D(m_RotX, m_RotY, m_RotZ);
|
||||
}
|
||||
|
||||
@ -474,6 +555,32 @@ public:
|
||||
|
||||
virtual CMatrix3D GetInterpolatedTransform(float frameOffset, bool forceFloating)
|
||||
{
|
||||
if (m_TurretParent != INVALID_ENTITY)
|
||||
{
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent);
|
||||
if (!cmpPosition)
|
||||
{
|
||||
LOGERROR(L"Turret with parent without position component");
|
||||
CMatrix3D m;
|
||||
m.SetIdentity();
|
||||
return m;
|
||||
}
|
||||
if (!cmpPosition->IsInWorld())
|
||||
{
|
||||
LOGERROR(L"CCmpPosition::GetInterpolatedTransform called on turret entity when IsInWorld is false");
|
||||
CMatrix3D m;
|
||||
m.SetIdentity();
|
||||
return m;
|
||||
}
|
||||
else
|
||||
{
|
||||
CMatrix3D parentTransformMatrix = cmpPosition->GetInterpolatedTransform(frameOffset, forceFloating);
|
||||
CMatrix3D ownTransformation = CMatrix3D();
|
||||
ownTransformation.SetYRotation(m_InterpolatedRotY);
|
||||
ownTransformation.Translate(-m_TurretPosition.X.ToFloat(), m_TurretPosition.Y.ToFloat(), -m_TurretPosition.Z.ToFloat());
|
||||
return parentTransformMatrix * ownTransformation;
|
||||
}
|
||||
}
|
||||
if (!m_InWorld)
|
||||
{
|
||||
LOGERROR(L"CCmpPosition::GetInterpolatedTransform called on entity when IsInWorld is false");
|
||||
@ -562,6 +669,7 @@ public:
|
||||
}
|
||||
case MT_TurnStart:
|
||||
{
|
||||
|
||||
m_LastInterpolatedRotX = m_InterpolatedRotX;
|
||||
m_LastInterpolatedRotZ = m_InterpolatedRotZ;
|
||||
|
||||
@ -606,6 +714,12 @@ public:
|
||||
private:
|
||||
void AdvertisePositionChanges()
|
||||
{
|
||||
for (std::set<entity_id_t>::const_iterator it = m_Turrets.begin(); it != m_Turrets.end(); ++it)
|
||||
{
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), *it);
|
||||
if (cmpPosition)
|
||||
cmpPosition->UpdateTurretPosition();
|
||||
}
|
||||
if (m_InWorld)
|
||||
{
|
||||
CMessagePositionChanged msg(GetEntityId(), true, m_X, m_Z, m_RotY);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "simulation2/system/InterfaceScripted.h"
|
||||
|
||||
BEGIN_INTERFACE_WRAPPER(Position)
|
||||
DEFINE_INTERFACE_METHOD_2("SetTurretParent", void, ICmpPosition, SetTurretParent, entity_id_t, CFixedVector3D)
|
||||
DEFINE_INTERFACE_METHOD_0("IsInWorld", bool, ICmpPosition, IsInWorld)
|
||||
DEFINE_INTERFACE_METHOD_0("MoveOutOfWorld", void, ICmpPosition, MoveOutOfWorld)
|
||||
DEFINE_INTERFACE_METHOD_2("MoveTo", void, ICmpPosition, MoveTo, entity_pos_t, entity_pos_t)
|
||||
|
@ -58,6 +58,21 @@ class CMatrix3D;
|
||||
class ICmpPosition : public IComponent
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Set this as a turret of an other entity
|
||||
*/
|
||||
virtual void SetTurretParent(entity_id_t parent, CFixedVector3D offset) = 0;
|
||||
|
||||
/**
|
||||
* Has to be called to update the simulation position of the turret
|
||||
*/
|
||||
virtual void UpdateTurretPosition() = 0;
|
||||
|
||||
/**
|
||||
* Get the list of turrets to read or edit
|
||||
*/
|
||||
virtual std::set<entity_id_t>* GetTurrets() = 0;
|
||||
|
||||
/**
|
||||
* Returns true if the entity currently exists at a defined position in the world.
|
||||
*/
|
||||
|
@ -40,6 +40,9 @@ class MockPosition : public ICmpPosition
|
||||
public:
|
||||
DEFAULT_MOCK_COMPONENT()
|
||||
|
||||
virtual void SetTurretParent(entity_id_t UNUSED(id), CFixedVector3D UNUSED(pos)) {}
|
||||
virtual void UpdateTurretPosition() {}
|
||||
virtual std::set<entity_id_t>* GetTurrets() { return NULL; }
|
||||
virtual bool IsInWorld() { return true; }
|
||||
virtual void MoveOutOfWorld() { }
|
||||
virtual void MoveTo(entity_pos_t UNUSED(x), entity_pos_t UNUSED(z)) { }
|
||||
|
Loading…
Reference in New Issue
Block a user