The scratch code below is intended to demonstrate the use of OSSL to get and set terrain height. It is intended for use with a 256x256 m region/world.
As ever, make sure you have a satisfactory backup before trying it.
Put the script in a prim positioned well above the maximum intended terrain level. Touch the prim and you should see four options:
recorder,
flatten,
terra and
plant (although plant doesn't work in this version). Selecting the
recorder option creates a series of 31 notecards stored in the prim. These contain terrain height values determined by the topography of the current world. Selecting
flatten creates a flat terrain at 21 m. Finally,
terra restores the terrain from the values stored in the notecards (make sure your avatar is hovering above the new terrain or it will be catapaulted to 700+ m as the new terrain is formed).
There is presently no management of the notecards so if you want to reuse the script you first need to delete the notecards manually. Also, as the script uses a fixed channel for the dialog, prims may suffer cross-talk, i.e. have only one prim rezzed. You are free to use and, indeed, improve the code but please respect the intellectual property of terrain creators.
You can get a brief glimpse of the script operating alongside a functional plant state:
https://twitter.com/vrsimility/status/8 ... 9734266880
Code: Select all
default
{
state_entry()
{
llListen(-101, "", NULL_KEY, "");
}
touch_start(integer n)
{
llDialog(llDetectedKey(0), "Options", ["flatten", "recorder", "terra", "plant"], -101);
}
listen(integer c, string name, key id, string msg)
{
if (msg == "flatten")
{
state flatten;
}
else if (msg == "recorder")
{
state recorder; //need to delete existing nc
}
else if (msg == "terra")
{
state terra;
}
else if (msg == "plant")
{
//state plant;
}
}
}
state terra
{
state_entry()
{
integer x;
integer y;
integer nc = 0;
integer i;
list heights;
for (nc = 0; nc < 31; nc++)
{
heights = heights + llParseString2List(osGetNotecard("terrain_"+(string)nc), ["\n"], []);
}
i = 0;
for (x = 1; x < 256; x++)
{
for (y = 1; y < 256; y++)
{
osSetTerrainHeight(x, y, llList2Float(heights, i));
i++;
}
}
osTerrainFlush();
state default;
}
}
state flatten
{
state_entry()
{
integer x;
integer y;
for (x = 1; x < 256; x++)
{
for (y = 1; y < 256; y++)
{
osSetTerrainHeight(x, y, 21.0);
}
}
osTerrainFlush();
state default;
}
}
state recorder
{
state_entry()
{
integer x;
integer y;
list heights = [];
integer nc = 0;
llOwnerSay("Please wait");
for(x = 1; x < 255; x++)
{
for(y = 1; y < 255; y++)
{
heights = heights + [llGetSubString((string)osGetTerrainHeight(x, y), 0, 4)];
}
if ((x % 8 == 0) && (x > 0))
{
osMakeNotecard("terrain_"+(string)nc, heights);
heights = [];
nc++;
}
}
llOwnerSay("Done");
state default;
}
}