Пример #1
0
 protected override bool Validate(HengeInteraction interaction)
 {
     bool result = false;
     if (!interaction.Finished)
     {
         if (interaction.Antagonist != null)
         {
                 if (interaction.Antagonist.Traits.ContainsKey("Health") && interaction.Antagonist.Traits["Health"].Flavour=="Dead")
                 {
                     interaction.Failure("You are dead", false);
                 }
                 else result = true;
         }
         else interaction.Failure("Interactors are invalid", true);
     }
     return result;
 }
Пример #2
0
        protected override IInteraction Apply(HengeInteraction interaction)
        {
            Location antagonist	= interaction.Antagonist as Location;
                double tariff = antagonist.Traits.ContainsKey("Impede")? antagonist.Traits["Impede"].Value : Constants.Impedance;
                double difficulty = antagonist.Traits["Movement"].Value / Constants.MaxMovementDifficulty;
                double successTariff = tariff - (1-tariff) * (interaction.Protagonist.Skills.ContainsKey("Swim")? interaction.Protagonist.Skills["Swim"].Value : 0);

                interaction.Actions.Add( ()=>{
                switch (interaction.ProtagonistCache.SkillCheck("Swim", difficulty+interaction.Difficulty, successTariff+interaction.Impedance, tariff+interaction.Impedance, EnergyType.Strength))
                {
                case SkillResult.PassExhausted:
                    if (interaction.Protagonist.Location.Traits.ContainsKey("Movement") && (interaction.Protagonist.Location.Traits["Movement"].Flavour=="Swim"))
                        interaction.Failure("You feel you are too weak to swim that far, and tread water while your strength returns.", false);
                    else interaction.Failure("You begin to swim, but realise you are too tired to swim that far. You return to dry land while you gather your strength", false);
                    break;
                case SkillResult.PassSufficient:
                    interaction.Log+=("You swim strongly through the water. ");
                    break;
                default:
                    interaction.Log+= ("You struggle to keep your head above the water. You cough and splutter, panicking, as you realise you can't breathe. ");
                    Trait health = interaction.Protagonist.Traits["Health"];
                    Trait constitution = interaction.Protagonist.Traits["Constitution"];
                    using (interaction.Lock(interaction.Protagonist, health, constitution))
                    {
                        health.Value -= 2;
                        constitution.Value -= 4;
                        if (health.Value<=0) health.Flavour = "Dead";
                    }
                    if (health.Flavour=="Dead")	interaction.Failure("The light of the surface fades above you. Your struggles subside as your breath runs out. You have died.", false);
                    else
                    {
                        if (interaction.Protagonist.Location.Traits.ContainsKey("Movement") && (interaction.Protagonist.Location.Traits["Movement"].Flavour=="Swim"))
                            interaction.Failure("As you flounder, the currents carry you back the way you came", false);
                        else interaction.Failure("As you flounder, the currents carry you back to shore. You haul yourself back out of the water, gasping for breath", false);
                    }
                    break;
                }
                });
                if (!(interaction.Protagonist.Location.Traits.ContainsKey("Movement") && interaction.Protagonist.Location.Traits["Movement"].Flavour == "Swim"))
                {
                    this.AddTransition(interaction);
                }
                this.AddGuards(interaction);
            return interaction;
        }
Пример #3
0
 protected override IInteraction Apply(HengeInteraction interaction)
 {
     if (this.Validate(interaction))
     {
         if (!interaction.Antagonist.Traits.ContainsKey("Nutrition"))
             interaction.Failure("After a mighty struggle with yourself, you are forced to admit that you cannot bring yourself to try to eat that", false);
     }
     return interaction;
 }
Пример #4
0
        protected override IInteraction Apply(HengeInteraction interaction)
        {
            if (this.Validate(interaction))
            {

                Location antagonist	= interaction.Antagonist as Location;
                double tariff = antagonist.Traits.ContainsKey("Impede")? antagonist.Traits["Impede"].Value : Constants.Impedance;
                double difficulty = antagonist.Traits["Movement"].Value / Constants.MaxMovementDifficulty;
                double successTariff = tariff - (1-tariff) * (interaction.Protagonist.Skills.ContainsKey("Climb")? interaction.Protagonist.Skills["Climb"].Value : 0);

                interaction.Actions.Add( ()=>{
                    switch (interaction.ProtagonistCache.SkillCheck("Climb", difficulty+interaction.Difficulty, successTariff+interaction.Impedance, tariff+interaction.Impedance, EnergyType.Strength))
                    {
                    case SkillResult.PassExhausted:
                        interaction.Failure("You can see a likely-looking route over the rocks, but are too tired to follow it. You turn back.", false);
                        break;
                    case SkillResult.PassSufficient:
                        interaction.Log+=("You climb over the rocks. ");
                        break;
                    default:
                        interaction.Log+=("You slip as you climb across the rocks, falling painfully. ");
                        Trait health = interaction.Protagonist.Traits["Health"];
                        Trait constitution = interaction.Protagonist.Traits["Constitution"];
                        using (interaction.Lock(interaction.Protagonist, health, constitution))
                        {
                            health.Value -= 3;
                            constitution.Value -= 3;
                            if (health.Value<=0)
                            {
                                constitution.Value = constitution.Minimum;
                                health.Flavour = "Dead";
                            }
                        }
                        if (health.Flavour=="Dead")	interaction.Failure("You land badly. The fall is enough to kill you.", false);
                        else interaction.Failure("Defeated, you turn back", false);
                        break;
                    }
                });

                this.AddGuards(this.AddTransition(interaction));
            }
            return interaction;
        }
Пример #5
0
        protected IInteraction Climb(HengeInteraction interaction)
        {
            if(this.Validate(interaction))
            {

                Location antagonist	= interaction.Antagonist as Location;
                Actor protagonist = interaction.Protagonist;
                double tariff = 0.25 * (protagonist.Location.Traits.ContainsKey("Impede")? protagonist.Location.Traits["Impede"].Value : Constants.Impedance);
                double difficulty = 0.5 * protagonist.Location.Traits["Movement"].Value / Constants.MaxMovementDifficulty;
                double successTariff = tariff - (1-tariff) * (protagonist.Skills.ContainsKey("Climb")? protagonist.Skills["Climb"].Value : 0);
                switch (interaction.ProtagonistCache.SkillCheck("Climb", difficulty, successTariff, tariff, EnergyType.Strength))
                    {
                    case SkillResult.PassExhausted:
                        interaction.Log = string.Empty;
                        interaction.Failure("You feel too weak to set out; you pause to gather your strength.", false);
                        break;
                    case SkillResult.PassSufficient:
                        interaction.Log=string.Format("You climb across the {0}. {1}", interaction.Protagonist.Location.Inspect(interaction.Protagonist).ShortDescription, interaction.Log);

                        break;
                    default:
                        interaction.Log = string.Empty;
                        interaction.Failure("The terrain is too difficult for you to climb through. You appear to be trapped", false);
                        break;
                    }

                if (!interaction.Finished)
                {
                    foreach (Action action in interaction.Actions)
                    {
                        if (interaction.Finished) break;
                        else action.Invoke();
                    }
                }
                if (!interaction.Finished)
                {
                    this.ApplyInteraction(interaction, interaction.Protagonist, antagonist);
                }
            }
            return interaction;
        }
Пример #6
0
 protected override IList<Component> PrepareFindList(HengeInteraction interaction, double perception)
 {
     ComponentType type = interaction.Arguments["ItemType"] as ComponentType;
     IList<Component> hiddenItems = new List<Component>();
     if (type!=null)
     {
         (interaction.Antagonist as Location).Inventory
         .Where(c => c.Type == type && c.Traits.ContainsKey("Visibility") && c.Traits["Visibility"].Value < perception).ToList()
         .ForEach(c => hiddenItems.Add(c));
     }
     else interaction.Failure("You don't know what you're looking for", true);
     return hiddenItems;
 }
Пример #7
0
        protected override IInteraction Apply(HengeInteraction interaction)
        {
            if (!interaction.Finished && this.Validate(interaction))
            {
                if (interaction.ProtagonistCache.UseEnergy(Constants.TalkCost, EnergyType.None))
                {
                    if (interaction.Arguments.ContainsKey("Message"))
                    {
                        List<Avatar> recipients	= interaction.Arguments["Recipients"] as List<Avatar>;
                        if (recipients==null) recipients = new List<Avatar>();

                        string target		= (recipients.Count > 1) ? "out loud" : "to you";
                        string message		= string.Format("{0} says \"{1}\" {2}.", interaction.Protagonist.Name, interaction.Arguments["Message"] as string, target);
                        DateTime occurred	= DateTime.Now;
                        foreach (Avatar recipient in recipients)
                        {
                            //Log the speech
                            using (interaction.Lock(recipient.Log))
                            {
                                // Possibly inefficient to lock each recipient's log individually. Also, shouldn't
                                // we be using the relational DB for this sort of thing?
                                recipient.Log.Add(new LogEntry(){ Entry = message, Occurred = occurred});
                            }
                        }
                        if (recipients.Count == 1)
                        {
                            target = string.Format("to {0}", recipients[0].Name);
                        }
                        interaction.Success(string.Format("You say \"{0}\" {0}.", interaction.Arguments["Message"], target));
                    }
                    else interaction.Failure("You have nothing to say", false);
                }
                else interaction.Failure("You are too tired even to speak", false);
            }
            return interaction;
        }
Пример #8
0
 protected override IInteraction Apply(HengeInteraction interaction)
 {
     if (this.Validate(interaction))
     {
         Actor protagonist = interaction.Protagonist as Actor;
         if (protagonist.Location == interaction.Antagonist)
         {
             //potentially want to check for interferers here
             IList<Component> hiddenItems = new List<Component>();
             double perception = 1 - (protagonist.Skills.ContainsKey("Perception")? protagonist.Skills["Perception"].Value : Constants.DefaultSkill);
             this.PrepareFindList(interaction, perception);
             Constants.Randomise(hiddenItems);
             interaction.Arguments.Add("Items", hiddenItems);
         }
         else interaction.Failure("You're unable to search a location you aren't in", true);
     }
     return interaction;
 }
Пример #9
0
        protected override IInteraction Apply(HengeInteraction interaction)
        {
            if (this.Validate(interaction))
            {
                Location venue	= ((Actor)interaction.Protagonist).Location;
                Item antagonist = interaction.Antagonist as Item;

                //check no one is guarding the item, if they are then add them to the interferers list
                if (venue.Inventory.Contains(antagonist))
                {
                    venue.Fauna
                        .Where(c => c.Traits.ContainsKey("Guard") && c.Traits["Guard"].Subject == antagonist).ToList()
                        .ForEach(c => interaction.Interferers.Add(c));
                    venue.Inhabitants
                        .Where(c => c.Traits.ContainsKey("Guard") && c.Traits["Guard"].Subject == antagonist).ToList()
                        .ForEach(c => interaction.Interferers.Add(c));

                    if (interaction.Interferers.Any()) Constants.Randomise(interaction.Interferers);
                }
                else interaction.Failure("The item is no longer here", false);
            }
            return interaction;
        }
Пример #10
0
        protected override IInteraction Apply(HengeInteraction interaction)
        {
            if (!interaction.Finished && this.Validate(interaction))
            {
                Item food			= interaction.Antagonist as Item;
                Actor actor 		= interaction.Protagonist as Actor;
                double nutrition	= food.Traits["Nutrition"].Value;

                if (nutrition > 0)
                {
                    interaction.Success(string.Format("You eat the {0} with relish", food.Inspect(actor)));
                }
                else
                {
                    if (nutrition == 0) interaction.Success(string.Format("You eat the {0}", food.Inspect(actor)));
                    else interaction.Success(string.Format("You eat the {0}. You feel queasy.", food.Inspect(actor)));
                }

                if (food.Owner == actor)
                {
                    Trait weight 		= actor.Traits["Weight"];
                    Trait constitution	= actor.Traits["Constitution"];

                    using (interaction.Lock(actor.Inventory, weight, constitution))
                    {
                        weight.SetValue(weight.Value - food.Traits["Weight"].Value);
                        constitution.SetValue(constitution.Value + nutrition);
                        actor.Inventory.Remove(food);
                    }
                    interaction.Delete(food);
                }
                else interaction.Failure("You no longer have that", true);

            }
            return interaction;
        }
Пример #11
0
        protected new bool Validate(HengeInteraction interaction)
        {
            bool result = false;
            if (!interaction.Finished)
            {
                Location antagonist	= interaction.Antagonist as Location;
                Location source		= interaction.Protagonist.Location;
                if (base.Validate(interaction))
                {
                    if (this.CalculateDistance(source, antagonist) <= 2)
                    {
                        result = true;
                    }
                    else interaction.Failure("You cannot move that far", true);
                }

            }
            return result;
        }
Пример #12
0
        protected IInteraction Move(HengeInteraction interaction)
        {
            // structure of this rule is
            //
            //  IF (ConditionsMet(protagonist, antagonists, interaction))
            //  THEN ApplyChanges (protagonist, antagonists, interaction)
            //
            if (this.Validate(interaction))
            {
                Location antagonist	= interaction.Antagonist as Location;
                Location source		= interaction.Protagonist.Location;
                double impedance = 0.25 * (source.Traits.ContainsKey("Impede") ? source.Traits["Impede"].Value : Constants.Impedance);
                if (!interaction.ProtagonistCache.UseEnergy(impedance, EnergyType.Fitness))
                {
                    interaction.Log = string.Empty;
                    if (impedance > interaction.ProtagonistCache.Strength * interaction.Protagonist.Traits["Energy"].Maximum)
                    {

                        interaction.Failure("You seem to be trapped.", false);
                    }
                    else interaction.Failure("You are unable to summon sufficient energy to set out", false);

                }
                else
                {
                    interaction.Log = string.Format("You set off through the {0}. {1}", source.Inspect(interaction.Protagonist).ShortDescription, interaction.Log);
                    foreach (Action action in interaction.Actions)
                    {
                        if (interaction.Finished) break;
                        else action.Invoke();
                    }
                }
                if (!interaction.Finished)
                {
                    this.ApplyInteraction(interaction, interaction.Protagonist, antagonist);
                }

            }

            return interaction;
        }
Пример #13
0
        protected override IInteraction Apply(HengeInteraction interaction)
        {
            if (this.Validate(interaction) )
            {
                if ( interaction.ProtagonistCache.Energy > 0)
                {
                    Actor protagonist	= interaction.Protagonist as Actor;
                    Location source		= protagonist.Location;
                    Location target		= interaction.Antagonist as Location;

                    if (target.Map == source.Map)
                    {
                        if (source.CanSee(target))
                        {
                            double dx			= target.X - source.X;
                            double dy			= target.Y - source.Y;
                            double distance		= dx * dx + dy * dy;
                            double sourceCover	= source.Traits.ContainsKey("Cover") ? source.Traits["Cover"].Value : Constants.DefaultCover;
                            double targetCover	= target.Traits.ContainsKey("Cover") ? target.Traits["Cover"].Value : Constants.DefaultCover;
                            distance			= distance * Math.Max(sourceCover, targetCover);
                            double detection	= protagonist.Skills["Perception"].Value;
                            double difficulty	= distance * Constants.EdificeScouting;
                            int success = 0;
                            bool weary = false;

                            switch (interaction.ProtagonistCache.SkillCheck("Perception", distance * Constants.LocationScouting, Constants.ScoutCost, Constants.ScoutCost, EnergyType.Concentration))
                            {
                            case SkillResult.PassSufficient:
                                    interaction.Results.Add("Location", target);
                                    success=1;
                                    break;
                            case SkillResult.FailSufficient: break;
                            default: weary = true; break;
                            }
                            switch (interaction.ProtagonistCache.SkillCheck("Perception", difficulty, Constants.ScoutCost, Constants.ScoutCost, EnergyType.Concentration))
                            {
                            case SkillResult.PassSufficient:
                                    success++;
                                    interaction.Results.Add("Structures", target.Structures.Where(c => c.Traits.ContainsKey("Visibility") && c.Traits["Visibility"].Value >= detection - difficulty).ToList());
                                    difficulty = distance * Constants.ActorScouting;
                                    break;
                            case SkillResult.FailSufficient: break;
                            default: weary = true; break;
                            }
                            switch (interaction.ProtagonistCache.SkillCheck("Perception", difficulty, Constants.ScoutCost, Constants.ScoutCost, EnergyType.Concentration))
                            {
                            case SkillResult.PassSufficient:
                                        difficulty = detection - difficulty;
                                        interaction.Results.Add("NPCs", target.Fauna.Where(c => c.Traits.ContainsKey("Visibility") && c.Traits["Visibility"].Value >= difficulty).ToList());
                                        interaction.Results.Add("Avatars", target.Inhabitants.Where(c => c.Traits.ContainsKey("Visibility") && c.Traits["Visibility"].Value >= difficulty).ToList());
                                        success ++;
                                        break;
                            case SkillResult.FailSufficient: break;
                            default: weary = true; break;
                            }
                            if (weary) interaction.Log+="Your tired eyes may not be trustworthy, but you";
                            else interaction.Log+= "You ";
                            switch (success)
                            {
                            case 3: interaction.Success("feel that you have a good view of the area");
                                    break;
                            case 2: interaction.Success("can see the area reasonably well");
                                    break;
                            case 1: interaction.Success("can just about make out the terrain");
                                    break;
                            default: interaction.Failure("can't make anything out", false); break;
                            }
                        }
                        else interaction.Failure("You can't see from here", false);
                    }
             		else interaction.Failure("You are attempting to scout a location you cannot see", true);
                } else interaction.Failure("You are too tired to focus on scouting", false);
            }
            return interaction;
        }
Пример #14
0
        protected override IInteraction Apply(HengeInteraction interaction)
        {
            if (!interaction.Finished && this.Validate(interaction))
            {
                Actor protagonist		= interaction.Protagonist as Actor;
                Component antagonist	= interaction.Antagonist;

                //Hiding a Location is dumb, and will just fail.
                if (antagonist is Location)
                {
                    interaction.Failure("You cannot hide a location", true);
                }
                else
                {
                    //You can try to hide pretty much anything else.
                    //I suspect hiding a building is going to be a bit very impossible,
                    //but we can handle that by simply giving Edifices very, very large Conspicuousness values.
                    //Difficulty of hiding something depends upon
                    // 1) Conspicuousness of the thing being hidden
                    // 2) Things interfering
                    // - Up to this point, the running total is cached in interaction.Impedance -
                    // 3) The "Cover" trait of the Location - even if you're useless at hiding stuff, this could make it easier
                    // 4) The protagonists "Hide" skill

                    double visibility = Constants.StandardVisibility;

                    //This is going to cost us Some Energy. The better we hid it, the more effort it took, so...
                    double maxEnergy	= interaction.Protagonist.Traits["Energy"].Maximum;
                    double best			= interaction.ProtagonistCache.Energy / maxEnergy;
                    double randomNumber	= Constants.RandomNumber;
                    randomNumber		= (randomNumber > best) ? best : randomNumber;

                    if (randomNumber > 0)
                    {

                        //So, the worst-case visibility is now known.
                        //difficulty is in Impedance, need to modify it by the cover available:
                        switch (interaction.ProtagonistCache.SkillCheck("Hide", interaction.Impedance / protagonist.Location.Traits["Cover"].Value, randomNumber * maxEnergy, randomNumber * maxEnergy, EnergyType.Concentration))
                        {
                        case SkillResult.PassSufficient:
                            //You've hidden it. But how well?
                            //Let's add our rng result to the hide skill and divide by two
                            visibility -= visibility * (interaction.Protagonist.Skills.ContainsKey("Hide") ? 0.5 * (randomNumber + interaction.Protagonist.Skills["Hide"].Value) : 0.5 * randomNumber);

                            if (antagonist is Avatar)	interaction.Success(string.Format("You attempt to conceal {0}", antagonist.Name));
                            else 						interaction.Success(string.Format("You attempt to conceal the {0}", antagonist.Inspect(protagonist).ShortDescription));
                            break;

                        case SkillResult.PassExhausted:
                            interaction.Failure("You are too tired", false);
                            break;

                        default: interaction.Failure("Your skill at concealing things isn't up to the task", false);
                            break;
                        }
                        visibility *= interaction.AntagonistCache.Conspicuousness;
                        if (antagonist is Item && (antagonist as Item).Owner == protagonist)
                        {
                            Item item 				= antagonist as Item;
                            Trait protagonistWeight = protagonist.Traits["Weight"];

                            using (interaction.Lock(protagonist.Location.Inventory, item, protagonistWeight, protagonist.Inventory))
                            {
                                protagonist.Location.Inventory.Add(item);
                                item.Owner = protagonist.Location;
                                protagonist.Traits["Weight"].SetValue(protagonist.Traits["Weight"].Value - item.Traits["Weight"].Value);
                                protagonist.Inventory.Remove(item);
                            }
                        }
                        using (interaction.Lock(antagonist.Traits))
                        {
                            if (antagonist.Traits.ContainsKey("Visibility"))
                            {
                                // Not sure how safe it is to use recursive locking?
                                using (interaction.Lock(antagonist.Traits["Visibility"]))
                                {
                                    antagonist.Traits["Visibility"].SetValue(visibility);
                                }
                            }
                            else antagonist.Traits.Add("Visibility", new Trait(double.MaxValue, 0, visibility));

                        }
                    }
                    else
                    {
                        interaction.Failure("You can see nowhere to hide that", false);
                    }
                }
            }
            return interaction;
        }