Adds animation and sound support to wall gates. Uses temporary sounds for now. Adds new animation choices to actor viewer/editor. Refs #619
This was SVN commit r12103.
This commit is contained in:
parent
fd22b91138
commit
1d677156fd
@ -1,12 +1,16 @@
|
|||||||
function Gate() {}
|
function Gate() {}
|
||||||
|
|
||||||
Gate.prototype.Schema =
|
Gate.prototype.Schema =
|
||||||
"<element name='PassRange'>" +
|
"<a:help>Controls behavior of wall gates</a:help>" +
|
||||||
|
"<a:example>" +
|
||||||
|
"<PassRange>20</PassRange>" +
|
||||||
|
"</a:example>" +
|
||||||
|
"<element name='PassRange' a:help='Units must be within this distance (in meters) of the gate for it to open'>" +
|
||||||
"<ref name='nonNegativeDecimal'/>" +
|
"<ref name='nonNegativeDecimal'/>" +
|
||||||
"</element>";
|
"</element>";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize Gate Component
|
* Initialize Gate component
|
||||||
*/
|
*/
|
||||||
Gate.prototype.Init = function()
|
Gate.prototype.Init = function()
|
||||||
{
|
{
|
||||||
@ -20,8 +24,9 @@ Gate.prototype.OnOwnershipChanged = function(msg)
|
|||||||
if (msg.to != -1)
|
if (msg.to != -1)
|
||||||
{
|
{
|
||||||
this.SetupRangeQuery(msg.to);
|
this.SetupRangeQuery(msg.to);
|
||||||
|
// Set the initial state, but don't play unlocking sound
|
||||||
if (!this.locked)
|
if (!this.locked)
|
||||||
this.UnlockGate();
|
this.UnlockGate(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -37,7 +42,7 @@ Gate.prototype.OnDestroy = function()
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup the Range Query to detect units coming in & out of range
|
* Setup the range query to detect units coming in & out of range
|
||||||
*/
|
*/
|
||||||
Gate.prototype.SetupRangeQuery = function(owner)
|
Gate.prototype.SetupRangeQuery = function(owner)
|
||||||
{
|
{
|
||||||
@ -46,19 +51,18 @@ Gate.prototype.SetupRangeQuery = function(owner)
|
|||||||
if (this.unitsQuery)
|
if (this.unitsQuery)
|
||||||
cmpRangeManager.DestroyActiveQuery(this.unitsQuery);
|
cmpRangeManager.DestroyActiveQuery(this.unitsQuery);
|
||||||
var players = []
|
var players = []
|
||||||
|
|
||||||
var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(owner), IID_Player);
|
|
||||||
var numPlayers = cmpPlayerManager.GetNumPlayers();
|
var numPlayers = cmpPlayerManager.GetNumPlayers();
|
||||||
|
|
||||||
|
// Ignore gaia units
|
||||||
for (var i = 1; i < numPlayers; ++i)
|
for (var i = 1; i < numPlayers; ++i)
|
||||||
{
|
|
||||||
players.push(i);
|
players.push(i);
|
||||||
}
|
|
||||||
|
var range = this.GetPassRange();
|
||||||
if (this.GetPassRange() > 0)
|
if (range > 0)
|
||||||
{
|
{
|
||||||
var range = this.GetPassRange();
|
// Only find entities with IID_UnitAI interface
|
||||||
this.unitsQuery = cmpRangeManager.CreateActiveQuery(this.entity, 0, range, players, 0, cmpRangeManager.GetEntityFlagMask("normal"));
|
this.unitsQuery = cmpRangeManager.CreateActiveQuery(this.entity, 0, range, players, IID_UnitAI, cmpRangeManager.GetEntityFlagMask("normal"));
|
||||||
cmpRangeManager.EnableActiveQuery(this.unitsQuery);
|
cmpRangeManager.EnableActiveQuery(this.unitsQuery);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -72,25 +76,12 @@ Gate.prototype.OnRangeUpdate = function(msg)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (msg.added.length > 0)
|
if (msg.added.length > 0)
|
||||||
{
|
|
||||||
for each (var entity in msg.added)
|
for each (var entity in msg.added)
|
||||||
{
|
this.units.push(entity);
|
||||||
var cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
|
|
||||||
if(cmpIdentity)
|
|
||||||
{
|
|
||||||
var classes = cmpIdentity.GetClassesList();
|
|
||||||
if(classes.indexOf("Unit") != -1)
|
|
||||||
this.units.push(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (msg.removed.length > 0)
|
if (msg.removed.length > 0)
|
||||||
{
|
|
||||||
for each (var entity in msg.removed)
|
for each (var entity in msg.removed)
|
||||||
{
|
|
||||||
this.units.splice(this.units.indexOf(entity), 1);
|
this.units.splice(this.units.indexOf(entity), 1);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.OperateGate();
|
this.OperateGate();
|
||||||
};
|
};
|
||||||
@ -104,7 +95,9 @@ Gate.prototype.GetPassRange = function()
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open or close the gate
|
* Attempt to open or close the gate.
|
||||||
|
* An ally unit must be in range to open the gate, but there must be
|
||||||
|
* no units (including enemies) in range to close it again.
|
||||||
*/
|
*/
|
||||||
Gate.prototype.OperateGate = function()
|
Gate.prototype.OperateGate = function()
|
||||||
{
|
{
|
||||||
@ -112,9 +105,7 @@ Gate.prototype.OperateGate = function()
|
|||||||
{
|
{
|
||||||
// If no units are in range, close the gate
|
// If no units are in range, close the gate
|
||||||
if (this.units.length == 0)
|
if (this.units.length == 0)
|
||||||
{
|
|
||||||
this.CloseGate();
|
this.CloseGate();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -135,6 +126,9 @@ Gate.prototype.IsLocked = function()
|
|||||||
return this.locked;
|
return this.locked;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock the gate, with sound. It will close at the next opportunity.
|
||||||
|
*/
|
||||||
Gate.prototype.LockGate = function()
|
Gate.prototype.LockGate = function()
|
||||||
{
|
{
|
||||||
this.locked = true;
|
this.locked = true;
|
||||||
@ -147,9 +141,16 @@ Gate.prototype.LockGate = function()
|
|||||||
return;
|
return;
|
||||||
cmpObstruction.SetDisableBlockMovementPathfinding(false, false, 0);
|
cmpObstruction.SetDisableBlockMovementPathfinding(false, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Possibly move the lock/unlock sounds to UI? Needs testing
|
||||||
|
PlaySound("gate_locked", this.entity);
|
||||||
};
|
};
|
||||||
|
|
||||||
Gate.prototype.UnlockGate = function()
|
/**
|
||||||
|
* Unlock the gate, with sound. May open the gate if allied units are within range.
|
||||||
|
* If quiet is true, no sound will be played (used for initial setup).
|
||||||
|
*/
|
||||||
|
Gate.prototype.UnlockGate = function(quiet)
|
||||||
{
|
{
|
||||||
var cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
|
var cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
|
||||||
if (!cmpObstruction)
|
if (!cmpObstruction)
|
||||||
@ -159,11 +160,18 @@ Gate.prototype.UnlockGate = function()
|
|||||||
cmpObstruction.SetDisableBlockMovementPathfinding(false, true, 0);
|
cmpObstruction.SetDisableBlockMovementPathfinding(false, true, 0);
|
||||||
this.locked = false;
|
this.locked = false;
|
||||||
|
|
||||||
|
// TODO: Possibly move the lock/unlock sounds to UI? Needs testing
|
||||||
|
if (!quiet)
|
||||||
|
PlaySound("gate_unlocked", this.entity);
|
||||||
|
|
||||||
// If the gate is closed, open it if necessary
|
// If the gate is closed, open it if necessary
|
||||||
if (!this.opened)
|
if (!this.opened)
|
||||||
this.OperateGate();
|
this.OperateGate();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the gate if unlocked, with sound and animation.
|
||||||
|
*/
|
||||||
Gate.prototype.OpenGate = function()
|
Gate.prototype.OpenGate = function()
|
||||||
{
|
{
|
||||||
// Do not open the gate if it has been locked
|
// Do not open the gate if it has been locked
|
||||||
@ -177,8 +185,16 @@ Gate.prototype.OpenGate = function()
|
|||||||
// Disable 'block movement'
|
// Disable 'block movement'
|
||||||
cmpObstruction.SetDisableBlockMovementPathfinding(true, true, 0);
|
cmpObstruction.SetDisableBlockMovementPathfinding(true, true, 0);
|
||||||
this.opened = true;
|
this.opened = true;
|
||||||
|
|
||||||
|
PlaySound("gate_opening", this.entity);
|
||||||
|
var cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
|
||||||
|
if (cmpVisual)
|
||||||
|
cmpVisual.SelectAnimation("gate_opening", true, 1.0, "");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the gate, with sound and animation.
|
||||||
|
*/
|
||||||
Gate.prototype.CloseGate = function()
|
Gate.prototype.CloseGate = function()
|
||||||
{
|
{
|
||||||
var cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
|
var cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
|
||||||
@ -192,6 +208,11 @@ Gate.prototype.CloseGate = function()
|
|||||||
else
|
else
|
||||||
cmpObstruction.SetDisableBlockMovementPathfinding(false, true, 0);
|
cmpObstruction.SetDisableBlockMovementPathfinding(false, true, 0);
|
||||||
this.opened = false;
|
this.opened = false;
|
||||||
|
|
||||||
|
PlaySound("gate_closing", this.entity);
|
||||||
|
var cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
|
||||||
|
if (cmpVisual)
|
||||||
|
cmpVisual.SelectAnimation("gate_closing", true, 1.0, "");
|
||||||
};
|
};
|
||||||
|
|
||||||
Engine.RegisterComponentType(IID_Gate, "Gate", Gate);
|
Engine.RegisterComponentType(IID_Gate, "Gate", Gate);
|
||||||
|
@ -5,9 +5,6 @@
|
|||||||
<Pierce>40.0</Pierce>
|
<Pierce>40.0</Pierce>
|
||||||
<Crush>10.0</Crush>
|
<Crush>10.0</Crush>
|
||||||
</Armour>
|
</Armour>
|
||||||
<Gate>
|
|
||||||
<PassRange>20</PassRange>
|
|
||||||
</Gate>
|
|
||||||
<BuildRestrictions>
|
<BuildRestrictions>
|
||||||
<Category>Wall</Category>
|
<Category>Wall</Category>
|
||||||
</BuildRestrictions>
|
</BuildRestrictions>
|
||||||
@ -21,6 +18,9 @@
|
|||||||
<Square width="6.0" depth="6.0"/>
|
<Square width="6.0" depth="6.0"/>
|
||||||
<Height>8.0</Height>
|
<Height>8.0</Height>
|
||||||
</Footprint>
|
</Footprint>
|
||||||
|
<Gate>
|
||||||
|
<PassRange>20</PassRange>
|
||||||
|
</Gate>
|
||||||
<Health>
|
<Health>
|
||||||
<Max>3000</Max>
|
<Max>3000</Max>
|
||||||
</Health>
|
</Health>
|
||||||
@ -29,7 +29,7 @@
|
|||||||
<Tooltip>Allow units access through a city wall. (Currently not a working feature).</Tooltip>
|
<Tooltip>Allow units access through a city wall. (Currently not a working feature).</Tooltip>
|
||||||
<Classes datatype="tokens">-ConquestCritical Defensive Wall Gates</Classes>
|
<Classes datatype="tokens">-ConquestCritical Defensive Wall Gates</Classes>
|
||||||
<Icon>structures/gate.png</Icon>
|
<Icon>structures/gate.png</Icon>
|
||||||
<RequiredTechnology>phase_town</RequiredTechnology>
|
<RequiredTechnology>phase_town</RequiredTechnology>
|
||||||
</Identity>
|
</Identity>
|
||||||
<Loot>
|
<Loot>
|
||||||
<xp>100</xp>
|
<xp>100</xp>
|
||||||
@ -51,6 +51,10 @@
|
|||||||
<select>interface/select/building/sel_gate.xml</select>
|
<select>interface/select/building/sel_gate.xml</select>
|
||||||
<constructed>interface/complete/building/complete_gate.xml</constructed>
|
<constructed>interface/complete/building/complete_gate.xml</constructed>
|
||||||
<death>attack/destruction/building_collapse_large.xml</death>
|
<death>attack/destruction/building_collapse_large.xml</death>
|
||||||
|
<gate_closing>interface/select/building/sel_gate.xml</gate_closing>
|
||||||
|
<gate_opening>interface/select/building/sel_gate.xml</gate_opening>
|
||||||
|
<gate_locked>interface/select/building/sel_gate.xml</gate_locked>
|
||||||
|
<gate_unlocked>interface/select/building/sel_gate.xml</gate_unlocked>
|
||||||
</SoundGroups>
|
</SoundGroups>
|
||||||
</Sound>
|
</Sound>
|
||||||
<TerritoryInfluence>
|
<TerritoryInfluence>
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
<item>melee </item>
|
<item>melee </item>
|
||||||
<item>death </item>
|
<item>death </item>
|
||||||
<item>build </item>
|
<item>build </item>
|
||||||
|
<item>heal </item>
|
||||||
<item>promotion </item>
|
<item>promotion </item>
|
||||||
<item>gather_fruit </item>
|
<item>gather_fruit </item>
|
||||||
<item>gather_grain </item>
|
<item>gather_grain </item>
|
||||||
@ -42,18 +43,10 @@
|
|||||||
<item>gather_treasure </item>
|
<item>gather_treasure </item>
|
||||||
<item>feeding </item>
|
<item>feeding </item>
|
||||||
<item>garrisoned </item>
|
<item>garrisoned </item>
|
||||||
|
<item>gate_closed </item>
|
||||||
|
<item>gate_closing </item>
|
||||||
|
<item>gate_open </item>
|
||||||
|
<item>gate_opening </item>
|
||||||
</animations>
|
</animations>
|
||||||
|
|
||||||
<playercolours>
|
|
||||||
<colour name="Gaia" rgb="255 255 255"/>
|
|
||||||
<colour name="Player 1" rgb="80 80 200" buttontext="255 255 255"/>
|
|
||||||
<colour name="Player 2" rgb="150 20 20" buttontext="255 255 255"/>
|
|
||||||
<colour name="Player 3" rgb="50 165 5" buttontext="255 255 255"/>
|
|
||||||
<colour name="Player 4" rgb="230 230 75" buttontext="255 255 255"/>
|
|
||||||
<colour name="Player 5" rgb="50 170 170" buttontext="255 255 255"/>
|
|
||||||
<colour name="Player 6" rgb="160 80 200" buttontext="255 255 255"/>
|
|
||||||
<colour name="Player 7" rgb="230 120 20" buttontext="255 255 255"/>
|
|
||||||
<colour name="Player 8" rgb="64 64 64" buttontext="255 255 255"/>
|
|
||||||
</playercolours>
|
|
||||||
|
|
||||||
</lists>
|
</lists>
|
||||||
|
Loading…
Reference in New Issue
Block a user