| @@ -165,7 +165,8 @@ function grappleDevour(attacker) { | |||
| }, requirements: [ | |||
| function(attacker, defender) { return isNormal(attacker) && isGrappled(defender) && defender.flags.shrunk != true; } | |||
| ], conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; } | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.oral > 0; } | |||
| ], | |||
| priority: 1, | |||
| weight: function(attacker, defender) { return 1 - defender.health / defender.maxHealth; } | |||
| @@ -189,7 +190,8 @@ function grappledDevour(attacker) { | |||
| }, requirements: [ | |||
| function(attacker, defender) { return isGrappled(attacker) && isNormal(defender) && attacker.flags.shrunk != true; } | |||
| ], conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; } | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.oral > 0; } | |||
| ], | |||
| priority: 1, | |||
| }; | |||
| @@ -217,7 +219,8 @@ function grappleAnalVore(attacker) { | |||
| }, requirements: [ | |||
| function(attacker, defender) { return isNormal(attacker) && isGrappled(defender) && defender.flags.shrunk != true ; } | |||
| ], conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey && defender.prefs.analVore; } | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.anal > 0; } | |||
| ], | |||
| priority: 1, | |||
| }; | |||
| @@ -307,7 +310,7 @@ function grappledReverse(attacker) { | |||
| }, | |||
| requirements: [ | |||
| function(attacker, defender) { return isGrappled(attacker) && isNormalSize(attacker) && isNormal(defender); }, | |||
| function(attacker, defender) { return defender.flags.grapple; } | |||
| function(attacker, defender) { return attacker.flags.grappled; } | |||
| ], | |||
| priority: 1, | |||
| }; | |||
| @@ -350,6 +353,9 @@ function shrunkSwallow(attacker) { | |||
| function(attacker, defender) { | |||
| return isNormal(attacker) && defender.flags.grappled == true && defender.flags.shrunk == true; | |||
| } | |||
| ], conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.oral > 0; } | |||
| ], | |||
| priority: 2 | |||
| }; | |||
| @@ -412,18 +418,16 @@ function pass(attacker) { | |||
| function devourPlayer(attacker) { | |||
| return { | |||
| name: "Devours YOU!", | |||
| desc: "You won't see this", | |||
| conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; } | |||
| ], | |||
| requirements: [ | |||
| function(attacker, defender) { return attacker.leering == true; } | |||
| ], | |||
| attackPlayer: function(defender) { | |||
| changeMode("eaten"); | |||
| return ["The voracious " + attacker.description() + " pins you down, his slimy maw spreading wide and engulfing your upper body with ease. He swallows and shoves you deeper, cramming your succulent frame into churning, crushing depths in seconds. A lazy, drawn-out <i>belch</i> escapes his gullet, his hunger briefly sated...and your existence now in inescapable peril."]; | |||
| }, | |||
| }, conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.oral > 0; } | |||
| ], | |||
| priority: 1, | |||
| }; | |||
| } | |||
| @@ -28,7 +28,7 @@ function Geta() { | |||
| this.struggles.push(new rub(this)); | |||
| this.prefs.scat = false; | |||
| this.prefs.analVore = false; | |||
| this.prefs.vore.anal = 0; | |||
| } | |||
| function getaShrink(attacker) { | |||
| @@ -227,6 +227,8 @@ function Trance() { | |||
| this.attacks.push(new grappleSubdue(this)); | |||
| this.attacks.push(new tranceGrappleMaul(this)); | |||
| this.attacks.push(new tranceGrappleThroat(this)); | |||
| this.attacks.push(new tranceGrappleConsume(this)); | |||
| this.attacks.push(new tranceGrappleKill(this)); | |||
| this.attacks.push(new grappledReverse(this)); | |||
| this.attacks.push(new grappledDevour(this)); | |||
| @@ -329,10 +331,11 @@ function tranceGrappleDevour(attacker) { | |||
| }, requirements: [ | |||
| function(attacker, defender) { return isNormal(attacker) && isGrappled(defender) && defender.flags.shrunk != true; } | |||
| ], conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; } | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.oral > 0; } | |||
| ], | |||
| priority: 1, | |||
| weight: function(attacker, defender) { return 3 - 2 * defender.health / defender.maxHealth; } | |||
| weight: function(attacker, defender) { return (defender.prefs.vore.oral) * (3 - 2 * defender.health / defender.maxHealth); } | |||
| }; | |||
| } | |||
| @@ -359,6 +362,56 @@ function tranceGrappleMaul(attacker) { | |||
| }; | |||
| } | |||
| function tranceGrappleConsume(attacker) { | |||
| return { | |||
| attackPlayer: function(defender) { | |||
| defender.health = -100; | |||
| return ["The sergal sets about consuming your broken body, ripping you apart like deli meat as he sates his hunger. You are dead. Dead, dead, dead."]; | |||
| }, | |||
| requirements: [ | |||
| function(attacker, defender) { | |||
| return isNormal(attacker) && isGrappled(defender); | |||
| }, | |||
| function(attacker, defender) { | |||
| return defender.stamina <= 0 && defender.health <= 0; | |||
| } | |||
| ], | |||
| conditions: [ | |||
| function(attacker, defender) { | |||
| return defender.prefs.vore.hard > 0; | |||
| } | |||
| ], | |||
| priority: 3, | |||
| weight: function(attacker, defender) { return defender.prefs.vore.hard; }, | |||
| gameover: function() { return "Ripped apart and devoured by Trance"; } | |||
| }; | |||
| } | |||
| function tranceGrappleKill(attacker) { | |||
| return { | |||
| attackPlayer: function(defender) { | |||
| defender.health = -100; | |||
| return ["You're too tired to fight back as Trance's powerful hands grip your head, wrenching it to the side and snapping your neck like a twig - moments before his crushing jaws clamp down around your skull and crush it, killing you instantly."]; | |||
| }, | |||
| requirements: [ | |||
| function(attacker, defender) { | |||
| return isNormal(attacker) && isGrappled(defender); | |||
| }, | |||
| function(attacker, defender) { | |||
| return defender.stamina <= 0; | |||
| } | |||
| ], | |||
| conditions: [ | |||
| function(attacker, defender) { | |||
| return defender.prefs.vore.hard > 0; | |||
| } | |||
| ], | |||
| priority: 2, | |||
| weight: function(attacker, defender) { return defender.prefs.vore.hard; }, | |||
| gameover: function() { return "Ripped apart and devoured by Trance"; } | |||
| }; | |||
| } | |||
| function tranceGrappleThroat(attacker) { | |||
| return { | |||
| attackPlayer: function(defender) { | |||
| @@ -540,10 +593,11 @@ function taluthusGrabDevour(attacker) { | |||
| function(attacker, defender) { return isNormal(attacker) && isGrappled(defender) && defender.flags.shrunk != true; }, | |||
| function(attacker, defender) { return attacker.flags.grappleType == "hands"; } | |||
| ], conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; } | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.oral > 0; } | |||
| ], | |||
| priority: 1, | |||
| weight: function(attacker, defender) { return 1; } | |||
| weight: function(attacker, defender) { return defender.prefs.vore.oral; } | |||
| }; | |||
| } | |||
| @@ -569,10 +623,10 @@ function taluthusGrabCockVore(attacker) { | |||
| function(attacker, defender) { return attacker.flags.grappleType == "hands"; } | |||
| ], conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.cock; } | |||
| function(attacker, defender) { return defender.prefs.vore.cock > 0; } | |||
| ], | |||
| priority: 1, | |||
| weight: function(attacker, defender) { return 1; } | |||
| weight: function(attacker, defender) { return defender.prefs.vore.cock; } | |||
| }; | |||
| } | |||
| @@ -598,7 +652,7 @@ function taluthusTailDevour(attacker) { | |||
| function(attacker, defender) { return isNormal(attacker) && isNormal(defender); } | |||
| ], | |||
| priority: 1, | |||
| weight: function(attacker, defender) { return 7 - 6 * defender.health / defender.maxHealth; } | |||
| weight: function(attacker, defender) { return (7 - 6 * defender.health / defender.maxHealth) * defender.prefs.vore.tail; } | |||
| }; | |||
| } | |||
| @@ -897,8 +951,8 @@ function Selicia() { | |||
| this.defeated = function() { player.cash += 500; changeMode("explore"); moveToByName("Nature Trail"); update(["The dragoness yelps as you land your last blow, turning tail and darting away into the forest. You duck into her cave, finding a whole <i>pile</i> of wallets. Score!"]); }; | |||
| this.prefs.scat = false; | |||
| this.prefs.analVore = false; | |||
| this.prefs.prey = false; | |||
| this.attacks = []; | |||
| this.attacks.push(seliciaBite(this)); | |||
| @@ -1016,7 +1070,7 @@ function seliciaTailUnbirth(attacker) { | |||
| }, | |||
| conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.cock; } | |||
| function(attacker, defender) { return defender.prefs.vore.unbirth > 0; } | |||
| ], | |||
| requirements: [ | |||
| function(attacker, defender) { return isNormal(attacker) && isGrappled(defender); }, | |||
| @@ -1070,10 +1124,11 @@ function seliciaGrabSwallow(attacker) { | |||
| function(attacker, defender) { return isNormal(attacker) && isGrappled(defender); }, | |||
| function(attacker, defender) { return attacker.flags.voreType == "stomach"; } | |||
| ], conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; } | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.oral > 0; } | |||
| ], | |||
| priority: 1, | |||
| weight: function(attacker, defender) { return 1; } | |||
| weight: function(attacker, defender) { return defender.prefs.vore.oral; } | |||
| }; | |||
| } | |||
| @@ -1090,10 +1145,10 @@ function seliciaGrabUnbirth(attacker) { | |||
| function(attacker, defender) { return attacker.flags.voreType == "stomach"; } | |||
| ], conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.cock; } | |||
| function(attacker, defender) { return defender.prefs.vore.unbirth > 0; } | |||
| ], | |||
| priority: 1, | |||
| weight: function(attacker, defender) { return 2; } | |||
| weight: function(attacker, defender) { return defender.prefs.vore.unbirth; } | |||
| }; | |||
| } | |||
| @@ -1141,10 +1196,10 @@ function seliciaPinUnbirth(attacker) { | |||
| function(attacker, defender) { return attacker.flags.voreType == "unbirth"; } | |||
| ], conditions: [ | |||
| function(attacker, defender) { return defender.prefs.prey; }, | |||
| function(attacker, defender) { return defender.prefs.vore.cock; } | |||
| function(attacker, defender) { return defender.prefs.vore.unbirth > 0; } | |||
| ], | |||
| priority: 1, | |||
| weight: function(attacker, defender) { return 1; } | |||
| weight: function(attacker, defender) { return defender.prefs.vore.unbirth; } | |||
| }; | |||
| } | |||
| @@ -163,9 +163,40 @@ button { | |||
| } | |||
| #character-form-list { | |||
| margin: auto; | |||
| list-style-type: none; | |||
| } | |||
| #character-form { | |||
| font-size: 20pt; | |||
| } | |||
| .pref-radio { | |||
| display: none; | |||
| } | |||
| .pref-radio + label { | |||
| color: #666; | |||
| width: 150px; | |||
| } | |||
| .pref-radio:checked + label { | |||
| background: #333; | |||
| color: #eee; | |||
| } | |||
| .pref-select { | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| } | |||
| .pref-list { | |||
| text-align: center; | |||
| margin: auto; | |||
| user-select: none; | |||
| } | |||
| .pref-type { | |||
| width: 150px; | |||
| } | |||
| @@ -185,26 +185,89 @@ | |||
| <label for="character-species">Species</label> | |||
| <input type="text" id="character-species" name="species" placeholder="nerd"/> | |||
| </li> | |||
| <li> | |||
| <label for="character-prefs-prey">Player can be eaten</label> | |||
| <input type="checkbox" id="character-prefs-prey" name="prefs-prey" checked="true" /> | |||
| </li> | |||
| <li> | |||
| <label for="character-prefs-vore-cock">Cock vore</label> | |||
| <input type="checkbox" id="character-prefs-vore-cock" name="prefs-vore-cock" checked="true" /> | |||
| </li> | |||
| <li> | |||
| <label for="character-prefs-vore-unbirth">Unbirth</label> | |||
| <input type="checkbox" id="character-prefs-vore-unbirth" name="prefs-vore-unbirth" checked="true" /> | |||
| </li> | |||
| <li> | |||
| <label for="character-prefs-scat">Disposal/scat</label> | |||
| <input type="checkbox" id="character-prefs-scat" name="prefs-scat"/> | |||
| </li> | |||
| <li> | |||
| <label for="character-prefs-prey">Player can be eaten</label> | |||
| <input type="checkbox" id="character-prefs-prey" name="prefs-prey" checked="true" /> | |||
| </li> | |||
| <li> | |||
| <label for="character-prefs-gore">Gore</label> | |||
| <input type="checkbox" id="character-prefs-gore" name="prefs-gore"/> | |||
| </li> | |||
| <li> | |||
| <ul class="pref-list"> | |||
| <div>Enemy vore types</div> | |||
| <li class="pref-select"> | |||
| <span class="pref-type">Oral</span> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-oral-0" name="prefs-vore-oral" value="0" /> | |||
| <label for="character-prefs-vore-oral-0">Disabled</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-oral-1" name="prefs-vore-oral" value="1" /> | |||
| <label for="character-prefs-vore-oral-1">Avoid</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-oral-2" name="prefs-vore-oral" checked="true" value="2" /> | |||
| <label for="character-prefs-vore-oral-2">Enable</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-oral-3" name="prefs-vore-oral" value="3" /> | |||
| <label for="character-prefs-vore-oral-3">Prefer</label> | |||
| </li> | |||
| <li class="pref-select"> | |||
| <span class="pref-type">Cock</span> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-cock-0" name="prefs-vore-cock" value="0" /> | |||
| <label for="character-prefs-vore-cock-0">Disabled</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-cock-1" name="prefs-vore-cock" value="1" /> | |||
| <label for="character-prefs-vore-cock-1">Avoid</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-cock-2" name="prefs-vore-cock" checked="true" value="2" /> | |||
| <label for="character-prefs-vore-cock-2">Enable</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-cock-3" name="prefs-vore-cock" value="3" /> | |||
| <label for="character-prefs-vore-cock-3">Prefer</label> | |||
| </li> | |||
| <li class="pref-select"> | |||
| <span class="pref-type">Unbirth</span> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-unbirth-0" name="prefs-vore-unbirth" value="0" /> | |||
| <label for="character-prefs-vore-unbirth-0">Disabled</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-unbirth-1" name="prefs-vore-unbirth" value="1" /> | |||
| <label for="character-prefs-vore-unbirth-1">Avoid</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-unbirth-2" name="prefs-vore-unbirth" checked="true" value="2" /> | |||
| <label for="character-prefs-vore-unbirth-2">Enable</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-unbirth-3" name="prefs-vore-unbirth" value="3" /> | |||
| <label for="character-prefs-vore-unbirth-3">Prefer</label> | |||
| </li> | |||
| <li class="pref-select"> | |||
| <span class="pref-type">Anal</span> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-anal-0" name="prefs-vore-anal" value="0" /> | |||
| <label for="character-prefs-vore-anal-0">Disabled</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-anal-1" name="prefs-vore-anal" value="1" /> | |||
| <label for="character-prefs-vore-anal-1">Avoid</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-anal-2" name="prefs-vore-anal" checked="true" value="2" /> | |||
| <label for="character-prefs-vore-anal-2">Enable</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-anal-3" name="prefs-vore-anal" value="3" /> | |||
| <label for="character-prefs-vore-anal-3">Prefer</label> | |||
| </li> | |||
| <li class="pref-select"> | |||
| <span class="pref-type">Hard</span> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-hard-0" name="prefs-vore-hard" value="0" /> | |||
| <label for="character-prefs-vore-hard-0">Disabled</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-hard-1" name="prefs-vore-hard" value="1" /> | |||
| <label for="character-prefs-vore-hard-1">Avoid</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-hard-2" name="prefs-vore-hard" checked="true" value="2" /> | |||
| <label for="character-prefs-vore-hard-2">Enable</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-hard-3" name="prefs-vore-hard" value="3" /> | |||
| <label for="character-prefs-vore-hard-3">Prefer</label> | |||
| </li> | |||
| <li class="pref-select"> | |||
| <span class="pref-type">Tail</span> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-tail-0" name="prefs-vore-tail" value="0" /> | |||
| <label for="character-prefs-vore-tail-0">Disabled</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-tail-1" name="prefs-vore-tail" value="1" /> | |||
| <label for="character-prefs-vore-tail-1">Avoid</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-tail-2" name="prefs-vore-tail" checked="true" value="2" /> | |||
| <label for="character-prefs-vore-tail-2">Enable</label> | |||
| <input type="radio" class="pref-radio" id="character-prefs-vore-tail-3" name="prefs-vore-tail" value="3" /> | |||
| <label for="character-prefs-vore-tail-3">Prefer</label> | |||
| </li> | |||
| </ul> | |||
| </li> | |||
| <li> | |||
| <button type="button" id="start-button">Start</button> | |||
| </li> | |||
| @@ -304,6 +304,7 @@ window.addEventListener('load', function(event) { | |||
| function start() { | |||
| applySettings(generateSettings()); | |||
| transformVorePrefs(player.prefs); | |||
| document.getElementById("create").style.display = "none"; | |||
| document.getElementById("game").style.display = "block"; | |||
| document.getElementById("stat-button-status").addEventListener("click", status, false); | |||
| @@ -365,6 +366,21 @@ function applySettings(settings) { | |||
| } | |||
| } | |||
| // turn things like "1" into a number | |||
| function transformVorePrefs(prefs) { | |||
| for (let key in prefs.vore) { | |||
| if (prefs.vore.hasOwnProperty(key)) { | |||
| switch(prefs.vore[key]) { | |||
| case "0": prefs.vore[key] = 0; break; | |||
| case "1": prefs.vore[key] = 0.5; break; | |||
| case "2": prefs.vore[key] = 1; break; | |||
| case "3": prefs.vore[key] = 2; break; | |||
| } | |||
| } | |||
| } | |||
| return prefs; | |||
| } | |||
| function saveSettings() { | |||
| window.localStorage.setItem("settings", JSON.stringify(generateSettings())); | |||
| } | |||
| @@ -41,9 +41,14 @@ function Creature(name = "Creature", str=10, dex=10, con=10) { | |||
| this.prefs = { | |||
| prey: true, | |||
| scat: true, | |||
| analVore: true, | |||
| gore: true, | |||
| grapple: true | |||
| grapple: true, | |||
| vore: { | |||
| oral: 1, | |||
| anal: 1, | |||
| cock: 1, | |||
| unbirth: 1, | |||
| hard: 1 | |||
| } | |||
| }; | |||
| this.cash = Math.floor(Math.random() * 10 + 5); | |||