## [2.6.0] - 2025-08-09
This commit is contained in:
parent
9e480e6bcc
commit
9f918be0c9
9 changed files with 155 additions and 120 deletions
|
|
@ -1,5 +1,7 @@
|
|||
# Changelog
|
||||
|
||||
**Peril Dice Game System - Created by Rebecca Nod and Noose the Bunny**
|
||||
|
||||
All notable changes to Peril Dice will be documented in this file.
|
||||
|
||||
## [2.6.0] - 2025-08-09
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# 🎲 **PERIL DICE GAME - OFFICIAL RULES**
|
||||
|
||||
**Created by Rebecca Nod and Noose the Bunny**
|
||||
|
||||
*Original concept by **Noose the Bunny** (djmusica28) in Second Life*
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -166,9 +166,9 @@ default {
|
|||
integer playerCount = (integer)str;
|
||||
llOwnerSay("📈 Calculator: Calculating dice type for " + (string)playerCount + " players");
|
||||
integer result = getDiceType(playerCount);
|
||||
// Send result ONLY back to the requesting script to prevent duplicate processing
|
||||
// Main Controller will forward it to Game Manager as needed
|
||||
llMessageLinked(sender, MSG_DICE_TYPE_RESULT, (string)result, NULL_KEY);
|
||||
// Send result to ALL scripts via LINK_SET so Game Manager receives it directly
|
||||
// Each script will handle duplicate prevention on their end
|
||||
llMessageLinked(LINK_SET, MSG_DICE_TYPE_RESULT, (string)result, NULL_KEY);
|
||||
}
|
||||
else if (num == MSG_GET_PICKS_REQUIRED) {
|
||||
integer result = getPicksRequiredFromName(str);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ integer diceType = 6;
|
|||
key currentPicker;
|
||||
integer roundStarted = FALSE;
|
||||
integer diceTypeProcessed = FALSE; // Track if we've already processed dice type for this round
|
||||
integer ignorePicksSync = FALSE; // Temporarily ignore picks data sync during round initialization
|
||||
|
||||
// Duplicate request prevention
|
||||
string lastHumanPickMessage = "";
|
||||
|
|
@ -50,6 +51,8 @@ continueCurrentRound() {
|
|||
picksData = [];
|
||||
globalPickedNumbers = [];
|
||||
|
||||
llOwnerSay("🔄 [Game Manager] continueCurrentRound: Cleared picks data, starting fresh");
|
||||
|
||||
// Set round as started for the new round
|
||||
roundStarted = TRUE;
|
||||
diceTypeProcessed = FALSE; // Reset dice type processing for new round
|
||||
|
|
@ -65,7 +68,9 @@ continueCurrentRound() {
|
|||
}
|
||||
currentPickerIdx = 0;
|
||||
|
||||
// Request dice type for the new round
|
||||
llOwnerSay("🎯 [Game Manager] Pick queue created: " + llList2CSV(pickQueue) + ", requesting dice type");
|
||||
|
||||
// Request dice type directly from Calculator for the new round
|
||||
llMessageLinked(LINK_SET, MSG_GET_DICE_TYPE, (string)llGetListLength(names), NULL_KEY);
|
||||
|
||||
// Note: showNextPickerDialog() will be called when dice type result is received
|
||||
|
|
@ -282,49 +287,59 @@ default {
|
|||
newPicksData = llParseString2List(picksDataStr, ["^"], []);
|
||||
}
|
||||
|
||||
// Don't sync peril player from Main Controller - Game Manager is authoritative
|
||||
// string receivedPeril = llList2String(parts, 2);
|
||||
// Game Manager manages its own peril player state
|
||||
names = llCSV2List(llList2String(parts, 3));
|
||||
// Game Manager is authoritative for peril player, but check for eliminations
|
||||
list newNames = llCSV2List(llList2String(parts, 3));
|
||||
|
||||
// Check if current peril player was eliminated
|
||||
if (perilPlayer != "" && perilPlayer != "NONE") {
|
||||
integer perilStillExists = llListFindList(newNames, [perilPlayer]) != -1;
|
||||
if (!perilStillExists && llListFindList(names, [perilPlayer]) != -1) {
|
||||
// Peril player was eliminated! Game Manager needs to assign new peril player
|
||||
llOwnerSay("🚨 [Game Manager] Detected elimination of peril player: " + perilPlayer);
|
||||
|
||||
// Find first remaining alive player to be new peril player
|
||||
string newPerilPlayer = "";
|
||||
integer k;
|
||||
for (k = 0; k < llGetListLength(newNames) && newPerilPlayer == ""; k++) {
|
||||
string candidateName = llList2String(newNames, k);
|
||||
integer candidateIdx = llListFindList(newNames, [candidateName]);
|
||||
if (candidateIdx != -1 && candidateIdx < llGetListLength(newLives)) {
|
||||
integer candidateLives = llList2Integer(newLives, candidateIdx);
|
||||
if (candidateLives > 0) {
|
||||
newPerilPlayer = candidateName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newPerilPlayer != "") {
|
||||
llOwnerSay("🎯 [Game Manager] Assigning new peril player: " + newPerilPlayer);
|
||||
perilPlayer = newPerilPlayer;
|
||||
} else {
|
||||
llOwnerSay("⚠️ [Game Manager] No valid peril player candidates found!");
|
||||
perilPlayer = "NONE";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
names = newNames;
|
||||
|
||||
// New: also receive players list if available (for dialog targeting)
|
||||
if (llGetListLength(parts) >= 5) {
|
||||
players = llCSV2List(llList2String(parts, 4));
|
||||
}
|
||||
|
||||
// AUTOMATIC ROUND CONTINUATION: Detect post-roll state
|
||||
// Check if lives have changed (indicating a roll occurred) and all picks are now empty
|
||||
// Always update state normally - don't auto-continue rounds
|
||||
// The Roll module will handle post-roll logic and Main Controller will manage round flow
|
||||
lives = newLives;
|
||||
picksData = newPicksData;
|
||||
|
||||
// Only log if this appears to be a post-roll update for debugging
|
||||
string oldLivesStr = llList2CSV(lives);
|
||||
string newLivesStr = llList2CSV(newLives);
|
||||
integer livesChanged = (oldLivesStr != newLivesStr);
|
||||
|
||||
// Check if all picks are empty (indicating post-roll state)
|
||||
integer allPicksEmpty = TRUE;
|
||||
integer i;
|
||||
for (i = 0; i < llGetListLength(newPicksData) && allPicksEmpty; i++) {
|
||||
string entry = llList2String(newPicksData, i);
|
||||
list entryParts = llParseString2List(entry, ["|"], []);
|
||||
if (llGetListLength(entryParts) >= 2 && llList2String(entryParts, 1) != "") {
|
||||
allPicksEmpty = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// If lives changed and all picks are empty, this is post-roll - start new round
|
||||
if (livesChanged && allPicksEmpty && roundStarted && perilPlayer != "" && perilPlayer != "NONE") {
|
||||
llOwnerSay("🎯 [Game Manager] Post-roll detected - automatically continuing to next round");
|
||||
|
||||
// Update our state first
|
||||
lives = newLives;
|
||||
picksData = newPicksData;
|
||||
|
||||
// Reset for new round and continue
|
||||
roundStarted = FALSE;
|
||||
currentPickerIdx = 0;
|
||||
continueCurrentRound();
|
||||
} else {
|
||||
// Normal state update
|
||||
lives = newLives;
|
||||
picksData = newPicksData;
|
||||
if (livesChanged) {
|
||||
llOwnerSay("🔍 [Game Manager] Lives changed - roll completed, waiting for proper round continuation signal");
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -133,8 +133,6 @@ list floaterChannels = []; // Track actual floater channels for cleanup
|
|||
|
||||
list pickQueue = [];
|
||||
integer currentPickerIdx = 0;
|
||||
integer diceType = 6;
|
||||
|
||||
integer MSG_SHOW_DIALOG = 101;
|
||||
integer MSG_ROLL_RESULT = 102;
|
||||
integer MSG_UPDATE_FLOAT = 103;
|
||||
|
|
@ -157,10 +155,9 @@ integer CONTROLLER_FACE = 1; // Face to display start image on (front face)
|
|||
string TEXTURE_START = "title_start"; // Start image texture
|
||||
string TEXTURE_GAME_ACTIVE = "game_active"; // Optional: different texture during game
|
||||
|
||||
integer MSG_GET_DICE_TYPE = 1001;
|
||||
// Dice type handling is now done by Game Manager directly
|
||||
integer MSG_GET_PICKS_REQUIRED = 1002;
|
||||
integer MSG_GET_PICKER_INDEX = 1003;
|
||||
integer MSG_DICE_TYPE_RESULT = 1005;
|
||||
integer MSG_SERIALIZE_GAME_STATE = 1004;
|
||||
integer MSG_SYNC_PICKQUEUE = 2001;
|
||||
|
||||
|
|
@ -168,12 +165,13 @@ integer MSG_SYNC_PICKQUEUE = 2001;
|
|||
// mirror the value used in Floater Manager to avoid inconsistencies.
|
||||
integer MAX_PLAYERS = 10;
|
||||
|
||||
integer TIMEOUT_SECONDS = 600;
|
||||
integer TIMEOUT_SECONDS = 120; // Reduced from 600 (10 min) to 120 (2 min)
|
||||
integer timeoutTimer;
|
||||
|
||||
integer warning2min = 120;
|
||||
integer warning5min = 300;
|
||||
integer warning9min = 540;
|
||||
// Updated warning times for 2-minute timeout
|
||||
integer warning30sec = 30; // 30 seconds remaining
|
||||
integer warning1min = 60; // 1 minute remaining
|
||||
integer warning90sec = 90; // 1.5 minutes remaining
|
||||
integer lastWarning = 0;
|
||||
|
||||
key currentPicker;
|
||||
|
|
@ -266,10 +264,6 @@ updateHelpers() {
|
|||
}
|
||||
|
||||
// Request helper-calculated values
|
||||
requestDiceType() {
|
||||
llMessageLinked(LINK_SET, MSG_GET_DICE_TYPE, (string)llGetListLength(names), NULL_KEY);
|
||||
}
|
||||
|
||||
requestPicksRequired(integer idx) {
|
||||
llMessageLinked(LINK_SET, MSG_GET_PICKS_REQUIRED, llList2String(names, idx), NULL_KEY);
|
||||
}
|
||||
|
|
@ -329,11 +323,9 @@ resetGame() {
|
|||
currentPickerIdx = 0;
|
||||
roundStarted = FALSE; // Reset round flag
|
||||
gameStarting = FALSE; // Reset game starting flag
|
||||
diceTypeProcessed = FALSE; // Reset dice type processing flag
|
||||
currentPicker = NULL_KEY; // Reset current picker
|
||||
timeoutTimer = 0; // Reset timeout timer
|
||||
lastWarning = 0; // Reset warning timer
|
||||
diceType = 6; // Reset dice type to default
|
||||
|
||||
// Send reset message to all other scripts to clear their state
|
||||
llMessageLinked(LINK_SET, -99999, "FULL_RESET", NULL_KEY);
|
||||
|
|
@ -370,7 +362,6 @@ resetGame() {
|
|||
|
||||
integer roundStarted = FALSE;
|
||||
integer gameStarting = FALSE; // Track when game is in startup sequence
|
||||
integer diceTypeProcessed = FALSE; // Track if we've already processed initial dice type
|
||||
|
||||
// CONTINUE_ROUND logic now handled entirely by Game Manager
|
||||
|
||||
|
|
@ -547,24 +538,8 @@ if (toucher == llGetOwner() && roundStarted) {
|
|||
|
||||
link_message(integer sender, integer num, string str, key id) {
|
||||
// Player list and pick data handling now delegated to Controller_MessageHandler.lsl
|
||||
// Handle dice type result from helper - forward to Game Manager once
|
||||
if (num == MSG_DICE_TYPE_RESULT) {
|
||||
// Prevent duplicate processing of the same dice type result
|
||||
if (diceTypeProcessed) {
|
||||
return;
|
||||
}
|
||||
|
||||
diceType = (integer)str;
|
||||
diceTypeProcessed = TRUE;
|
||||
|
||||
// Set round started flag and update helpers
|
||||
roundStarted = TRUE;
|
||||
updateHelpers();
|
||||
|
||||
// Forward to Game Manager ONCE
|
||||
llMessageLinked(LINK_SET, MSG_DICE_TYPE_RESULT, (string)diceType, NULL_KEY);
|
||||
return;
|
||||
}
|
||||
// Main Controller no longer needs to handle dice type results
|
||||
// Game Manager handles all dice type logic directly
|
||||
if (num == MSG_GET_PICKS_REQUIRED) {
|
||||
integer picksRequired = (integer)str;
|
||||
llOwnerSay(" Picks required: " + str);
|
||||
|
|
@ -704,41 +679,9 @@ sendStatusMessage("Victory"); // Show victory status
|
|||
return;
|
||||
}
|
||||
|
||||
// If the eliminated player was the peril player, assign a new one and continue game
|
||||
if (eliminatedPlayer == perilPlayer) {
|
||||
// Find first remaining alive player to be new peril player
|
||||
perilPlayer = "";
|
||||
integer k;
|
||||
for (k = 0; k < llGetListLength(names) && perilPlayer == ""; k++) {
|
||||
string candidateName = llList2String(names, k);
|
||||
if (llList2Integer(lives, k) > 0) {
|
||||
perilPlayer = candidateName;
|
||||
llOwnerSay("🔄 After elimination, new peril player: " + perilPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
// Continue the game with the new peril player (don't reset roundStarted)
|
||||
if (perilPlayer != "") {
|
||||
llOwnerSay("🎯 Continuing game with " + perilPlayer + " as new peril player");
|
||||
// Reset picks and queue for new round, but keep roundStarted = TRUE
|
||||
picksData = [];
|
||||
globalPickedNumbers = [];
|
||||
pickQueue = [perilPlayer];
|
||||
integer i;
|
||||
for (i = 0; i < llGetListLength(names); i++) {
|
||||
string playerName = llList2String(names, i);
|
||||
if (playerName != perilPlayer) {
|
||||
pickQueue += [playerName];
|
||||
}
|
||||
}
|
||||
currentPickerIdx = 0;
|
||||
updateHelpers();
|
||||
requestDiceType();
|
||||
}
|
||||
} else {
|
||||
// Continue with existing peril player
|
||||
updateHelpers();
|
||||
}
|
||||
// Let Game Manager handle peril player reassignment after elimination
|
||||
// Just update helpers and let Game Manager detect the elimination via sync
|
||||
updateHelpers();
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
@ -836,11 +779,18 @@ resetGame();
|
|||
}
|
||||
// Handle start next round request - delegate to Game Manager
|
||||
if (num == 997) {
|
||||
// Check sender to prevent infinite loops - don't process our own messages
|
||||
if (sender == llGetLinkNumber()) {
|
||||
return; // Ignore messages from ourself
|
||||
}
|
||||
|
||||
// Additional protection against round start spam
|
||||
if (roundStarted && str == "START_NEXT_ROUND") {
|
||||
llOwnerSay("⚠️ [Main Controller] Round already in progress, ignoring START_NEXT_ROUND");
|
||||
return;
|
||||
}
|
||||
// Game Manager will handle dice type processing for new round
|
||||
llOwnerSay("🔄 [Main Controller] Starting new round - Game Manager will handle dice type");
|
||||
// Forward the request to Game Manager
|
||||
llMessageLinked(LINK_SET, num, str, id);
|
||||
// Don't request dice type here - it's handled in the "Start Game" listener below
|
||||
|
|
@ -1016,6 +966,31 @@ llRegionSay(SCOREBOARD_CHANNEL_1, "RESET_LEADERBOARD"); // Reset leaderboard sco
|
|||
llMessageLinked(LINK_SET, MSG_SHOW_MENU, "owner|" + (string)ownerIsStarter, llGetOwner());
|
||||
return;
|
||||
}
|
||||
if (msg == "Force Floaters") {
|
||||
// Force creation of floaters for all registered players
|
||||
llOwnerSay("🔧 Forcing floater creation for all " + (string)llGetListLength(names) + " players...");
|
||||
integer i;
|
||||
for (i = 0; i < llGetListLength(names); i++) {
|
||||
string playerName = llList2String(names, i);
|
||||
key playerKey = llList2Key(players, i);
|
||||
llMessageLinked(LINK_SET, MSG_REZ_FLOAT, playerName, playerKey);
|
||||
llSleep(0.3); // Brief delay between rezzing to prevent spam
|
||||
}
|
||||
llOwnerSay("✅ Floater creation requests sent for all players!");
|
||||
// Refresh owner menu
|
||||
integer ownerIdx = llListFindList(players, [llGetOwner()]);
|
||||
integer ownerIsStarter = TRUE; // Default to TRUE for owner
|
||||
integer n;
|
||||
for (n = 0; n < ownerIdx && ownerIsStarter; n++) {
|
||||
string existingName = llList2String(names, n);
|
||||
// If there's a human player before the owner, owner is not starter
|
||||
if (llSubStringIndex(existingName, "TestBot") != 0) {
|
||||
ownerIsStarter = FALSE;
|
||||
}
|
||||
}
|
||||
llMessageLinked(LINK_SET, MSG_SHOW_MENU, "owner|" + (string)ownerIsStarter, llGetOwner());
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Allow the first registered player (index 0) or the owner to start the game.
|
||||
// When the starter clicks "Start Game", begin the round.
|
||||
|
|
@ -1102,15 +1077,15 @@ llRegionSay(SCOREBOARD_CHANNEL_1, "RESET_LEADERBOARD"); // Reset leaderboard sco
|
|||
llSetTimerEvent(0);
|
||||
} else {
|
||||
integer remaining = TIMEOUT_SECONDS - elapsed;
|
||||
if (remaining <= warning2min && lastWarning < warning2min) {
|
||||
llOwnerSay("⚠️ " + (string)(remaining / 60) + " minutes remaining for dialog response");
|
||||
lastWarning = warning2min;
|
||||
} else if (remaining <= warning5min && lastWarning < warning5min) {
|
||||
llOwnerSay("⚠️ " + (string)(remaining / 60) + " minutes remaining for dialog response");
|
||||
lastWarning = warning5min;
|
||||
} else if (remaining <= warning9min && lastWarning < warning9min) {
|
||||
llOwnerSay("⚠️ " + (string)(remaining / 60) + " minutes remaining for dialog response");
|
||||
lastWarning = warning9min;
|
||||
if (remaining <= warning30sec && lastWarning < warning30sec) {
|
||||
llOwnerSay("⚠️ 30 seconds remaining for dialog response");
|
||||
lastWarning = warning30sec;
|
||||
} else if (remaining <= warning1min && lastWarning < warning1min) {
|
||||
llOwnerSay("⚠️ 1 minute remaining for dialog response");
|
||||
lastWarning = warning1min;
|
||||
} else if (remaining <= warning90sec && lastWarning < warning90sec) {
|
||||
llOwnerSay("⚠️ 1.5 minutes remaining for dialog response");
|
||||
lastWarning = warning90sec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ list mainOwnerOptions = ["🎮 Game Participation", "👥 Player Management", "
|
|||
list gameParticipationOptions = ["Join Game", "Leave Game", "⬅️ Back to Main"];
|
||||
list playerManagementOptions = ["Add Test Player", "⬅️ Back to Main"];
|
||||
list resetOptions = ["Reset Game", "Reset Leaderboard", "Reset All", "⬅️ Back to Main"];
|
||||
list troubleshootingOptions = ["Cleanup Floaters", "Reset Follower Positions", "⬅️ Back to Main"];
|
||||
list troubleshootingOptions = ["Cleanup Floaters", "Force Floaters", "Reset Follower Positions", "⬅️ Back to Main"];
|
||||
|
||||
// State tracking for dynamic ready menu with race condition protection
|
||||
key pendingMenuPlayer = NULL_KEY;
|
||||
|
|
@ -102,7 +102,7 @@ integer pendingMenuIsOwner = FALSE;
|
|||
integer pendingMenuRequestID = 0; // Unique ID for each menu request
|
||||
integer currentRequestID = 0; // Counter for generating unique request IDs
|
||||
float pendingMenuTimestamp = 0.0; // Timeout for pending requests
|
||||
float MENU_REQUEST_TIMEOUT = 10.0; // 10 second timeout for menu requests
|
||||
float MENU_REQUEST_TIMEOUT = 5.0; // 5 second timeout for menu requests
|
||||
|
||||
// Display the main categorized owner menu
|
||||
showOwnerMenu(key id) {
|
||||
|
|
@ -372,9 +372,15 @@ default {
|
|||
}
|
||||
else if (msg == "Cleanup Floaters") {
|
||||
// Universal floater cleanup that works even after script resets
|
||||
llOwnerSay("🧹 Force cleaning ALL possible floater channels...");
|
||||
llOwnerSay("🧩 Force cleaning ALL possible floater channels...");
|
||||
llMessageLinked(LINK_SET, MSG_CLEANUP_ALL_FLOATERS, "", NULL_KEY);
|
||||
}
|
||||
else if (msg == "Force Floaters") {
|
||||
// Force creation of floaters for all registered players - send as dialog response to Main Controller
|
||||
llOwnerSay("🔧 Requesting floater creation for all registered players...");
|
||||
// This will be handled by Main Controller's dialog listener
|
||||
// No need to forward via link_message - the Main Controller is already listening on DIALOG_CHANNEL
|
||||
}
|
||||
else if (msg == "Reset Follower Positions") {
|
||||
// Integrated position reset functionality with automation options
|
||||
if (id == llGetOwner()) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# 🎲 Peril Dice — Modular Game System for Second Life
|
||||
|
||||
**Created by Rebecca Nod and Noose the Bunny**
|
||||
|
||||
## Overview
|
||||
|
||||
Peril Dice is a multiplayer elimination game where each player selects numbers before a die is rolled. If the peril player's number is rolled, they lose a life. Players are eliminated when they reach zero lives.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
🎲 PERIL DICE — MODULAR GAME SYSTEM FOR SECOND LIFE
|
||||
========================================================
|
||||
|
||||
CREATED BY REBECCA NOD AND NOOSE THE BUNNY
|
||||
|
||||
OVERVIEW
|
||||
--------
|
||||
Peril Dice is a multiplayer elimination game where each player selects numbers before a die is rolled. If the peril player's number is rolled, they lose a life. Players are eliminated when they reach zero lives.
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ list names = [];
|
|||
list lives = [];
|
||||
list picksData = [];
|
||||
string perilPlayer = "";
|
||||
integer diceType = 6; // Store the dice type for rolling
|
||||
integer shouldRoll = FALSE; // Flag to trigger roll after dice type is received
|
||||
|
||||
list getPicksFor(string nameInput) {
|
||||
integer i;
|
||||
|
|
@ -197,7 +199,9 @@ default {
|
|||
if (llSubStringIndex(str, "TestBot") == 0) {
|
||||
// Auto-roll for bots
|
||||
llOwnerSay("🤖 " + str + " (bot) is auto-rolling...");
|
||||
llMessageLinked(LINK_SET, 996, "GET_DICE_TYPE", NULL_KEY);
|
||||
shouldRoll = TRUE; // Set flag for bot auto-roll
|
||||
// Request dice type directly from Calculator
|
||||
llMessageLinked(LINK_SET, 1001, (string)llGetListLength(names), NULL_KEY);
|
||||
} else {
|
||||
// Show dialog for human players
|
||||
llDialog(id, "🎲 THE MOMENT OF TRUTH! You're in ultimate peril. Will you face your fate?", ["ROLL THE DICE OF FATE"], rollDialogChannel);
|
||||
|
|
@ -205,6 +209,31 @@ default {
|
|||
}
|
||||
}
|
||||
|
||||
// Handle dice type requests from listen() events
|
||||
else if (num == 996) {
|
||||
// This is a GET_DICE_TYPE request from our own listen handler
|
||||
// Forward it to the Main Controller to get the current dice type
|
||||
llMessageLinked(LINK_SET, 1001, (string)llGetListLength(names), NULL_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle dice type response - store dice type and perform roll if requested
|
||||
else if (num == 1005) { // MSG_DICE_TYPE_RESULT
|
||||
diceType = (integer)str;
|
||||
llOwnerSay("🎲 [Roll Module] Received dice type: d" + (string)diceType);
|
||||
|
||||
// If roll was requested from listen handler, perform it now
|
||||
if (shouldRoll) {
|
||||
shouldRoll = FALSE; // Reset flag
|
||||
llOwnerSay("🎲 [Roll Module] Performing requested roll with d" + (string)diceType);
|
||||
|
||||
// Use MSG_ROLL_RESULT handler to perform the actual roll
|
||||
llMessageLinked(LINK_THIS, MSG_ROLL_RESULT, (string)diceType, NULL_KEY);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Legacy MSG_ROLL_RESULT handler (if still used somewhere)
|
||||
else if (num == MSG_ROLL_RESULT) {
|
||||
integer diceType = (integer)str;
|
||||
integer result = rollDice(diceType);
|
||||
|
|
@ -344,9 +373,11 @@ default {
|
|||
|
||||
listen(integer channel, string name, key id, string msg) {
|
||||
if (msg == "Roll" || msg == "ROLL THE DICE OF FATE") {
|
||||
// Handle dice roll - need to get dice type from main controller
|
||||
// Handle dice roll - need to get dice type from Calculator
|
||||
llOwnerSay("🎲 Roll button clicked by " + name + " (key: " + (string)id + ")");
|
||||
llMessageLinked(LINK_SET, 996, "GET_DICE_TYPE", NULL_KEY);
|
||||
shouldRoll = TRUE; // Set flag to perform roll when dice type is received
|
||||
// Request dice type directly from Calculator
|
||||
llMessageLinked(LINK_SET, 1001, (string)llGetListLength(names), NULL_KEY);
|
||||
} else {
|
||||
llMessageLinked(LINK_THIS, channel, msg, id);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue