Implemented hunger mechanic

This commit is contained in:
thepaperpilot 2021-08-28 07:42:38 -05:00
parent 6b5c94d62e
commit 856809cade
2 changed files with 183 additions and 25 deletions

View file

@ -49,7 +49,7 @@ enum LinkType {
// Links cause gain/loss of one resource to also affect other resources // Links cause gain/loss of one resource to also affect other resources
type ResourceLink = { type ResourceLink = {
resource: string; resource: string;
amount: DecimalSource; amount: DecimalSource | (() => DecimalSource);
linkType: LinkType; linkType: LinkType;
}; };
@ -64,11 +64,28 @@ type Resource = {
const resources = { const resources = {
time: createResource("time", "#3EB489", 24 * 60 * 60, 24 * 60 * 60, [ time: createResource("time", "#3EB489", 24 * 60 * 60, 24 * 60 * 60, [
{ resource: "mental", amount: 1 / (120 * 60), linkType: LinkType.LossOnly } { resource: "mental", amount: 1 / (120 * 60), linkType: LinkType.LossOnly },
{ resource: "hunger", amount: -1 / (15 * 60), linkType: LinkType.LossOnly }
]), ]),
energy: createResource("energy", "#FFA500", 100, 100), energy: createResource("energy", "#FFA500", 100, 100),
mental: createResource("mental", "#32CD32", 100, 100), mental: createResource("mental", "#32CD32", 100, 100),
focus: createResource("focus", "#0000FF", 100, 0) focus: createResource("focus", "#0000FF", 100, 0),
hunger: createResource("hunger", "#FFFF00", 100, 0, [
{
resource: "focus",
amount() {
// the higher hunger goes, the more focus it consumes
// the idea being the amount lost is the area under the y=x line
// that's right, using calculus in a video game :sunglasses:
return new Decimal(resources.hunger.amount)
.div(10)
.pow(1.5)
.div(1.5)
.neg();
},
linkType: LinkType.GainOnly
}
])
} as Record<string, Resource>; } as Record<string, Resource>;
function createResource( function createResource(
@ -279,7 +296,8 @@ const actions = {
], ],
baseChanges: [ baseChanges: [
{ resource: "time", amount: 16 * 60 * 60, assign: true }, { resource: "time", amount: 16 * 60 * 60, assign: true },
{ resource: "energy", amount: 100, assign: true } { resource: "energy", amount: 100, assign: true },
{ resource: "hunger", amount: 20 }
] ]
}, },
forcedSleep: { forcedSleep: {
@ -298,7 +316,10 @@ const actions = {
weight: 1 weight: 1
} }
], ],
baseChanges: [{ resource: "mental", amount: -10 }] baseChanges: [
{ resource: "mental", amount: -10 },
{ resource: "hunger", amount: 20 }
]
}, },
rest: { rest: {
icon: "chair", icon: "chair",
@ -306,10 +327,7 @@ const actions = {
events: [ events: [
{ {
event: () => { event: () => {
resources.energy.amount = Decimal.sub( resources.energy.amount = Decimal.add(resources.energy.amount, 10);
resources.energy.amount || 100,
Decimal.times(10, focusMult.value)
);
return { description: "You rest your eyes for a bit and wake up rejuvenated" }; return { description: "You rest your eyes for a bit and wake up rejuvenated" };
}, },
weight: 90 weight: 90
@ -324,10 +342,7 @@ const actions = {
}, },
{ {
event: () => { event: () => {
resources.energy.amount = Decimal.add( resources.energy.amount = Decimal.add(resources.energy.amount, 20);
resources.energy.amount,
Decimal.times(20, focusMult.value)
);
return { return {
description: description:
"You take an incredible power nap and wake up significantly more refreshed", "You take an incredible power nap and wake up significantly more refreshed",
@ -380,6 +395,118 @@ const actions = {
{ resource: "energy", amount: -5 }, { resource: "energy", amount: -5 },
{ resource: "mental", amount: 5 } { resource: "mental", amount: 5 }
] ]
},
eat: {
icon: "restaurant",
tooltip: "Eat meal",
events: [
{
event: () => ({ description: `You eat a delicious meal. Nice!` }),
weight: 8
},
{
event: () => {
resources.mental.amount = Decimal.add(resources.mental.amount, 10);
return {
description: `This is your favorite meal! Oh, what a treat!`,
effectDescription: `+10% <span style="color: ${resources.mental.color}">Mental</span> `
};
},
weight: 1
},
{
event: () => {
resources.energy.amount = Decimal.sub(resources.energy.amount, 10);
resources.hunger.amount = Decimal.add(resources.hunger.amount, 25);
return {
description: `Oh no, I'm not sure that food was still good`,
effectDescription: `-10% <span style="color: ${resources.energy.color}">Energy</span>, -25% <span style="color: ${resources.hunger.color}">Hunger</span> depletion `
};
},
weight: 1
}
],
baseChanges: [
{ resource: "time", amount: -30 * 60 },
{ resource: "energy", amount: 10 },
{ resource: "hunger", amount: -70 }
]
},
snack: {
icon: "icecream",
tooltip: "Eat snack",
events: [
{
event: () => ({ description: `You have a nice, small snack. Nice!` }),
weight: 8
},
{
event: () => {
resources.energy.amount = Decimal.add(resources.energy.amount, 10);
return {
description: `You chose a healthy, delicious snack. You feel really good!`,
effectDescription: `+10% <span style="color: ${resources.energy.color}">Energy</span> `
};
},
weight: 1
},
{
event: () => {
resources.mental.amount = Decimal.sub(resources.mental.amount, 5);
resources.hunger.amount = Decimal.add(resources.hunger.amount, 10);
return {
description: `You gorge yourself on unhealthy foods, and don't feel so good`,
effectDescription: `-5% <span style="color: ${resources.mental.color}">Mental</span>, -10% <span style="color: ${resources.hunger.color}">Hunger</span> depletion `
};
},
weight: 1
}
],
baseChanges: [
{ resource: "time", amount: -20 * 60 },
{ resource: "mental", amount: 2 },
{ resource: "hunger", amount: -25 }
]
},
forcedSnack: {
events: [
{
event: () => {
resources.mental.amount = Decimal.sub(resources.mental.amount, 15);
return {
description: `You scarf down anything and everything around you. That can't be good for you.`,
effectDescription: `-15% <span style="color: ${resources.mental.color}">Mental</span> `
};
},
weight: 1
}
],
baseChanges: [
{ resource: "time", amount: -20 * 60 },
{ resource: "hunger", amount: -25 }
]
},
brush: {
icon: "mood",
tooltip: "Brush Teeth",
enabled: () =>
Decimal.lt(player.lastDayBrushed as DecimalSource, player.day as DecimalSource),
events: [
{
event: () => {
player.lastDayBrushed = player.day;
return {
description: `Brushing once a day is 33% of the way towards keeping the dentist at bay`
};
},
weight: 1
}
],
baseChanges: [
{ resource: "time", amount: -5 * 60 },
{ resource: "energy", amount: -2 },
{ resource: "mental", amount: 2 }
]
} }
} as Record<string, Action>; } as Record<string, Action>;
@ -425,6 +552,10 @@ const actionNodes = {
bed: { bed: {
actions: ["sleep", "rest", "makeBed"], actions: ["sleep", "rest", "makeBed"],
display: "Bed" display: "Bed"
},
food: {
actions: ["eat", "snack", "brush"],
display: "Food"
} }
} as Record<string, ActionNode>; } as Record<string, ActionNode>;
@ -474,9 +605,10 @@ for (const id in resources) {
} }
const resource = resources[link.resource]; const resource = resources[link.resource];
if (resource.amount != null) { if (resource.amount != null) {
const amount = typeof link.amount === "function" ? link.amount() : link.amount;
resource.amount = Decimal.add( resource.amount = Decimal.add(
resource.amount, resource.amount,
Decimal.times(link.amount, resourceGain) Decimal.times(amount, resourceGain)
); );
} }
}); });
@ -532,14 +664,17 @@ const resourceNodeType = {
const link = selectedResource.links.find(link => link.resource === resource.name); const link = selectedResource.links.find(link => link.resource === resource.name);
if (link) { if (link) {
let text; let text;
const amount = new Decimal(
typeof link.amount === "function" ? link.amount() : link.amount
).neg();
if (resource.name === "time") { if (resource.name === "time") {
text = formatTime(link.amount); text = formatTime(amount);
} else if (Decimal.eq(resource.maxAmount, 100)) { } else if (Decimal.eq(resource.maxAmount, 100)) {
text = formatWhole(link.amount) + "%"; text = formatWhole(amount) + "%";
} else { } else {
text = format(link.amount); text = format(amount);
} }
let negativeLink = Decimal.lt(link.amount, 0); let negativeLink = Decimal.gt(amount, 0);
if (link.linkType === LinkType.LossOnly) { if (link.linkType === LinkType.LossOnly) {
negativeLink = !negativeLink; negativeLink = !negativeLink;
} }
@ -709,14 +844,19 @@ const actionNodeType = {
} }
} as RawFeature<NodeType>; } as RawFeature<NodeType>;
function registerResourceDepletedAction(resource: string, nodeID: string, action: string) { function registerResourceDepletedAction(
resource: string,
nodeID: string,
action: string,
threshold: 0 | 100 = 0
) {
watch( watch(
() => ({ () => ({
amount: resources[resource].amount, amount: resources[resource].amount,
forcedAction: player.layers.main?.forcedAction forcedAction: player.layers.main?.forcedAction
}), }),
({ amount, forcedAction }) => { ({ amount, forcedAction }) => {
if (Decimal.eq(amount, 0) && forcedAction == null) { if (Decimal.eq(amount, threshold) && forcedAction == null) {
toast.error(coerceComponent(`${camelToTitle(resources[resource].name)} depleted!`)); toast.error(coerceComponent(`${camelToTitle(resources[resource].name)} depleted!`));
player.layers.main.forcedAction = { player.layers.main.forcedAction = {
resource, resource,
@ -735,6 +875,7 @@ function registerResourceDepletedAction(resource: string, nodeID: string, action
registerResourceDepletedAction("time", "bed", "forcedSleep"); registerResourceDepletedAction("time", "bed", "forcedSleep");
registerResourceDepletedAction("energy", "bed", "forcedRest"); registerResourceDepletedAction("energy", "bed", "forcedRest");
registerResourceDepletedAction("hunger", "food", "forcedSnack", 100);
export default { export default {
id: "main", id: "main",
@ -822,6 +963,14 @@ export default {
amount: new Decimal(100) amount: new Decimal(100)
} as ResourceNodeData } as ResourceNodeData
}, },
{
position: { x: 150, y: 0 },
type: "resource",
data: {
resourceType: "hunger",
amount: new Decimal(0)
} as ResourceNodeData
},
{ {
position: { x: -150, y: 150 }, position: { x: -150, y: 150 },
type: "action", type: "action",
@ -837,6 +986,14 @@ export default {
actionType: "bed", actionType: "bed",
log: [] log: []
} as ActionNodeData } as ActionNodeData
},
{
position: { x: -300, y: 150 },
type: "action",
data: {
actionType: "food",
log: []
} as ActionNodeData
} }
]; ];
}, },
@ -892,14 +1049,14 @@ export default {
links.push( links.push(
...resource.links.map(link => { ...resource.links.map(link => {
const linkResource = resources[link.resource]; const linkResource = resources[link.resource];
let negativeLink = Decimal.lt(link.amount, 0); const amount =
if (link.linkType === LinkType.LossOnly) { typeof link.amount === "function"
negativeLink = !negativeLink; ? link.amount()
} : link.amount;
return { return {
from: selectedNode.value, from: selectedNode.value,
to: linkResource.node, to: linkResource.node,
stroke: negativeLink ? "red" : "green", stroke: Decimal.gt(amount, 0) ? "red" : "green",
"stroke-width": 4, "stroke-width": 4,
pulsing: true pulsing: true
} as BoardNodeLink; } as BoardNodeLink;

View file

@ -14,6 +14,7 @@ export function getStartingData(): Record<string, unknown> {
points: new Decimal(10), points: new Decimal(10),
day: new Decimal(1), day: new Decimal(1),
lastDayBedMade: new Decimal(0), lastDayBedMade: new Decimal(0),
lastDayBrushed: new Decimal(0),
devStep: 0 devStep: 0
}; };
} }