Peril_Dice/Follower_Script_Template.lsl

109 lines
4.3 KiB
Text

// Peril Game Display Follower Script - Config Version
// This script reads position settings from a "config" notecard
// Change DISPLAY_TYPE below to match your display object
string DISPLAY_TYPE = "scoreboard"; // Change to: "scoreboard", "leaderboard", or "dice"
// These will be loaded from config notecard
vector MY_OFFSET;
rotation MY_ROTATION;
integer MY_CHANNEL;
integer MY_DATA_CHANNEL;
// Controller tracking
key master_key;
vector last_master_pos;
rotation last_master_rot;
// Config reading
integer config_line = 0;
key config_query;
default {
state_entry() {
llOwnerSay("Starting " + DISPLAY_TYPE + " follower - reading config...");
// Start reading config notecard
if (llGetInventoryType("config") == INVENTORY_NOTECARD) {
config_query = llGetNotecardLine("config", 0);
config_line = 0;
} else {
llOwnerSay("ERROR: No 'config' notecard found!");
llOwnerSay("Please add a config notecard to this object.");
return;
}
}
dataserver(key query_id, string data) {
if (query_id == config_query) {
if (data == EOF) {
// Finished reading config
llOwnerSay(DISPLAY_TYPE + " config loaded. Listening for controller...");
llListen(MY_CHANNEL, "", "", ""); // Position sync channel
llListen(MY_DATA_CHANNEL, "", "", ""); // Data/scan channel
llRegionSay(MY_CHANNEL, "FOLLOWER_READY|" + DISPLAY_TYPE);
} else if (data != "") {
// Parse config line
data = llStringTrim(data, STRING_TRIM);
if (llGetSubString(data, 0, 0) != "#") { // Skip comments
integer eq_pos = llSubStringIndex(data, "=");
if (eq_pos != -1) {
string config_key = llStringTrim(llGetSubString(data, 0, eq_pos - 1), STRING_TRIM);
string value = llStringTrim(llGetSubString(data, eq_pos + 1, -1), STRING_TRIM);
// Load values for this display type
if (config_key == DISPLAY_TYPE + "_offset") {
MY_OFFSET = (vector)value;
} else if (config_key == DISPLAY_TYPE + "_rotation") {
MY_ROTATION = (rotation)value;
} else if (config_key == DISPLAY_TYPE + "_channel") {
MY_CHANNEL = (integer)value;
} else if (config_key == DISPLAY_TYPE + "_data_channel") {
MY_DATA_CHANNEL = (integer)value;
}
}
}
// Read next line
config_line++;
config_query = llGetNotecardLine("config", config_line);
} else {
// Read next line even if this one is empty
config_line++;
config_query = llGetNotecardLine("config", config_line);
}
}
}
listen(integer channel, string name, key id, string msg) {
if (channel == MY_CHANNEL) {
if (llSubStringIndex(msg, "CONTROLLER_MOVE|") == 0) {
list parts = llParseString2List(msg, ["|"], []);
master_key = (key)llList2String(parts, 1);
vector master_pos = (vector)llList2String(parts, 2);
rotation master_rot = (rotation)llList2String(parts, 3);
// Calculate new position
vector new_pos = master_pos + (MY_OFFSET * master_rot);
rotation new_rot = MY_ROTATION * master_rot;
llSetPos(new_pos);
llSetRot(new_rot);
last_master_pos = master_pos;
last_master_rot = master_rot;
}
} else if (channel == MY_DATA_CHANNEL) {
if (llSubStringIndex(msg, "POSITION_SCAN|") == 0) {
// Respond to position scan for reset tool
llRegionSay(MY_DATA_CHANNEL, "POSITION_RESPONSE|" + DISPLAY_TYPE + "|" +
(string)llGetPos() + "|" + (string)llGetRot());
}
}
}
on_rez(integer start_param) {
llResetScript();
}
}