Changeset View
Standalone View
binaries/data/mods/public/simulation/components/UnitAI.js
Show First 20 Lines • Show All 269 Lines • ▼ Show 20 Lines | "Order.Stop": function(msg) { | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
if (this.IsAnimal()) | if (this.IsAnimal()) | ||||
this.SetNextState("ANIMAL.IDLE"); | this.SetNextState("ANIMAL.IDLE"); | ||||
else if (this.IsFormationMember()) | else if (this.IsFormationMember()) | ||||
this.SetNextState("FORMATIONMEMBER.IDLE"); | this.SetNextState("FORMATIONMEMBER.IDLE"); | ||||
else | else | ||||
this.SetNextState("INDIVIDUAL.IDLE"); | this.SetNextState("INDIVIDUAL.IDLE"); | ||||
Stan: Revert | |||||
}, | }, | ||||
"Order.Walk": function(msg) { | "Order.Walk": function(msg) { | ||||
if (!this.AbleToMove()) | if (!this.AbleToMove()) | ||||
{ | { | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
return; | return; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 388 Lines • ▼ Show 20 Lines | UnitAI.prototype.UnitFsmSpec = { | ||||
"Order.CancelUnpack": function(msg) { | "Order.CancelUnpack": function(msg) { | ||||
var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); | var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); | ||||
if (cmpPack && cmpPack.IsPacking() && cmpPack.IsPacked()) | if (cmpPack && cmpPack.IsPacking() && cmpPack.IsPacked()) | ||||
cmpPack.CancelPack(); | cmpPack.CancelPack(); | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
}, | }, | ||||
"Order.CollectTreasure": function(msg) { | |||||
if (!Engine.QueryInterface(this.entity, IID_TreasureCollecter)) | |||||
return { "discardOrder": true }; | |||||
Done Inline Actionsrebase wraitii: rebase | |||||
this.SetNextState("COLLECTTREASURE"); | |||||
}, | |||||
// States for the special entity representing a group of units moving in formation: | // States for the special entity representing a group of units moving in formation: | ||||
"FORMATIONCONTROLLER": { | "FORMATIONCONTROLLER": { | ||||
"Order.Walk": function(msg) { | "Order.Walk": function(msg) { | ||||
this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); | ||||
this.SetNextState("WALKING"); | this.SetNextState("WALKING"); | ||||
}, | }, | ||||
▲ Show 20 Lines • Show All 1,827 Lines • ▼ Show 20 Lines | "GATHER": { | ||||
this.SetNextState("FINDINGNEWTARGET"); | this.SetNextState("FINDINGNEWTARGET"); | ||||
return; | return; | ||||
} | } | ||||
// Gather the resources: | // Gather the resources: | ||||
let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); | let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); | ||||
// Try to gather treasure | |||||
if (cmpResourceGatherer.TryInstantGather(this.gatheringTarget)) | |||||
return; | |||||
// If we've already got some resources but they're the wrong type, | // If we've already got some resources but they're the wrong type, | ||||
// drop them first to ensure we're only ever carrying one type | // drop them first to ensure we're only ever carrying one type | ||||
if (cmpResourceGatherer.IsCarryingAnythingExcept(resourceType.generic)) | if (cmpResourceGatherer.IsCarryingAnythingExcept(resourceType.generic)) | ||||
cmpResourceGatherer.DropResources(); | cmpResourceGatherer.DropResources(); | ||||
this.FaceTowardsTarget(this.order.data.target); | this.FaceTowardsTarget(this.order.data.target); | ||||
// Collect from the target | // Collect from the target | ||||
▲ Show 20 Lines • Show All 299 Lines • ▼ Show 20 Lines | "RETURNRESOURCE": { | ||||
} | } | ||||
// Oh no, couldn't find any drop sites. Give up on returning. | // Oh no, couldn't find any drop sites. Give up on returning. | ||||
this.FinishOrder(); | this.FinishOrder(); | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
"COLLECTTREASURE": { | |||||
"enter": function() { | |||||
let cmpTreasureCollecter = Engine.QueryInterface(this.entity, IID_TreasureCollecter); | |||||
if (!cmpTreasureCollecter) | |||||
{ | |||||
this.FinishOrder(); | |||||
return true; | |||||
} | |||||
if (this.CheckTargetRange(this.order.data.target, IID_TreasureCollecter)) | |||||
Done Inline ActionsErr, actually quite inefficient. Freagarach: Err, actually quite inefficient. | |||||
this.SetNextState("COLLECTING"); | |||||
else | |||||
this.SetNextState("APPROACHING"); | |||||
return true; | |||||
}, | |||||
"leave": function() { | |||||
}, | |||||
"APPROACHING": { | |||||
"enter": function() { | |||||
if (!this.MoveToTargetRange(this.order.data.target, IID_TreasureCollecter)) | |||||
{ | |||||
this.FinishOrder(); | |||||
return true; | |||||
} | |||||
return false; | |||||
}, | |||||
"leave": function() { | |||||
this.StopMoving(); | |||||
}, | |||||
"MovementUpdate": function(msg) { | |||||
if ((msg.likelyFailure || msg.likelySuccess) && | |||||
this.CheckTargetRange(this.order.data.target, IID_TreasureCollecter)) | |||||
Done Inline ActionsUsual behaviour in UnitAI is to call FinishOrder(), and only if that returns false (no pending order) do something generic. wraitii: Usual behaviour in UnitAI is to call FinishOrder(), and only if that returns false (no pending… | |||||
this.SetNextState("COLLECTING"); | |||||
}, | |||||
}, | |||||
"COLLECTING": { // ToDo: Autocontinue. | |||||
"enter": function() { | |||||
Done Inline Actions@Imarok I would like to have also your opinion on this method of performing actions in UnitAI. Freagarach: @Imarok I would like to have also your opinion on this method of performing actions in UnitAI. | |||||
Done Inline ActionsWhat exactly do you mean? Imarok: What exactly do you mean?
(I haven't really done anything in this area ;)) | |||||
Done Inline ActionsI've been discussing with @wraitii (and @bb earlier) about how UnitAI performs actions. If one looks at e.g. resource gathering, one can see a lot of gathering-specific stuff is done in UnitAI. I have some diffs moving those specific actions to their respective components, for that is much more fitting, IMHO. This diff uses the same concept:
To me this sounds like it should be. UnitAI should only care about how to react to situations, not precisely how to perform them. But @wraitii does not fully agree. Hence I would like some thought of more people for perhaps I am looking past some important stuff. Freagarach: I've been discussing with @wraitii (and @bb earlier) about how `UnitAI` performs actions. If… | |||||
if (!this.CheckTargetRange(this.order.data.target, IID_TreasureCollecter)) | |||||
{ | |||||
this.OutOfRange(); | |||||
return true; | |||||
} | |||||
let callback = { | |||||
Done Inline ActionsDoesn't look like a callback function? Stan: Doesn't look like a callback function? | |||||
Done Inline ActionsSee also D2662. Freagarach: See also D2662.
It specifies what component to call and what functions under which… | |||||
"iid": IID_UnitAI, | |||||
"outOfRange": "OutOfRange", | |||||
"targetInvalidated": "TargetInvalidated" | |||||
}; | |||||
let cmpTreasureCollecter = Engine.QueryInterface(this.entity, IID_TreasureCollecter); | |||||
if (!cmpTreasureCollecter.StartCollecting(this.order.data.target, callback)) | |||||
{ | |||||
this.TargetInvalidated(); | |||||
return true; | |||||
} | |||||
this.FaceTowardsTarget(this.order.data.target); | |||||
this.SelectAnimation("collecting_treasure"); | |||||
}, | |||||
"leave": function() { | |||||
this.ResetAnimation(); | |||||
}, | |||||
"OutOfRange": function(msg) { | |||||
this.SetNextState("APPROACHING"); | |||||
}, | |||||
"TargetInvalidated": function(msg) { | |||||
this.FinishOrder(); | |||||
}, | |||||
}, | |||||
}, | |||||
"TRADE": { | "TRADE": { | ||||
"Attacked": function(msg) { | "Attacked": function(msg) { | ||||
// Ignore attack | // Ignore attack | ||||
// TODO: Inform player | // TODO: Inform player | ||||
}, | }, | ||||
"APPROACHINGMARKET": { | "APPROACHINGMARKET": { | ||||
"enter": function() { | "enter": function() { | ||||
▲ Show 20 Lines • Show All 1,464 Lines • ▼ Show 20 Lines | else if (msg.tag == this.losAttackRangeQuery) | ||||
this.UnitFsm.ProcessMessage(this, { "type": "LosAttackRangeUpdate", "data": msg }); | this.UnitFsm.ProcessMessage(this, { "type": "LosAttackRangeUpdate", "data": msg }); | ||||
}; | }; | ||||
UnitAI.prototype.OnPackFinished = function(msg) | UnitAI.prototype.OnPackFinished = function(msg) | ||||
{ | { | ||||
this.UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed}); | this.UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed}); | ||||
}; | }; | ||||
UnitAI.prototype.OutOfRange = function(msg) | |||||
{ | |||||
this.UnitFsm.ProcessMessage(this, { "type": "OutOfRange", "data": msg }); | |||||
}; | |||||
UnitAI.prototype.TargetInvalidated = function(msg) | |||||
{ | |||||
this.UnitFsm.ProcessMessage(this, { "type": "TargetInvalidated", "data": msg }); | |||||
}; | |||||
//// Helper functions to be called by the FSM //// | //// Helper functions to be called by the FSM //// | ||||
UnitAI.prototype.GetWalkSpeed = function() | UnitAI.prototype.GetWalkSpeed = function() | ||||
{ | { | ||||
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); | let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); | ||||
if (!cmpUnitMotion) | if (!cmpUnitMotion) | ||||
return 0; | return 0; | ||||
return cmpUnitMotion.GetWalkSpeed(); | return cmpUnitMotion.GetWalkSpeed(); | ||||
▲ Show 20 Lines • Show All 1,321 Lines • ▼ Show 20 Lines | UnitAI.prototype.ReturnResource = function(target, queued) | ||||
{ | { | ||||
this.WalkToTarget(target, queued); | this.WalkToTarget(target, queued); | ||||
return; | return; | ||||
} | } | ||||
this.AddOrder("ReturnResource", { "target": target, "force": true }, queued); | this.AddOrder("ReturnResource", { "target": target, "force": true }, queued); | ||||
}; | }; | ||||
/** | |||||
* Adds order to collect a treasure to queue, forced by the player. | |||||
*/ | |||||
UnitAI.prototype.CollectTreasure = function(target, queued) | |||||
{ | |||||
this.AddOrder("CollectTreasure", { "target": target, "force": true }, queued); | |||||
}; | |||||
UnitAI.prototype.CancelSetupTradeRoute = function(target) | UnitAI.prototype.CancelSetupTradeRoute = function(target) | ||||
{ | { | ||||
let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader); | let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader); | ||||
if (!cmpTrader) | if (!cmpTrader) | ||||
return; | return; | ||||
cmpTrader.RemoveTargetMarket(target); | cmpTrader.RemoveTargetMarket(target); | ||||
if (this.IsFormationController()) | if (this.IsFormationController()) | ||||
▲ Show 20 Lines • Show All 885 Lines • Show Last 20 Lines |
Revert