#M&M Macros #10: World Scripts

1 messages · Page 1 of 1 (latest)

gilded nexus
#

The following three bits of code are World Scripts. World Scripts are a little like a mini-module in that they change how the game works. Putting in these world scripts there is a hard way and an easy way.

The hard way is to follow the info here: https://foundryvtt.wiki/en/basics/world-scripts

The easy way is to use the World Scripter module. When it is loaded, you just load the world scripts into the World Scripter compendium and refresh your screen (F5).

You can find more info on World Scripter at https://foundryvtt.com/packages/world-scripter

#

WS - Hero Point Reporter listens for updates to an actor's Hero Points in the M&M system in Foundry VTT and, if updated, creates a whispered chat message to the GM saying so. This can be handy if running one shots and new players and you are not sure if you trust them not to cheat. Or to play with friends if you have...."THOSE" sort of friends. 🙂

**Hero Point Reporter **

//Hero Point Reporter World Script by Zhell

//This is a world script. More info here: https://foundryvtt.wiki/en/basics/world-scripts 

//That being said, the easiest method to use this is the World Scripter module. When it is loaded, you just load the world scripts into the World Scripter compendium and refresh your screen (F5).
//You can find more info on World Scripter at https://foundryvtt.com/packages/world-scripter

//This world script listens for updates to an actor's Hero Points in the M&M system in Foundry VTT and, if updated, creates a whispered chat message to the GM. 

// Step 1: Set up a hook to listen for updates to actors.
Hooks.on("preUpdateActor", (actor, update) => {

  // Step 2: Check if the user is not the Game Master and if "heroisme" is being updated in the system data.
  if (!game.user.isGM && ("heroisme" in update.system ?? {})) {

    // Step 3: Create a chat message with the updated hero points information.
    ChatMessage.create({ content: `${actor.name} 's Hero Points have been updated to ${update.system.heroisme}` });
  }
});
#

Round Caller sends a message to chat and narrates for the players to see when combat begins, when a turn rolls by and the end of the combat. Needs the Narrator module to work. Real fun. and helps you keep track of the rounds.

Round Caller

#
//World Script -Round Caller by Bithir, roninseven, Zhell, and Devioushearts

//This is a world script. More info here: https://foundryvtt.wiki/en/basics/world-scripts 

//That being said, the easiest method to use this is the World Scripter module. When it is loaded, you just load the world scripts into the World Scripter compendium and refresh your screen (F5).
//You can find more info on World Scripter at https://foundryvtt.com/packages/world-scripter

//Round Caller sends a message to chat and narrates for the players to see when combat begins, when a turn rolls by and the end of the combat.

//Required Modules: Narrator Tools (you can still use it if you don't have the module but you will want to take out the note and the sections of code that mention the "/narrate" command second from the bottom) and you may want to eleiminate the whisper to GM portion of the chatmessages so it is reported to all players

// Initialize variable to track previous round
let previousRound = 0; // Keep track of the previous round

// Array of portrait image paths to randomly select from
const portraits = ["icons/magic/death/skull-energy-light-white.webp",
  "icons/magic/death/skull-fire-white-yellow.webp",
  "icons/magic/death/skull-flames-white-blue.webp",
  "icons/magic/death/skull-humanoid-white-blue.webp",
  "icons/magic/death/skull-humanoid-crown-white-blue.webp"
];

// Randomly select a portrait image path
const portrait = portraits[Math.floor(Math.random() * portraits.length)];

// Hook to announce the start of combat
Hooks.on("createCombat", (combat) => {

//Change all player's Roll modes to Public
game.settings.set("core", "rollMode", CONST.DICE_ROLL_MODES.PUBLIC)

    // Only execute for GM
    if (!game.user.isGM) {
        // Only do message chats for GMs and not everyone
        return;
    }

    // Narrate a message visible to all players
    ui.chat.processMessage(`/narrate Ready? FIGHT!!!`);

    // Create a ChatMessage whispered to GM
    ChatMessage.create({
        whisper: ChatMessage.getWhisperRecipients("GM"),
        flags: { "chat-portrait.src": portrait },
        content: 'Ready? FIGHT!!!',
        speaker: { actor: null, alias: "Announcer" },
    });
});

// Hook to announce the end of combat
Hooks.on("deleteCombat", (combat) => {
    if (!game.user.isGM) {
        // Only do message chats for GMs and not everyone
        return;
    }

    // Announce the end of combat using the /em command and send a chat message.
    ui.chat.processMessage(`/narrate Combat has ENDED!`);

    ChatMessage.create({
        whisper: ChatMessage.getWhisperRecipients("GM"),
        flags: { "chat-portrait.src": portrait },
        content: 'Combat has ENDED!',
        speaker: { actor: null, alias: "Announcer" },
    });
});

// Hook to announce the start of each new round
Hooks.on('updateCombat', (combat, update) => {
    if (!game.user.isGM) {
        // Only do message chats for GMs and not everyone
        return;
    }

    if (update && combat.round && combat.round !== previousRound) {
        // Check if it's the start of a new round (and not a repeat).

        // Announce the start of each new combat round using the /narrate command and send a chat message.

        ChatMessage.create({
            whisper: ChatMessage.getWhisperRecipients("GM"),
            flags: { "chat-portrait.src": portrait },
            content: `Round ${combat.round} ! FIGHT!!!`,
            speaker: { actor: null, alias: "Announcer" },
        });
        ui.chat.processMessage(`/narrate Round ${combat.round}! FIGHT!!!`);

        // Update the previousRound variable to prevent announcing it again during the same round.
        previousRound = combat.round;
    }
});
#

M&M Macros #10: World Scripts

#

Turn Reminder sends a whisper to the GM with a health overview (Hero Points, Injury Level, and Active Statuses and how long they have been in effect) of the character whose turn has just started in combat.

Turn Reminder

#
// World Script - Turn Reminder by Devioushearts and Code Monkey.

//This is a world script. More info here: https://foundryvtt.wiki/en/basics/world-scripts 

//That being said, the easiest method to use this is the World Scripter module. When it is loaded, you just load the world scripts into the World Scripter compendium and refresh your screen (F5).
//You can find more info on World Scripter at https://foundryvtt.com/packages/world-scripter

// This World Script sends a single whisper to the GM from "Turn Reminder" with a health overview and effect details of the character whose turn has just started in combat.

// Check if it's a new turn and if the update is being handled by the GM
Hooks.on("updateCombat", (combat, update, options, userId) => {
  if (!("turn" in update) || !game.user.isGM) return;

  // Get the token for the current combatant
  const currentToken = combat.combatant.token;

  // Ensure the token exists and represents a character
  if (currentToken && currentToken.actor) {
    const character = currentToken.actor;

    // Gather active effects and their start rounds
    const activeEffects = character.effects.map(effect => {
      const startRound = effect.data.duration?.startRound || 'Unknown';
      return `${effect.data.label} (Round: ${startRound})`;
    }).join(', ');

    // Construct token health information
    const tokenInfo = {
      name: character.name,
      heroPoints: character.data.data.heroisme,
      injuries: character.data.data.blessure,
      activeEffects: activeEffects
    };

    // Construct the whisper message content
    const whisperContent = `
      <p><strong>Hero Points:</strong> ${tokenInfo.heroPoints}, <strong>Injuries:</strong> ${tokenInfo.injuries}</p>
      <p><strong>Active Effects:</strong> <em>${tokenInfo.activeEffects}</em></p>
    `;

    // Send a single whisper message to the GM
    ChatMessage.create({
      speaker: { alias: "Turn Reminder" },
      content: `<h3>${tokenInfo.name}'s Turn - Round ${combat.round}</h3>${whisperContent}`,
      whisper: [game.user.id]
    });
  }
});
#

Round Caller and Turn Reminder work very well hand in hand with the Ready to Rumble macro.

gilded nexus
#
Hooks.on('renderTokenHUD', (app, [html], context) => {

//Add a heart to injuries Window in the Token HUD
    html.querySelector('.attribute.bar1').insertAdjacentHTML('afterbegin', '<i class="fas fa-heart" style="font-size: 2.1rem;color: red;text-shadow: 0px 0px 10px white, 1px 1px 4px red;top:unset;bottom:4px;left:-10px;-webkit-text-stroke-width: 2px;-webkit-text-stroke-color: white"></i>')

// Add a star to the Hero Point window in the Token HUD
    html.querySelector('.attribute.bar1').insertAdjacentHTML('afterbegin', '<i class="fas fa-star" style="font-size: 2.1rem;color: yellow;text-shadow: 0px 0px 10px white, 1px 1px 4px red;top:4px; left:-11px;-webkit-text-stroke-width: 2px;-webkit-text-stroke-color: white"></i>')
})
#

This macro should be read first before running the Hearts and Stars HUD world script as it will ensure all character tokens display the Hero Points on the top and the Injuries on the bottom of a token when right-clicked. THIS IS NOT A WORLD SCRIPT but does need to be run to make the world script above work properly.

//Add Hero Points to Bar 2 Attribute by mxzf
//This macro adds the Hero Point number to the Bar 2 Attribute which is the box above a token when you right click on a token

game.actors.updateAll({'prototypeToken.bar2.attribute': 'heroisme'})
gilded nexus
left turtle
#

Does anyone know how to get rid of this? I have pressed the button one to many times and I ended up with this mess. It will not go away and it affects all my actors and NPCs even after I deleted them or unlinked the sheets. I have also tried deleting the sheets and making new ones from scratch and it does not go away.

#

Nvm I fixed it. Just need to remove the module and re-add it.

gilded nexus
#

What version of Foundry are you using? I have yet to be able to make it work in v12.