protected override void ReadyInternal(ActionBase action) { bool actionTaken = false; ActionType finishedAction = action.ActionType; //call the base for actions that we don't handle if (finishedAction != ActionType.Idle && finishedAction != ActionType.Move) { base.ReadyInternal(action); return; } if (true)//!IsUnderAttack() && !IsAttacking() && !IsEnRoute()) { if (finishedAction == ActionType.Idle) { Debug.WriteLineIf(Id == 0, "VillagerNpc: Finished idling."); //move somewhere Debug.WriteLineIf(Id == 0, "VillagerNpc: Moving to random position."); actionTaken = MoveToARandomPosition(); } else if (finishedAction == ActionType.Move) { // if the unit did not arrive at the destination, then we need to move to the next leg if (IsFollowingRoute) { actionTaken = MoveToNextLegInTheRoute(); if (!actionTaken) { //the next leg is obstructed, try to find a bypass actionTaken = Move(Destination.Value); //if moving to the initial destination is not possible //we should let the unit to idle till it's possible to move somewhere //or ther actions are possible if (!actionTaken) { RouteEnded(true); } } } } } //if there was no action then just idle if (!actionTaken) { Idle(); actionTaken = true; } }
protected override void ReadyInternal(ActionBase action) { ActionType finishedAction = action.ActionType; //TODO: filter by the types of handled actions //call the base first! base.ReadyInternal(action); bool actionTaken = false; CharacterBase unitToAttack; //if attacking a unit if (AttackedUnit != null) { // if in attack range, just attack it // else // if moving, check that the destination is a cell next to the attacked unit // else adjust the route to the attacked unit // if not moving, then start moving } //if there is a unit worth attacking in range, attack it else if ((unitToAttack = FindUnitToAttack()) != null) { //let's not forget that if we are moving, we should stop first if (IsFollowingRoute) { RouteEnded(true); } //TOOD: attack the unit! // set the attacked unit property AttackedUnit = unitToAttack; // if in attack range, just attack it Engine.ProcessAttack(this, AttackedUnit); // else move to the attacked unit } if (true)//!IsUnderAttack() && !IsAttacking() && !IsEnRoute()) { if (finishedAction == ActionType.Idle) { Debug.WriteLineIf(Id == 0, "VillagerNpc: Finished idling."); //move somewhere Debug.WriteLineIf(Id == 0, "VillagerNpc: Moving to random position."); actionTaken = MoveToARandomPosition(); } else if (finishedAction == ActionType.Move) { // if the unit did not arrive at the destination, then we need to move to the next leg if (IsFollowingRoute) { actionTaken = MoveToNextLegInTheRoute(); if (!actionTaken) { //the next leg is obstructed, try to find a bypass actionTaken = Move(Destination.Value); //if moving to the initial destination is not possible //we should let the unit to idle till it's possible to move somewhere //or ther actions are possible if (!actionTaken) { RouteEnded(interrupted: true); } } } } } //if there was no action then just idle if (!actionTaken) { Idle(); } }
protected virtual void ReadyInternal(ActionBase finishedAction) { }
private void AddAction(CharacterBase unit, ActionBase action) { if (action.Tick <= _timeKeeper.Tick) { } _unitActionDict.TryAdd(unit, action); ConcurrentQueue<CharacterBase> actionList = _scheduledActionsDict .GetOrAdd(action.Tick, new ConcurrentQueue<CharacterBase>()); actionList.Enqueue(unit); }
/// <summary> /// Engine event. Notifies the unit that it's ready for new actions. /// The EndMove event will be fired if the Location is the same as the Destination. /// </summary> public void Ready(ActionBase action) { //call the EndMove first if (action.ActionType == ActionType.Move) { EndMove((action as MoveAction).Location); } ReadyInternal(action); }