public override void Push(IWorld world, IUserinterface ui, ActionStack stack, IActor actor) { stack.Push(new Frame(actor, this, GetAttitude(actor, Owner) ?? Attitude) { TargetIfAny = Owner }); }
protected override void PopImpl(IWorld world, IUserinterface ui, ActionStack stack, Frame frame) { var f = (EquipmentFrame)frame; switch (f.ToPerform) { case EquipmentActionToPerform.None: break; case EquipmentActionToPerform.PutOn: if (f.PerformedBy.CanEquip(f.Item, out string reason)) { f.Item.IsEquipped = true; } else { ShowNarrative(ui, f.PerformedBy, "Equip failed", $"You struggle to equip {f.Item} but find it just won't fit ({reason})", null, stack.Round); } break; case EquipmentActionToPerform.TakeOff: f.Item.IsEquipped = false; break; default: throw new ArgumentOutOfRangeException(); } }
public override void OnPop(IWorld world, IUserinterface ui, ActionStack stack, Frame frame) { base.OnPop(world, ui, stack, frame); if (!(frame.TargetIfAny is IActor)) { return; } //if the target is me then I might get angry if (frame.TargetIfAny == Owner) { IDoCare(world, ui, frame, stack, frame.Attitude); } else { //is the target one of my friends? double howMuchICare = world.Relationships.Where(r => r.AppliesTo((IActor)Owner, (IActor)frame.TargetIfAny)) .Sum(r => r.Attitude); //Your hurting one of my friends, im unhappy if (howMuchICare > 0.0001) { IDoCare(world, ui, frame, stack, frame.Attitude); } //your hurting my enemies, I'm happy! if (howMuchICare < 0.001) { IDoCare(world, ui, frame, stack, -0.5 * frame.Attitude); } } }
private bool RunStack(IWorld world, IUserinterface ui) { //If the action decided not to push after all (e.g. UI cancel or decision not to push) if (this.Count == 0) { return(false); //initial action was aborted } //check all behaviours to see if they want to respond (by pushing actions etc) foreach (IBehaviour responder in Behaviours.ToArray()) //ToArray needed because they can self destruct at this time! { responder.OnPush(world, ui, this, Peek()); } //run all tasks that are not pending cancellation while (Count > 0) { Frame current = Pop(); if (!current.Cancelled) { current.Action.Pop(world, ui, this, current); foreach (IBehaviour responder in Behaviours.ToArray()) { responder.OnPop(world, ui, this, current); } } } Clear(); return(true); }
public override void OnPush(IWorld world, IUserinterface ui, ActionStack stack, Frame frame) { base.OnPush(world, ui, stack, frame); var coerceFrame = Coerced.CoercedFrame; //if the coerced frame has had all it's decisions made and is about to be pushed onto the stack if (ReferenceEquals(frame.Action, coerceFrame.CoerceAction)) { var args = new NegotiationSystemArgs(world, ui, coerceFrame.PerformedBy.GetFinalStats()[Stat.Coerce], coerceFrame.PerformedBy, coerceFrame.TargetIfAny, stack.Round); //the final frame that is being pushed is what we are proposing they do args.Proposed = frame; //Check with the negotiation system to see if the actor is still willing to go ahead //with the action as configured Coerced.CoercedFrame.NegotiationSystem.Apply(args); //if not then cancel if (!args.Willing) { var narrative = new Narrative(coerceFrame.PerformedBy, "Coerce Failed", $"{coerceFrame.TargetIfAny} refused to perform action", $"{coerceFrame.PerformedBy} failed to coerce {coerceFrame.TargetIfAny} - {args.WillingReason}", stack.Round); narrative.Show(ui); frame.Cancelled = true; } } }
protected override void PopImpl(IWorld world, IUserinterface ui, ActionStack stack, Frame frame) { _toForbid.Cancelled = true; ui.Log.Info(new LogEntry( $"{frame.PerformedBy} prevented {_toForbid.PerformedBy} from performing action {_toForbid.Action.Name}", stack.Round, _toForbid.PerformedBy)); }
public virtual void Kill(IInjured injured, IUserinterface ui, Guid round, string diedOf) { if (injured.Owner is IActor a) { a.Kill(ui, round, diedOf); } }
/// <inheritdoc/> public void RunRound(IUserinterface ui, IAction playerAction) { if (Player.Dead) { ui.ShowMessage("Dead", "Alas you are too dead to do that"); return; } //get fresh round logs ui.Log.RoundResults.Clear(); var stack = new ActionStack(); var actionRun = stack.RunStack(this, ui, playerAction, Player, GetAllBehaviours()); if (actionRun) { RunNpcActions(stack, ui); foreach (IBehaviour b in GetAllBehaviours()) { b.OnRoundEnding(this, ui, stack.Round); } var results = GetPlayerVisibleLogResults(ui).ToArray(); if (results.Any()) { ui.ShowMessage("Round Results", string.Join("\n", results)); } } }
public override void Push(IWorld world, IUserinterface ui, ActionStack stack, IActor actor) { if (Owner != null) { ui.ShowStats(Owner); } }
public override void Push(IWorld world, IUserinterface ui, ActionStack stack, IActor actor) { //ask actor to pick a direction if (actor.Decide <Direction>(ui, "LeaveAction Direction", null, out var direction, GetLeaveDirections(actor), 0)) { stack.Push(new LeaveFrame(actor, this, direction, 0)); } }
public CoerceFrame(IActor performedBy, CoerceAction action, Npc toCoerce, IAction coerceAction, IUserinterface ui, INegotiationSystem negotiationSystem, double attitude) : base(performedBy, action, attitude) { TargetIfAny = toCoerce; CoerceAction = coerceAction; UserInterface = ui; NegotiationSystem = negotiationSystem; }
protected override void PopImpl(IWorld world1, IUserinterface ui, ActionStack stack, Frame frame) { var f = (DialogueFrame)frame; var world = frame.PerformedBy.CurrentLocation.World; //apply the dialogue system world.Dialogue.Apply(new SystemArgs(world, ui, 0, f.PerformedBy, f.DialogueTarget, stack.Round)); }
/// <summary> /// Runs the <paramref name="frameToRun"/> and evaluates all responders /// </summary> /// <param name="world">Where the action is happening</param> /// <param name="ui">When decisions require user input, this handles it</param> /// <param name="frameToRun">The initial action frame (to go on bottom of stack)</param> /// <param name="responders">All valid responders</param> public bool RunStack(IWorld world, IUserinterface ui, Frame frameToRun, IEnumerable <IBehaviour> responders) { Behaviours = responders?.ToArray() ?? new IBehaviour[0]; Push(frameToRun); return(RunStack(world, ui)); }
public SystemArgs(IWorld world, IUserinterface ui, double intensity, IActor aggressorIfAny, IHasStats recipient, Guid round) { World = world; Intensity = intensity; AggressorIfAny = aggressorIfAny; Recipient = recipient; Round = round; UserInterface = ui; }
/// <summary> /// Override to your action once it is confirmed /// </summary> /// <param name="world"></param> /// <param name="ui"></param> /// <param name="stack"></param> /// <param name="frame"></param> public virtual void Pop(IWorld world, IUserinterface ui, ActionStack stack, Frame frame) { foreach (var e in Effect) { e.Apply(new ActionFrameSystemArgs(this, world, ui, stack, frame)); } PopImpl(world, ui, stack, frame); }
protected override void PopImpl(IWorld world, IUserinterface ui, ActionStack stack, Frame frame) { var f = (HealFrame)frame; if (f.TargetIfAny.Adjectives.Contains(f.Injury)) { f.Injury.Heal(ui, stack.Round); } }
public override void OnRoundEnding(IWorld world, IUserinterface ui, Guid round) { var inj = (IInjured)Owner; if (inj.InjurySystem.HasFatalInjuries(inj, out string reason)) { inj.InjurySystem.Kill(inj, ui, round, reason); } }
public override void Push(IWorld world, IUserinterface ui, ActionStack stack, IActor actor) { var chosen = PrimeWithTarget; if (chosen != null || actor.Decide(ui, "Pick Up", null, out chosen, GetTargets(actor).Cast <IItem>().ToArray(), 0)) { stack.Push(new PickUpFrame(actor, this, chosen, actor.CurrentLocation, 0)); } }
/// <summary> /// Runs the <paramref name="firstAction"/> and evaluates all responders. /// This overload shortcuts decision making and allows arbitrary action frames /// to run even when the <paramref name="performer"/> could not normally pick them /// (so be careful using it). /// </summary> /// <param name="world">Where the action is happening</param> /// <param name="ui">When decisions require user input, this handles it</param> /// <param name="firstAction">The initial action (to go on bottom of stack)</param> /// <param name="performer">Who is attempting <paramref name="firstAction"/></param> /// <param name="responders">All valid responders</param> public bool RunStack(IWorld world, IUserinterface ui, IAction firstAction, IActor performer, IEnumerable <IBehaviour> responders) { Behaviours = responders?.ToArray() ?? new IBehaviour[0]; //and run push event on the action firstAction.Push(world, ui, this, performer); return(RunStack(world, ui)); }
public void Setup() { _light = new Light(); _output = new Output(); _cookcontroller = new Cookcontroller(); _display = new Display(); _powertube = new Powertube(); _timer = new Timer(); _userinterface = new Userinterface(); }
protected override void PopImpl(IWorld world, IUserinterface ui, ActionStack stack, Frame frame) { var f = frame; //if we still have the item we should drop it if (f.PerformedBy.Items.Contains(f.TargetIfAny)) { ((IItem)f.TargetIfAny).Drop(ui, f.PerformedBy, stack.Round); } }
public override void OnRoundEnding(IWorld world, IUserinterface ui, Guid round) { RoundsSeen.Add(round); if (RoundsSeen.Count >= RoundsBeforeRemoval) { Adjective.Owner.Adjectives.Remove(Adjective); Adjective.BaseBehaviours.Remove(this); } }
public override void Push(IWorld world, IUserinterface ui, ActionStack stack, IActor actor) { if (Owner is IItem toGive || actor.Decide(ui, "Give", "Select an item to give", out toGive, GetTargets(actor).Cast <IItem>().ToArray(), -10)) { if (actor.Decide(ui, "To whom", $"Select who to give {toGive}", out IActor toGiveTo, actor.GetCurrentLocationSiblings(false), 10)) { stack.Push(new GiveFrame(actor, this, toGive, toGiveTo, GetItemWorthInAttitude(actor, toGive, toGiveTo))); } } }
public override void Push(IWorld world, IUserinterface ui, ActionStack stack, Wanderer.Actors.IActor actor) { if (ui.GetChoice("Destroy the world", null, out bool chosen, new [] { true, false })) { if (chosen) { stack.Push(new Frame(actor, this, 0)); } } }
protected override void PopImpl(IWorld world, IUserinterface ui, ActionStack stack, Frame frame) { var f = (CoerceFrame)frame; PrimeWithTarget = null; ((Npc)f.TargetIfAny).NextAction = f; f.TargetIfAny.Adjectives.Add(new Coerced(f)); ui.Log.Info(new LogEntry($"{f.PerformedBy} coerced {f.TargetIfAny} to perform {f.CoerceAction.Name}", stack.Round, frame.PerformedBy)); }
public override void OnPush(IWorld world, IUserinterface ui, ActionStack stack, Frame frame) { // For testing the condition var args = new ActionFrameSystemArgs(frame.PerformedBy, world, ui, stack, frame); foreach (var matchingFrame in stack.Where(a => a.Action is T && Condition.IsMet(world, args)).ToArray()) { var a = new ForbidAction(matchingFrame); a.Push(world, ui, stack, (IActor)Owner); } }
public ActionFrameSystemArgs(IHasStats source, IWorld world, IUserinterface ui, ActionStack stack, Frame frame) : base(source, world, ui, frame.PerformedBy, frame.TargetIfAny ?? frame.PerformedBy, stack.Round) { Stack = stack; Frame = frame; if (Action == null) { Action = frame.Action; } }
public override void Push(IWorld world, IUserinterface ui, ActionStack stack, IActor actor) { if (ValidatePick(actor, Owner, out string reason)) { stack.Push(new DialogueFrame(actor, this, Owner, 0)); } else { ui.ShowMessage("Not Possible", reason); } }
public override void Kill(IUserinterface ui, Guid round, string reason) { //although you might get double dead in a round. Only show the message once if (!Dead) { var narrative = new Narrative(this, "Dead", $"You have tragically met your end. Don't worry, many of your comrades will benefit from you sacrifice (at breakfast tomorrow).", $"You died of {reason}", round); narrative.Show(ui, true); } Dead = true; }
public override bool Decide <T>(IUserinterface ui, string title, string body, out T chosen, T[] options, double attitude) { if (Dead) { chosen = default; return(false); } //if we are being asked to pick an action and we have a coercion if (typeof(IAction).IsAssignableFrom(typeof(T)) && NextAction != null) { //if it is the first time we are being asked what to do (action) after coercion if (!NextAction.Chosen) { //pick the coerced act chosen = (T)NextAction.CoerceAction; NextAction.Chosen = true; //and mark that we are not going to pick it again return(true); } //we have already attempted the coerced action, clear it NextAction = null; } //if we are mid coercion we must let the coercer pick targets. //when picking targets the coercer should know the Attitude (how kind) //the action they are forcing is (in order to pick a good target) if (NextAction != null) { return(NextAction.PerformedBy.Decide(ui, title, body, out chosen, options, NextAction.Attitude)); } List <T> narrowOptions = new List <T>(options); if (typeof(T) == typeof(IActor)) { narrowOptions = DecideActor(narrowOptions.OfType <IActor>(), attitude).Cast <T>().ToList(); } //If there are no options pick null return false if (!narrowOptions.Any()) { chosen = default; return(false); } //pick random option chosen = narrowOptions[CurrentLocation.World.R.Next(0, narrowOptions.Count)]; //if picked option was default (e.g. None Enums) return false return(!chosen.Equals(default(T))); }