Open dylanpiera opened 1 year ago
fvtt-Macro-fishing-fENgYnFGORHrQDcZ.json
// 2023-11-18
// The first controlled token, or the first target, or your main character as per foundry
const fisherActor = game.canvas.tokens?.controlled?.at(0)?.actor || game.user.targets.first()?.actor || game.user.character;
function fishReelBaitDcFromHtml($html){
return {
fish: $html.find("input[name='fishDc']")[0].value,
reel: $html.find("input[name='reelDc']")[0].value,
lure: $html.find("input[name='baitLossDc']")[0].value
}
}
async function flatCheck (){
const roll = new Roll("1d20");
console.log(roll)
const r = await roll.evaluate()
return r._total
}
async function athleticsCheck(actor){
const athleticsRoll = `${actor.system.skills.athletics.value.total}d6+${actor.system.skills.athletics.modifier.total}`
const r = await (new Roll(athleticsRoll)).evaluate()
return r._total
}
async function fishUpToThreeAttemptsWithBait(actor, dcs){
let attempts = 0;
while (attempts < 3){
attempts += 1;
if (await flatCheck() >= dcs["fish"]){
if (await athleticsCheck(actor) >= dcs["reel"])
return ChatMessage.create({
content: `Caught something after ${attempts*5} minutes!`
})
return ChatMessage.create({
content: `Lost your bait when losing your fish after ${attempts*5} minutes!`
})
}
}
ChatMessage.create({
content: `Not a single nibble in ${attempts*5} minutes - and your bait is lost.`
})
}
async function fishUntilReelInWithLure(actor, dcs){
let attempts = 0;
let nibbles = 0;
while (attempts < 12){
attempts += 1;
if (await flatCheck() >= dcs["fish"]){
nibbles += 1;
if (await athleticsCheck(actor) >= dcs["reel"])
return ChatMessage.create({
content: `Caught something after ${nibbles} nibbles in ${attempts*5} minutes!`
})
if (await flatCheck() < dcs["lure"])
return ChatMessage.create({
content: `Lost your lure on nibble #${nibbles} after ${attempts*5} minutes!`
})
}
}
ChatMessage.create({
content: `${nibbles} nibbles in ${attempts*5} minutes - but you kept your lure.`
})
}
async function fishOneHourWithLure(actor, dcs){
let attempts = 0;
let nibbles = 0;
let caught = 0;
while (attempts < 12){
attempts += 1;
if (await flatCheck() >= dcs["fish"]){
nibbles += 1;
if (await athleticsCheck(actor) >= dcs["reel"])
caught += 1;
else if (await flatCheck() < dcs["lure"])
return ChatMessage.create({
content: `Lost your lure on nibble #${nibbles} after ${attempts*5} minutes! Got ${caught} fishes until then.`
})
}
}
ChatMessage.create({
content: `Reeled in ${caught} fishes after ${nibbles} nibbles in ${attempts*5} minutes.`
})
}
async function fishOneHourCountBait(actor, dcs){
let attempts = 0;
let nibbles = 0;
let caught = 0;
let bait = 1;
while (attempts < 12){
attempts += 1;
if (await flatCheck() >= dcs["fish"]){
nibbles += 1;
bait += 1;
if (await athleticsCheck(actor) >= dcs["reel"]){
caught += 1;
}
}
}
ChatMessage.create({
content: `Reeled in ${caught} fishes after ${nibbles} nibbles in ${attempts*5} minutes - costing you ${bait} baits.`
})
}
class FishinDialog extends Dialog{
constructor(props) {
super(props);
}
activateListeners($html) {
super.activateListeners($html);
$html.find("button[name='noLure']").on("click", () => {
$html.find("input[name='fishDc']")[0].value = 20
console.log($html.find("input[name='fishDc']"))
});
$html.find("button[name='yesLure']").on("click", () => {
$html.find("input[name='fishDc']")[0].value = 15
});
$html.find("button[name='defaultReel']").on("click", () => {
$html.find("input[name='reelDc']")[0].value = 8
});
$html.find("button[name='defaultBaitLoss']").on("click", () => {
$html.find("input[name='baitLossDc']")[0].value = 11
});
}
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
closeOnSubmit: false
});
};
}
const c = `
<div class="swsh-body d-flex flex-row highlight pb-2 center-text justify-content-between">
<div class="fb-48">
<img src="${fisherActor.img}" height="100" width="auto" alt="${fisherActor.name}"/>
</div>
<div class="fb-48">
<p>Roll Athletics for ${actor.system.skills.athletics.value.total}d6+${actor.system.skills.athletics.modifier.total}</p>
</div>
</div>
<div class="swsh-body d-flex flex-row highlight pb-2 center-text justify-content-between">
<p>Flat DC for nibbles.</p>
</div>
<div class="swsh-body d-flex flex-row highlight pb-2 center-text justify-content-between">
<button name="yesLure">With Bait/Bait</button>
</div>
<div class="swsh-body d-flex flex-row highlight pb-2 center-text justify-content-between">
<input type="number" name="fishDc" min="1" max="20" value="15"/>
</div>
<div class="swsh-body d-flex flex-row highlight pb-2 center-text justify-content-between">
<div class="fb-48">
<p>Athletics DC to reel in.</p>
<button name="defaultReel">Default</button>
<input type="number" name="reelDc" min="1" max="20" value="8"/>
</div>
<div class="fb-48">
<p>Flat DC to keep Lure.</p>
<button name="defaultBaitLoss">Default</button>
<input type="number" name="baitLossDc" min="1" max="20" value="11"/>
</div>
</div>
`
const dcDialog = new FishinDialog({
title: "Fishin time!",
buttons: {
one: {
icon: '<i class="fa-solid fa-worm"></i>',
label: "Bait - Up to 3 times",
callback: html => fishUpToThreeAttemptsWithBait(fisherActor, fishReelBaitDcFromHtml(html))
},
two: {
icon: '<i class="fa-solid fa-worm"></i>',
label: "Bait - One hour",
callback: html => fishOneHourCountBait(fisherActor, fishReelBaitDcFromHtml(html))
},
three: {
icon: '<i class="fa-solid fa-anchor"></i>',
label: "Lure - Until reel in",
callback: html => fishUntilReelInWithLure(fisherActor, fishReelBaitDcFromHtml(html))
},
four: {
icon: '<i class="fa-solid fa-anchor"></i>',
label: "Lure - One hour",
callback: html => fishOneHourWithLure(fisherActor, fishReelBaitDcFromHtml(html))
}
},
content: c,
closeOnSubmit: false
});
dcDialog.render(true)
Added to compendium - only needs commit to repo
@dylanpiera please add next version - this one was missed with 4.0.7/4.0.8
Create a Fishing Macro
Issue opened on Discord by asheeon#0000