Bosskills

  • community
  • events
  • by Mad
  • Takaro v0.0.21
  • all
View export JSON

Pay and Announcement for Bosses

Configuration 14

Settings you fill in when installing the module on a server.

SettingTypeDefaultDescription
coinAmountMiniBoss required coinAmountMiniBoss number 0 Amount of Coin to award for a miniboss
coinAmountBoss coinAmountBoss number 0 Amount of Coin to award for a Boss
announceDevourer announceDevourer string Use {pname} for player name and {amount} for currency
announceGargul announceGargul string Use {pname} for player name and {amount} for currency
announceBear announceBear string Use {pname} for player name and {amount} for currency
announceBitch announceBitch string Use {pname} for player name and {amount} for currency
announceBurningFlesh announceBurningFlesh string Use {pname} for player name and {amount} for currency
announceCholera announceCholera string Use {pname} for player name and {amount} for currency
announceBull announceBull string "" Use {pname} for player name and {amount} for currency
announceShocker announceShocker string Use {pname} for player name and {amount} for currency
coinAmountTinyBoss coinAmountTinyBoss string Amount of Coin to award for a tinyboss
announceVeteran announceVeteran string Use {pname} for player name and {amount} for currency
announceCarrier announceCarrier string Use {pname} for player name and {amount} for currency
announceOstiarius announceOstiarius string Use {pname} for player name and {amount} for currency
Raw config schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "coinAmountMiniBoss"
  ],
  "additionalProperties": false,
  "properties": {
    "coinAmountMiniBoss": {
      "title": "coinAmountMiniBoss",
      "description": "Amount of Coin to award for a miniboss",
      "default": 0,
      "type": "number"
    },
    "coinAmountBoss": {
      "title": "coinAmountBoss",
      "description": "Amount of Coin to award for a Boss",
      "default": 0,
      "type": "number"
    },
    "announceDevourer": {
      "title": "announceDevourer",
      "description": "Use {pname} for player name and {amount} for currency",
      "type": "string"
    },
    "announceGargul": {
      "title": "announceGargul",
      "description": "Use {pname} for player name and {amount} for currency",
      "type": "string"
    },
    "announceBear": {
      "title": "announceBear",
      "description": "Use {pname} for player name and {amount} for currency",
      "type": "string"
    },
    "announceBitch": {
      "title": "announceBitch",
      "description": "Use {pname} for player name and {amount} for currency",
      "type": "string"
    },
    "announceBurningFlesh": {
      "title": "announceBurningFlesh",
      "description": "Use {pname} for player name and {amount} for currency",
      "type": "string"
    },
    "announceCholera": {
      "title": "announceCholera",
      "description": "Use {pname} for player name and {amount} for currency",
      "type": "string"
    },
    "announceBull": {
      "title": "announceBull",
      "description": "Use {pname} for player name and {amount} for currency",
      "default": "",
      "type": "string"
    },
    "announceShocker": {
      "title": "announceShocker",
      "description": "Use {pname} for player name and {amount} for currency",
      "type": "string"
    },
    "coinAmountTinyBoss": {
      "title": "coinAmountTinyBoss",
      "description": "Amount of Coin to award for a tinyboss",
      "type": "string"
    },
    "announceVeteran": {
      "title": "announceVeteran",
      "description": "Use {pname} for player name and {amount} for currency",
      "type": "string"
    },
    "announceCarrier": {
      "title": "announceCarrier",
      "description": "Use {pname} for player name and {amount} for currency",
      "type": "string"
    },
    "announceOstiarius": {
      "title": "announceOstiarius",
      "description": "Use {pname} for player name and {amount} for currency",
      "type": "string"
    }
  }
}
Raw UI schema
{}

Hooks 11

Code that runs in reaction to a game or Takaro event.

  • Cholera

    Announce Cholera Kill

    Hook source
    import { data, takaro } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, eventData } = data;
    
        const namePattern = /entityKilled: (\w+) \(Steam_/;
        const nameMatch = eventData.msg.match(namePattern);
        const amountx = data.module.userConfig.coinAmountTinyBoss;
        const message = data.module.userConfig.announceCholera;
        const playerName = nameMatch ? nameMatch[1] : "Unknown";
        const formattedMessage = message
            .replace('{pname}', playerName)
            .replace('{amount}', amountx);
    
    
        const pattern = /Steam_(\d+)/;
        const match = data.eventData.msg.match(pattern);
        const steamIdx = match[1];
        const playerid = (await takaro.player.playerControllerSearch({ filters: { steamId: [steamIdx] } })).data.data[0].id;
    
        // Send the message with backticks
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: formattedMessage
        });
    
        // Grant currency to the player
        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, playerid, {
            currency: amountx
        });
    }
    
    await main();
  • Bull

    Announce Bull Kill

    Hook source
    import { data, takaro } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, eventData } = data;
    
        const namePattern = /entityKilled: (\w+) \(Steam_/;
        const nameMatch = eventData.msg.match(namePattern);
        const amountx = data.module.userConfig.coinAmountBoss;
        const message = data.module.userConfig.announceBull;
        const playerName = nameMatch ? nameMatch[1] : "Unknown";
        const formattedMessage = message
            .replace('{pname}', playerName)
            .replace('{amount}', amountx);
    
    
        const pattern = /Steam_(\d+)/;
        const match = data.eventData.msg.match(pattern);
        const steamIdx = match[1];
        const playerid = (await takaro.player.playerControllerSearch({ filters: { steamId: [steamIdx] } })).data.data[0].id;
    
        // Send the message with backticks
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: formattedMessage
        });
    
        // Grant currency to the player
        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, playerid, {
            currency: amountx
        });
    }
    
    await main();
  • Shocker

    Kill Boss Shocker

    Hook source
    import { data, takaro } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, eventData } = data;
    
        const namePattern = /entityKilled: (\w+) \(Steam_/;
        const nameMatch = eventData.msg.match(namePattern);
        const amountx = data.module.userConfig.coinAmountBoss;
        const message = data.module.userConfig.announceShocker;
        const playerName = nameMatch ? nameMatch[1] : "Unknown";
        const formattedMessage = message
            .replace('{pname}', playerName)
            .replace('{amount}', amountx);
    
    
        const pattern = /Steam_(\d+)/;
        const match = data.eventData.msg.match(pattern);
        const steamIdx = match[1];
        const playerid = (await takaro.player.playerControllerSearch({ filters: { steamId: [steamIdx] } })).data.data[0].id;
    
        // Send the message with backticks
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: formattedMessage
        });
    
        // Grant currency to the player
        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, playerid, {
            currency: amountx
        });
    }
    
    await main();
  • Bear

    Boss Bear Kill

    Hook source
    import { data, takaro } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, eventData } = data;
    
        const namePattern = /entityKilled: (\w+) \(Steam_/;
        const nameMatch = eventData.msg.match(namePattern);
        const amountx = data.module.userConfig.coinAmountMiniBoss;
        const message = data.module.userConfig.announceBear;
        const playerName = nameMatch ? nameMatch[1] : "Unknown";
        const formattedMessage = message
            .replace('{pname}', playerName)
            .replace('{amount}', amountx);
    
    
        const pattern = /Steam_(\d+)/;
        const match = data.eventData.msg.match(pattern);
        const steamIdx = match[1];
        const playerid = (await takaro.player.playerControllerSearch({ filters: { steamId: [steamIdx] } })).data.data[0].id;
    
        // Send the message with backticks
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: formattedMessage
        });
    
        // Grant currency to the player
        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, playerid, {
            currency: amountx
        });
    }
    
    await main();
  • Ostiarius

    Kill Boss Ostiarius

    Hook source
    import { data, takaro } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, eventData } = data;
    
        const namePattern = /entityKilled: (\w+) \(Steam_/;
        const nameMatch = eventData.msg.match(namePattern);
        const amountx = data.module.userConfig.coinAmountBoss;
        const message = data.module.userConfig.announceOstiarius;
        const playerName = nameMatch ? nameMatch[1] : "Unknown";
        const formattedMessage = message
            .replace('{pname}', playerName)
            .replace('{amount}', amountx);
    
    
        const pattern = /Steam_(\d+)/;
        const match = data.eventData.msg.match(pattern);
        const steamIdx = match[1];
        const playerid = (await takaro.player.playerControllerSearch({ filters: { steamId: [steamIdx] } })).data.data[0].id;
    
        // Send the message with backticks
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: formattedMessage
        });
    
        // Grant currency to the player
        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, playerid, {
            currency: amountx
        });
    }
    
    await main();
  • Bitch

    Boss Bitch Kill

    Hook source
    import { data, takaro } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, eventData } = data;
    
        const namePattern = /entityKilled: (\w+) \(Steam_/;
        const nameMatch = eventData.msg.match(namePattern);
        const amountx = data.module.userConfig.coinAmountTinyBoss;
        const message = data.module.userConfig.announceBitch;
        const playerName = nameMatch ? nameMatch[1] : "Unknown";
        const formattedMessage = message
            .replace('{pname}', playerName)
            .replace('{amount}', amountx);
    
    
        const pattern = /Steam_(\d+)/;
        const match = data.eventData.msg.match(pattern);
        const steamIdx = match[1];
        const playerid = (await takaro.player.playerControllerSearch({ filters: { steamId: [steamIdx] } })).data.data[0].id;
    
        // Send the message with backticks
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: formattedMessage
        });
    
        // Grant currency to the player
        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, playerid, {
            currency: amountx
        });
    }
    
    await main();
  • Devourer

    Boss Devourer Kill

    Hook source
    import { data, takaro } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, eventData } = data;
    
        const namePattern = /entityKilled: (\w+) \(Steam_/;
        const nameMatch = eventData.msg.match(namePattern);
        const amountx = data.module.userConfig.coinAmountMiniBoss;
        const message = data.module.userConfig.announceDevourer;
        const playerName = nameMatch ? nameMatch[1] : "Unknown";
        const formattedMessage = message
            .replace('{pname}', playerName)
            .replace('{amount}', amountx);
    
    
        const pattern = /Steam_(\d+)/;
        const match = data.eventData.msg.match(pattern);
        const steamIdx = match[1];
        const playerid = (await takaro.player.playerControllerSearch({ filters: { steamId: [steamIdx] } })).data.data[0].id;
    
        // Send the message with backticks
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: formattedMessage
        });
    
        // Grant currency to the player
        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, playerid, {
            currency: amountx
        });
    }
    
    await main();
  • Gargul

    Boss Gargul Kill

    Hook source
    import { data, takaro } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, eventData } = data;
    
        const namePattern = /entityKilled: (\w+) \(Steam_/;
        const nameMatch = eventData.msg.match(namePattern);
        const amountx = data.module.userConfig.coinAmountMiniBoss;
        const message = data.module.userConfig.announceGargul;
        const playerName = nameMatch ? nameMatch[1] : "Unknown";
        const formattedMessage = message
            .replace('{pname}', playerName)
            .replace('{amount}', amountx);
    
    
        const pattern = /Steam_(\d+)/;
        const match = data.eventData.msg.match(pattern);
        const steamIdx = match[1];
        const playerid = (await takaro.player.playerControllerSearch({ filters: { steamId: [steamIdx] } })).data.data[0].id;
    
        // Send the message with backticks
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: formattedMessage
        });
    
        // Grant currency to the player
        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, playerid, {
            currency: amountx
        });
    }
    
    await main();
  • Veteran

    Kill Boss Veteran

    Hook source
    import { takaro, data, TakaroUserError } from '@takaro/helpers';
    
    // Card representation
    class Card {
        constructor(suit, value, numericValue) {
            this.suit = suit;
            this.value = value;
            this.numericValue = numericValue;
        }
    }
    
    // Card utilities
    const CardUtils = {
        // Create a full deck of 52 cards
        createDeck() {
            const suits = ['S', 'H', 'D', 'C']; // Spades, Hearts, Diamonds, Clubs
            const values = [
                { value: '2', numericValue: 2 },
                { value: '3', numericValue: 3 },
                { value: '4', numericValue: 4 },
                { value: '5', numericValue: 5 },
                { value: '6', numericValue: 6 },
                { value: '7', numericValue: 7 },
                { value: '8', numericValue: 8 },
                { value: '9', numericValue: 9 },
                { value: '10', numericValue: 10 },
                { value: 'J', numericValue: 10 },
                { value: 'Q', numericValue: 10 },
                { value: 'K', numericValue: 10 },
                { value: 'A', numericValue: 11 }
            ];
    
            const deck = [];
            suits.forEach(suit => {
                values.forEach(val => {
                    deck.push(new Card(suit, val.value, val.numericValue));
                });
            });
    
            return this.shuffleDeck(deck);
        },
    
        // Shuffle the deck using Fisher-Yates algorithm
        shuffleDeck(deck) {
            for (let i = deck.length - 1; i > 0; i--) {
                const j = Math.floor(Math.random() * (i + 1));
                [deck[i], deck[j]] = [deck[j], deck[i]];
            }
            return deck;
        },
    
        // Calculate the total value of a hand, accounting for Aces
        calculateHandValue(hand) {
            let total = hand.reduce((sum, card) => sum + card.numericValue, 0);
            const aces = hand.filter(card => card.value === 'A').length;
    
            // Adjust for Aces
            for (let i = 0; i < aces; i++) {
                if (total > 21) {
                    total -= 10;
                }
            }
    
            return total;
        },
    
        // Convert hand to a readable string
        handToString(hand) {
            return hand.map(card => `${card.value}${card.suit}`).join(', ');
        }
    };
    
    // Game logic
    const GameLogic = {
        // Variable key for game state
        getGameKey(playerId) {
            return `bj_game_${playerId}`;
        },
    
        // Save game state
        async saveGame(game) {
            const key = this.getGameKey(game.playerId);
            const gameData = JSON.stringify(game);
    
            try {
                // Search for existing game variable
                const existingVar = await takaro.variable.variableControllerSearch({
                    filters: {
                        key: [key],
                        playerId: [game.playerId]
                    }
                });
    
                if (existingVar.data.data.length > 0) {
                    // Update existing variable
                    await takaro.variable.variableControllerUpdate(existingVar.data.data[0].id, {
                        value: gameData
                    });
                } else {
                    // Create new variable
                    await takaro.variable.variableControllerCreate({
                        key,
                        value: gameData,
                        playerId: game.playerId
                    });
                }
            } catch (error) {
                console.error('Failed to save game state:', error);
                throw new Error('Failed to save game state');
            }
        },
    
        // Load game state
        async loadGame(playerId) {
            const key = this.getGameKey(playerId);
    
            try {
                const gameVar = await takaro.variable.variableControllerSearch({
                    filters: {
                        key: [key],
                        playerId: [playerId]
                    }
                });
    
                if (gameVar.data.data.length > 0) {
                    return JSON.parse(gameVar.data.data[0].value);
                }
    
                return null;
            } catch (error) {
                console.error('Failed to load game state:', error);
                throw new Error('Failed to load game state');
            }
        },
    
        // Start a new game
        async startGame(playerId, bet) {
            // Check if player already has a game
            const existingGame = await this.loadGame(playerId);
            if (existingGame && existingGame.status === 'active') {
                throw new Error('You already have an active game. Use /bjstatus to see your current game.');
            }
    
            // Create deck and deal initial cards
            const deck = CardUtils.createDeck();
            const playerHand = [deck.pop(), deck.pop()];
            const dealerHand = [deck.pop(), deck.pop()];
    
            // Create new game state
            const game = {
                playerId,
                playerHand,
                dealerHand,
                bet,
                status: 'active',
                lastActivity: Date.now()
            };
    
            // Check for immediate blackjack
            const playerValue = CardUtils.calculateHandValue(playerHand);
            const dealerValue = CardUtils.calculateHandValue(dealerHand);
    
            if (playerValue === 21) {
                // Player has blackjack
                if (dealerValue === 21) {
                    // Both have blackjack - push
                    game.result = 'push';
                    game.status = 'complete';
                } else {
                    // Player wins with blackjack
                    game.result = 'win';
                    game.status = 'complete';
                }
            }
    
            // Save game state
            await this.saveGame(game);
            return game;
        }
    };
    
    export async function main() {
        const { player, arguments: args } = data;
        const gameServerId = data.gameServerId;
    
        // Return object required by Takaro
        const result = {
            success: true,
            message: 'Game started successfully'
        };
    
        try {
            // Validate bet
            if (!args || !args.bet) {
                await player.pm('Please provide a bet amount. Usage: /BJplay [amount]');
                result.success = false;
                result.message = 'Missing bet amount';
                return result;
            }
    
            const bet = parseInt(args.bet);
            if (isNaN(bet) || bet <= 0) {
                await player.pm('Please provide a valid bet amount (a positive number).');
                result.success = false;
                result.message = 'Invalid bet amount';
                return result;
            }
    
            // Get module config
            const config = await takaro.getModuleConfig();
            const minBet = config.minBet || 10;
            const maxBet = config.maxBet || 1000;
    
            if (bet < minBet) {
                await player.pm(`Minimum bet is ${minBet}.`);
                result.success = false;
                result.message = `Bet below minimum (${minBet})`;
                return result;
            }
    
            if (bet > maxBet) {
                await player.pm(`Maximum bet is ${maxBet}.`);
                result.success = false;
                result.message = `Bet above maximum (${maxBet})`;
                return result;
            }
    
            // Get current player balance
            const playerInfo = await takaro.playerOnGameserver.playerOnGameServerControllerGetOne(gameServerId, player.id);
            const playerBalance = playerInfo.data.currency;
    
            // Check balance
            if (playerBalance < bet) {
                await player.pm(`You don't have enough currency. Your balance: ${playerBalance}`);
                result.success = false;
                result.message = 'Insufficient funds';
                return result;
            }
    
            // Deduct bet using the correct currency API
            await takaro.playerOnGameserver.playerOnGameServerControllerDeductCurrency(gameServerId, player.id, {
                currency: bet
            });
    
            // Start the game using variable storage
            const game = await GameLogic.startGame(player.id, bet);
    
            // Construct game status message
            const playerHandString = CardUtils.handToString(game.playerHand);
            const playerHandValue = CardUtils.calculateHandValue(game.playerHand);
            const dealerUpCardString = `${game.dealerHand[0].value}${game.dealerHand[0].suit}`;
    
            // Check for immediate game over
            if (game.status === 'complete') {
                const dealerHandString = CardUtils.handToString(game.dealerHand);
                const dealerHandValue = CardUtils.calculateHandValue(game.dealerHand);
    
                let resultMessage = '';
                let winnings = 0;
    
                switch (game.result) {
                    case 'win':
                        // Check for blackjack bonus
                        if (playerHandValue === 21 && game.playerHand.length === 2) {
                            const blackjackPayout = config.blackjackPayout || 1.5;
                            winnings = bet + Math.floor(bet * blackjackPayout);
                            resultMessage = `BLACKJACK! You win ${winnings}!`;
                        } else {
                            winnings = bet * 2;
                            resultMessage = `You win ${winnings}!`;
                        }
    
                        // Add winnings using correct currency API
                        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, player.id, {
                            currency: winnings
                        });
                        break;
    
                    case 'push':
                        // Return bet using correct currency API
                        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, player.id, {
                            currency: bet
                        });
                        resultMessage = 'It\'s a tie (Push). Your bet has been returned.';
                        break;
    
                    case 'lose':
                        resultMessage = `You lose ${bet}.`;
                        break;
                }
    
                await player.pm(`GAME OVER\nYour Hand: ${playerHandString} (Total: ${playerHandValue})\nDealer's Hand: ${dealerHandString} (Total: ${dealerHandValue})\n${resultMessage}`);
            } else {
                await player.pm(`BLACKJACK GAME STARTED!\nBet: ${bet}\nYour Hand: ${playerHandString} (Total: ${playerHandValue})\nDealer's Visible Card: ${dealerUpCardString}\n\nUse /bjhit to take another card\nUse /bjstand to end your turn`);
            }
    
            return result;
        } catch (error) {
            console.error('BJplay error:', error);
            result.success = false;
            result.message = error.message;
    
            try {
                await player.pm(`Error: ${error.message}`);
            } catch {
                // Ignore messaging errors
            }
    
            return result;
        }
    }
  • Carrier

    Kill Boss Carrier

    Hook source
    import { data, takaro } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, eventData } = data;
    
        const namePattern = /entityKilled: (\w+) \(Steam_/;
        const nameMatch = eventData.msg.match(namePattern);
        const amountx = data.module.userConfig.coinAmountBoss;
        const message = data.module.userConfig.announceCarrier;
        const playerName = nameMatch ? nameMatch[1] : "Unknown";
        const formattedMessage = message
            .replace('{pname}', playerName)
            .replace('{amount}', amountx);
    
    
        const pattern = /Steam_(\d+)/;
        const match = data.eventData.msg.match(pattern);
        const steamIdx = match[1];
        const playerid = (await takaro.player.playerControllerSearch({ filters: { steamId: [steamIdx] } })).data.data[0].id;
    
        // Send the message with backticks
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: formattedMessage
        });
    
        // Grant currency to the player
        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, playerid, {
            currency: amountx
        });
    }
    
    await main();
  • BurningFlesh

    Burning Flesh Kill

    Hook source
    import { data, takaro } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, eventData } = data;
    
        const namePattern = /entityKilled: (\w+) \(Steam_/;
        const nameMatch = eventData.msg.match(namePattern);
        const amountx = data.module.userConfig.coinAmountTinyBoss;
        const message = data.module.userConfig.announceBurningFlesh;
        const playerName = nameMatch ? nameMatch[1] : "Unknown";
        const formattedMessage = message
            .replace('{pname}', playerName)
            .replace('{amount}', amountx);
    
    
        const pattern = /Steam_(\d+)/;
        const match = data.eventData.msg.match(pattern);
        const steamIdx = match[1];
        const playerid = (await takaro.player.playerControllerSearch({ filters: { steamId: [steamIdx] } })).data.data[0].id;
    
        // Send the message with backticks
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: formattedMessage
        });
    
        // Grant currency to the player
        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, playerid, {
            currency: amountx
        });
    }
    
    await main();