diff --git a/binaries/data/mods/public/simulation/components/AnimalAI.js b/binaries/data/mods/public/simulation/components/AnimalAI.js deleted file mode 100644 index ed4fae0eff..0000000000 --- a/binaries/data/mods/public/simulation/components/AnimalAI.js +++ /dev/null @@ -1,387 +0,0 @@ -function AnimalAI() {} - -AnimalAI.prototype.Schema = - "" + - "" + - "" + - "violent" + - "aggressive" + - "defensive" + - "passive" + - "skittish" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - ""; - -var AnimalFsmSpec = { - - "MoveCompleted": function() { - // ignore spurious movement messages - // (these can happen when stopping moving at the same time - // as switching states) - }, - - "MoveStarted": function() { - // ignore spurious movement messages - }, - - "HealthChanged": function(msg) { - // If we died (got reduced to 0 hitpoints), stop the AI and act like a corpse - if (msg.to == 0) - this.SetNextState("CORPSE"); - }, - - "CORPSE": { - "enter": function() { - this.StopMoving(); - }, - - "Attacked": function(msg) { - // Do nothing, because we're dead already - }, - - "LeaveFoundation": function(msg) { - // We can't walk away from the foundation (since we're dead), - // but we mustn't block its construction (since the builders would get stuck), - // and we don't want to trick gatherers into trying to reach us when - // we're stuck in the middle of a building, so just delete our corpse. - Engine.DestroyEntity(this.entity); - }, - }, - - "SKITTISH": { - - "Attacked": function(msg) { - // If someone's attacking us, then run away - this.MoveAwayFrom(msg.data.attacker, +this.template.FleeDistance); - this.SetNextState("FLEEING"); - this.PlaySound("panic"); - }, - - "LeaveFoundation": function(msg) { - // Run away from the foundation - this.MoveAwayFrom(msg.target, +this.template.FleeDistance); - this.SetNextState("FLEEING"); - this.PlaySound("panic"); - }, - - "ROAMING": { - "enter": function() { - // Walk in a random direction - this.SelectAnimation("walk", false, this.GetWalkSpeed()); - this.MoveRandomly(+this.template.RoamDistance); - // Set a random timer to switch to feeding state - this.StartTimer(RandomInt(+this.template.RoamTimeMin, +this.template.RoamTimeMax)); - }, - - "leave": function() { - this.StopTimer(); - }, - - "Timer": function(msg) { - this.SetNextState("FEEDING"); - }, - - "MoveCompleted": function() { - this.MoveRandomly(+this.template.RoamDistance); - }, - }, - - "FEEDING": { - "enter": function() { - // Stop and eat for a while - this.SelectAnimation("feeding"); - this.StopMoving(); - this.StartTimer(RandomInt(+this.template.FeedTimeMin, +this.template.FeedTimeMax)); - }, - - "leave": function() { - this.StopTimer(); - }, - - "MoveCompleted": function() { }, - - "Timer": function(msg) { - this.SetNextState("ROAMING"); - }, - }, - - "FLEEING": { - "enter": function() { - // Run quickly - var speed = this.GetRunSpeed(); - this.SelectAnimation("run", false, speed); - this.SetMoveSpeed(speed); - }, - - "leave": function() { - // Reset normal speed - this.SetMoveSpeed(this.GetWalkSpeed()); - }, - - "MoveCompleted": function() { - // When we've run far enough, go back to the roaming state - this.SetNextState("ROAMING"); - }, - }, - }, - - "PASSIVE": { - - "Attacked": function(msg) { - // Do nothing, just let them kill us - }, - - "LeaveFoundation": function(msg) { - // Walk away from the foundation - this.MoveAwayFrom(msg.target, 4); - this.SetNextState("FLEEING"); - }, - - "ROAMING": { - "enter": function() { - // Walk in a random direction - this.SelectAnimation("walk", false, this.GetWalkSpeed()); - this.MoveRandomly(+this.template.RoamDistance); - // Set a random timer to switch to feeding state - this.StartTimer(RandomInt(+this.template.RoamTimeMin, +this.template.RoamTimeMax)); - }, - - "leave": function() { - this.StopTimer(); - }, - - "Timer": function(msg) { - this.SetNextState("FEEDING"); - }, - - "MoveCompleted": function() { - this.MoveRandomly(+this.template.RoamDistance); - }, - }, - - "FEEDING": { - "enter": function() { - // Stop and eat for a while - this.SelectAnimation("feeding"); - this.StopMoving(); - this.StartTimer(RandomInt(+this.template.FeedTimeMin, +this.template.FeedTimeMax)); - }, - - "leave": function() { - this.StopTimer(); - }, - - "MoveCompleted": function() { }, - - "Timer": function(msg) { - this.SetNextState("ROAMING"); - }, - }, - - "FLEEING": { - "enter": function() { - this.SelectAnimation("walk", false, this.GetWalkSpeed()); - }, - - "MoveCompleted": function() { - this.SetNextState("ROAMING"); - }, - }, - }, - -}; - -var AnimalFsm = new FSM(AnimalFsmSpec); - -AnimalAI.prototype.Init = function() -{ -}; - -// FSM linkage functions: - -AnimalAI.prototype.OnCreate = function() -{ - var startingState = this.template.NaturalBehaviour; - startingState = startingState.toUpperCase(startingState); - - if (startingState == "SKITTISH") - startingState = startingState + ".FEEDING"; - else - startingState = "PASSIVE.FEEDING"; - - AnimalFsm.Init(this, startingState); -}; - -AnimalAI.prototype.SetNextState = function(state) -{ - AnimalFsm.SetNextState(this, state); -}; - -AnimalAI.prototype.DeferMessage = function(msg) -{ - AnimalFsm.DeferMessage(this, msg); -}; - -AnimalAI.prototype.OnMotionChanged = function(msg) -{ - if (msg.starting && !msg.error) - { - AnimalFsm.ProcessMessage(this, {"type": "MoveStarted", "data": msg}); - } - else if (!msg.starting || msg.error) - { - AnimalFsm.ProcessMessage(this, {"type": "MoveCompleted", "data": msg}); - } -}; - -AnimalAI.prototype.OnAttacked = function(msg) -{ - AnimalFsm.ProcessMessage(this, {"type": "Attacked", "data": msg}); -}; - -AnimalAI.prototype.OnHealthChanged = function(msg) -{ - AnimalFsm.ProcessMessage(this, {"type": "HealthChanged", "from": msg.from, "to": msg.to}); -}; - -AnimalAI.prototype.TimerHandler = function(data, lateness) -{ - AnimalFsm.ProcessMessage(this, {"type": "Timer", "data": data, "lateness": lateness}); -}; - -AnimalAI.prototype.LeaveFoundation = function(target) -{ - AnimalFsm.ProcessMessage(this, {"type": "LeaveFoundation", "target": target}); -}; - -// 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); -}; - -AnimalAI.prototype.SelectAnimation = function(name, once, speed, sound) -{ - var cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); - if (!cmpVisual) - return; - - var soundgroup; - if (sound) - { - var cmpSound = Engine.QueryInterface(this.entity, IID_Sound); - if (cmpSound) - soundgroup = cmpSound.GetSoundGroup(sound); - } - - // Set default values if unspecified - if (typeof once == "undefined") - once = false; - if (typeof speed == "undefined") - speed = 1.0; - if (typeof soundgroup == "undefined") - soundgroup = ""; - - cmpVisual.SelectAnimation(name, once, speed, soundgroup); -}; - -AnimalAI.prototype.MoveRandomly = function(distance) -{ - // We want to walk in a random direction, but avoid getting stuck - // in obstacles or narrow spaces. - // So pick a circular range from approximately our current position, - // and move outwards to the nearest point on that circle, which will - // lead to us avoiding obstacles and moving towards free space. - - // TODO: we probably ought to have a 'home' point, and drift towards - // that, so we don't spread out all across the whole map - - var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); - if (!cmpPosition) - return; - - if (!cmpPosition.IsInWorld()) - return; - - var pos = cmpPosition.GetPosition(); - - var jitter = 0.5; - - // Randomly adjust the range's center a bit, so we tend to prefer - // moving in random directions (if there's nothing in the way) - var tx = pos.x + (2*Math.random()-1)*jitter; - var tz = pos.z + (2*Math.random()-1)*jitter; - - var cmpMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); - cmpMotion.MoveToPointRange(tx, tz, distance, distance); -}; - -AnimalAI.prototype.MoveAwayFrom = function(ent, distance) -{ - var cmpMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); - cmpMotion.MoveToTargetRange(ent, distance, distance); -}; - -AnimalAI.prototype.StopMoving = function() -{ - var cmpMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); - cmpMotion.StopMoving(); -}; - -AnimalAI.prototype.SetMoveSpeed = function(speed) -{ - var cmpMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); - cmpMotion.SetSpeed(speed); -}; - -AnimalAI.prototype.StartTimer = function(interval, data) -{ - if (this.timer) - error("Called StartTimer when there's already an active timer"); - - var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); - this.timer = cmpTimer.SetTimeout(this.entity, IID_AnimalAI, "TimerHandler", interval, data); -}; - -AnimalAI.prototype.StopTimer = function() -{ - if (!this.timer) - return; - - var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); - cmpTimer.CancelTimer(this.timer); - this.timer = undefined; -}; - -Engine.RegisterComponentType(IID_AnimalAI, "AnimalAI", AnimalAI); diff --git a/binaries/data/mods/public/simulation/components/Foundation.js b/binaries/data/mods/public/simulation/components/Foundation.js index db12068058..0f62eb23f5 100644 --- a/binaries/data/mods/public/simulation/components/Foundation.js +++ b/binaries/data/mods/public/simulation/components/Foundation.js @@ -90,11 +90,7 @@ Foundation.prototype.Build = function(builderEnt, work) if (cmpUnitAI) cmpUnitAI.LeaveFoundation(this.entity); - var cmpAnimalAI = Engine.QueryInterface(ent, IID_AnimalAI); - if (cmpAnimalAI) - cmpAnimalAI.LeaveFoundation(this.entity); - - // TODO: What if an obstruction has no UnitAI/AnimalAI? + // TODO: What if an obstruction has no UnitAI? } // TODO: maybe we should tell the builder to use a special diff --git a/binaries/data/mods/public/simulation/components/UnitAI.js b/binaries/data/mods/public/simulation/components/UnitAI.js index 94d3733312..a35a1316cb 100644 --- a/binaries/data/mods/public/simulation/components/UnitAI.js +++ b/binaries/data/mods/public/simulation/components/UnitAI.js @@ -5,7 +5,38 @@ UnitAI.prototype.Schema = "" + "" + "" + - ""; + "" + + "" + + "" + + "" + + "" + + "violent" + + "aggressive" + + "defensive" + + "passive" + + "skittish" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + ""+ + "" + + ""; // Very basic stance support (currently just for test maps where we don't want // everyone killing each other immediately after loading) @@ -18,6 +49,7 @@ var g_Stances = { }, }; +// See ../helpers/FSM.js for some documentation of this FSM specification syntax var UnitFsmSpec = { // Default event handlers: @@ -44,6 +76,9 @@ var UnitFsmSpec = { // ignore attacker }, + "HealthChanged": function(msg) { + // ignore + }, // Formation handlers: @@ -53,6 +88,13 @@ var UnitFsmSpec = { // Called when being told to walk as part of a formation "Order.FormationWalk": function(msg) { + if (this.IsAnimal()) + { + // TODO: let players move captured animals around + this.FinishOrder(); + return; + } + var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); cmpUnitMotion.MoveToFormationOffset(msg.data.target, msg.data.x, msg.data.z); @@ -71,11 +113,25 @@ var UnitFsmSpec = { // (these will switch the unit out of formation mode) "Order.Walk": function(msg) { + if (this.IsAnimal()) + { + // TODO: let players move captured animals around + this.FinishOrder(); + return; + } + this.MoveToPoint(this.order.data.x, this.order.data.z); this.SetNextState("INDIVIDUAL.WALKING"); }, "Order.WalkToTarget": function(msg) { + if (this.IsAnimal()) + { + // TODO: let players move captured animals around + this.FinishOrder(); + return; + } + var ok = this.MoveToTarget(this.order.data.target); if (ok) { @@ -111,14 +167,20 @@ var UnitFsmSpec = { if (this.MoveToTargetRange(this.order.data.target, IID_Attack, this.attackType)) { // We've started walking to the given point - this.SetNextState("INDIVIDUAL.COMBAT.APPROACHING"); + if (this.IsAnimal()) + this.SetNextState("ANIMAL.COMBAT.APPROACHING"); + else + this.SetNextState("INDIVIDUAL.COMBAT.APPROACHING"); } else { // We are already at the target, or can't move at all, // so try attacking it from here. // TODO: need better handling of the can't-reach-target case - this.SetNextState("INDIVIDUAL.COMBAT.ATTACKING"); + if (this.IsAnimal()) + this.SetNextState("ANIMAL.COMBAT.ATTACKING"); + else + this.SetNextState("INDIVIDUAL.COMBAT.ATTACKING"); } }, @@ -299,6 +361,12 @@ var UnitFsmSpec = { // States for entities not part of a formation: "INDIVIDUAL": { + "enter": function() { + // Sanity-checking + if (this.IsAnimal()) + error("Animal got moved into INDIVIDUAL.* state"); + }, + "Attacked": function(msg) { // Default behaviour: attack back at our attacker if (this.CanAttack(msg.data.attacker)) @@ -454,7 +522,7 @@ var UnitFsmSpec = { // Can't reach it, or it doesn't exist any more - give up this.FinishOrder(); - + // TODO: see if we can switch to a new nearby enemy }, @@ -841,6 +909,178 @@ var UnitFsmSpec = { }, }, + + "ANIMAL": { + + "HealthChanged": function(msg) { + // If we died (got reduced to 0 hitpoints), stop the AI and act like a corpse + if (msg.to == 0) + this.SetNextState("CORPSE"); + }, + + "Attacked": function(msg) { + if (this.template.NaturalBehaviour == "skittish" || + this.template.NaturalBehaviour == "passive") + { + this.MoveToTargetRangeExplicit(msg.data.attacker, +this.template.FleeDistance, +this.template.FleeDistance); + this.SetNextState("FLEEING"); + this.PlaySound("panic"); + } + else if (this.template.NaturalBehaviour == "violent" || + this.template.NaturalBehaviour == "aggressive" || + this.template.NaturalBehaviour == "defensive") + { + if (this.CanAttack(msg.data.attacker)) + this.ReplaceOrder("Attack", { "target": msg.data.attacker }); + } + }, + + "Order.LeaveFoundation": function(msg) { + // Run away from the foundation + this.MoveToTargetRangeExplicit(msg.data.target, +this.template.FleeDistance, +this.template.FleeDistance); + this.SetNextState("FLEEING"); + this.PlaySound("panic"); + }, + + "IDLE": { + // (We need an IDLE state so that FinishOrder works) + + "enter": function() { + // Start feeding immediately + this.SetNextState("FEEDING"); + return true; + }, + }, + + "CORPSE": { + "enter": function() { + this.StopMoving(); + }, + + // Ignore all orders that animals might otherwise respond to + "Order.FormationWalk": function() { }, + "Order.Walk": function() { }, + "Order.WalkToTarget": function() { }, + "Order.Attack": function() { }, + + "Attacked": function(msg) { + // Do nothing, because we're dead already + }, + + "Order.LeaveFoundation": function(msg) { + // We can't walk away from the foundation (since we're dead), + // but we mustn't block its construction (since the builders would get stuck), + // and we don't want to trick gatherers into trying to reach us when + // we're stuck in the middle of a building, so just delete our corpse. + Engine.DestroyEntity(this.entity); + }, + }, + + "ROAMING": { + "enter": function() { + // Walk in a random direction + this.SelectAnimation("walk", false, this.GetWalkSpeed()); + this.MoveRandomly(+this.template.RoamDistance); + // Set a random timer to switch to feeding state + this.StartTimer(RandomInt(+this.template.RoamTimeMin, +this.template.RoamTimeMax)); + }, + + "leave": function() { + this.StopTimer(); + }, + + "LosRangeUpdate": function(msg) { + if (this.template.NaturalBehaviour == "skittish") + { + if (msg.data.added.length > 0) + { + this.MoveToTargetRangeExplicit(msg.data.added[0], +this.template.FleeDistance, +this.template.FleeDistance); + this.SetNextState("FLEEING"); + this.PlaySound("panic"); + return; + } + } + // Start attacking one of the newly-seen enemy (if any) + else if (this.template.NaturalBehaviour == "violent" || + this.template.NaturalBehaviour == "aggressive") + { + this.AttackVisibleEntity(msg.data.added); + } + + // TODO: if two units enter our range together, we'll attack the + // first and then the second won't trigger another LosRangeUpdate + // so we won't notice it. Probably we should do something with + // ResetActiveQuery in ROAMING.enter/FEEDING.enter in order to + // find any units that are already in range. + }, + + "Timer": function(msg) { + this.SetNextState("FEEDING"); + }, + + "MoveCompleted": function() { + this.MoveRandomly(+this.template.RoamDistance); + }, + }, + + "FEEDING": { + "enter": function() { + // Stop and eat for a while + this.SelectAnimation("feeding"); + this.StopMoving(); + this.StartTimer(RandomInt(+this.template.FeedTimeMin, +this.template.FeedTimeMax)); + }, + + "leave": function() { + this.StopTimer(); + }, + + "LosRangeUpdate": function(msg) { + if (this.template.NaturalBehaviour == "skittish") + { + if (msg.data.added.length > 0) + { + this.MoveToTargetRangeExplicit(msg.data.added[0], +this.template.FleeDistance, +this.template.FleeDistance); + this.SetNextState("FLEEING"); + this.PlaySound("panic"); + return; + } + } + // Start attacking one of the newly-seen enemy (if any) + else if (this.template.NaturalBehaviour == "violent") + { + this.AttackVisibleEntity(msg.data.added); + } + }, + + "MoveCompleted": function() { }, + + "Timer": function(msg) { + this.SetNextState("ROAMING"); + }, + }, + + "FLEEING": { + "enter": function() { + // Run quickly + var speed = this.GetRunSpeed(); + this.SelectAnimation("run", false, speed); + this.SetMoveSpeed(speed); + }, + + "leave": function() { + // Reset normal speed + this.SetMoveSpeed(this.GetWalkSpeed()); + }, + + "MoveCompleted": function() { + // When we've run far enough, go back to the roaming state + this.SetNextState("ROAMING"); + }, + }, + + "COMBAT": "INDIVIDUAL.COMBAT", // reuse the same combat behaviour for animals + }, }; var UnitFsm = new FSM(UnitFsmSpec); @@ -860,6 +1100,11 @@ UnitAI.prototype.IsFormationController = function() return (this.template.FormationController == "true"); }; +UnitAI.prototype.IsAnimal = function() +{ + return (this.template.NaturalBehaviour ? true : false); +}; + UnitAI.prototype.IsIdle = function() { return this.isIdle; @@ -867,7 +1112,9 @@ UnitAI.prototype.IsIdle = function() UnitAI.prototype.OnCreate = function() { - if (this.IsFormationController()) + if (this.IsAnimal()) + UnitFsm.Init(this, "ANIMAL.FEEDING"); + else if (this.IsFormationController()) UnitFsm.Init(this, "FORMATIONCONTROLLER.IDLE"); else UnitFsm.Init(this, "INDIVIDUAL.IDLE"); @@ -916,7 +1163,7 @@ UnitAI.prototype.SetupRangeQuery = function(owner) // Get our diplomacy array var diplomacy = player.GetDiplomacy(); var numPlayers = playerMan.GetNumPlayers(); - + for (var i = 1; i < numPlayers; ++i) { // Exclude gaia, allies, and self @@ -1076,6 +1323,11 @@ UnitAI.prototype.OnAttacked = function(msg) UnitFsm.ProcessMessage(this, {"type": "Attacked", "data": msg}); }; +UnitAI.prototype.OnHealthChanged = function(msg) +{ + UnitFsm.ProcessMessage(this, {"type": "HealthChanged", "from": msg.from, "to": msg.to}); +}; + UnitAI.prototype.OnRangeUpdate = function(msg) { if (msg.tag == this.losRangeQuery) @@ -1544,7 +1796,13 @@ UnitAI.prototype.CanGarrison = function(target) var cmpGarrisonHolder = Engine.QueryInterface(target, IID_GarrisonHolder); if (!cmpGarrisonHolder) return false; - + + // Don't let animals garrison for now + // (If we want to support that, we'll need to change Order.Garrison so it + // doesn't move the animal into an INVIDIDUAL.* state) + if (this.IsAnimal()) + return false; + return true; }; @@ -1614,5 +1872,43 @@ UnitAI.prototype.CanRepair = function(target) return true; }; +//// Animal specific functions //// + +UnitAI.prototype.MoveRandomly = function(distance) +{ + // We want to walk in a random direction, but avoid getting stuck + // in obstacles or narrow spaces. + // So pick a circular range from approximately our current position, + // and move outwards to the nearest point on that circle, which will + // lead to us avoiding obstacles and moving towards free space. + + // TODO: we probably ought to have a 'home' point, and drift towards + // that, so we don't spread out all across the whole map + + var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); + if (!cmpPosition) + return; + + if (!cmpPosition.IsInWorld()) + return; + + var pos = cmpPosition.GetPosition(); + + var jitter = 0.5; + + // Randomly adjust the range's center a bit, so we tend to prefer + // moving in random directions (if there's nothing in the way) + var tx = pos.x + (2*Math.random()-1)*jitter; + var tz = pos.z + (2*Math.random()-1)*jitter; + + var cmpMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); + cmpMotion.MoveToPointRange(tx, tz, distance, distance); +}; + +UnitAI.prototype.SetMoveSpeed = function(speed) +{ + var cmpMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); + cmpMotion.SetSpeed(speed); +}; Engine.RegisterComponentType(IID_UnitAI, "UnitAI", UnitAI); diff --git a/binaries/data/mods/public/simulation/components/interfaces/AnimalAI.js b/binaries/data/mods/public/simulation/components/interfaces/AnimalAI.js deleted file mode 100644 index 51994c1459..0000000000 --- a/binaries/data/mods/public/simulation/components/interfaces/AnimalAI.js +++ /dev/null @@ -1 +0,0 @@ -Engine.RegisterInterface("AnimalAI"); diff --git a/binaries/data/mods/public/simulation/helpers/FSM.js b/binaries/data/mods/public/simulation/helpers/FSM.js index 27539d9e5f..8b0d60cb30 100644 --- a/binaries/data/mods/public/simulation/helpers/FSM.js +++ b/binaries/data/mods/public/simulation/helpers/FSM.js @@ -70,6 +70,9 @@ var FsmSpec = { }, }, + // Define a new state which is an exact copy of another + // state that is defined elsewhere in this FSM: + "OTHERSUBSTATENAME": "STATENAME.SUBSTATENAME", } } @@ -143,6 +146,23 @@ function FSM(spec) function process(fsm, node, path, handlers) { + // Handle string references to nodes defined elsewhere in the FSM spec + if (typeof node === "string") + { + var refpath = node.split("."); + var refd = spec; + for each (var p in refpath) + { + refd = refd[p]; + if (!refd) + { + error("FSM node "+path.join(".")+" referred to non-defined node "+node); + return {}; + } + } + node = refd; + } + var state = {}; fsm.states[path.join(".")] = state; diff --git a/binaries/data/mods/public/simulation/helpers/Player.js b/binaries/data/mods/public/simulation/helpers/Player.js index b7663f5d2f..d73d1d1b7b 100644 --- a/binaries/data/mods/public/simulation/helpers/Player.js +++ b/binaries/data/mods/public/simulation/helpers/Player.js @@ -53,7 +53,7 @@ function LoadPlayerSettings(settings) teams[team].push(i); } } - + for (var i = 0; i < numPlayers; ++i) { // Add player entity to engine @@ -112,6 +112,7 @@ function LoadPlayerSettings(settings) player.SetName(pDefs.Name); player.SetCiv(pDefs.Civ); player.SetColour(pDefs.Colour.r, pDefs.Colour.g, pDefs.Colour.b); + player.SetDiplomacy(diplomacy); } // Add player to player manager diff --git a/binaries/data/mods/public/simulation/templates/gaia/fauna_chicken.xml b/binaries/data/mods/public/simulation/templates/gaia/fauna_chicken.xml index 99dce7bc91..591b21a2d1 100644 --- a/binaries/data/mods/public/simulation/templates/gaia/fauna_chicken.xml +++ b/binaries/data/mods/public/simulation/templates/gaia/fauna_chicken.xml @@ -22,14 +22,14 @@ 1.5 - + 4.0 12.0 2000 8000 10000 40000 - + 1.0 diff --git a/binaries/data/mods/public/simulation/templates/gaia/fauna_whale_humpback.xml b/binaries/data/mods/public/simulation/templates/gaia/fauna_whale_humpback.xml index 2fef6f96bc..2458eaba5c 100644 --- a/binaries/data/mods/public/simulation/templates/gaia/fauna_whale_humpback.xml +++ b/binaries/data/mods/public/simulation/templates/gaia/fauna_whale_humpback.xml @@ -35,7 +35,7 @@ -4.0 true - + skittish 20.0 40.0 @@ -43,7 +43,7 @@ 30000 1000 2000 - + true 2000 diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna.xml index 8f7a6144ff..e13218ea0d 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna.xml @@ -25,13 +25,12 @@ 6.0 - - + 8.0 32.0 2000 8000 15000 60000 - + diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_breed_passive.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_breed_passive.xml index c0064a0745..9bedf79809 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_breed_passive.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_breed_passive.xml @@ -2,7 +2,7 @@ - + passive - + diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_fish.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_fish.xml index 3b10a16dc8..0f638a0288 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_fish.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_fish.xml @@ -18,7 +18,7 @@ true - + false 1000 diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_herd_passive.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_herd_passive.xml index 530e979b30..15d6927d22 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_herd_passive.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_herd_passive.xml @@ -2,7 +2,7 @@ - + passive - + diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_aggressive.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_aggressive.xml index ee8949679f..9eaedcd2df 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_aggressive.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_aggressive.xml @@ -2,7 +2,16 @@ - + aggressive - + + + + 1.0 + 1.0 + 0.0 + 4.0 + 1000 + + diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_defensive.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_defensive.xml index 37bf7b438b..e4969a8376 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_defensive.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_defensive.xml @@ -2,7 +2,7 @@ - + defensive - + diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_passive.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_passive.xml index 3ba6cf8fcf..f5aee67c91 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_passive.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_passive.xml @@ -2,7 +2,7 @@ - + passive - + diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_skittish.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_skittish.xml index 5041f72dbb..4e6b672730 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_skittish.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_skittish.xml @@ -2,7 +2,7 @@ - + skittish - + diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_violent.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_violent.xml index a894caf37e..88d0a6f6d7 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_violent.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_violent.xml @@ -2,7 +2,16 @@ - + violent - + + + + 1.0 + 1.0 + 0.0 + 4.0 + 1000 + + diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_aggressive.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_aggressive.xml index e151926438..6e9d8fa598 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_aggressive.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_aggressive.xml @@ -2,7 +2,16 @@ - - violent - + + aggressive + + + + 1.0 + 1.0 + 0.0 + 4.0 + 1000 + + diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_defensive.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_defensive.xml index a37f8ea63a..29d6320627 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_defensive.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_defensive.xml @@ -2,7 +2,7 @@ - + defensive - + diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_passive.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_passive.xml index 4c893034c2..5beb3c57d4 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_passive.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_passive.xml @@ -2,7 +2,7 @@ - + passive - + diff --git a/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_violent.xml b/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_violent.xml index e151926438..0ed57ab7d5 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_violent.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_violent.xml @@ -2,7 +2,16 @@ - + violent - + + + + 1.0 + 1.0 + 0.0 + 4.0 + 1000 + +