@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; }
@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); }
@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; }
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; }
@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); }
@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()); } }
@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; }
@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; }
public String debugMessage() { return "Stance: " + getStance().getClass().getName() + "\np1: " + p1.debugMessage(this, getStance()) + "\np2: " + p2.debugMessage(this, getStance()); }
private int stealXP(Character target) { int xpStolen = target.getXP(); if (xpStolen <= 0) { return 0; } target.loseXP(xpStolen); getSelf().gainXP(xpStolen); return xpStolen; }
@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); }
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)); } }
@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; }
@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."; } } }
@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; }
@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()); }
@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."; } }
@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)); }
@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."); } }
@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; }
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; }
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; }
@Override public boolean usable(Combat c, Character target) { return target.mostlyNude() && !c.getStance().sub(getSelf()) && getSelf().canAct() && !getSelf().has(Trait.shy); }
@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."; }
@Override public boolean usable(Combat c, Character target) { return getSelf().canRespond() && c.getStance().penetratedBy(c, getSelf(), target) && c.getStance().havingSexNoStrapped(c) && target.hasDick(); }
@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; }
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(); }
@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()))); }
@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; }
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(); } }