dylanpiera / Foundry-Pokemon-Tabletop-United-System

PTU System for FoundryVTT
33 stars 33 forks source link

Fishing Macro #445

Open dylanpiera opened 1 year ago

dylanpiera commented 1 year ago

Create a Fishing Macro

Issue opened on Discord by asheeon#0000

Muhsigbokz commented 12 months ago

image

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)
Muhsigbokz commented 12 months ago

Added to compendium - only needs commit to repo

Muhsigbokz commented 10 months ago

@dylanpiera please add next version - this one was missed with 4.0.7/4.0.8