Found the bug:
if (opponent.has(Trait.leveldrainer) && (c.getStance().penetratedBy(opponent, this) && !has(Trait.strapped)) || c.getStance().en == Stance.trib) {
Should be
if (opponent.has(Trait.leveldrainer) && ((c.getStance().penetratedBy(opponent, this) && !has(Trait.strapped)) || c.getStance().en == Stance.trib)) {
Additionally, in pussypart,
c.write(self, Global.format(
"{self:SUBJECT-ACTION:use|uses} {self
ossessive} " + desc
+ "vaginal muscles to milk {other:name-possessive} cock, adding to the pleasure.",
self, opponent));
this section doesn't check if opponent actually has a cock.
c.write(opponent, Global.capitalizeFirstLetter(String.format("%s %s contracts around %s %s, reinforcing"
+ " %s orgasm and drawing upon %s very strength and experience. Once it's over, %s"
+ " left considerably more powerful, at %s expense.", opponent.nameOrPossessivePronoun(),
c.getStance().insertedPartFor(opponent).describe(opponent), nameOrPossessivePronoun(),
c.getStance().insertablePartFor(this).describe(this), possessivePronoun(), possessivePronoun(),
opponent.subjectAction("is", "are"), nameOrPossessivePronoun())));
This part is wrong, you've swapped the body parts, if you make it like
c.write(opponent, Global.capitalizeFirstLetter(String.format("%s %s contracts around %s %s, reinforcing"
+ " %s orgasm and drawing upon %s very strength and experience. Once it's over, %s"
+ " left considerably more powerful, at %s expense.", opponent.nameOrPossessivePronoun(),
c.getStance().insertablePartFor(opponent).describe(opponent), nameOrPossessivePronoun(),
c.getStance().insertedPartFor(this).describe(this), possessivePronoun(), possessivePronoun(),
opponent.subjectAction("is", "are"), nameOrPossessivePronoun())));
then it'll be mostly fixed, although the "is" should possibly be "are". ("Once it's over, you is left considerably...")
Airi's intervene 3p is missing br br:
return Global.format(
"Your fight with {other:name} seemed to have ran into a stalemate. Neither of you is willing to get close enough to each other for anything substantial to happen. You just continue to trade taunt while waiting for an opportunity."
+ "Suddenly, a blue blob appears in your line of sight. It’s Airi! More swiftly than you would expect, Airi moves to {other:name}’s side and engulfs her body in her own. After dissolving her clothing with her slime, Airi surfaces only {other:name-possessive} torso and sex, presenting her to you. Well, presented with a gift on a silver platter, you’re not going to refuse!",
character, target);
Causes "opportunity.Suddenly" to appear in the output - missing a space. Either add a space or add 2 brs like the other case.
Typo in Mimicry:Witch:
+ "Looks like {self:NAME} is mimicking Cassie's witch form!.", getSelf(), target);
ends with "!.", remove the period
Opponent had a slime pet out; this exception occured:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at nightgames.characters.Character.resolveOrgasm(Character.java:1549)
at nightgames.characters.Character.doOrgasm(Character.java:1542)
at nightgames.characters.Character.resolvePleasure(Character.java:566)
at nightgames.characters.body.Body.pleasure(Body.java:599)
at nightgames.characters.body.Body.pleasure(Body.java:473)
at nightgames.pet.Slime.act(Slime.java:34)
at nightgames.combat.Combat.act(Combat.java:419)
at nightgames.gui.SkillButton.lambda$0(SkillButton.java:77)
at nightgames.gui.SkillButton$$Lambda$278/1362909116.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$400(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
---
Thanks for adding the drain challenge mode; I really like it.