Example #1
0
 @Override
 public boolean resolve(Combat c, Character target) {
   if (target.roll(this, c, accuracy(c))) {
     if (getSelf().get(Attribute.Dark) >= 1) {
       if (getSelf().human()) {
         c.write(getSelf(), deal(c, 0, Result.special, target));
       } else if (target.human()) {
         c.write(getSelf(), receive(c, 0, Result.special, target));
       }
       int m = 10 + Math.min(20, getSelf().get(Attribute.Dark) / 2);
       target.drain(c, getSelf(), m);
     } else {
       if (getSelf().human()) {
         c.write(getSelf(), deal(c, 0, Result.normal, target));
       } else if (target.human()) {
         c.write(getSelf(), receive(c, 0, Result.normal, target));
       }
     }
     int m = 1 + Global.random(8);
     target.body.pleasure(
         getSelf(), getSelf().body.getRandom("mouth"), target.body.getRandom("skin"), m, c);
   } else {
     if (getSelf().human()) {
       c.write(getSelf(), deal(c, 0, Result.miss, target));
     } else if (target.human()) {
       c.write(getSelf(), receive(c, 0, Result.miss, target));
     }
     return false;
   }
   return true;
 }
Example #2
0
 @Override
 public boolean requirements(Combat c, Character user, Character target) {
   Collection<BodyPart> tails = user.body.get("tail");
   boolean hasFuckableTail = tails.stream().anyMatch(p -> p.isType("tail") && p != TailPart.cat);
   return hasFuckableTail
       && (user.get(Attribute.Dark) >= 1 || user.get(Attribute.Seduction) >= 20);
 }
Example #3
0
  @Override
  public String receive(Combat c, int damage, Result modifier, Character target) {
    String m = "";
    if (modifier == Result.miss) {
      m += getSelf().name() + " tries to suck your c**k, but you pull your hips back to avoid her.";
    } else if (modifier == Result.special) {
      m +=
          getSelf().name()
              + "'s soft lips and talented tongue work over your dick, drawing out dangerously irresistible pleasure with each touch.";
    } else if (modifier == Result.intercourse) {
      m +=
          getSelf().name()
              + "'s pussy lips suddenly quiver and you feel a long sinuous object wrap around your c**k. You realize she's controlling her vaginal tongue to blow you with her pussy! "
              + "Her lower tongue runs up and down your shaft causing you to shudder with arousal.";
    } else if (modifier == Result.reverse) {
      m +=
          "Faced with your dick sitting squarely in front of her face, "
              + getSelf().name()
              + " obediently tongues your c**k in defeat.";
    } else if (target.getArousal().get() < 15) {
      m +=
          getSelf().name()
              + " takes your soft penis into her mouth and sucks on it until it hardens";
    } else if (target.getArousal().percent() >= 90) {
      m +=
          getSelf().name()
              + " laps up the precum leaking from your c**k and takes the entire length into her mouth, sucking relentlessly";
    } else {
      int r = Global.random(4);
      if (r == 0) {
        m +=
            getSelf().name()
                + " runs her tongue up the length of your dick, sending a jolt of pleasure up your spine. She slowly wraps her lips around your dick and sucks.";
      } else if (r == 1) {
        m += getSelf().name() + " sucks on the head of your c**k while her hand strokes the shaft.";
      } else if (r == 2) {
        m +=
            getSelf().name()
                + " licks her way down to the base of your c**k and gently sucks on your balls.";
      } else {
        m +=
            getSelf().name()
                + " runs her tongue around the glans of your penis and teases your urethra.";
      }
    }

    if (modifier != Result.miss && getSelf().body.getRandom("mouth").isErogenous()) {
      m +=
          "<br>Unfortunately for her, as "
              + getSelf().subject()
              + " mouth f***s "
              + target.possessivePronoun()
              + " c**k "
              + getSelf().nameOrPossessivePronoun()
              + " sensitive modified mouth pussy sends spasms of pleasure into "
              + getSelf().reflectivePronoun()
              + " too.";
    }
    return m;
  }
Example #4
0
 private boolean resolveSkill(Skill skill, Character target) {
   boolean orgasmed = false;
   if (Skill.skillIsUsable(this, skill, target)) {
     write(skill.user().subjectAction("use ", "uses ") + skill.getLabel(this) + ".");
     if (skill.makesContact()
         && !getStance().dom(target)
         && target.canAct()
         && checkCounter(skill.user(), target, skill)) {
       write("Countered!");
       target.counterattack(skill.user(), skill.type(this), this);
     } else if (target.is(Stsflag.counter) && skill.makesContact()) {
       write("Countered!");
       CounterStatus s = (CounterStatus) target.getStatus(Stsflag.counter);
       if (skill.user().is(Stsflag.wary)) {
         write(target, s.getCounterSkill().getBlockedString(this, skill.user()));
       } else {
         s.resolveSkill(this, skill.user());
       }
     } else {
       Skill.resolve(skill, this, target);
     }
     checkStamina(target);
     checkStamina(skill.user());
     orgasmed = checkOrgasm(skill.user(), target, skill);
   } else {
     write(skill.user().possessivePronoun() + " " + skill.getLabel(this) + " failed.");
   }
   return orgasmed;
 }
Example #5
0
 @Override
 public double priority(Character c) {
   return (c.has(Trait.tight) ? 1 : 0)
       + (c.has(Trait.holecontrol) ? 1 : 0)
       + (c.has(Trait.oiledass) ? 1 : 0)
       + (c.has(Trait.autonomousAss) ? 4 : 0);
 }
Example #6
0
 @Override
 public String receive(Combat c, int damage, Result modifier, Character target) {
   if (modifier == Result.miss) {
     return String.format(
         "%s aims a slap at %s ass, but %s %s it.",
         getSelf().subject(),
         target.nameOrPossessivePronoun(),
         target.pronoun(),
         target.action("dodge"));
   }
   if (modifier == Result.special) {
     String victim = target.hasBalls() ? "balls" : "c**t";
     String hood = target.hasBalls() ? "manhood" : "womanhood";
     return String.format(
         "%s bends %s over like a misbehaving child and spanks %s"
             + " ass twice. The third spank aims lower and connects solidly with %s %s, "
             + "injuring %s %s along with %s pride.",
         getSelf().subject(),
         target.nameDirectObject(),
         target.possessivePronoun(),
         target.possessivePronoun(),
         victim,
         target.possessivePronoun(),
         hood,
         target.possessivePronoun());
   } else {
     return String.format(
         "%s lands a stinging slap on %s bare ass.",
         getSelf().subject(), target.nameOrPossessivePronoun());
   }
 }
Example #7
0
 @Override
 public Combat clone() throws CloneNotSupportedException {
   Combat c = (Combat) super.clone();
   c.p1 = p1.clone();
   c.p2 = p2.clone();
   c.p1.finishClone(c.p2);
   c.p2.finishClone(c.p1);
   c.p1Data = (CombatantData) p1Data.clone();
   c.p2Data = (CombatantData) p2Data.clone();
   c.stance = getStance().clone();
   c.state = state;
   if (c.getStance().top == p1) {
     c.getStance().top = c.p1;
   }
   if (c.getStance().top == p2) {
     c.getStance().top = c.p2;
   }
   if (c.getStance().bottom == p1) {
     c.getStance().bottom = c.p1;
   }
   if (c.getStance().bottom == p2) {
     c.getStance().bottom = c.p2;
   }
   return c;
 }
Example #8
0
 @Override
 public double getPleasure(Character self, BodyPart target) {
   double pleasureMod = super.getPleasure(self, target);
   pleasureMod += self.has(Trait.analTraining1) ? .5 : 0;
   pleasureMod += self.has(Trait.analTraining2) ? .7 : 0;
   pleasureMod += self.has(Trait.analTraining3) ? .7 : 0;
   return pleasureMod;
 }
Example #9
0
 public String debugMessage() {
   return "Stance: "
       + getStance().getClass().getName()
       + "\np1: "
       + p1.debugMessage(this, getStance())
       + "\np2: "
       + p2.debugMessage(this, getStance());
 }
Example #10
0
 private int stealXP(Character target) {
   int xpStolen = target.getXP();
   if (xpStolen <= 0) {
     return 0;
   }
   target.loseXP(xpStolen);
   getSelf().gainXP(xpStolen);
   return xpStolen;
 }
Example #11
0
 @Override
 public boolean usable(Combat c, Character target) {
   return (getSelf().has(Item.D***o) || getSelf().has(Item.Dildo2))
       && getSelf().canAct()
       && target.hasPussy()
       && c.getStance().reachBottom(getSelf())
       && target.crotchAvailable()
       && !c.getStance().vaginallyPenetrated(target);
 }
Example #12
0
 public void checkStanceStatus(Character c, Position oldStance, Position newStance) {
   if ((oldStance.prone(c) || !oldStance.mobile(c))
       && !newStance.prone(c)
       && newStance.mobile(c)) {
     c.add(this, new Braced(c));
     c.add(this, new Wary(c, 3));
   } else if (!oldStance.mobile(c) && newStance.mobile(c)) {
     c.add(this, new Wary(c, 3));
   }
 }
Example #13
0
  @Override
  public boolean resolve(Combat c, Character target) {
    double m = Global.random(6, 13);
    if (getSelf().has(Trait.disciplinarian)) {
      boolean shamed =
          Global.random(10) >= 5 || !target.is(Stsflag.shamed) && getSelf().canSpend(5);
      if (shamed) {
        getSelf().spendMojo(c, 5);
      }
      writeOutput(c, Result.special, target);
      if (shamed) {
        target.add(c, new Shamed(target));
        target.emote(Emotion.angry, 10);
        target.emote(Emotion.nervous, 15);
      }
      if (target.has(Trait.achilles)) {
        m += 10;
      } else {
        m += 5;
      }
    } else {
      writeOutput(c, Result.normal, target);
    }
    target.pain(c, (int) getSelf().modifyDamage(DamageType.physical, target, m));

    target.emote(Emotion.angry, 25);
    target.emote(Emotion.nervous, 15);
    target.loseMojo(c, 10);
    return true;
  }
Example #14
0
 @Override
 public String deal(Combat c, int damage, Result modifier, Character target) {
   if (getSelf().hasPussy()) {
     String base =
         "You put your powerful vaginal muscles to work whilst"
             + " transfixing "
             + target.name()
             + "'s gaze with your own, goading his energy into his c**k."
             + " Soon it erupts from him, ";
     switch (damage) {
       case 0:
         return base
             + "but unfortunately you made a mistake, and the feedback leaves"
             + " you on the edge of climax!";
       case 1:
         return base
             + "and you can feel his memories and experiences flow"
             + " into you, adding to your skill.";
       case 2:
         return base
             + "far more powerfully than you even thought possible."
             + " You feel a fragment of his soul break away from him and"
             + " spew into you, taking with it a portion of his very being"
             + "and merging with your own. You have clearly"
             + " won this fight, and a lot more than that.";
       default:
         // Should never happen
         return " but nothing happens, you feel strangely impotent.";
     }
   } else {
     String base =
         "With your c**k deep inside "
             + target.name()
             + ", you can feel the heat from her core. You draw the energy from her, mining her depths. ";
     switch (damage) {
       case 0:
         return "You attempt to drain "
             + target.name()
             + "'s energy through your intimate connection, but it goes wrong. You feel intense pleasure feeding "
             + "back into you and threatening to overwhelm you. You brink the spiritual link as fast as you can, but you're still left on the brink of "
             + "climax.";
       case 1:
         return "You attempt to drain "
             + target.name()
             + "'s energy through your intimate connection, taking a bit of her experience.";
       case 2:
         return base
             + "You succeed in siphoning off a portion of her soul, stealing a portion of her very being. This energy permanently "
             + "settles within you!";
       default:
         // Should never happen
         return " but nothing happens, you feel strangely impotent.";
     }
   }
 }
Example #15
0
 @Override
 public boolean resolve(Combat c, Character target) {
   if (getSelf().human()) {
     c.write(getSelf(), deal(c, 0, Result.normal, target));
   } else if (target.human()) {
     c.write(getSelf(), receive(c, 0, Result.normal, target));
   }
   double m =
       (6 + Global.random(4) + getSelf().body.getHotness(getSelf(), target))
           * Math.min(2, 1 + getSelf().getExposure());
   if (target.has(Trait.imagination)) {
     m += 4;
     target.tempt(c, getSelf(), (int) Math.round(m));
     if (Global.random(4) >= 1) {
       target.add(c, new Shamed(target));
     }
   } else {
     target.tempt(c, getSelf(), (int) Math.round(m));
     if (Global.random(4) >= 2) {
       target.add(c, new Shamed(target));
     }
   }
   target.emote(Emotion.angry, 30);
   target.emote(Emotion.nervous, 15);
   getSelf().emote(Emotion.dominant, 20);
   target.loseMojo(c, 5);
   return true;
 }
Example #16
0
 @Override
 public String receive(Combat c, int damage, Result modifier, Character target) {
   return String.format(
       "%s asks for a quick time out and starts sexily slipping %s clothes off."
           + " Although there are no time outs in the rules, %s can't help staring "
           + "at the seductive display until %s finishes with a cute wiggle of %s naked ass.",
       getSelf().subject(),
       target.nameOrPossessivePronoun(),
       target.subject(),
       getSelf().subject(),
       getSelf().possessivePronoun());
 }
Example #17
0
 @Override
 public String deal(Combat c, int damage, Result modifier, Character target) {
   if (modifier == Result.miss) {
     return "You lean in to kiss " + target.name() + "'s neck, but she slips away.";
   } else if (modifier == Result.special) {
     return "You draw close to "
         + target.name()
         + " as she's momentarily too captivated to resist. You run your tongue along her neck and bite gently. She shivers and you "
         + "can feel the energy of her pleasure flow into you, giving you strength.";
   } else {
     return "You lick and suck " + target.name() + "'s neck hard enough to leave a hickey.";
   }
 }
Example #18
0
 @Override
 public boolean usable(Combat c, Character target) {
   boolean canUse =
       (c.getStance().enumerate() == Stance.facesitting && getSelf().canRespond())
           || getSelf().canAct();
   return (target.crotchAvailable()
           && target.hasDick()
           && c.getStance().oral(getSelf())
           && c.getStance().front(getSelf())
           && canUse
           && !c.getStance().inserted(target))
       || (getSelf().canRespond() && isVaginal(c));
 }
Example #19
0
 @Override
 public void describeLong(StringBuilder b, Character c) {
   switch (this) {
     case cat:
       b.append("Cute " + fullDescribe(c) + " tops " + c.possessivePronoun() + " head.");
       break;
     default:
       b.append(
           Global.capitalizeFirstLetter(fullDescribe(c))
               + " frames "
               + c.possessivePronoun()
               + " face.");
   }
 }
Example #20
0
 @Override
 public Movement execute(Character user) {
   if (user.human()) {
     if (user.location().name == "Showers") {
       Global.gui()
           .message("It's a bit dangerous, but a shower sounds especially inviting right now.");
     } else if (user.location().name == "Pool") {
       Global.gui()
           .message("There's a jacuzzi in the pool area and you decide to risk a quick soak.");
     }
   }
   user.state = State.shower;
   user.delay(1);
   return Movement.bathe;
 }
Example #21
0
 public int dc(Character attacker) {
   if (attacker != null
       && attacker.has(Trait.bramaster)
       && layer == 0
       && slots.contains(ClothingSlot.top)) {
     return dc / 2;
   }
   if (attacker != null
       && attacker.has(Trait.pantymaster)
       && layer == 0
       && slots.contains(ClothingSlot.bottom)) {
     return dc / 2;
   }
   return dc;
 }
Example #22
0
 public Combat(Character p1, Character p2, Area loc, int code) {
   this(p1, p2, loc);
   stance = new Neutral(p1, p2);
   message = "";
   timer = 0;
   switch (code) {
     case 1:
       p2.undress(this);
       p1.emote(Emotion.dominant, 50);
       p2.emote(Emotion.nervous, 50);
     default:
   }
   p1.state = State.combat;
   p2.state = State.combat;
 }
Example #23
0
 @Override
 public boolean usable(Combat c, Character target) {
   return target.mostlyNude()
       && !c.getStance().sub(getSelf())
       && getSelf().canAct()
       && !getSelf().has(Trait.shy);
 }
Example #24
0
 @Override
 public String deal(Combat c, int damage, Result modifier, Character target) {
   return "During a brief respite in the fight as "
       + target.name()
       + " is catching her breath, you make a show of seductively removing your clothes. "
       + "By the time you finish, she's staring with undisguised arousal, pressing a hand unconsciously against her groin.";
 }
Example #25
0
 @Override
 public boolean usable(Combat c, Character target) {
   return getSelf().canRespond()
       && c.getStance().penetratedBy(c, getSelf(), target)
       && c.getStance().havingSexNoStrapped(c)
       && target.hasDick();
 }
Example #26
0
  @Override
  public boolean resolve(Combat c, Character target) {
    BodyPart selfO = getSelfOrgan(c);
    BodyPart targetO = getTargetOrgan(c, target);
    Result result;
    if (c.getStance().inserted(target)) {
      result = Result.reverse;
    } else if (c.getStance().en == Stance.anal) {
      result = Result.anal;
    } else {
      result = Result.normal;
    }

    writeOutput(c, result, target);

    int[] m = getDamage(c, target);
    assert (m.length >= 2);

    if (m[0] != 0) target.body.pleasure(getSelf(), selfO, targetO, m[0], c, this);
    if (m[1] != 0) getSelf().body.pleasure(target, targetO, selfO, m[1], 0, c, false, this);
    if (selfO.isType("ass") && Global.random(100) < 2 + getSelf().get(Attribute.Fetish)) {
      target.add(c, new BodyFetish(target, getSelf(), "ass", .25));
    }
    return true;
  }
Example #27
0
 public Combat(Character p1, Character p2, Area loc) {
   this.p1 = p1;
   p1Data = new CombatantData();
   this.p2 = p2;
   p2Data = new CombatantData();
   p1.startBattle(this);
   p2.startBattle(this);
   location = loc;
   stance = new Neutral(p1, p2);
   message = "";
   timer = 0;
   images = new HashMap<String, String>();
   p1.state = State.combat;
   p2.state = State.combat;
   winner = Optional.empty();
 }
Example #28
0
 @Override
 public boolean usable(Combat c, Character target) {
   return !target.hasStatus(Stsflag.knotted)
       && getSelf().canAct()
       && (c.getStance().en == Stance.facesitting
           || (c.getStance().inserted() && c.getStance().dom(getSelf())));
 }
Example #29
0
 @Override
 public boolean usable(Combat c, Character target) {
   return getSelf().getArousal().get() >= 30
       && getSelf().canAct()
       && target.crotchAvailable()
       && c.getStance().en != Stance.standing
       && c.getStance().en != Stance.standingover;
 }
Example #30
0
 public void act(Character c, Skill action, String choice) {
   if (c == p1) {
     p1act = action;
   }
   if (c == p2) {
     p2act = action;
   }
   action.choice = choice;
   if (p1act == null) {
     p1.act(this);
   } else if (p2act == null) {
     p2.act(this);
   } else if (p1act != null && p2act != null) {
     clear();
     if (p1.human() || p2.human()) {
       Global.gui().clearText();
     }
     p1act = checkWorship(p1, p2, p1act);
     p2act = checkWorship(p2, p1, p2act);
     if (Global.isDebugOn(DebugFlags.DEBUG_SCENE)) {
       System.out.println(p1.name() + " uses " + p1act.getLabel(this));
       System.out.println(p2.name() + " uses " + p2act.getLabel(this));
     }
     if (p1.pet != null && p2.pet != null) {
       petbattle(p1.pet, p2.pet);
     } else if (p1.pet != null) {
       p1.pet.act(this, p2);
     } else if (p2.pet != null) {
       p2.pet.act(this, p1);
     }
     useSkills();
     this.write("<br>");
     p1.eot(this, p2, p2act);
     p2.eot(this, p1, p1act);
     checkStamina(p1);
     checkStamina(p2);
     getStance().decay(this);
     getStance().checkOngoing(this);
     phase = 0;
     if (!(p1.human() || p2.human())) {
       timer++;
       turn();
     }
     updateMessage();
   }
 }