// Wolf Territories - a hurricane button (wolf-hurricane, wolfCall weather.hurricane*). // Put it in a prim on your region. Touch it (its owner only) for a menu: start a hurricane of category 1 to 5, let it die // away now, or take it away at once. While a storm runs the prim shows its stage, the time left and the wind as floating // text. Only the region's owner, its estate owner or an estate manager can make a hurricane (the grid checks); anyone's // script can read its state. integer CHANNEL; integer listener; key ask; string asked; show() { list s = wolfCall("weather.hurricane.state", []); if (llGetListLength(s) == 0 || llList2String(s, 0) == "none") { llSetText("No hurricane\n(touch for the menu)", <0.8, 0.9, 1.0>, 1.0); llSetTimerEvent(0.0); // nothing to watch: no timer while no storm runs return; } // [stage, category, seconds left, , radius, eye radius, wind now, organisation, eye clear, hemisphere, id] string stage = llList2String(s, 0); if (stage == "decaying") stage = "dying away"; integer left = llList2Integer(s, 2); llSetText("Category " + llList2String(s, 1) + " hurricane: " + stage + "\n" + (string)(left / 60) + " min " + (string)(left % 60) + " s left" + "\nstrongest wind now " + (string)llRound(llList2Float(s, 6)) + " m/s" + "\nwind here " + (string)llRound(llVecMag(llWind(ZERO_VECTOR))) + " m/s", <1.0, 0.8, 0.4>, 1.0); } default { state_entry() { CHANNEL = -1 - (integer)("0x" + llGetSubString((string)llGetKey(), 0, 6)); llSetTimerEvent(5.0); show(); } on_rez(integer p) { llResetScript(); } touch_start(integer n) { if (llDetectedKey(0) != llGetOwner()) return; llListenRemove(listener); listener = llListen(CHANNEL, "", llGetOwner(), ""); llDialog(llGetOwner(), "Hurricane over this region\n\nStart one (it forms from the clouds over 10 minutes and lasts 40), let the one now die away, or take it away at once.", ["Cat 1", "Cat 2", "Cat 3", "Cat 4", "Cat 5", "Die away", "Gone now", "Close"], CHANNEL); llSetTimerEvent(5.0); } listen(integer ch, string name, key id, string msg) { llListenRemove(listener); if (llGetSubString(msg, 0, 3) == "Cat ") { asked = msg; // every option is optional: "minutes" 5-300 in all, "form" 2-60, "centre" , "radius" 1000-60000 m, // "heading" 0-360 (degrees it moves towards), "speed" 0-30 m/s, "rain" TRUE/FALSE ask = wolfCallAsync("weather.hurricane", ["category", (integer)llGetSubString(msg, 4, -1), "minutes", 40, "form", 10]); } else if (msg == "Die away") { asked = msg; ask = wolfCallAsync("weather.hurricane.end", []); } else if (msg == "Gone now") { asked = msg; ask = wolfCallAsync("weather.hurricane.end", ["now"]); } else return; if (ask == NULL_KEY) llOwnerSay(asked + ": " + wolfGetLastError()); } dataserver(key q, string data) { if (q != ask) return; // "ok|id|category|form s|mature s|decay s|radius|eye|hemisphere", "ok|decaying|seconds left", "ok|gone" or "error: why" list d = llParseStringKeepNulls(data, ["|"], []); if (llList2String(d, 0) != "ok") llOwnerSay(asked + ": " + data); else if (llGetListLength(d) == 9) llOwnerSay("A category " + llList2String(d, 2) + " hurricane is forming: " + (string)(llList2Integer(d, 3) / 60) + " minutes forming, " + (string)(llList2Integer(d, 4) / 60) + " at full strength, " + (string)(llList2Integer(d, 5) / 60) + " dying away; " + "reaching " + llList2String(d, 6) + " m from its eye, turning " + llList2String(["clockwise (south)", "anticlockwise (north)"], llList2Integer(d, 8) > 0) + "."); else llOwnerSay(asked + ": " + data); llSetTimerEvent(5.0); show(); } timer() { show(); } }