Peril_Dice/Position_Reset_Tool.lsl

105 lines
4.5 KiB
Text

// Position Reset Tool for Peril Game Display Objects
// Drop this script in your CONTROLLER object and click it
// This will generate config values for your notecard
// =============================================================================
// DYNAMIC CHANNEL CONFIGURATION
// =============================================================================
// Base channel offset - should match Main.lsl
integer CHANNEL_BASE = -77000;
// Calculate channels dynamically to avoid hardcoded conflicts
integer calculateChannel(integer offset) {
// Use BOTH owner's key AND object's key to make channels unique per game instance
// This prevents interference when same owner has multiple game tables
string ownerStr = (string)llGetOwner();
string objectStr = (string)llGetKey();
string combinedStr = ownerStr + objectStr;
// Create a more unique hash using both keys
string hashStr = llMD5String(combinedStr, 0);
integer hash1 = llSubStringIndex("0123456789abcdef", llGetSubString(hashStr, 0, 0));
integer hash2 = llSubStringIndex("0123456789abcdef", llGetSubString(hashStr, 1, 1));
integer combinedHash = hash1 * 16 + hash2; // Creates 0-255 range
return CHANNEL_BASE - (offset * 1000) - combinedHash;
}
key controller_key;
vector controller_pos;
rotation controller_rot;
// Dynamic channels
integer SCOREBOARD_DATA_CHANNEL;
integer LEADERBOARD_DATA_CHANNEL;
integer DICE_DATA_CHANNEL;
// Listen handle management
integer scoreboardHandle = -1;
integer leaderboardHandle = -1;
integer diceHandle = -1;
default {
state_entry() {
// Initialize dynamic channels
SCOREBOARD_DATA_CHANNEL = calculateChannel(6); // ~-83000 range
LEADERBOARD_DATA_CHANNEL = calculateChannel(7); // ~-84000 range
DICE_DATA_CHANNEL = calculateChannel(8); // ~-85000 range
controller_key = llGetKey();
llOwnerSay("🔧 [Position Reset Tool] Dynamic channels initialized:");
llOwnerSay(" Scoreboard: " + (string)SCOREBOARD_DATA_CHANNEL);
llOwnerSay(" Leaderboard: " + (string)LEADERBOARD_DATA_CHANNEL);
llOwnerSay(" Dice: " + (string)DICE_DATA_CHANNEL);
llOwnerSay("Position Reset Tool ready - Click to scan for display objects");
// Clean up any existing listeners
if (scoreboardHandle != -1) llListenRemove(scoreboardHandle);
if (leaderboardHandle != -1) llListenRemove(leaderboardHandle);
if (diceHandle != -1) llListenRemove(diceHandle);
// Set up managed listeners with dynamic channels
scoreboardHandle = llListen(SCOREBOARD_DATA_CHANNEL, "", "", "");
leaderboardHandle = llListen(LEADERBOARD_DATA_CHANNEL, "", "", "");
diceHandle = llListen(DICE_DATA_CHANNEL, "", "", "");
}
touch_start(integer total_number) {
if (llDetectedKey(0) == llGetOwner()) {
controller_pos = llGetPos();
controller_rot = llGetRot();
llOwnerSay("Scanning for display objects within 20 meters...");
// Send scan messages on all data channels to find display objects
llRegionSay(SCOREBOARD_DATA_CHANNEL, "POSITION_SCAN|" + (string)controller_key);
llRegionSay(LEADERBOARD_DATA_CHANNEL, "POSITION_SCAN|" + (string)controller_key);
llRegionSay(DICE_DATA_CHANNEL, "POSITION_SCAN|" + (string)controller_key);
llSetTimerEvent(3.0); // Wait 3 seconds for responses
}
}
listen(integer channel, string name, key id, string msg) {
if ((channel == SCOREBOARD_DATA_CHANNEL || channel == LEADERBOARD_DATA_CHANNEL || channel == DICE_DATA_CHANNEL) &&
llSubStringIndex(msg, "POSITION_RESPONSE|") == 0) {
list parts = llParseString2List(msg, ["|"], []);
string object_type = llList2String(parts, 1);
vector object_pos = (vector)llList2String(parts, 2);
rotation object_rot = (rotation)llList2String(parts, 3);
// Calculate offset and relative rotation
vector offset = (object_pos - controller_pos) / controller_rot;
rotation rel_rot = object_rot / controller_rot;
llOwnerSay("\n=== " + llToUpper(object_type) + " CONFIG ===");
llOwnerSay(object_type + "_offset=" + (string)offset);
llOwnerSay(object_type + "_rotation=" + (string)rel_rot);
}
}
timer() {
llSetTimerEvent(0.0);
llOwnerSay("\nScan complete. Copy values to your 'config' notecard.");
}
}