killEarner
- community
- PvP
- by Limon
- Takaro main
- all
Rewards players with currency and messages for PvP kills. Configurable reward amounts, random messages for killer and victim, and option to send messages publicly or as PMs.
Configuration 6
Settings you fill in when installing the module on a server.
| Setting | Type | Default | Description |
|---|---|---|---|
killReward | number | 100 | Currency reward for killing another player |
enableKillerMessages | boolean | true | Send messages to the killer |
enableVictimMessages | boolean | true | Send messages to the victim |
usePublicMessages | boolean | false | Send messages publicly instead of as PMs |
killerMessages | array | ["Nice kill!","You're on fire!","Dominating!","Excellent work!","Keep it up!"] | Random messages for killers |
victimMessages | array | ["Better luck next time!","Ouch!","You'll get them next time!","Don't give up!","Respawn and try again!"] | Random messages for victims |
Raw config schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"killReward": {
"type": "number",
"description": "Currency reward for killing another player",
"default": 100,
"minimum": 0
},
"enableKillerMessages": {
"type": "boolean",
"description": "Send messages to the killer",
"default": true
},
"enableVictimMessages": {
"type": "boolean",
"description": "Send messages to the victim",
"default": true
},
"usePublicMessages": {
"type": "boolean",
"description": "Send messages publicly instead of as PMs",
"default": false
},
"killerMessages": {
"type": "array",
"description": "Random messages for killers",
"items": {
"type": "string"
},
"default": [
"Nice kill!",
"You're on fire!",
"Dominating!",
"Excellent work!",
"Keep it up!"
]
},
"victimMessages": {
"type": "array",
"description": "Random messages for victims",
"items": {
"type": "string"
},
"default": [
"Better luck next time!",
"Ouch!",
"You'll get them next time!",
"Don't give up!",
"Respawn and try again!"
]
}
},
"additionalProperties": false
} Raw UI schema
{
"killReward": {
"ui:help": "Amount of currency to give to the killer"
},
"killerMessages": {
"ui:help": "List of random messages to send to killers"
},
"victimMessages": {
"ui:help": "List of random messages to send to victims"
},
"usePublicMessages": {
"ui:help": "When enabled, messages are sent to global chat instead of private messages"
}
} Commands 1
Chat commands players trigger in game.
-
killstats
Use /killstats to see your own stats, or /killstats [playername] to see another player's stats
Argument Type Default Help playerplayer The player to view stats for (optional - defaults to yourself) Command source
import { takaro, data, TakaroUserError } from '@takaro/helpers'; async function main() { const { player, gameServerId, module, arguments: args } = data; try { let targetPlayer = player; // If a player argument is provided, use that player if (args && args.player) { // Verify the player exists on this game server const pogResponse = await takaro.playerOnGameserver.playerOnGameServerControllerSearch({ filters: { gameServerId: [gameServerId], playerId: [args.player.id] }, limit: 1 }); if (pogResponse.data.data && pogResponse.data.data.length > 0) { targetPlayer = args.player; } else { await player.pm(`Player "${args.player.name}" not found on this server.`); return; } } else if (args && args.playerName) { // Fallback for string-based player lookup const playersResponse = await takaro.player.playerControllerSearch({ filters: { name: [args.playerName] // Use filters instead of search }, limit: 1 }); if (!playersResponse.data.data || playersResponse.data.data.length === 0) { await player.pm(`Player "${args.playerName}" not found.`); return; } targetPlayer = playersResponse.data.data[0]; } // Get kill count const killCountVar = await takaro.variable.variableControllerSearch({ filters: { key: ['pvp_kills'], gameServerId: [gameServerId], moduleId: [module.moduleId], playerId: [targetPlayer.id] }, limit: 1 }); const kills = killCountVar.data.data && killCountVar.data.data.length > 0 ? parseInt(killCountVar.data.data[0].value) || 0 : 0; // Get death count const deathCountVar = await takaro.variable.variableControllerSearch({ filters: { key: ['pvp_deaths'], gameServerId: [gameServerId], moduleId: [module.moduleId], playerId: [targetPlayer.id] }, limit: 1 }); const deaths = deathCountVar.data.data && deathCountVar.data.data.length > 0 ? parseInt(deathCountVar.data.data[0].value) || 0 : 0; // Calculate K/D ratio const kdRatio = deaths > 0 ? (kills / deaths).toFixed(2) : kills.toString(); const statsMessage = targetPlayer.id === player.id ? `🎯 Your PvP Stats:\n Kills: ${kills}\n Deaths: ${deaths}\n K/D Ratio: ${kdRatio}` : `🎯 ${targetPlayer.name}'s PvP Stats:\n Kills: ${kills}\n Deaths: ${deaths}\n K/D Ratio: ${kdRatio}`; await player.pm(statsMessage); } catch (error) { console.error(`Error in showKillStats: ${error.message}`); await player.pm('Error retrieving kill statistics.'); } } await main();
Hooks 1
Code that runs in reaction to a game or Takaro event.
-
PvP Kill Detector
Detects when a player is killed by another player and triggers rewards and messages
Hook source
import { takaro, data, TakaroUserError } from '@takaro/helpers'; async function main() { const { gameServerId, module, eventData } = data; try { // Extract event data (not eventMeta) if (!eventData || !eventData.victim || !eventData.attacker) { console.log('Missing required event data for PvP detection'); return; } const victim = eventData.victim; const attacker = eventData.attacker; // Check if this is actually a PvP kill (player killed by another player) if (!attacker.gameId || attacker.gameId === victim.gameId) { console.log('Not a PvP kill - same player or invalid attacker'); return; } // Check if attacker is a player (has gameId) and not an NPC if (!attacker.name || attacker.name.includes('zombie') || attacker.name.includes('bot')) { console.log('Attacker appears to be NPC, skipping reward'); return; } console.log(`PvP Kill detected: ${attacker.name} killed ${victim.name}`); // Get module configuration const config = module.userConfig || {}; const killReward = config.killReward || 100; const enableKillerMessages = config.enableKillerMessages !== false; const enableVictimMessages = config.enableVictimMessages !== false; const usePublicMessages = config.usePublicMessages || false; const killerMessages = config.killerMessages || ['Nice kill!', 'You\'re on fire!', 'Dominating!']; const victimMessages = config.victimMessages || ['Better luck next time!', 'Ouch!', 'You\'ll get them next time!']; // Find the killer player in Takaro system const killersResponse = await takaro.player.playerControllerSearch({ filters: { name: [attacker.name] // Use filters for exact matches }, limit: 1 }); if (!killersResponse.data.data || killersResponse.data.data.length === 0) { console.log(`Could not find killer player: ${attacker.name}`); return; } const killerPlayer = killersResponse.data.data[0]; // Find the victim player in Takaro system const victimsResponse = await takaro.player.playerControllerSearch({ filters: { name: [victim.name] // Use filters for exact matches }, limit: 1 }); if (!victimsResponse.data.data || victimsResponse.data.data.length === 0) { console.log(`Could not find victim player: ${victim.name}`); return; } const victimPlayer = victimsResponse.data.data[0]; // Award currency to killer if reward is configured if (killReward > 0) { // Fixed: Use correct API method name (lowercase 's') await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency( gameServerId, killerPlayer.id, { currency: killReward } ); console.log(`Awarded ${killReward} currency to ${killerPlayer.name}`); } // Update kill statistics try { // Get current kill count for killer const killCountVar = await takaro.variable.variableControllerSearch({ filters: { key: ['pvp_kills'], gameServerId: [gameServerId], moduleId: [module.moduleId], playerId: [killerPlayer.id] }, limit: 1 }); let currentKills = 0; if (killCountVar.data.data && killCountVar.data.data.length > 0) { currentKills = parseInt(killCountVar.data.data[0].value) || 0; // Update existing variable await takaro.variable.variableControllerUpdate(killCountVar.data.data[0].id, { value: (currentKills + 1).toString() }); } else { // Create new variable await takaro.variable.variableControllerCreate({ key: 'pvp_kills', value: '1', gameServerId, moduleId: module.moduleId, playerId: killerPlayer.id }); } console.log(`Updated kill count for ${killerPlayer.name}: ${currentKills + 1}`); // Update death count for victim const deathCountVar = await takaro.variable.variableControllerSearch({ filters: { key: ['pvp_deaths'], gameServerId: [gameServerId], moduleId: [module.moduleId], playerId: [victimPlayer.id] }, limit: 1 }); let currentDeaths = 0; if (deathCountVar.data.data && deathCountVar.data.data.length > 0) { currentDeaths = parseInt(deathCountVar.data.data[0].value) || 0; await takaro.variable.variableControllerUpdate(deathCountVar.data.data[0].id, { value: (currentDeaths + 1).toString() }); } else { await takaro.variable.variableControllerCreate({ key: 'pvp_deaths', value: '1', gameServerId, moduleId: module.moduleId, playerId: victimPlayer.id }); } console.log(`Updated death count for ${victimPlayer.name}: ${currentDeaths + 1}`); } catch (statsError) { console.log(`Error updating statistics: ${statsError.message}`); } // Send messages const promises = []; if (enableKillerMessages && killerMessages.length > 0) { const randomKillerMessage = killerMessages[Math.floor(Math.random() * killerMessages.length)]; const killerMessage = `${randomKillerMessage} You earned ${killReward} currency for the kill!`; if (usePublicMessages) { promises.push( takaro.gameserver.gameServerControllerSendMessage(gameServerId, { message: `${killerPlayer.name}: ${killerMessage}` }) ); } else { promises.push( takaro.gameserver.gameServerControllerSendMessage(gameServerId, { message: killerMessage, opts: { recipient: { gameId: attacker.gameId } } }) ); } } if (enableVictimMessages && victimMessages.length > 0) { const randomVictimMessage = victimMessages[Math.floor(Math.random() * victimMessages.length)]; if (usePublicMessages) { promises.push( takaro.gameserver.gameServerControllerSendMessage(gameServerId, { message: `${victimPlayer.name}: ${randomVictimMessage}` }) ); } else { promises.push( takaro.gameserver.gameServerControllerSendMessage(gameServerId, { message: randomVictimMessage, opts: { recipient: { gameId: victim.gameId } } }) ); } } // Execute all message sends in parallel if (promises.length > 0) { await Promise.all(promises); console.log('Messages sent successfully'); } } catch (error) { console.error(`Error in handlePvPKill: ${error.message}`); } } await main();