Esempio n. 1
0
        protected override IInteraction Apply(HengeInteraction interaction)
        {
            //TODO: Need to check if the Actor is a logged-out Avatar and give them bonuses if so.
            if (this.Validate(interaction) && !interaction.Finished)
            {
                Actor actor			= interaction.Antagonist as Actor;
                Trait health		= actor.Traits["Health"];
                Trait energy		= actor.Traits["Energy"];
                Trait reserve		= actor.Traits["Reserve"];
                Trait constitution	= actor.Traits["Constitution"];
                string message		= "you rested and recuperated a little";
                double constDelta	= Constants.Tick.MetabolicRate;
                double healthDelta	= (health.Value < health.Maximum) ? Constants.Tick.Healthy.Heal : 0;
                double energyDelta	= (reserve.Value < reserve.Maximum) ? Constants.Tick.Healthy.Revitalise : 0;
                constDelta+= (healthDelta + energyDelta);

                if (constitution.Value <= 0)
                {
                    // Decrease Health, increase Energy by less
                    healthDelta	= Constants.Tick.Ill.Heal;
                    energyDelta	= Constants.Tick.Ill.Revitalise;
                    constDelta	= -constDelta;
                    message		= "you felt weaker";

                    // Increase Constitution
                    if (constitution.Value == 0) constDelta = 0;
                }

                if (health.Value + healthDelta < 0)
                {
                    using (interaction.Lock(health, reserve, energy, constitution, actor.Ticks))
                    {
                        //When the actor dies, all ticks should be cancelled
                        actor.Ticks.Clear();
                        health.SetValue(0);
                        energy.SetValue(0);
                        reserve.SetValue(0);
                        constitution.SetValue(constitution.Minimum);
                        health.Flavour = "Dead";
                    }
                    interaction.Success("you succumbed to your ailments. Your story is over... will your line continue?");
                }
                else
                {
                    using (interaction.Lock(health, reserve, constitution))
                    {
                        health.SetValue(health.Value + healthDelta);
                        reserve.SetValue(reserve.Value + energyDelta);
                        constitution.SetValue(constitution.Value - constDelta);
                    }
                    interaction.Success(message);
                }
            }
            return interaction;
        }
Esempio n. 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;
        }
Esempio n. 3
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;
        }
Esempio n. 4
0
File: Talk.cs Progetto: justen/henge
        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;
        }
Esempio n. 5
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;
        }
Esempio n. 6
0
        protected void ApplyInteraction(HengeInteraction interaction, Actor actor, Location target)
        {
            int dx					= actor.Location.X - target.X;
            int dy 					= actor.Location.Y - target.Y;
            char [] inDirection		= new char [] {
                (dx > 0) ? 'e' : (dx < 0) ? 'w' : '-',
                (dy > 0) ? 's' : (dy < 0) ? 'n' : '-'
            };

            char [] outDirection		= new char [] {
                (dx < 0) ? 'e' : (dx > 0) ? 'w' : '-',
                (dy < 0) ? 's' : (dy > 0) ? 'n' : '-'
            };
            double baseTrack =  actor.Traits.ContainsKey("Tracks")? actor.Traits["Tracks"].Value : Constants.BaseTrack;
            double trackOut = baseTrack * (actor.Location.Traits.ContainsKey("Tracks")?actor.Location.Traits["Tracks"].Value : 0);
            double trackIn = baseTrack * (target.Traits.ContainsKey("Tracks")?target.Traits["Tracks"].Value : 0);

            if (actor is Avatar)
            {
                Dictionary<string, int> timesIn = new Dictionary<string, int>();
                Dictionary<string, int> timesOut = new Dictionary<string, int>();
                foreach(Trait track in target.TracesOut)
                {
                    if (DateTime.Now<(DateTime)(track.Expiry))
                    {
                        Actor person = track.Subject as Actor;
                        if (timesOut.ContainsKey(person.Name))
                        {
                            timesOut[person.Name]++;
                        }
                        else timesOut.Add(person.Name, 1);
                    }
                }
                foreach(Trait track in target.TracesIn)
                {
                    if(DateTime.Now<(DateTime)(track.Expiry))
                    {
                        Actor person = track.Subject as Actor;
                        if (timesIn.ContainsKey(person.Name))
                        {
                            timesIn[person.Name]++;
                        }
                        else timesIn.Add(person.Name, 1);
                    }
                }
                bool beenHere = false;
                foreach(string name in timesIn.Keys)
                {
                    if (name!=actor.Name)
                    {
                        int outTimes = timesOut.ContainsKey(name)?timesOut[name] : 0;
                        int totalTraffic = timesIn[name] + outTimes;
                        if (totalTraffic <3)
                        {
                            interaction.Log += (name + " has been here. ");
                        }
                        else
                        {
                            if (totalTraffic < 6)
                            {
                                interaction.Log += (name + " has been here more than once. ");
                            }
                            else
                            {
                                interaction.Log += (name + " has been here frequently. ");
                            }
                        }
                        if (outTimes < timesIn[name]) interaction.Log += "You cannot see any of their tracks leading away. ";
                    }
                    else beenHere = true;
                }
                if (timesOut.ContainsKey(actor.Name))
                {
                    beenHere = true;
                }
                if (beenHere) interaction.Log += " It looks like you've been here before. ";
                Avatar avatar = actor as Avatar;
                                //potential bottleneck here - may want to do smarter locking
                using (interaction.Lock(avatar, avatar.Location.Inhabitants, target.Inhabitants, avatar.Location.TracesOut, target.TracesIn))
                {
                    this.AddTracks(avatar.Location, avatar, false, outDirection.ToString(), trackOut, interaction);
                    this.AddTracks(target, avatar, true, inDirection.ToString(), trackIn, interaction);
                    avatar.Location.Inhabitants.Remove(avatar);
                    target.Inhabitants.Add(avatar);
                    avatar.Location = target;

                }
                interaction.Success(string.Format("You reach your destination, a {0}", target.Inspect(avatar).ShortDescription));
            }
            else
            {
                Npc npc = actor as Npc;

                using (interaction.Lock(npc, npc.Location.Fauna, target.Fauna, npc.Location.TracesOut, target.TracesIn))
                {
                    this.AddTracks(npc.Location, npc, false, outDirection.ToString(), trackOut, interaction);
                    this.AddTracks(target, npc, true, inDirection.ToString(), trackIn, interaction);
                    npc.Location.Fauna.Remove(npc);
                    target.Fauna.Add(npc);
                    npc.Location = target;
                }

                interaction.Success("Moved");
            }
        }
Esempio n. 7
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;
        }