protected override string OnCombatConsumeAttempt(CombatCreature consumer, CombatCreature opponent, out bool consumeItem, out bool isBadEnd) { isBadEnd = false; StringBuilder sb = new StringBuilder(); sb.Append("You toss a wingstick at your foe! It flies straight and true, almost as if it has a mind of its own as it arcs towards " + opponent.Article(true) + opponent.name + "!" + Environment.NewLine); if (opponent.speed - 80 > Utils.Rand(100) + 1) { //1% dodge for each point of speed over 80 sb.Append("Somehow " + opponent.Article(true) + opponent.name + "'"); sb.Append(" incredible speed allows " + opponent.objectNoun + " to avoid the spinning blades! The deadly device shatters when it impacts " + "something in the distance."); } else { //Not dodged uint damage = (uint)(40 + Utils.Rand(61) + (consumer.strength * 2)); sb.Append(opponent.Article(true).CapitalizeFirstLetter() + opponent.name + " is hit with the wingstick! It breaks apart as it lacerates " + opponent.objectNoun + ". <b>(<font color=\"#800000\">" + damage + "</font>)</b>"); opponent.TakeDamage(damage); } consumeItem = true; return(sb.ToString()); }
private void AddToTable(Player player, int cardNumber) { Card card = manager.CreateCardByNumber(cardNumber); var creature = new CombatCreature(card); player.Table.Add(card.Id, creature); }
public bool Execute(Player player, Player opponent) { if (!IsActionValid(player, opponent)) { return(true); } CombatCreature attackCreature = player.Table[id]; CombatCreature defenseCreature = target >= 0 ? opponent.Table[target] : null; int attackCreatureAttack = attackCreature.Attack; int damageDealt = 0; if (defenseCreature == null) { damageDealt = attackCreature.AttackPlayer(opponent); } else { int exceedDamage = 0; (damageDealt, exceedDamage) = attackCreature.AttackCreature(defenseCreature); opponent.TakeDamage(exceedDamage); } if (attackCreature.IsDrain) { player.TakeDamage(-damageDealt); } return(true); }
protected override string OnCombatConsumeAttempt(CombatCreature consumer, CombatCreature opponent, out bool consumeItem, out bool isBadEnd) { CanineTFs transform = new CanineTFs(modifiers); consumeItem = true; return(transform.DoTransformationFromCombat(consumer, opponent, out isBadEnd)); }
protected override string OnCombatConsumeAttempt(CombatCreature consumer, CombatCreature opponent, out bool consumeItem, out bool isBadEnd) { HorseTFs tf = new HorseTFs(); consumeItem = true; return(tf.DoTransformationFromCombat(consumer, opponent, out isBadEnd)); }
protected override SimpleDescriptor DoAttack(CombatCreature attacker, CombatCreature defender) { int attackStrength = resourceCount / 2; //num turns it'll last. resourceCount = 0; //remove all tendrils. throw new NotImplementedException(); }
protected override string OnCombatConsumeAttempt(CombatCreature consumer, CombatCreature opponent, out bool consumeItem, out bool isBadEnd) { #warning when Ember implemented, set these to the correct values. DragonTF tf = new DragonTF(false, true); consumeItem = true; return(tf.DoTransformationFromCombat(consumer, opponent, out isBadEnd)); }
protected override SimpleDescriptor DoAttack(CombatCreature attacker, CombatCreature defender) { //if (!CanUseAttack()) //{ // return NotEnoughResources(); //} //attempt the webbing. resourceCount -= ATTACK_COST; throw new Tools.InDevelopmentExceptionThatBreaksOnRelease(); }
private protected virtual DisplayBase AttemptToUseItemInCombat(CombatCreature user, CombatCreature opponent, UseItemCombatCallback postItemUseCallback) { if (!CanUse(user, true, out string whyNot)) { postItemUseCallback(false, whyNot, Author(), this); return(null); } else { CapacityItem retVal = UseItemInCombat(user, opponent, out string resultsOfUse); postItemUseCallback(true, resultsOfUse, Author(), retVal); return(null); } }
protected override string OnCombatConsumeAttempt(CombatCreature consumer, CombatCreature opponent, out bool consumeItem, out bool isBadEnd) { consumeItem = true; //fun fact: Ferret Fruit has a 1/100 chance of doing nothing. if (Utils.Rand(100) == 0) { isBadEnd = false; return(RottenFruitOrSomething(consumer)); } else { FerretTFs tf = new FerretTFs(); return(tf.DoTransformationFromCombat(consumer, opponent, out isBadEnd)); } }
protected virtual CapacityItem CombatConsumeItem(CombatCreature user, CombatCreature opponent, out string resultsOfUseText, out bool isBadEnd) { resultsOfUseText = OnCombatConsumeAttempt(user, opponent, out bool consumedItem, out isBadEnd); CapacityItem item = this; if (consumedItem) { if (user is PlayerBase player) { player.RefillHunger(sateHungerAmount); } item = null; } return(item); }
private void RunAttackCreatureTest(int sourceId, int targetId) { CombatCreature attackCreature = player1.Table[sourceId]; attackCreature.ResetAttacks(); CombatCreature defenseCreature = player2.Table[targetId]; int expectedAttCreatureAttack = !defenseCreature.IsWard ? attackCreature.Attack : 0; int expectedDefCreatureAttack = !attackCreature.IsWard ? defenseCreature.Attack : 0; int expectedMyHealthChange = attackCreature.IsDrain ? expectedAttCreatureAttack : 0; int expectedOppHealthChange = attackCreature.IsTrample ? Math.Max(expectedAttCreatureAttack - defenseCreature.Defense, 0) : 0; int expectedMyHealth = player1.Data.Health + expectedMyHealthChange; int expectedOppHealth = player2.Data.Health - expectedOppHealthChange; int expectedMyCardDefense = attackCreature.Defense - expectedDefCreatureAttack; int expectedOppCardDefense = defenseCreature.Defense - expectedAttCreatureAttack; bool expectedMyShouldDie = defenseCreature.IsLethal && expectedDefCreatureAttack > 0; bool expectedOppShouldDie = attackCreature.IsLethal && expectedAttCreatureAttack > 0; bool expectedMyIsDead = expectedMyShouldDie || expectedMyCardDefense <= 0; bool expectedOppIsDead = expectedOppShouldDie || expectedOppCardDefense <= 0; int expectedMyTableCount = expectedMyIsDead ? player1.Table.Count - 1 : player1.Table.Count; int expectedOppTableCount = expectedOppIsDead ? player2.Table.Count - 1 : player2.Table.Count; AttackAction action = new AttackAction(sourceId, targetId); bool result = action.Execute(player1, player2); Assert.IsTrue(result); Assert.AreEqual(expectedMyHealth, player1.Data.Health); Assert.AreEqual(expectedOppHealth, player2.Data.Health); Assert.AreEqual(expectedMyCardDefense, attackCreature.Defense); Assert.AreEqual(expectedOppCardDefense, defenseCreature.Defense); Assert.AreEqual(expectedMyShouldDie, attackCreature.ShouldDie); Assert.AreEqual(expectedOppShouldDie, defenseCreature.ShouldDie); Assert.AreEqual(expectedMyIsDead, attackCreature.IsDead); Assert.AreEqual(expectedOppIsDead, defenseCreature.IsDead); Assert.IsFalse(attackCreature.IsWard); Assert.IsFalse(defenseCreature.IsWard); Assert.IsFalse(attackCreature.CanAttack); Assert.AreEqual(expectedMyTableCount, player1.Table.Count); Assert.AreEqual(expectedOppTableCount, player2.Table.Count); }
private void RunAttackPlayerTest(int sourceId) { int target = -1; CombatCreature attackCreature = player1.Table[sourceId]; attackCreature.ResetAttacks(); int expectedMyHealth = player1.Data.Health + (attackCreature.IsDrain ? attackCreature.Attack : 0); int expectedOppHealth = player2.Data.Health - attackCreature.Attack; AttackAction action = new AttackAction(sourceId, target); bool result = action.Execute(player1, player2); Assert.IsTrue(result); Assert.AreEqual(expectedMyHealth, player1.Data.Health); Assert.AreEqual(expectedOppHealth, player2.Data.Health); Assert.IsFalse(attackCreature.CanAttack); }
private protected override DisplayBase AttemptToUseItemInCombat(CombatCreature user, CombatCreature opponent, UseItemCombatCallback postItemUseCallback) { if (!CanUse(user, true, out string whyNot)) { postItemUseCallback(false, whyNot, Author(), this); return(null); } else { CapacityItem retVal = CombatConsumeItem(user, opponent, out string resultsOfUse, out bool isBadEnd); if (!isBadEnd) { postItemUseCallback(true, resultsOfUse, Author(), retVal); return(null); } else { throw new System.NotImplementedException(); } } }
//libido affects lust damage. //toughness affects physical damage. //intellect affects magic damage. //speed affects evasion. //sensitivity: affects physical sexual stimulation. generally not in combat, but some attacks may use it. //libido: affects general lust generation over time, and any lust damage obtained during combat. //corruption: affects lust gain over time, and allows certain interactions or attacks. some combat abilities may be affected by corruption as well. //lust: causes combat loss if maxed. //hp: causes combat loss if drops to 0. // //Range stats: close, medium, far. knockback causes player to reach medium level. // //hit rate - should generally factor in attacker's speed, defender's evade, but can be overridden to ignore if needed. //crit rate - physical only? idk. //range type - ranged, melee? //attack type - physical, magical, mixed? //damage type - lust, hp, both. //on hit text - damage dealt, critical hit //generic on miss text //attack, tease, physical special, magical special. special attacks assume a 100% hitrate, though you can override this if necessary. //attack takes weapon attack, attack rate, etc. protected abstract bool CanUseAttack(CombatCreature attacker, CombatCreature defender);
//additionally, it came to my attention that transformations are a free action, and some people don't want that. it's now (technically) possible for transformations to //note that they should cause the target to lose combat if a tf knocks them out, for example. Note that as of this writing, this is actually never done - anything that //overrides this simply does so to alter the text of the default transformation ever so slightly. //a note to implementers: if your code is 99% the same aside from a few lines of text, create a common function that both use, and take a boolean for the in combat flag. //you can differentiate the text as you desire based on that flag. //ex: DoTransformationGeneric(Creature target, bool isInCombat, out bool isBadEnd) ... //this can get more complicated if you actually do decide to allow combat losses from tfs, but i don't really think that'll ever happen. protected internal virtual string DoTransformationFromCombat(CombatCreature target, CombatCreature opponent, out bool isBadEnd) { return(DoTransformation(target, out isBadEnd)); }
protected override bool CanUseAttack(CombatCreature attacker, CombatCreature defender) { return(resourceCount > ATTACK_COST); }
protected override bool CanUseAttack(CombatCreature attacker, CombatCreature defender) { return(base.CanUseAttack(attacker, defender)); // && !defender.isConstricted; //should be a combat status effect. so !defender.hasCombatStatusEffect(CombatStatusEffect.Constricted); }
private protected virtual CapacityItem UseItemInCombat(CombatCreature target, CombatCreature opponent, out string resultsOfUseText) { return(UseItem(target, out resultsOfUseText)); }
private protected virtual T UseItemInCombatSafe(CombatCreature user, CombatCreature opponent, out string resultsOfUseText) { return(UseItemSafe(user, out resultsOfUseText)); }
public DisplayBase UseItemInCombat(CombatCreature user, CombatCreature opponent, UseItemCombatCallback postItemUseCallback) { return(AttemptToUseItemInCombat(user, opponent, postItemUseCallback)); }
protected override bool CanUseAttack(CombatCreature attacker, CombatCreature defender) { return(true); }
private protected override CapacityItem UseItemInCombat(CombatCreature target, CombatCreature opponent, out string resultsOfUseText) { return(UseItemInCombatSafe(target, opponent, out resultsOfUseText)); }
private string Tip(CombatCreature attacker) { return("Whip your foe with your tail to enrage them and lower their defense!" + Environment.NewLine + Environment.NewLine + "Fatigue Cost: " + attacker.physicalCost(attackCost)); }
private string Tip(CombatCreature attacker) { return("Use a ramming headbutt to try and stun your foe. " + Environment.NewLine + Environment.NewLine + "Fatigue Cost: " + attacker.physicalCost(attackCost)); }
private string Tip(CombatCreature attacker) { return("Slam your foe with your mighty " + name() + "! This attack causes grievous harm and can stun your opponent or let it bleed. " + Environment.NewLine + Environment.NewLine + "Fatigue Cost: " + attacker.physicalCost(attackCost)); }
protected override SimpleDescriptor DoAttack(CombatCreature attacker, CombatCreature defender) { throw new System.NotImplementedException(); }
protected abstract SimpleDescriptor DoAttack(CombatCreature attacker, CombatCreature defender);
private string Tip(CombatCreature attacker) { return("Attempt to bind an enemy in your long snake-tail." + Environment.NewLine + Environment.NewLine + "Fatigue Cost: " + attacker.physicalCost(attackCost)); }
protected override SimpleDescriptor DoAttack(CombatCreature attacker, CombatCreature defender) { return(GlobalStrings.None); }