1
0
forked from 0ad/0ad

Extend animal AI to all animals.

This was SVN commit r7771.
This commit is contained in:
Ykkrosh 2010-07-20 08:45:09 +00:00
parent c4350d86de
commit bd2fd6c713
21 changed files with 115 additions and 83 deletions

View File

@ -4,40 +4,45 @@
<castshadow/>
<group>
<variant frequency="1" name="male">
<variant frequency="100" name="base">
<animations>
<animation file="quadraped/deer_idle_01.dae" name="idle" speed="20"/>
<animation file="quadraped/deer_idle_02.dae" name="idle" speed="20"/>
<animation file="quadraped/deer_idle_03.dae" name="idle" speed="20"/>
<animation file="quadraped/deer_idle_04.dae" name="idle" speed="20"/>
<animation file="quadraped/deer_death_01.dae" name="death" speed="40"/>
<animation file="quadraped/deer_walk_01.dae" name="walk" speed="20"/>
<animation file="quadraped/deer_walk_02.dae" name="walk" speed="20"/>
<animation file="quadraped/deer_run_01.dae" name="run" speed="15"/>
<animation file="quadraped/deer_walk_01.dae" name="walk" speed="40"/>
<animation file="quadraped/deer_run_01.dae" name="run" speed="20"/>
<animation file="quadraped/deer_attack_01.dae" name="melee" speed="20"/>
</animations>
<mesh>skeletal/deer_mesh.dae</mesh>
<props>
<prop actor="props/fauna/deer_antlers.xml" attachpoint="antler"/>
</props>
<texture>skeletal/animal_deer.dds</texture>
</variant>
<variant frequency="5" name="female">
<animations>
<animation file="quadraped/deer_idle_01.dae" name="idle" speed="5"/>
<animation file="quadraped/deer_idle_02.dae" name="idle" speed="5"/>
<animation file="quadraped/deer_idle_03.dae" name="idle" speed="5"/>
<animation file="quadraped/deer_idle_04.dae" name="idle" speed="5"/>
<animation file="quadraped/deer_death_02.dae" name="death" speed="40"/>
<animation file="quadraped/deer_walk_01.dae" name="walk" speed="20"/>
<animation file="quadraped/deer_walk_02.dae" name="walk" speed="20"/>
<animation file="quadraped/deer_run_01.dae" name="run" speed="15"/>
<animation file="quadraped/deer_attack_01.dae" name="melee" speed="20"/>
<animation name=""/>
</animations>
<mesh>skeletal/deer_mesh.dae</mesh>
<texture>skeletal/animal_deer.dds</texture>
</variant>
</group>
<group>
<variant frequency="1" name="male">
<animations>
<animation file="quadraped/deer_death_01.dae" name="death" speed="40"/>
</animations>
<props>
<prop actor="props/fauna/deer_antlers.xml" attachpoint="antler"/>
</props>
</variant>
<variant frequency="5" name="female">
<animations>
<animation file="quadraped/deer_death_02.dae" name="death" speed="40"/>
</animations>
</variant>
</group>
<group>
<variant frequency="100" name="normal">
</variant>
<variant frequency="0" name="feeding">
<animations>
<animation file="quadraped/deer_idle_04.dae" name="idle" speed="20"/>
<animation file="quadraped/deer_walk_02.dae" name="walk" speed="20"/>
</animations>
</variant>
</group>
</actor>

View File

@ -10,6 +10,12 @@ AnimalAI.prototype.Schema =
"<value a:help='Will never attack units'>passive</value>" +
"<value a:help='Will never attack units. Will typically attempt to flee for short distances when units approach'>skittish</value>" +
"</choice>" +
"</element>" +
"<element name='RoamDistance'>" +
"<ref name='positiveDecimal'/>" +
"</element>" +
"<element name='FleeDistance'>" +
"<ref name='positiveDecimal'/>" +
"</element>";
var AnimalFsmSpec = {
@ -18,7 +24,7 @@ var AnimalFsmSpec = {
"ResourceGather": function(msg) {
// If someone's carving chunks of meat off us, then run away
this.MoveAwayFrom(msg.gatherer, 12);
this.MoveAwayFrom(msg.gatherer, +this.template.FleeDistance);
this.SetNextState("FLEEING");
this.PlaySound("panic");
},
@ -26,8 +32,8 @@ var AnimalFsmSpec = {
"ROAMING": {
"enter": function() {
// Walk in a random direction
this.SelectAnimation("walk", false);
this.MoveRandomly();
this.SelectAnimation("walk", false, this.GetWalkSpeed());
this.MoveRandomly(+this.template.RoamDistance);
// Set a random timer to switch to feeding state
this.StartTimer(RandomInt(2000, 8000));
},
@ -41,14 +47,14 @@ var AnimalFsmSpec = {
},
"MoveStopped": function() {
this.MoveRandomly();
this.MoveRandomly(+this.template.RoamDistance);
},
},
"FEEDING": {
"enter": function() {
// Stop and eat for a while
this.SelectAnimation("idle");
this.SelectAnimation("feeding");
this.StopMoving();
this.StartTimer(RandomInt(1000, 4000));
},
@ -67,13 +73,14 @@ var AnimalFsmSpec = {
"FLEEING": {
"enter": function() {
// Run quickly
this.SelectAnimation("run", false);
this.SetMoveSpeedFactor(6.0);
var speed = this.GetRunSpeed();
this.SelectAnimation("run", false, speed);
this.SetMoveSpeed(speed);
},
"leave": function() {
// Reset normal speed
this.SetMoveSpeedFactor(1.0);
this.SetMoveSpeed(this.GetWalkSpeed());
},
"MoveStopped": function() {
@ -95,7 +102,7 @@ AnimalAI.prototype.Init = function()
AnimalAI.prototype.OnCreate = function()
{
AnimalFsm.Init(this, "SKITTISH.ROAMING");
AnimalFsm.Init(this, "SKITTISH.FEEDING");
};
AnimalAI.prototype.SetNextState = function(state)
@ -139,6 +146,18 @@ AnimalAI.prototype.TimerHandler = function(data, lateness)
// Functions to be called by the FSM:
AnimalAI.prototype.GetWalkSpeed = function()
{
var cmpMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return cmpMotion.GetWalkSpeed();
};
AnimalAI.prototype.GetRunSpeed = function()
{
var cmpMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return cmpMotion.GetRunSpeed();
};
AnimalAI.prototype.PlaySound = function(name)
{
PlaySound(name, this.entity);
@ -169,7 +188,7 @@ AnimalAI.prototype.SelectAnimation = function(name, once, speed, sound)
cmpVisual.SelectAnimation(name, once, speed, soundgroup);
};
AnimalAI.prototype.MoveRandomly = function()
AnimalAI.prototype.MoveRandomly = function(distance)
{
// We want to walk in a random direction, but avoid getting stuck
// in obstacles or narrow spaces.
@ -189,7 +208,6 @@ AnimalAI.prototype.MoveRandomly = function()
var pos = cmpPosition.GetPosition();
var distance = 4;
var jitter = 0.5;
// Randomly adjust the range's center a bit, so we tend to prefer
@ -213,10 +231,10 @@ AnimalAI.prototype.StopMoving = function()
cmpMotion.StopMoving();
};
AnimalAI.prototype.SetMoveSpeedFactor = function(factor)
AnimalAI.prototype.SetMoveSpeed = function(speed)
{
var cmpMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
cmpMotion.SetSpeedFactor(factor);
cmpMotion.SetSpeed(speed);
};
AnimalAI.prototype.StartTimer = function(interval, data)

View File

@ -37,15 +37,7 @@ function UnitAI() {}
UnitAI.prototype.Schema =
"<a:help>Controls the unit's movement, attacks, etc, in response to commands from the player.</a:help>" +
"<a:example/>" +
"<element name='NaturalBehaviour' a:help='Behaviour of the unit in the absence of player commands (intended for animals)'>" + // TODO: implement this
"<choice>" +
"<value a:help='Will actively attack any unit it encounters, even if not threatened'>violent</value>" +
"<value a:help='Will attack nearby units if it feels threatened (if they linger within LOS for too long)'>aggressive</value>" +
"<value a:help='Will attack nearby units if attacked'>defensive</value>" +
"<value a:help='Will never attack units'>passive</value>" +
"<value a:help='Will never attack units. Will typically attempt to flee for short distances when units approach'>skittish</value>" +
"</choice>" +
"</element>";
"<empty/>";
UnitAI.prototype.Init = function()
{

View File

@ -16,12 +16,14 @@
<Height>1.5</Height>
</Footprint>
<AnimalAI>
<NaturalBehaviour>skittish</NaturalBehaviour>
<RoamDistance>4.0</RoamDistance>
<FleeDistance>12.0</FleeDistance>
</AnimalAI>
<UnitMotion>
<WalkSpeed>1</WalkSpeed>
<PassabilityClass>default</PassabilityClass>
<CostClass>default</CostClass>
<WalkSpeed>1.0</WalkSpeed>
<Run>
<Speed>6.0</Speed>
</Run>
</UnitMotion>
<Sound>
<SoundGroups>

View File

@ -5,9 +5,9 @@
<SpecificName>Deer</SpecificName>
</Identity>
<UnitMotion>
<WalkSpeed>5.0</WalkSpeed>
<WalkSpeed>2.0</WalkSpeed>
<Run>
<Speed>12.0</Speed>
<Speed>10.0</Speed>
<Range>600.0</Range>
<RangeMin>5.0</RangeMin>
</Run>
@ -15,4 +15,8 @@
<VisualActor>
<Actor>fauna/deer.xml</Actor>
</VisualActor>
<AnimalAI>
<RoamDistance>8.0</RoamDistance>
<FleeDistance>32.0</FleeDistance>
</AnimalAI>
</Entity>

View File

@ -7,9 +7,7 @@
<Minimap>
<Type>unit</Type>
</Minimap>
<UnitAI>
<NaturalBehaviour>passive</NaturalBehaviour>
</UnitAI>
<UnitAI/>
<Cost>
<Population>1</Population>
<Resources>

View File

@ -16,4 +16,15 @@
<Circle radius="1.0"/>
<Height>2.5</Height>
</Footprint>
<UnitMotion>
<WalkSpeed>2.0</WalkSpeed>
<Run>
<Speed>6.0</Speed>
</Run>
</UnitMotion>
<UnitAI disable=""/>
<AnimalAI>
<RoamDistance>4.0</RoamDistance>
<FleeDistance>12.0</FleeDistance>
</AnimalAI>
</Entity>

View File

@ -2,7 +2,7 @@
<Entity parent="template_unit_fauna_breed">
<Identity>
</Identity>
<UnitAI>
<AnimalAI>
<NaturalBehaviour>passive</NaturalBehaviour>
</UnitAI>
</AnimalAI>
</Entity>

View File

@ -2,7 +2,7 @@
<Entity parent="template_unit_fauna_herd">
<Identity>
</Identity>
<UnitAI>
<AnimalAI>
<NaturalBehaviour>passive</NaturalBehaviour>
</UnitAI>
</AnimalAI>
</Entity>

View File

@ -2,7 +2,7 @@
<Entity parent="template_unit_fauna_hunt">
<Identity>
</Identity>
<UnitAI>
<AnimalAI>
<NaturalBehaviour>aggressive</NaturalBehaviour>
</UnitAI>
</AnimalAI>
</Entity>

View File

@ -2,7 +2,7 @@
<Entity parent="template_unit_fauna_hunt">
<Identity>
</Identity>
<UnitAI>
<AnimalAI>
<NaturalBehaviour>defensive</NaturalBehaviour>
</UnitAI>
</AnimalAI>
</Entity>

View File

@ -2,7 +2,7 @@
<Entity parent="template_unit_fauna_hunt">
<Identity>
</Identity>
<UnitAI>
<AnimalAI>
<NaturalBehaviour>passive</NaturalBehaviour>
</UnitAI>
</AnimalAI>
</Entity>

View File

@ -2,7 +2,7 @@
<Entity parent="template_unit_fauna_hunt">
<Identity>
</Identity>
<UnitAI>
<AnimalAI>
<NaturalBehaviour>skittish</NaturalBehaviour>
</UnitAI>
</AnimalAI>
</Entity>

View File

@ -2,7 +2,7 @@
<Entity parent="template_unit_fauna_hunt">
<Identity>
</Identity>
<UnitAI>
<AnimalAI>
<NaturalBehaviour>violent</NaturalBehaviour>
</UnitAI>
</AnimalAI>
</Entity>

View File

@ -2,7 +2,7 @@
<Entity parent="template_unit_fauna_wild">
<Identity>
</Identity>
<UnitAI>
<AnimalAI>
<NaturalBehaviour>violent</NaturalBehaviour>
</UnitAI>
</AnimalAI>
</Entity>

View File

@ -2,7 +2,7 @@
<Entity parent="template_unit_fauna_wild">
<Identity>
</Identity>
<UnitAI>
<AnimalAI>
<NaturalBehaviour>defensive</NaturalBehaviour>
</UnitAI>
</AnimalAI>
</Entity>

View File

@ -2,7 +2,7 @@
<Entity parent="template_unit_fauna_wild">
<Identity>
</Identity>
<UnitAI>
<AnimalAI>
<NaturalBehaviour>passive</NaturalBehaviour>
</UnitAI>
</AnimalAI>
</Entity>

View File

@ -2,7 +2,7 @@
<Entity parent="template_unit_fauna_wild">
<Identity>
</Identity>
<UnitAI>
<AnimalAI>
<NaturalBehaviour>violent</NaturalBehaviour>
</UnitAI>
</AnimalAI>
</Entity>

View File

@ -214,9 +214,9 @@ public:
return m_RunSpeed;
}
virtual void SetSpeedFactor(fixed factor)
virtual void SetSpeed(fixed speed)
{
m_Speed = m_WalkSpeed.Multiply(factor);
m_Speed = speed;
}
virtual void SetDebugOverlay(bool enabled)

View File

@ -27,6 +27,8 @@ DEFINE_INTERFACE_METHOD_3("IsInAttackRange", bool, ICmpUnitMotion, IsInAttackRan
DEFINE_INTERFACE_METHOD_3("MoveToAttackRange", bool, ICmpUnitMotion, MoveToAttackRange, entity_id_t, entity_pos_t, entity_pos_t)
DEFINE_INTERFACE_METHOD_4("MoveToPointRange", bool, ICmpUnitMotion, MoveToPointRange, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t)
DEFINE_INTERFACE_METHOD_0("StopMoving", void, ICmpUnitMotion, StopMoving)
DEFINE_INTERFACE_METHOD_1("SetSpeedFactor", void, ICmpUnitMotion, SetSpeedFactor, fixed)
DEFINE_INTERFACE_METHOD_1("SetSpeed", void, ICmpUnitMotion, SetSpeed, fixed)
DEFINE_INTERFACE_METHOD_0("GetWalkSpeed", fixed, ICmpUnitMotion, GetWalkSpeed)
DEFINE_INTERFACE_METHOD_0("GetRunSpeed", fixed, ICmpUnitMotion, GetRunSpeed)
DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpUnitMotion, SetDebugOverlay, bool)
END_INTERFACE_WRAPPER(UnitMotion)

View File

@ -71,9 +71,9 @@ public:
virtual void StopMoving() = 0;
/**
* Set the current movement speed to be the default multiplied by the given factor.
* Set the current movement speed.
*/
virtual void SetSpeedFactor(fixed factor) = 0;
virtual void SetSpeed(fixed speed) = 0;
/**
* Get the default speed that this unit will have when walking, in metres per second.