// IF YOU VALUE THIS WORK, PLEASE LEAVE ATTRIBUTION INTACT // // // // _|_| // // _| _| _|_|_|_| _|_| _|_|_| _|_| // // _| _| _| _| _| _| _| _|_|_|_| // // _| _| _| _| _| _| _| _| // // _|_| _|_|_|_| _|_| _| _| _|_|_| // // MiniVerse // //............................................................// //.....................▒▓▓▒▒▒▒▓▓▓▓▓▓▒▒▒▓▓░....................// //.................._▒▓▒.Ozone.MiniVerse.▒▓▒_.................// //................_▒▓▓▓▒____PRESENTS____▒▓▓▓▓▓▒_..............// //..............░▓▓▓▓▓▓▒___I.M.A.G.E.___▒▓▓▓▓▓▓▓░.............// //.............▒▓▓▓▓▓▓▓▒__IMAGE_MATRIX__▒▓▓▓▓▓▓▓▓▒............// //............▒▓▒▓▓▓▓▒_ACTION_GAME_ENGINE_▒▓▓▓▓▒▓▓▒...........// //..........▒▓▓▓▓░...▒▓▓▒_By_Spax_Orion_▒▓▓▒...░▓▓▓▓▒.........// //.........▒▓▓▓▓░......▒▓_& Dirty Helga_▓▓▒░.....░▒▓▓▓........// //.........▓▓▓▓▒░.._......░▒▓▓▓▓▓▓▓▓▓▓▓▒░......_..░▒▓▓▓.......// //.........▓▓▓▓░.._▓░▓░_....▓▓▓▓▓▓▓▓▓▓...._▒▓▒▓_..░▓▓▓▓.......// //.........▓▓▓▓.._▓█░▒█▒.....▒▓▓▓▓▓▓▒.....▒█▒░█▒_..▓▓▓▓.......// //........▒▓▓▓▓▓▒_..▒._░_▒▓▓▒░.▒▒.░▒▓▓▒_░_.▒.._▒▓▓▓▓▓▓▒.......// //.......▒▓▓▓▓▓▓▓▓▓_...▒▓▓▓▓▓░..▒▒..░▓▓▓▓▓▒..._▓▓▓▓▓▓▓▓▒......// //......▓▓▓▓▓▓▓▓▓▓▓_.▓▓▓▓▓▒.._▓▓▓█_..▒▓▓▓▓▓._▓▓▓▓▓▓▓▓▓▓▓......// //......▓▓▓▓▓▒▒▓▓▓▒▓▓▓▓▓▓▒░.▒▓▓▓▓▓█▒.░▒▓▓▓▓▓▒▒▓▓▓▒▓▓▓▓▓▓......// //......▓▓▓▓▓░.▓▓▓.▒▓▓▓▓▓░..▒▓▓▓▓▓▓▒..░▓▓▓▓▓░.▓▓▓.░▓▓▓▓▓......// //........▒▓▓█░.▓▓▓.▒▓▓▓▓▓__▓_..▒▒.._▓__▓▓▓▓▓░.▓▓▓.▒▓▓▓▒......// //.........░▒░░▒▓▒░▒▓▓▓▓▓▓▒▒▓▒▒▒▓▓▒▒▒▓▒▒▓▓▓▓▓▒░▒▓▒░░▒░░.......// //.........░▒.░▓▓░.▓▓▓▓█▒▒▒█▒▒▒█▒▒█▒▒▒█▒▒▒█▓▓▓▓.░▓▓░.▒░.......// //.............░▓▓░_▓▓▓▓█................█▓▓▓▓_░▓▓░...........// //..............░▒▓▓▓█▓._▒_.█░....█░._█_.▓█▓▓▓▒░..............// //.................░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░................// //.................░▒▓▓▓▒▒▓▒▒▓▓▓▓▒▒▓▓▓▓▒▒▓▓▒░.................// //..................▒▓▓░░▓░░▓▓▓▓░░▓▓▓▓░░▓▓▒...................// //.................▒▓░..█__▓▓▓▓__▓▓▓▓__█..░▓▒.................// //...................░...░..░▓▓░..░▓▓░..░...░.................// //.................... ..░...░▒░....░▒░...░...................// //............................................................// // Common sense not included and must be supplied by end user // // Read ENTIRE script first and LEARN: KNOW what you're using // // CC BY-NC https://creativecommons.org/licenses/by-nc/4.0/ // // ===========================================================// // LINKSET SPARK FX + GLOW LISTENER // // OpenSim 0.9.2.1 (Yeti) / Mono / BulletSim friendly // // ===================== CONFIG ==============================// // Scoreboard channel (match your scoreboard) integer EXPO_CH = -777777; // Commands expected from scoreboard string CMD_START = "START"; string CMD_STOP = "STOP"; // IMAGE Core-Game local bus (link_message), avoids chat weirdness integer IMAGE_BUS_EXPO = 7777001; // must match Core-Game // Linkname targeting (case-sensitive) string TIP_PRIM_NAME = "TIP"; // emitters string HEATRINGS_PRIM_NAME = "HeatRings"; // glow targets // Glow strength when active (only applied to HeatRings prims) float ACTIVE_GLOW = 0.5; // Set TRUE if you only want the object OWNER to be able to touch-toggle for debug integer OWNER_ONLY_TOUCH = TRUE; //build your linkset and make sure your links match the names above and you will //get a nice expo flare which ctivates with your game... // ===================== PARTICLE PARAMS ===================== // Particle system parameters (applied only to TIP prims when active) list PARTICLE_PARAMS = [ PSYS_PART_FLAGS, ( 0 | PSYS_PART_INTERP_COLOR_MASK | PSYS_PART_INTERP_SCALE_MASK | PSYS_PART_FOLLOW_VELOCITY_MASK | PSYS_PART_EMISSIVE_MASK ), PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE, PSYS_PART_START_ALPHA, 1.0, PSYS_PART_END_ALPHA, 0.0, PSYS_PART_START_GLOW, 1.0, PSYS_PART_END_GLOW, 0.0, PSYS_PART_START_COLOR, <0.000, 0.6, 1.0>, PSYS_PART_END_COLOR, <0.000, 0.6, 1.0>, PSYS_PART_START_SCALE, <0.25, 2.50, 0.0>, PSYS_PART_END_SCALE, <0.10, 3.50, 0.0>, PSYS_PART_MAX_AGE, 0.6, PSYS_SRC_MAX_AGE, 0.0, PSYS_SRC_ACCEL, <0.0, 0.0, 0.20>, PSYS_SRC_BURST_PART_COUNT, 14, PSYS_SRC_BURST_RATE, 0.05, PSYS_SRC_BURST_RADIUS, 0.8, PSYS_SRC_BURST_SPEED_MIN, 5.0, PSYS_SRC_BURST_SPEED_MAX, 9.0, PSYS_SRC_ANGLE_BEGIN, 0.0, PSYS_SRC_ANGLE_END, 0.0, PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>, PSYS_SRC_TEXTURE, (key) "a86c821e-9beb-48ad-86cc-20d49a01fb4a", PSYS_SRC_TARGET_KEY, NULL_KEY ]; // ===================== RUNTIME VARIABLES ===================== // (Keep these grouped for consistent patching across IMAGE modules.) integer gListenHandle = 0; integer gActive = FALSE; // ===================== HELPERS ===================== // Apply glow only to HeatRings prims. Everyone else is forced to 0 glow. // This prevents stale glow on non-target prims after link changes. ApplyGlowTargets(integer on) { float g = 0.0; if (on) g = ACTIVE_GLOW; integer links = llGetNumberOfPrims(); integer i; for (i = 1; i <= links; ++i) { string ln = llGetLinkName(i); if (ln == HEATRINGS_PRIM_NAME) llSetLinkPrimitiveParamsFast(i, [PRIM_GLOW, ALL_SIDES, g]); else llSetLinkPrimitiveParamsFast(i, [PRIM_GLOW, ALL_SIDES, 0.0]); } } // Apply particles only to TIP prims. Everyone else is forced to clear particles. // This prevents stale emitters if someone renames prims or swaps parts mid-game. ApplyParticlesTargets(integer on) { integer links = llGetNumberOfPrims(); integer i; for (i = 1; i <= links; ++i) { string ln = llGetLinkName(i); if (ln == TIP_PRIM_NAME) { if (on) llLinkParticleSystem(i, PARTICLE_PARAMS); else llLinkParticleSystem(i, []); } else { // Non-TIP prims never emit particles llLinkParticleSystem(i, []); } } } StartFX() { if (gActive) return; gActive = TRUE; ApplyGlowTargets(TRUE); ApplyParticlesTargets(TRUE); } StopFX() { if (!gActive) return; gActive = FALSE; ApplyParticlesTargets(FALSE); ApplyGlowTargets(FALSE); } // Robust-ish command match integer IsCmd(string msg, string cmd) { msg = llStringTrim(llToUpper(msg), STRING_TRIM); cmd = llStringTrim(llToUpper(cmd), STRING_TRIM); return (msg == cmd); } // ===================== STATES ===================== default { state_entry() { // Default state: no glow, no particles // (StopFX is guarded, but we want baseline behavior.) gActive = FALSE; ApplyParticlesTargets(FALSE); ApplyGlowTargets(FALSE); // Listen to scoreboard channel if (gListenHandle) llListenRemove(gListenHandle); gListenHandle = llListen(EXPO_CH, "", NULL_KEY, ""); // Optional debug line. Keep it commented for production. // llOwnerSay("Spark FX ready. Listening on channel " + (string)EXPO_CH); } on_rez(integer start_param) { // Ensures “no glow” baseline after sim restart / rez llResetScript(); } changed(integer c) { // If the linkset changes, re-apply current mode so new prims match. if (c & CHANGED_LINK) { if (gActive) { ApplyGlowTargets(TRUE); ApplyParticlesTargets(TRUE); } else { gActive = FALSE; ApplyParticlesTargets(FALSE); ApplyGlowTargets(FALSE); } } } touch_start(integer n) { if (OWNER_ONLY_TOUCH && (llDetectedKey(0) != llGetOwner())) return; // Debug toggle if (gActive) StopFX(); else StartFX(); } listen(integer channel, string name, key id, string message) { if (channel != EXPO_CH) return; if (IsCmd(message, CMD_START)) { StartFX(); } else if (IsCmd(message, CMD_STOP)) { StopFX(); } // else: ignore } }