Browse Source

Merge branch 'master' into mass-vore

mass-vore
Fen Dweller 5 years ago
parent
commit
a3e49f5f00
26 changed files with 404 additions and 41 deletions
  1. +1
    -0
      .gitattributes
  2. +18
    -2
      .gitignore
  3. +167
    -0
      .vscode/templates.code-snippets
  4. +3
    -0
      README.md
  5. +6
    -10
      game.js
  6. BIN
      media/demo/audio/sfx/oof.ogg
  7. BIN
      media/fen-snack/audio/loop/fen-bowels.ogg
  8. BIN
      media/fen-snack/audio/loop/fen-intestines.ogg
  9. BIN
      media/fen-snack/audio/loop/fen-stomach.ogg
  10. BIN
      media/fen-snack/audio/sfx/bowels-churn-danger.ogg
  11. BIN
      media/fen-snack/audio/sfx/bowels-churn-safe.ogg
  12. BIN
      media/fen-snack/audio/sfx/bowels-to-intestines.ogg
  13. BIN
      media/fen-snack/audio/sfx/digested-test.ogg
  14. BIN
      media/fen-snack/audio/sfx/intestines-churn-stay.ogg
  15. BIN
      media/fen-snack/audio/sfx/intestines-to-bowels.ogg
  16. BIN
      media/fen-snack/audio/sfx/intestines-to-stomach-forced.ogg
  17. BIN
      media/fen-snack/audio/sfx/intestines-to-stomach.ogg
  18. BIN
      media/fen-snack/audio/sfx/stomach-churn.ogg
  19. BIN
      media/fen-snack/audio/sfx/stomach-to-intestines-fail.ogg
  20. BIN
      media/fen-snack/audio/sfx/stomach-to-intestines.ogg
  21. +5
    -0
      satiate.css
  22. +4
    -2
      satiate.html
  23. +6
    -1
      satiate.js
  24. +5
    -5
      stories/demo.js
  25. +141
    -20
      stories/fen-snack.js
  26. +3
    -1
      world.js

+ 1
- 0
.gitattributes View File

@@ -0,0 +1 @@
*.ogg filter=lfs diff=lfs merge=lfs -text

+ 18
- 2
.gitignore View File

@@ -1,2 +1,18 @@
media/
.vscode

# Created by https://www.gitignore.io/api/visualstudiocode
# Edit at https://www.gitignore.io/?templates=visualstudiocode

### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

### VisualStudioCode Patch ###
# Ignore all local history of files
.history

# End of https://www.gitignore.io/api/visualstudiocode

!.vscode/templates.code-snippets

+ 167
- 0
.vscode/templates.code-snippets View File

@@ -0,0 +1,167 @@
{
// Place your satiate workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
// Placeholders with the same ids are connected.
// Example:
// "Print to console": {
// "scope": "javascript,typescript",
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }
"Room": {
"prefix": "room",
"body": [
"\"$1\": {",
" \"id\": \"$1\",",
" \"name\": \"$2\",",
" \"desc\": \"$3\",",
" \"move\": (room, state) => {",
"",
" },",
" \"enter\": (room, state) => {",
"",
" },",
" \"exit\": (room, state) => {",
"",
" },",
" \"actions\": [",
"",
" ],",
" \"exits\": {",
"",
" },",
" \"hooks\": [",
"",
" ],",
" \"data\": {",
" \"stats\": {",
" ",
" }",
" }",
"},"
],
"description": "Room"
},
"Action": {
"prefix": "action",
"body": [
"{",
" name: \"$1\",",
" desc: \"$2\",",
" execute: (room, state) => {",
"",
" },",
" show: [",
"",
" ],",
" conditions: [",
"",
" ]",
"},"
],
"description": "Action"
},
"Exit": {
"prefix": "exit",
"body": [
"\"$1\": {",
" \"target\": \"$2\",",
" \"desc\": \"$3\",",
" \"show\": [",
" ",
" ],",
" \"conditions\": [",
"",
" ],",
" \"hooks\": [",
" ",
" ]",
"},"
],
"description": "Exit"
},
"Condition": {
"prefix": "cond",
"body": [
"(room, state) => {",
" return ${1:true}",
"}",
""
],
"description": "Condition"
},
"Hook": {
"prefix": "hook",
"body": [
"(room, exit, state) => {",
" return ${1:true}",
"}",
""
],
"description": "Condition"
},
"Stat": {
"prefix": "stat",
"body": [
"{\"name\": \"$1\", \"type\": \"${2|foo,bar|}\", \"value\": $3, \"max\": $4, \"color\": \"rgb(0,0,0)\" }"
],
"description": "Stat"
},
"Timer": {
"prefix": "timer",
"body": [
"startTimer({",
" id: \"$1\",",
" func: state => {",
" return true;",
" },",
" delay: $2,",
" loop: $3,",
" classes: [",
"",
" ]",
"}, state);",
""
],
"description": "Timer"
},
"Story": {
"prefix": "story",
"body": [
"stories.push({",
" \"id\": \"$1\",",
" \"name\": \"$2\",",
" \"tags\": [",
"",
" ],",
" \"intro\": {",
" \"start\": \"$3\",",
" \"setup\": state => {",
"",
" },",
" \"intro\": state => {",
"",
" }",
" },",
" \"sounds\": [",
"",
" ],",
" \"preload\": [",
"",
" ],",
" \"world\": {",
" ",
" }",
"});",
""
],
"description": "Story"
}
}

+ 3
- 0
README.md View File

@@ -0,0 +1,3 @@
big monch

https://satiate.crux.sexy

+ 6
- 10
game.js View File

@@ -55,6 +55,10 @@ function initGamePostSetup(state) {
createStatDisplays(state.player.stats, "player");
}

function getStat(stat, state) {
return state.player.stats[stat].value;
}

function changeStat(stat, amount, state) {
let value = state.player.stats[stat].value;
value += amount;
@@ -98,7 +102,6 @@ function updateStatDisplay(stats, statType) {
func: the function to invoke
delay: how long to wait between invocations
loop: false = no looping, true = loop forever
room: the room associated with the timer
}

Returns the timeout id - but you still need to cancel it through stopTimer!
@@ -126,8 +129,8 @@ function startTimer(config, state) {
}

}, config.delay);
state.timers.push({id: config.id, timeout: timeout, room: config.room, classes: config.classes || []});
state.timers.push({id: config.id, timeout: timeout, classes: config.classes || []});

return timeout;
}
@@ -139,13 +142,6 @@ function stopTimer(id, state) {
state.timers = state.timers.filter(timer => timer.id != id);
}

function stopRoomTimers(room, state) {
const matches = state.timers.filter(timer => timer.room == room);
matches.forEach(timer => clearTimeout(timer.timeout));

state.timers = state.timers.filter(timer => timer.room != room);
}

function stopClassTimers(timerClass, state, inverse) {
const matches = state.timers.filter(timer => timer.classes.includes(timerClass));
const others = state.timers.filter(timer => !timer.classes.includes(timerClass));


BIN
media/demo/audio/sfx/oof.ogg (Stored with Git LFS) View File

oid sha256:e3476f4fd3e3eacb3fcc7c6616c3573c35289c8486f60e9e64c262d38aa290fb
size 8461

BIN
media/fen-snack/audio/loop/fen-bowels.ogg (Stored with Git LFS) View File

oid sha256:cad1673ea5f4a85a7eb2cd125073ac9daf1bc27d105520e847af06549bd44abb
size 2698636

BIN
media/fen-snack/audio/loop/fen-intestines.ogg (Stored with Git LFS) View File

oid sha256:7f7645ce0b6fed13c6222edc1c66b73aa5c71c7f9fd8df6d651d28e1cfeaa94c
size 3251342

BIN
media/fen-snack/audio/loop/fen-stomach.ogg (Stored with Git LFS) View File

oid sha256:0dcd827ff7f1daafaed20af0b8f34f5aa249b005e60380ff75ce5e356eeafa9d
size 5468962

BIN
media/fen-snack/audio/sfx/bowels-churn-danger.ogg (Stored with Git LFS) View File

oid sha256:353212c0b88d5acf1cba7795462b516e07c5743117e8773f8694d7e1e1d52490
size 294651

BIN
media/fen-snack/audio/sfx/bowels-churn-safe.ogg (Stored with Git LFS) View File

oid sha256:545cbe12f08f53c70c841c7fa1c1d55283804a0d72b39667c9763a24c7acb842
size 248493

BIN
media/fen-snack/audio/sfx/bowels-to-intestines.ogg (Stored with Git LFS) View File

oid sha256:a81d487034696805b5862119b4b0e71336ac9fbc4eee22e89b6d20e82f16d967
size 176136

BIN
media/fen-snack/audio/sfx/digested-test.ogg (Stored with Git LFS) View File

oid sha256:1c3494e1f10d3c8839d666c2fec151e92b0b17bf96ddb08693db059f02050fbb
size 170395

BIN
media/fen-snack/audio/sfx/intestines-churn-stay.ogg (Stored with Git LFS) View File

oid sha256:9d0420d895f80cb90a3950ebf9d021684b03db28fd1f1a8c450f4a0d72845b6b
size 271976

BIN
media/fen-snack/audio/sfx/intestines-to-bowels.ogg (Stored with Git LFS) View File

oid sha256:cb38da98e5d9761d49b985472cb3ba857fc5f87740417e296a013d2877848ea9
size 192147

BIN
media/fen-snack/audio/sfx/intestines-to-stomach-forced.ogg (Stored with Git LFS) View File

oid sha256:54234c188544a284d98ce95620428614b56d5d7c599b5f8ad63a990566beb84f
size 344218

BIN
media/fen-snack/audio/sfx/intestines-to-stomach.ogg (Stored with Git LFS) View File

oid sha256:fd78e3b1e6ef70d937368e3b27a794d0091c8ed41f0b3d1e4f5152f79a67b956
size 204429

BIN
media/fen-snack/audio/sfx/stomach-churn.ogg (Stored with Git LFS) View File

oid sha256:00bef9333b297f6d8b4e56360f7eb45a886f353a9e218adf850e288e2c18b8ba
size 249950

BIN
media/fen-snack/audio/sfx/stomach-to-intestines-fail.ogg (Stored with Git LFS) View File

oid sha256:54fcf614d14a8dd17512a69963bc5807bfd9429a0090fb81842f50c3bf904a1a
size 205753

BIN
media/fen-snack/audio/sfx/stomach-to-intestines.ogg (Stored with Git LFS) View File

oid sha256:515dc49dc92add3ab47d0e1444dbe40ebb147245f6ed738b71037a183ee1c1ea
size 193869

+ 5
- 0
satiate.css View File

@@ -350,6 +350,11 @@ a:hover {
border: none;
}

.missing {
background-color: #444;
color: #aaa !important;
}

#move-up-left {
position: absolute;
left: -140px;


+ 4
- 2
satiate.html View File

@@ -16,8 +16,8 @@
<meta name="description" content="A text adventure!" />
<meta property="og:title" content="Satiate" />
<meta property="og:description" content="A text adventure!" />
<meta property="og:image" content="/satiate.png" />
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<meta property="og:image" content="https://crux.sexy/images/satiate.png" />
<link rel="icon" href="https://crux.sexy/images/satiate.ico">
</head>

<body>
@@ -25,6 +25,8 @@
<div id="pick-blurb">
<p>Welcome to Satiate</p>
<a href="https://discord.gg/dSwNN8T">Discord Server</a>
<br>
<a href="https://crux.sexy/changelog#satiate">Changelog</a>
<p class="version">Version: </p>
<p><b>This game contains 18+ content</b></p>
<p><b>Most of the games have sound!</b></p>


+ 6
- 1
satiate.js View File

@@ -3,7 +3,7 @@
let activeModal = null;

const newline = String.fromCharCode(160);
const version = "0.1.1";
const version = "0.1.2";

let state;

@@ -22,6 +22,11 @@ function print(lines) {
log.scrollTop = log.scrollHeight;
}

function printRandom(list) {
let choice = Math.floor(Math.random() * list.length)
print(list[choice])
}

function refresh() {
updateRoom(state);
updateStatDisplay(state.info, "world");


+ 5
- 5
stories/demo.js View File

@@ -46,15 +46,14 @@ stories.push({
delay: 1000,
loop: true,
classes: [
"Home"
],
room: "Home",
}, state);
},
"exit": (room, state) => {
print(["You are exiting your house"]);

stopRoomTimers("Home", state);
stopClassTimers("Home", state);
},
"actions": [
{
@@ -99,9 +98,10 @@ stories.push({
},
"descend": {
"target": "Stairs",
"desc": "Dare you go down the stiars?",
"desc": "Dare you go down the stairs?",
"hooks": [
(room, state) => {
(room, exit, state) => {
console.log(state)
print(["You're very concerned that you'll fall down all these stairs."]);
return false;
}


+ 141
- 20
stories/fen-snack.js View File

@@ -32,6 +32,22 @@ stories.push({
state.player.stats.health = {name: "Health", type: "meter", value: 100, min: 0, max: 100, color: "rgb(255,0,0)"};
state.player.stats.stamina = {name: "Stamina", type: "meter", value: 100, min: 0, max: 100, color: "rgb(100,255,0)"};

startTimer({
id: "taunting",
func: state => {
printRandom([
["The crux strokes over his snarling gut, enjoying your dwindling squirms."],
["\"Enjoying yourself, meal?\"", "Your captor's oh-so-smug voice booms in your ears."]
])
return 25000 + Math.random() * 10000;
},
delay: 5000,
loop: true,
classes: [
"alive"
]
}, state);
startTimer({
id: "movement",
func: state => {
@@ -79,6 +95,36 @@ stories.push({
if (state.player.stats.health.value <= 0) {
state.player.stats.health.value = 0;

const start = 86400 - 60 * 25 - 25;
const end = state.info.time.value;

const time_survived = end - start;
const minutes = Math.floor(time_survived / 60);
const seconds = time_survived % 60;
const minute_text = minutes + (minutes == 1 ? " minute" : " minutes");
const second_text = seconds + (seconds == 1 ? " second" : " seconds");

let time_text;

if (minutes == 0)
time_text = "You survived for " + second_text + ".";
else
time_text = "You survived for " + minute_text + " and " + second_text + ".";

startTimer({
id: "time-text",
func: state => {
print([time_text]);
return true;
},
delay: 2000,
loop: false,
classes: [
]
}, state);

if (location.startsWith("stomach")) {
goToRoom("digested-stomach", state);
}
@@ -109,11 +155,11 @@ stories.push({
let bonus = state.player.flags.submission ? -3 : 0;
bonus += state.player.flags.pinned ? -0.5 : 0;
if (location.startsWith("stomach")) {
changeStat("stamina", 1 + bonus, state);
changeStat("stamina", 0.75 + bonus, state);
}

if (location.startsWith("intestines")) {
changeStat("stamina", 0.5 + bonus, state);
changeStat("stamina", 1.25 + bonus, state);
}

if (location.startsWith("bowels")) {
@@ -144,7 +190,7 @@ stories.push({
}, state);
},
intro: state => {
print(["Hot, slimy walls ripple and squeeze, the stomach of your captor stewing you in a churning bath of chyme and acid. The blue crux made a late-night meal out of you with ease. You've only been trapped under the Fen's pelt for a few minutes...and it doesn't seem like you'll last much longer than that, either."]);
print(["Hot, slimy walls ripple and squeeze, the stomach of your captor stewing you in a churning bath of chyme and acid. The purple crux made a late-night meal out of you with ease. You've only been trapped under the Fen's pelt for a few minutes...but it doesn't seem like you'll make it until midnight."]);
playSfx("sfx/stomach-churn.ogg");
}
},
@@ -174,15 +220,15 @@ stories.push({
},
delay: 10000,
loop: true,
room: "stomach",
classes: [
"alive"
"alive",
"stomach"
]
}, state);
},
exit: (room, state) => {
stopLoop("loop/fen-stomach.ogg");
stopRoomTimers("stomach", state);
stopClassTimers("stomach", state);
},
hooks: [

@@ -196,6 +242,22 @@ stories.push({
print(["You rub all over your prison's walls. Fen's stomach gurgles in response."]);
}
},
{
name: "Thrash",
desc: "Kick and struggle",
execute: (room, state) => {
changeStat("health", -10, state);
changeStat("stamina", -35, state);
print(["Your thrash and kick and punch - and, for your insolence, you are rewarded with a crushing CLENCH. Fen's grinding guts smother and squeeze your softening body, nearly popping you like a grape."]);
playSfx("sfx/stomach-churn.ogg");
},
show: [
],
conditions: [
]
},
{
name: "Submit",
desc: "Let Fen digest you",
@@ -264,7 +326,7 @@ stories.push({
startTimer({
id: "intestines-churns",
func: state => {
if (Math.random() > 0.6) {
if (Math.random() > 0.5) {
if (state.player.stats.stamina.value > 50) {
changeStat("stamina", -25, state);
print(["Your prison's walls ripple and grind, shoving you against the valve leading to the crux's boiling stomach - but you manage to resist the powerful pull."]);
@@ -274,20 +336,25 @@ stories.push({
playSfx("sfx/intestines-to-stomach-forced.ogg");
goToRoom("stomach", state);
}
} else {
changeStat("stamina", -25, state);
print(["Overwhelming peristalsis grips your body and crams it into the beast's hot, life-sapping bowels."]);
playSfx("sfx/intestines-to-stomach-forced.ogg");
goToRoom("bowels", state);
}
return true;
return 10000 + Math.random() * 5000;
},
delay: 10000,
loop: true,
room: "intestines",
classes: [
"alive"
"alive",
"intestines"
]
}, state);
},
exit: (room, state) => {
stopLoop("loop/fen-intestines.ogg");
stopRoomTimers("intestines", state);
stopClassTimers("intestines", state);
},
exits: {
"up": {
@@ -332,7 +399,7 @@ stories.push({
desc: "Knead on the muscular folds that surround your tasty little body",
execute: (room, state) => {
changeStat("stamina", -20, state);
print(["You rub all over your prison's walls. Fen's guts barely move."]);
print(["You rub all over your prison's walls. Fen's intestines quiver and clench in response."]);
}
},
{
@@ -340,7 +407,7 @@ stories.push({
desc: "Let Fen digest you",
execute: (room, state) => {
state.player.flags.submission = true;
print(["You go limp in the crux's intestines, letting the winding, worryingly-tight guts take you in..."]);
print(["You go limp in the crux's intestines, letting the winding guts take you in..."]);
},
show: [
(room, state) => {
@@ -385,9 +452,9 @@ stories.push({
},
delay: 1000,
loop: true,
room: "bowels",
classes: [
"alive"
"alive",
"bowels"
]
}, state);

@@ -399,15 +466,15 @@ stories.push({
},
delay: 10000,
loop: true,
room: "bowels",
classes: [
"alive"
"alive",
"bowels"
]
}, state);
},
exit: (room, state) => {
stopLoop("loop/fen-bowels.ogg");
stopRoomTimers("bowels", state);
stopClassTimers("bowels", state);
},
exits: {
"up": {
@@ -435,7 +502,33 @@ stories.push({
return true;
}
]
}
},
"down": {
"target": "freedom",
"desc": "Try to squirm out of the beast",
"show": [
],
"conditions": [
(room, state) => {
return !state.player.flags.submission;
},
(room, state) => {
return !state.player.flags.pinned;
},

(room, state) => {
return state.player.stats.stamina.value > 25;
}
],
"hooks": [
(room, exit, state) => {
print(["You make a desperate bid for freedom, grasping at the walls of Fen's sweltering bowels and dragging yourself forward. The predator growls in pleasure...and, after humoring your squirms for a long minute, crushes you within an inch of your life with a swift, staggeringly-strong clench. Every inch of escape is erased in a heartbeat...as is any hope of ending the evening as anything other than a permanent contribution to the crux's body."]);
changeStat("stamina", -100, state);
return false;
}
]
},
},
hooks: [

@@ -470,6 +563,34 @@ stories.push({
}
}
},
"freedom": {
"id": "freedom",
"name": "Freedom",
"desc": "A place you'll never reach!",
"move": (room, state) => {
},
"enter": (room, state) => {
},
"exit": (room, state) => {
},
"actions": [
],
"exits": {
},
"hooks": [
],
"data": {
"stats": {
}
}
},
"digested-stomach": {
id: "digested-stomach",
name: "Fen's Belly",
@@ -513,7 +634,7 @@ stories.push({
playSfx("sfx/digested-test.ogg");
playSfx("sfx/bowels-churn-danger.ogg");
stopClassTimers("alive", state);
print(["A powerful ripple of muscle pins you in a vice-grip of flesh - and within seconds, you're part of Fen's bowels.",newline,"Nothing's left but a bit of padding on your predator's ass..."]);
print(["A powerful ripple of muscle pins you in a vice-grip of flesh. Your exhausted form is molded like putty..and then, over the course of no more than seconds, Fen's bowels assimilate you. Numbness races through your body as you're absorbed like water into a sponge.",newline,"Nothing's left of you beyond some heft on his ass..."]);
},
"data": {
"stats": {


+ 3
- 1
world.js View File

@@ -40,7 +40,7 @@ function resetControls(state) {
const button = document.createElement("button");
button.classList.add("move-button")
button.id = "move-" + dir;
button.classList.add("disabled");
button.classList.add("missing");
button.setAttribute("disabled", "true");
button.textContent = dirs[dir];
moveHolder.appendChild(button);
@@ -177,6 +177,8 @@ function updateRoom(state) {
}
}

button.classList.remove("missing");
button.classList.add("disabled");
button.textContent = dest.name;

// if any condition fails, don't enable/add a listener


Loading…
Cancel
Save