| @@ -872,6 +872,11 @@ let macro = | |||||
| "stages": 3 | "stages": 3 | ||||
| }, | }, | ||||
| "breathEnabled": false, | |||||
| "baseBreathArea": 10, | |||||
| "breathStyle": "cone", | |||||
| get breathArea() { return this.scaling(this.baseBreathArea, this.scale, 2); }, | |||||
| "pawVoreEnabled": false, | "pawVoreEnabled": false, | ||||
| "pawsVore": { | "pawsVore": { | ||||
| @@ -3678,6 +3683,62 @@ function paw_vore() | |||||
| macro.arouse(5); | macro.arouse(5); | ||||
| } | } | ||||
| function breath(type, style) { | |||||
| let area = macro.breathArea; | |||||
| let prey = new Container(); | |||||
| if (style == "line") { | |||||
| area *= 10; | |||||
| prey = getOnePrey(biome, area, true); | |||||
| } else if (style == "cone") { | |||||
| prey = getPrey(biome, area, true); | |||||
| } | |||||
| let line = describe("breath-" + type, prey, macro, verbose); | |||||
| let linesummary = summarize(prey.sum(), true); | |||||
| let preyMass = prey.sum_property("mass"); | |||||
| let sound = getSound("breath", preyMass); | |||||
| update([sound, line, linesummary, newline]); | |||||
| add_victim_people("breath-" + type, prey); | |||||
| } | |||||
| function breath_fire() { | |||||
| breath("fire", macro.breathStyle); | |||||
| } | |||||
| function breath_ice() { | |||||
| breath("ice", macro.breathStyle); | |||||
| } | |||||
| function breath_electric() { | |||||
| breath("electric", macro.breathStyle); | |||||
| } | |||||
| function breath_smoke() { | |||||
| breath("smoke", macro.breathStyle); | |||||
| } | |||||
| function breath_radiation() { | |||||
| breath("radiation", macro.breathStyle); | |||||
| } | |||||
| function breath_foul() { | |||||
| breath("foul", macro.breathStyle); | |||||
| } | |||||
| function breath_line() { | |||||
| macro.breathStyle = "line"; | |||||
| update(["You prepare to exhale a focused line of breath!",newline]); | |||||
| } | |||||
| function breath_cone() { | |||||
| macro.breathStyle = "cone"; | |||||
| update(["You prepare to exhale a broad cone of breath!",newline]); | |||||
| } | |||||
| function cooldown_start(name) { | function cooldown_start(name) { | ||||
| let button = document.querySelector("#" + "button-action-" + name); | let button = document.querySelector("#" + "button-action-" + name); | ||||
| let parent = button.parentElement; | let parent = button.parentElement; | ||||
| @@ -4417,6 +4478,43 @@ function startGame(e) { | |||||
| } | } | ||||
| } | } | ||||
| if (macro.breathEnabled) { | |||||
| enable_panel("breath"); | |||||
| enable_button("breath_line"); | |||||
| enable_button("breath_cone"); | |||||
| if (macro.breathFire) { | |||||
| enable_button("breath_fire"); | |||||
| enable_victim("breath-fire","Incinerated by fiery breath"); | |||||
| } | |||||
| if (macro.breathIce) { | |||||
| enable_button("breath_ice"); | |||||
| enable_victim("breath-ice","Frozen in icy breath"); | |||||
| } | |||||
| if (macro.breathElectric) { | |||||
| enable_button("breath_electric"); | |||||
| enable_victim("breath-electric","Fried by an electric gale"); | |||||
| } | |||||
| if (macro.breathSmoke) { | |||||
| enable_button("breath_smoke"); | |||||
| enable_victim("breath-smoke","Snuffed out by smoke"); | |||||
| } | |||||
| if (macro.breathRadiation) { | |||||
| enable_button("breath_radiation"); | |||||
| enable_victim("breath-radiation","Vaporized by radioactive power"); | |||||
| } | |||||
| if (macro.breathFoul) { | |||||
| enable_button("breath_foul"); | |||||
| enable_victim("breath-foul","Smothered in humid breath"); | |||||
| } | |||||
| } | |||||
| document.getElementById("button-arousal").innerHTML = (macro.arousalEnabled ? "Arousal On" : "Arousal Off"); | document.getElementById("button-arousal").innerHTML = (macro.arousalEnabled ? "Arousal On" : "Arousal Off"); | ||||
| if (!macro.arousalEnabled) { | if (!macro.arousalEnabled) { | ||||
| document.getElementById("arousal").style.display = "none"; | document.getElementById("arousal").style.display = "none"; | ||||
| @@ -30,7 +30,8 @@ var actions = ["eat","chew","vomit","stomp","stomp-wedge","flex-toes","kick","an | |||||
| "soul-digest","wear-shoe","remove-shoe","wear-sock","remove-sock","stuff-shoe","dump-shoe","stuff-sock","dump-sock","piss","bladder-vore","scat", | "soul-digest","wear-shoe","remove-shoe","wear-sock","remove-sock","stuff-shoe","dump-shoe","stuff-sock","dump-sock","piss","bladder-vore","scat", | ||||
| "sheath-toy","slit-toy","breast-toy","melt","solidify","flood","stomp-goo","goo-digest","ass-goo","goo-stomach-pull","goo-stomach-push", | "sheath-toy","slit-toy","breast-toy","melt","solidify","flood","stomp-goo","goo-digest","ass-goo","goo-stomach-pull","goo-stomach-push", | ||||
| "goo-bowels-pull","goo-bowels-push","goo-womb-pull","goo-womb-push","goo-balls-pull","goo-balls-push","goo-breasts-pull","goo-breasts-push", | "goo-bowels-pull","goo-bowels-push","goo-womb-pull","goo-womb-push","goo-balls-pull","goo-balls-push","goo-breasts-pull","goo-breasts-push", | ||||
| "goo-tail-pull","goo-tail-push","goo-paws-pull","goo-paws-push","paw-vore","paw-vore-toes","paws","crop-swallow","crop-transfer"]; | |||||
| "goo-tail-pull","goo-tail-push","goo-paws-pull","goo-paws-push","paw-vore","paw-vore-toes","paws","crop-swallow","crop-transfer", | |||||
| "breath-fire","breath-ice","breath-electric","breath-smoke","breath-radiation","breath-foul"]; | |||||
| for (let i=0; i<actions.length; i++) { | for (let i=0; i<actions.length; i++) { | ||||
| rules[actions[i]] = []; | rules[actions[i]] = []; | ||||
| @@ -991,6 +992,109 @@ function defaultCropTransfer(container, macro, verbose) { | |||||
| return "Your throat squeezes, forcing " + container.describe(verbose) + " out of your crop and in to your stomach."; | return "Your throat squeezes, forcing " + container.describe(verbose) + " out of your crop and in to your stomach."; | ||||
| } | } | ||||
| function nonFatalBreath(container, macro, verbose, type, verb) { | |||||
| if (macro.breathStyle == "line") { | |||||
| return "You exhale a narrow gout of " + type + ", " + verb + " " + container.describe(verbose) + "."; | |||||
| } else if (macro.breathStyle == "cone") { | |||||
| return "You exhale a broad cone of " + type + ", " + verb + " " + container.describe(verbose) + "."; | |||||
| } | |||||
| } | |||||
| function defaultBreathFire(container, macro, verbose) { | |||||
| if (isNonFatal(macro)) { | |||||
| return nonFatalBreath(container, macro, verbose, "fire", "blasting"); | |||||
| } | |||||
| if (isFatal(macro)) { | |||||
| if (macro.breathStyle == "line") { | |||||
| return "A withering spear of fire gouts from your maw, spearing through " + container.describe(verbose) + " and incinerating it in a torrid display of power."; | |||||
| } else if (macro.breathStyle == "cone") { | |||||
| return "You exhale a broad cone of powerful fire, burning " + container.describe(verbose) + " to a crisp in an inescapable tide of flames."; | |||||
| } | |||||
| } | |||||
| return "FIRE" + container.describe(verbose); | |||||
| } | |||||
| function defaultBreathIce(container, macro, verbose) { | |||||
| if (isNonFatal(macro)) { | |||||
| return nonFatalBreath(container, macro, verbose, "cold", "freezing"); | |||||
| } | |||||
| if (isFatal(macro)) { | |||||
| if (macro.breathStyle == "line") { | |||||
| return "You heave a lance of frigid cold from your gullet, freezing a " + container.describe(verbose) + " to the core."; | |||||
| } else if (macro.breathStyle == "cone") { | |||||
| return "A blizzard erupts from your maw, flash-freezing " + container.describe(verbose) + ". " + (container.count > 1 ? "They" : "It") + " shatters a heartbeat later, reduced to dust by your power."; | |||||
| } | |||||
| } | |||||
| return "ICE" + container.describe(verbose); | |||||
| } | |||||
| function defaultBreathElectric(container, macro, verbose) { | |||||
| if (isNonFatal(macro)) { | |||||
| return nonFatalBreath(container, macro, verbose, "electricity", "shocking"); | |||||
| } | |||||
| if (isFatal(macro)) { | |||||
| if (macro.breathStyle == "line") { | |||||
| return "A blinding lance of lightning blasts from your spread " + macro.jawDesc(true) + ", cooking a " + container.describe(verbose) + " from the inside out."; | |||||
| } else if (macro.breathStyle == "cone") { | |||||
| return "You exhale a brilliant, forking spray of lightning. The flickering bolts arc through " + container.describe(verbose) + ", cooking everything to a crisp."; | |||||
| } | |||||
| } | |||||
| return "ELECTRIC" + container.describe(verbose); | |||||
| } | |||||
| function defaultBreathSmoke(container, macro, verbose) { | |||||
| if (isNonFatal(macro)) { | |||||
| return nonFatalBreath(container, macro, verbose, "smoke", "smothering"); | |||||
| } | |||||
| if (isFatal(macro)) { | |||||
| if (macro.breathStyle == "line") { | |||||
| return "You part your " + macro.jawDesc(true) + " a touch and blow, casting a thin gout of smoke that envelops a " + container.describe(verbose) + ". Your prey is snuffed out like a candle."; | |||||
| } else if (macro.breathStyle == "cone") { | |||||
| return "You open wide and exhale. A rolling storm of smoke pours forth, smothering " + container.describe(verbose) + " in a pyroclastic flow."; | |||||
| } | |||||
| } | |||||
| return "SMOKE" + container.describe(verbose); | |||||
| } | |||||
| function defaultBreathRadiation(container, macro, verbose) { | |||||
| if (isNonFatal(macro)) { | |||||
| return nonFatalBreath(container, macro, verbose, "radiation", "frying"); | |||||
| } | |||||
| if (isFatal(macro)) { | |||||
| if (macro.breathStyle == "line") { | |||||
| return "Your depths pour out a narrow beam of crackling green energy, striking a " + container.describe(verbose) + " and frying it to a crisp, turning your prey to dust in the wind."; | |||||
| } else if (macro.breathStyle == "cone") { | |||||
| return "You part your " + macro.jawDesc(true) + ", roaring as a massive tide of radiation spews forth. It rolls over " + container.describe(verbose) + ", evaporating " + (container.count > 1 ? "them" : "it") + " in seconds."; | |||||
| } | |||||
| } | |||||
| return "RADIATION" + container.describe(verbose); | |||||
| } | |||||
| function defaultBreathFoul(container, macro, verbose) { | |||||
| if (isNonFatal(macro)) { | |||||
| return nonFatalBreath(container, macro, verbose, "foul air", "withering"); | |||||
| } | |||||
| if (isFatal(macro)) { | |||||
| if (macro.breathStyle == "line") { | |||||
| return "You blow a narrow stream of breath, withering " + container.describe(verbose) + " in a focused torrent of foul, humid fumes."; | |||||
| } else if (macro.breathStyle == "cone") { | |||||
| return "You yawn wide and sigh, snuffing out " + container.describe(verbose) + " under a tide of hot, humid breath."; | |||||
| } | |||||
| } | |||||
| return "FOUL" + container.describe(verbose); | |||||
| } | |||||
| // EATING | // EATING | ||||
| rules["eat"].push({ | rules["eat"].push({ | ||||
| @@ -14,7 +14,9 @@ let sounds = { | |||||
| "goo": | "goo": | ||||
| ["Splat.", "Squish.", "Squish!", "SQLCH!", "SQLLLLRCH!", "SQQQQUEEEEELLCH!"], | ["Splat.", "Squish.", "Squish!", "SQLCH!", "SQLLLLRCH!", "SQQQQUEEEEELLCH!"], | ||||
| "vomit": | "vomit": | ||||
| ["Hurk.", "Hurrk.", "Bleugh.", "Bleugh!", "Bleeeugh!", "BLEEEUGHK!"] | |||||
| ["Hurk.", "Hurrk.", "Bleugh.", "Bleugh!", "Bleeeugh!", "BLEEEUGHK!"], | |||||
| "breath": | |||||
| ["Woosh.","Fwoosh.","FWOOSH.","FWOOSH!","FWOOOOOOSH!"] | |||||
| }; | }; | ||||
| function pickByMass(list, mass) { | function pickByMass(list, mass) { | ||||
| @@ -208,6 +208,7 @@ | |||||
| <button class="action-part-button" id="action-part-waste">Waste</button> | <button class="action-part-button" id="action-part-waste">Waste</button> | ||||
| <button class="action-part-button" id="action-part-goo">Goo</button> | <button class="action-part-button" id="action-part-goo">Goo</button> | ||||
| <button class="action-part-button" id="action-part-misc">Misc</button> | <button class="action-part-button" id="action-part-misc">Misc</button> | ||||
| <button class="action-part-button" id="action-part-breath">Breath</button> | |||||
| <button class="action-part-button" id="action-part-options">Options</button> | <button class="action-part-button" id="action-part-options">Options</button> | ||||
| </div> | </div> | ||||
| @@ -322,6 +323,17 @@ | |||||
| <button class="action-button" id="button-action-pouch_absorb">Absorb Pouch</button> | <button class="action-button" id="button-action-pouch_absorb">Absorb Pouch</button> | ||||
| </div> | </div> | ||||
| <div class="action-tab" id="actions-breath"> | |||||
| <button class="action-button" id="button-action-breath_line">Line Shape</button> | |||||
| <button class="action-button" id="button-action-breath_cone">Cone Shape</button> | |||||
| <button class="action-button" id="button-action-breath_fire">Fire</button> | |||||
| <button class="action-button" id="button-action-breath_ice">Ice</button> | |||||
| <button class="action-button" id="button-action-breath_electric">Electric</button> | |||||
| <button class="action-button" id="button-action-breath_smoke">Smoke</button> | |||||
| <button class="action-button" id="button-action-breath_radiation">Radiation</button> | |||||
| <button class="action-button" id="button-action-breath_foul">Foul</button> | |||||
| </div> | |||||
| <div class="action-tab" id="actions-options"> | <div class="action-tab" id="actions-options"> | ||||
| <button class="stat-button" id="button-arousal">Arousal On</button> | <button class="stat-button" id="button-arousal">Arousal On</button> | ||||
| <button class="stat-button" id="button-stroll">Status: Standing</button> | <button class="stat-button" id="button-stroll">Status: Standing</button> | ||||
| @@ -1075,6 +1087,37 @@ | |||||
| </li> | </li> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="custom-category"> | |||||
| <input autocomplete="off" class="custom-header-checkbox" type="checkbox" id="breathEnabled" name="breathEnabled" /> | |||||
| <label class="custom-header" for="breathEnabled">Breath</label> | |||||
| <div class="reveal-if-active"> | |||||
| <li> | |||||
| <input autocomplete="off" type="checkbox" name="breathFire" id="breathFire" /> | |||||
| <label for="breathFire">Fire</label> | |||||
| </li> | |||||
| <li> | |||||
| <input autocomplete="off" type="checkbox" name="breathIce" id="breathIce" /> | |||||
| <label for="breathIce">Ice</label> | |||||
| </li> | |||||
| <li> | |||||
| <input autocomplete="off" type="checkbox" name="breathElectric" id="breathElectric" /> | |||||
| <label for="breathElectric">Electric</label> | |||||
| </li> | |||||
| <li> | |||||
| <input autocomplete="off" type="checkbox" name="breathSmoke" id="breathSmoke" /> | |||||
| <label for="breathSmoke">Smoke</label> | |||||
| </li> | |||||
| <li> | |||||
| <input autocomplete="off" type="checkbox" name="breathRadiation" id="breathRadiation" /> | |||||
| <label for="breathRadiation">Radiation</label> | |||||
| </li> | |||||
| <li> | |||||
| <input autocomplete="off" type="checkbox" name="breathFoul" id="breathFoul" /> | |||||
| <label for="breathFoul">Foul</label> | |||||
| </li> | |||||
| </div> | |||||
| </div> | |||||
| </ul> | </ul> | ||||
| </form> | </form> | ||||
| </div> | </div> | ||||