| @@ -0,0 +1,42 @@ | ||
| using System; | ||
| using Lain.Utils; | ||
| using Microsoft.Xna.Framework; | ||
| using RnR.Systems.D20; | ||
| using SadConsole; | ||
|
|
||
| namespace RnR.Consoles | ||
| { | ||
| public class LeftCombatStatusConsole : AbstractCombatStatusConsole | ||
| { | ||
| public LeftCombatStatusConsole (GameCharacter character, int w, int h) | ||
| : base (character, w, h) | ||
| { | ||
| } | ||
|
|
||
| protected override void RenderStatus () | ||
| { | ||
| Clear (); | ||
|
|
||
| VirtualCursor.Position = new Point (4, STARTY); | ||
| VirtualCursor.Print (Character.Name); | ||
|
|
||
| if (IsSelected) | ||
| (new CellAppearance (Color.White, Color.Transparent, 17)).CopyAppearanceTo (this [(int)Math.Floor(Width * 0.6), STARTY]); | ||
|
|
||
| // Draw health bar | ||
| VirtualCursor.Position = new Point (4, STARTY + 2); | ||
| var hitPointsPerc = (int)Math.Floor (((float)Character.HitPoints / (float)Character.MaxHitPoints) * 10.0); | ||
|
|
||
| var g = new CellAppearance (Color.Transparent, Color.Green, 0); | ||
| var dg = new CellAppearance (Color.Transparent, MaterialColors.Green900, 0); | ||
|
|
||
| for (int i = 0; i < hitPointsPerc; i++) | ||
| g.CopyAppearanceTo (this [i + 4, STARTY + 2]); | ||
| for (int i = hitPointsPerc; i < 10; i++) | ||
| dg.CopyAppearanceTo (this [i + 4, STARTY + 2]); | ||
|
|
||
| VirtualCursor.Position = new Point (15, STARTY + 2); | ||
| VirtualCursor.Print (string.Format ("{0}/{1}", Character.HitPoints, Character.MaxHitPoints)); | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,47 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Runtime.Serialization; | ||
| using Microsoft.Xna.Framework; | ||
| using SadConsole; | ||
|
|
||
| namespace RnR.Consoles | ||
| { | ||
| [DataContract] | ||
| public class MenuConsole : SadConsole.Consoles.Console | ||
| { | ||
| [DataMember] | ||
| List<MenuItem> items; | ||
| const int STARTX = 1; | ||
| const int STARTY = 1; | ||
|
|
||
| [DataMember] | ||
| CellAppearance selectedCellAppearance; | ||
|
|
||
| public MenuConsole (List<MenuItem> items, int w, int h) | ||
| : base (w, h) | ||
| { | ||
| this.items = items; | ||
|
|
||
| selectedCellAppearance = new CellAppearance (Color.White, Color.Transparent, 16); | ||
| } | ||
|
|
||
| public override void Render () | ||
| { | ||
| base.Render (); | ||
|
|
||
| Clear (); | ||
|
|
||
| int i = STARTY; | ||
| foreach (MenuItem item in items) { | ||
| if (item.Selected) { | ||
| selectedCellAppearance.CopyAppearanceTo (this [STARTX, i]); | ||
| } | ||
|
|
||
| VirtualCursor.Position = new Point (STARTX + 2, i); | ||
| VirtualCursor.Print (item.Entry); | ||
|
|
||
| i += 2; | ||
| } | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,17 @@ | ||
| using System; | ||
| namespace RnR.Consoles | ||
| { | ||
| public class MenuItem | ||
| { | ||
| public MenuItem (int id, string entry, bool selected) | ||
| { | ||
| Id = id; | ||
| Entry = entry; | ||
| Selected = selected; | ||
| } | ||
|
|
||
| public int Id { get; set; } | ||
| public string Entry { get; set; } | ||
| public bool Selected { get; set; } | ||
| } | ||
| } |
| @@ -0,0 +1,53 @@ | ||
| using System; | ||
| using Lain.Utils; | ||
| using Microsoft.Xna.Framework; | ||
| using RnR.Systems.D20; | ||
| using SadConsole; | ||
| using SadConsole.Consoles; | ||
|
|
||
| namespace RnR.Consoles | ||
| { | ||
| public class PartyStatusConsole : SadConsole.Consoles.Console | ||
| { | ||
| Party party; | ||
|
|
||
| public PartyStatusConsole (Party party, int w, int h) | ||
| : base (w, h) | ||
| { | ||
| this.party = party; | ||
| } | ||
|
|
||
| public override void Render () | ||
| { | ||
| base.Render (); | ||
|
|
||
| Clear (); | ||
|
|
||
| int i = 1; | ||
| foreach (GameCharacter c in party) { | ||
| VirtualCursor.Position = new Point (1, i); | ||
| VirtualCursor.Print (c.Name); | ||
|
|
||
| //VirtualCursor.Position = new Point (1, i + 2); | ||
|
|
||
| var hitPointsPerc = (int)Math.Floor (c.HitPoints / (float)c.MaxHitPoints * Math.Min(20, (Width - 2))); | ||
|
|
||
| var g = new CellAppearance (Color.Transparent, Color.Green, 0); | ||
| var dg = new CellAppearance (Color.Transparent, MaterialColors.Green900, 0); | ||
|
|
||
| for (int j = 0; j < hitPointsPerc; j++) | ||
| g.CopyAppearanceTo (this [j + 1, i + 2]); | ||
| for (int j = hitPointsPerc; j < Math.Min (20, (Width - 2)); j++) | ||
| dg.CopyAppearanceTo (this [j + 1, i + 2]); | ||
|
|
||
| if (c == party.Leader) { | ||
| VirtualCursor.Position = new Point (3, i + 4); | ||
| VirtualCursor.Print ("Leader"); | ||
| } | ||
|
|
||
| i += 6; | ||
| //break; | ||
| } | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,46 @@ | ||
| using System; | ||
| using Lain.Utils; | ||
| using Microsoft.Xna.Framework; | ||
| using RnR.Systems.D20; | ||
| using SadConsole; | ||
|
|
||
| namespace RnR.Consoles | ||
| { | ||
| public class RightCombatStatusConsole : AbstractCombatStatusConsole | ||
| { | ||
| public RightCombatStatusConsole (GameCharacter character, int w, int h) | ||
| : base (character, w,h) | ||
| { | ||
| } | ||
|
|
||
| protected override void RenderStatus () | ||
| { | ||
| Clear (); | ||
| VirtualCursor.Position = new Point (STARTX, STARTY); | ||
|
|
||
| // Draw cursor if selected | ||
| if (IsSelected) | ||
| (new CellAppearance (Color.White, Color.Transparent, 16)).CopyAppearanceTo ( | ||
| this [VirtualCursor.Position.X, VirtualCursor.Position.Y]); | ||
|
|
||
| // Draw name | ||
| VirtualCursor.Position = new Point (4, STARTY); | ||
| VirtualCursor.Print (Character.Name); | ||
|
|
||
| // Draw health bar | ||
| VirtualCursor.Position = new Point (4, STARTY + 2); | ||
| var hitPointsPerc = (int)Math.Floor (((float)Character.HitPoints / (float)Character.MaxHitPoints) * 10.0); | ||
|
|
||
| var g = new CellAppearance (Color.Transparent, Color.Green, 0); | ||
| var dg = new CellAppearance (Color.Transparent, MaterialColors.Green900, 0); | ||
|
|
||
| for (int i = 0; i < hitPointsPerc; i++) | ||
| g.CopyAppearanceTo (this [i + 4, STARTY + 2]); | ||
| for (int i = hitPointsPerc; i < 10; i++) | ||
| dg.CopyAppearanceTo (this [i + 4, STARTY + 2]); | ||
|
|
||
| VirtualCursor.Position = new Point (15, STARTY + 2); | ||
| VirtualCursor.Print (string.Format ("{0}/{1}", Character.HitPoints, Character.MaxHitPoints)); | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,51 @@ | ||
| using Lain; | ||
| using Microsoft.Xna.Framework.Input; | ||
| using RnR.Actions; | ||
|
|
||
| namespace RnR.Scenes | ||
| { | ||
| public class AskingForActionState : CombatSceneState | ||
| { | ||
| bool actionSelected; | ||
| IAction selectedAction; | ||
|
|
||
| CombatSceneContext context; | ||
|
|
||
| public AskingForActionState (CombatSceneContext context) | ||
| { | ||
| this.context = context; | ||
|
|
||
| context.AvailableActions.Clear (); | ||
| context.AvailableActions.Add ("(a) Attack"); | ||
|
|
||
| actionSelected = false; | ||
| } | ||
|
|
||
| public void HandleInput () | ||
| { | ||
| KeyboardState s = Keyboard.GetState (); | ||
|
|
||
| if (s.IsKeyDown (Keys.A)) { | ||
| actionSelected = true; | ||
| selectedAction = new AttackAction (context.Log); | ||
| } | ||
| } | ||
|
|
||
| public void Update () | ||
| { | ||
| var gc = context.It.Current; | ||
|
|
||
| context.PlayerPartyStatusConsoles.ForEach ((statusConsole) => { | ||
| statusConsole.IsSelected = statusConsole.Character == gc; | ||
| }); | ||
|
|
||
| if (actionSelected) { | ||
| context.Actions [gc] = selectedAction; | ||
| if (selectedAction is AttackAction) { | ||
| (selectedAction as AttackAction).Attacker = gc; | ||
| } | ||
| context.State = new AskingForTargetState (context); | ||
| } | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,79 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using Lain; | ||
| using Microsoft.Xna.Framework.Input; | ||
| using RnR.Actions; | ||
| using RnR.Systems.D20; | ||
|
|
||
| namespace RnR.Scenes | ||
| { | ||
| public class AskingForTargetState : CombatSceneState | ||
| { | ||
| CombatSceneContext context; | ||
| int selectedTargetIdx; | ||
|
|
||
| KeyboardState lastKbState; | ||
|
|
||
| bool targetSelected; | ||
|
|
||
| public AskingForTargetState (CombatSceneContext context) | ||
| { | ||
| this.context = context; | ||
| selectedTargetIdx = 0; | ||
|
|
||
| context.AvailableActions.Clear (); | ||
| context.AvailableActions.Add ("(Up) Move up"); | ||
| context.AvailableActions.Add ("(Down) Move down"); | ||
| context.AvailableActions.Add ("(Enter) Select"); | ||
|
|
||
| targetSelected = false; | ||
| } | ||
|
|
||
| public void HandleInput () | ||
| { | ||
| KeyboardState ks = Keyboard.GetState (); | ||
|
|
||
| if (ks.IsKeyDown (Keys.Down) && | ||
| !lastKbState.IsKeyDown (Keys.Down)) { | ||
| // Go down | ||
| selectedTargetIdx++; | ||
| if (selectedTargetIdx >= context.EnemyPartyStatusConsoles.Count) | ||
| selectedTargetIdx = context.EnemyPartyStatusConsoles.Count - 1; | ||
| } else if (ks.IsKeyDown (Keys.Up) && | ||
| !lastKbState.IsKeyDown (Keys.Up)) { | ||
| // Go up | ||
| selectedTargetIdx--; | ||
| if (selectedTargetIdx < 0) | ||
| selectedTargetIdx = 0; | ||
| } else targetSelected |= ks.IsKeyDown (Keys.Enter); | ||
|
|
||
| lastKbState = ks; | ||
| } | ||
|
|
||
| public void Update () | ||
| { | ||
| System.Console.WriteLine ("AskingForTargetState::Update"); | ||
| for (int i = 0; i < context.EnemyPartyStatusConsoles.Count; i++) { | ||
| context.EnemyPartyStatusConsoles [i].IsSelected = i == selectedTargetIdx; | ||
| } | ||
|
|
||
| if (targetSelected) { | ||
| for (int i = 0; i < context.EnemyPartyStatusConsoles.Count; i++) { | ||
| context.EnemyPartyStatusConsoles [i].IsSelected = false; | ||
| } | ||
|
|
||
| IAction action = context.Actions [context.It.Current]; | ||
| if (action is AttackAction) { | ||
| (action as AttackAction).Target = context.Combat.EnemyParty.Members [selectedTargetIdx]; | ||
| } | ||
|
|
||
| if (context.It.MoveNext ()) { | ||
| context.State = new AskingForActionState (context); | ||
| } else { | ||
| context.State = new DoTurnState (context); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| } |
| @@ -0,0 +1,25 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using Lain; | ||
| using RnR.Consoles; | ||
| using RnR.Systems.D20; | ||
|
|
||
| namespace RnR.Scenes | ||
| { | ||
| public class CombatSceneContext | ||
| { | ||
| public List<string> Log { get; set; } | ||
| public List<string> AvailableActions { get; set; } | ||
|
|
||
| public Combat Combat { get; set; } | ||
|
|
||
| public CombatSceneState State { get; set; } | ||
|
|
||
| public IEnumerator<GameCharacter> It { get; set; } | ||
|
|
||
| public List<AbstractCombatStatusConsole> EnemyPartyStatusConsoles { get; set; } | ||
| public List<AbstractCombatStatusConsole> PlayerPartyStatusConsoles { get; set; } | ||
|
|
||
| public Dictionary<GameCharacter, IAction> Actions { get; set; } | ||
| } | ||
| } |
| @@ -0,0 +1,9 @@ | ||
| using System; | ||
| namespace RnR.Scenes | ||
| { | ||
| public interface CombatSceneState | ||
| { | ||
| void HandleInput (); | ||
| void Update (); | ||
| } | ||
| } |
| @@ -0,0 +1,27 @@ | ||
| using System; | ||
| namespace RnR.Scenes | ||
| { | ||
| public class DoTurnState : CombatSceneState | ||
| { | ||
| CombatSceneContext context; | ||
|
|
||
| public DoTurnState (CombatSceneContext context) | ||
| { | ||
| this.context = context; | ||
| } | ||
|
|
||
| public void HandleInput () | ||
| { | ||
| /* Do nothing */ | ||
| } | ||
|
|
||
| public void Update () | ||
| { | ||
| context.Combat.DoTurn (context.Actions); | ||
| context.Actions.Clear (); | ||
| context.It.Reset (); | ||
| context.It.MoveNext (); | ||
| context.State = new AskingForActionState (context); | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,97 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using Lain; | ||
| using Lain.Views; | ||
| using Microsoft.Xna.Framework.Input; | ||
| using RnR.Actions; | ||
| using RnR.Consoles; | ||
|
|
||
| namespace RnR.Scenes | ||
| { | ||
| public class MainMenuScene : Scene | ||
| { | ||
| MenuConsole mainMenuConsole; | ||
|
|
||
| int selectedItemIdx; | ||
| bool itemSelected; | ||
| KeyboardState lastKbState; | ||
| List<MenuItem> menuItems; | ||
|
|
||
| public override void OnCreate () | ||
| { | ||
| base.OnCreate (); | ||
| menuItems = new List<MenuItem>(new MenuItem [] { | ||
| new MenuItem(0, "New game", true), | ||
| new MenuItem(1, "Exit", false) | ||
| }); | ||
|
|
||
| mainMenuConsole = new MenuConsole (menuItems, Configuration.GridWidth, Configuration.GridHeight); | ||
| Add (mainMenuConsole); | ||
|
|
||
| selectedItemIdx = 0; | ||
| } | ||
|
|
||
| public override void OnDestroy () | ||
| { | ||
| base.OnDestroy (); | ||
| } | ||
|
|
||
| public override void OnPause () | ||
| { | ||
| base.OnPause (); | ||
| } | ||
|
|
||
| public override void OnResume () | ||
| { | ||
| base.OnResume (); | ||
| } | ||
|
|
||
| public void HandleInput () | ||
| { | ||
| KeyboardState ks = Keyboard.GetState (); | ||
|
|
||
| if (ks.IsKeyDown (Keys.Down) && | ||
| !lastKbState.IsKeyDown (Keys.Down)) { | ||
| // Go down | ||
| selectedItemIdx++; | ||
| if (selectedItemIdx >= menuItems.Count) | ||
| selectedItemIdx = menuItems.Count - 1; | ||
| } else if (ks.IsKeyDown (Keys.Up) && | ||
| !lastKbState.IsKeyDown (Keys.Up)) { | ||
| // Go up | ||
| selectedItemIdx--; | ||
| if (selectedItemIdx < 0) | ||
| selectedItemIdx = 0; | ||
| } else itemSelected |= ks.IsKeyDown (Keys.Enter); | ||
|
|
||
| lastKbState = ks; | ||
| } | ||
|
|
||
| public override void Update (Microsoft.Xna.Framework.GameTime delta) | ||
| { | ||
| base.Update (delta); | ||
|
|
||
| HandleInput (); | ||
|
|
||
| for (int i = 0; i < menuItems.Count; i++) | ||
| menuItems [i].Selected = i == selectedItemIdx; | ||
|
|
||
| if (itemSelected) { | ||
| switch (selectedItemIdx) { | ||
| case 0: | ||
| LoadNewGame (); | ||
| break; | ||
| case 1: | ||
| (new ExitAction (0)).Execute (); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| void LoadNewGame () | ||
| { | ||
| itemSelected = false; | ||
| Director.Instance.PushScene (new MainGameScene ()); | ||
| } | ||
| } | ||
| } |
| @@ -5,6 +5,6 @@ namespace RnR.Systems.D20.Base.FloorElements | ||
| { | ||
| public interface Stepable | ||
| { | ||
| string OnStep (Party target); | ||
| } | ||
| } | ||
| @@ -31,7 +31,7 @@ public int MaxDex | ||
|
|
||
| } | ||
|
|
||
| public IGameActor OnEquip (Actors.IGameActor target) | ||
| { | ||
| target.EquipedArmor = this; | ||
| return target; | ||
| @@ -53,7 +53,7 @@ public int CriticMultiplier | ||
| } | ||
| } | ||
|
|
||
| public virtual IGameActor OnEquip (Actors.IGameActor target) | ||
| { | ||
| target.EquipedWeapon = this; | ||
| return target; | ||
| @@ -6,6 +6,6 @@ namespace RnR.Systems.D20.Base.Objects | ||
| { | ||
| public interface EdibleObject | ||
| { | ||
| IGameActor OnEat(Actors.IGameActor target); | ||
| } | ||
| } | ||
| @@ -6,6 +6,6 @@ namespace RnR.Systems.D20.Base.Objects | ||
| { | ||
| public interface EquipableObject | ||
| { | ||
| IGameActor OnEquip(Actors.IGameActor target); | ||
| } | ||
| } | ||
| @@ -6,6 +6,6 @@ namespace RnR.Systems.D20.Base.Objects | ||
| { | ||
| public interface UsableObject | ||
| { | ||
| Party OnUse(Actors.IGameActor target); | ||
| } | ||
| } | ||
| @@ -1,15 +1,45 @@ | ||
| using System; | ||
| using System.Collections; | ||
| using System.Collections.Generic; | ||
| using Lain; | ||
| using RnR.Systems.D20.Util; | ||
|
|
||
| namespace RnR.Systems.D20 | ||
| { | ||
| public class Combat : IEnumerable<GameCharacter> | ||
| { | ||
| public Party PlayerParty { get; private set; } | ||
| public Party EnemyParty { get; private set; } | ||
|
|
||
| readonly InitiativeOrderPartyMembersIterator turnOrderIterator; | ||
|
|
||
| public Combat (Party playerParty, Party enemyParty) | ||
| { | ||
| PlayerParty = playerParty; | ||
| EnemyParty = enemyParty; | ||
|
|
||
| turnOrderIterator = | ||
| new InitiativeOrderPartyMembersIterator (playerParty.Members ?? new List<GameCharacter>()) | ||
| .AddCharacters (enemyParty.Members ?? new List<GameCharacter>()); | ||
| } | ||
|
|
||
| public void DoTurn (Dictionary<GameCharacter, IAction> actions) | ||
| { | ||
| foreach (var character in this) { | ||
| if (actions.ContainsKey (character)) { | ||
| actions [character].Execute (); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public IEnumerator<GameCharacter> GetEnumerator () | ||
| { | ||
| return turnOrderIterator; | ||
| } | ||
|
|
||
| IEnumerator IEnumerable.GetEnumerator () | ||
| { | ||
| return turnOrderIterator; | ||
| } | ||
| } | ||
| } |
| @@ -5,7 +5,7 @@ namespace RnR.Systems.D20.Effects | ||
| { | ||
| public class PoisonEffect : GameActorDecorator | ||
| { | ||
| public PoisonEffect (Base.Actors.IGameActor target) | ||
| : base(target) | ||
| { | ||
| } | ||
| @@ -5,7 +5,7 @@ namespace RnR.Systems.D20.Effects | ||
| { | ||
| public class StuntEffect : GameActorDecorator | ||
| { | ||
| public StuntEffect (Base.Actors.IGameActor target) | ||
| : base(target) | ||
| { | ||
| } | ||
| @@ -13,9 +13,10 @@ public FoodGrass (AbstractFood food) | ||
| this.food = food; | ||
| } | ||
|
|
||
| protected override string ApplyAction (Party target) | ||
| { | ||
| target.Inventory.Add (food); | ||
| return $"Found: {food.Name}"; | ||
| } | ||
| } | ||
| } | ||
| @@ -18,7 +18,7 @@ public RandomGrassFactory () | ||
|
|
||
| #region FloorElementFactory implementation | ||
|
|
||
| public AbstractFloorElement CreateFloorElement () | ||
| { | ||
| AbstractGrass newGrass = null; | ||
|
|
||
| @@ -6,7 +6,7 @@ | ||
|
|
||
| namespace RnR.Systems.D20.FloorElements | ||
| { | ||
| public class Stair : Drawable, Positionable | ||
| { | ||
| public StairDirection Direction { get; private set; } | ||
|
|
||
| @@ -0,0 +1,96 @@ | ||
| using System.Collections.Generic; | ||
| using RnR.Systems.D20.Base.Actors; | ||
| using RnR.Systems.Dice; | ||
|
|
||
| namespace RnR.Systems.D20 | ||
| { | ||
| public class GameCharacterBuilder | ||
| { | ||
| Attribute _STR, _DEX, _CON, _INT, _WIS, _CHA; | ||
| Dictionary<SkillType, Skill> skills; | ||
| string name; | ||
|
|
||
| public GameCharacterBuilder () | ||
| { | ||
| skills = new Dictionary<SkillType, Skill> (); | ||
| } | ||
|
|
||
| public GameCharacterBuilder SetAttribute (Attributes attr) | ||
| { | ||
| DiceRoll attrRoll = Dice.Dice.Roll (4, 6); | ||
| attrRoll.DiscardLower (); | ||
| var a = new Attribute (attrRoll.Sum, attr); | ||
|
|
||
| switch (attr) { | ||
| case Attributes.CHA: | ||
| _CHA = a; | ||
| break; | ||
| case Attributes.CON: | ||
| _CON = a; | ||
| break; | ||
| case Attributes.DEX: | ||
| _DEX = a; | ||
| break; | ||
| case Attributes.INT: | ||
| _INT = a; | ||
| break; | ||
| case Attributes.STR: | ||
| _STR = a; | ||
| break; | ||
| case Attributes.WIS: | ||
| _WIS = a; | ||
| break; | ||
| } | ||
|
|
||
| return this; | ||
| } | ||
|
|
||
| public GameCharacterBuilder SetSkill (SkillType type) | ||
| { | ||
| var val = Dice.Dice.Roll (1, 6).Sum; | ||
|
|
||
| switch (type) { | ||
| case SkillType.COMBAT: | ||
| skills.Add (type, new Skill (type, "Combat", val, _STR)); | ||
| break; | ||
| case SkillType.DETECT_MAGIC: | ||
| skills.Add (type, new Skill (type, "Detect magic", val, _INT)); | ||
| break; | ||
| case SkillType.DODGE_TRAP: | ||
| skills.Add (type, new Skill (type, "Dodge traps", val, _DEX)); | ||
| break; | ||
| case SkillType.PINLOCK: | ||
| skills.Add (type, new Skill (type, "Pinlock", val, _WIS)); | ||
| break; | ||
| } | ||
|
|
||
| return this; | ||
| } | ||
|
|
||
| public GameCharacterBuilder SetName (string name) | ||
| { | ||
| this.name = name; | ||
|
|
||
| return this; | ||
| } | ||
|
|
||
| public GameCharacter Build () | ||
| { | ||
| var ga = new GameActor (_STR.Value, | ||
| _DEX.Value, | ||
| _CON.Value, | ||
| _INT.Value, | ||
| _WIS.Value, | ||
| _CHA.Value); | ||
|
|
||
| var gc = new GameCharacter (name, | ||
| ga); | ||
|
|
||
| foreach (var skill in skills) { | ||
| ga.Skills.Add (skill.Key, skill.Value); | ||
| } | ||
|
|
||
| return gc; | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,112 @@ | ||
| using System; | ||
| using System.Collections; | ||
| using System.Collections.Generic; | ||
|
|
||
| namespace RnR.Systems.D20.Util | ||
| { | ||
| public class InitiativeOrderPartyMembersIterator : IEnumerator<GameCharacter> | ||
| { | ||
| struct MemberWrapper | ||
| { | ||
| GameCharacter character; | ||
| int rolledInitiative; | ||
|
|
||
| public GameCharacter Character { | ||
| get { | ||
| return character; | ||
| } | ||
|
|
||
| set { | ||
| character = value; | ||
| } | ||
| } | ||
|
|
||
| public int RolledInitiative { | ||
| get { | ||
| return rolledInitiative; | ||
| } | ||
|
|
||
| set { | ||
| rolledInitiative = value; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private class InitiativeComparer<K> : IComparer<K> where K : IComparable | ||
| { | ||
| public int Compare (K x, K y) | ||
| { | ||
| int result = x.CompareTo (y); | ||
| if (result == 0) | ||
| return 1; | ||
| else | ||
| return result; | ||
| } | ||
| } | ||
|
|
||
| SortedList<int, GameCharacter> membersByInitiative; | ||
|
|
||
| public InitiativeOrderPartyMembersIterator (List<GameCharacter> members) | ||
| { | ||
| membersByInitiative = new SortedList<int, GameCharacter> (new InitiativeComparer<int>()); | ||
| AddCharacters (members); | ||
| } | ||
|
|
||
| public InitiativeOrderPartyMembersIterator AddCharacters (List<GameCharacter> characters) | ||
| { | ||
| characters.ConvertAll ((character) => { | ||
| var mw = new MemberWrapper (); | ||
| mw.Character = character; | ||
| mw.RolledInitiative = Dice.Dice.Roll (1, 20).Sum + character.DEX ().Mod; | ||
| return mw; | ||
| }).ForEach ((mw) => { | ||
| membersByInitiative.Add (mw.RolledInitiative, mw.Character); | ||
| }); | ||
|
|
||
| return this; | ||
| } | ||
|
|
||
| bool loaded; | ||
| IEnumerator<KeyValuePair<int, GameCharacter>> e; | ||
|
|
||
| void LazyLoadEnumerator () | ||
| { | ||
| if (!loaded) { | ||
| e = membersByInitiative.GetEnumerator (); | ||
| loaded = true; | ||
| } | ||
| } | ||
|
|
||
| public GameCharacter Current { | ||
| get { | ||
| LazyLoadEnumerator (); | ||
| return e.Current.Value; | ||
| } | ||
| } | ||
|
|
||
| object IEnumerator.Current { | ||
| get { | ||
| LazyLoadEnumerator (); | ||
| return e.Current.Value; | ||
| } | ||
| } | ||
|
|
||
| public void Dispose () | ||
| { | ||
| LazyLoadEnumerator (); | ||
| e.Dispose (); | ||
| } | ||
|
|
||
| public bool MoveNext () | ||
| { | ||
| LazyLoadEnumerator (); | ||
| return e.MoveNext (); | ||
| } | ||
|
|
||
| public void Reset () | ||
| { | ||
| LazyLoadEnumerator (); | ||
| e.Reset (); | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,45 @@ | ||
| using System; | ||
| using System.Collections; | ||
| using System.Collections.Generic; | ||
|
|
||
| namespace RnR.Systems.D20.Util | ||
| { | ||
| public class PartyMembersIterator : IEnumerator<GameCharacter> | ||
| { | ||
| List<GameCharacter> members; | ||
| int p; | ||
|
|
||
| public PartyMembersIterator (List<GameCharacter> members) | ||
| { | ||
| this.members = members; | ||
| p = 0; | ||
| } | ||
|
|
||
| public GameCharacter Current { | ||
| get { | ||
| return members [p]; | ||
| } | ||
| } | ||
|
|
||
| object IEnumerator.Current { | ||
| get { | ||
| return members [p]; | ||
| } | ||
| } | ||
|
|
||
| public void Dispose () | ||
| { | ||
| } | ||
|
|
||
| public bool MoveNext () | ||
| { | ||
| p++; | ||
| return p < members.Count; | ||
| } | ||
|
|
||
| public void Reset () | ||
| { | ||
| p = 0; | ||
| } | ||
| } | ||
| } |