Author Topic: Script that changes the environment settings based on height only  (Read 1618 times)

This would be somewhat similar to the Environment Zones mod made by Zeblote, but would be a bit more simple.

Essentially, the script would change the client's environment settings based on their height in the world, and wouldn't be effected by their horizontal coordinates at all.
Probably the easiest way to implement this would be to just have a chat command that sets the environment boundary height at the user's current location. Something like /createHeightZone or something.
And to delete zones you could just type /deleteHeightZone while inside of that zone.
For safety sake, there should probably be a hard-limit on how low you can set zones. Probably the lowest/ground level zone should be the default zone/environment.

This would mainly be useful for setting up transitions for going from ground to space (or just high altitude). You could probably even set it up for going down into caves (forcing the lighting to be darker/different to avoid people needing shadows).
And with no horizontal limitations, it'll be more compatible with large builds or fast vehicles that would have a tendency to leave the environmental zones accidentally.

Also I actually need this pretty badly (and soon), so I figured I'd ask

Sounds like you can easily do that by just making a zone bigger than your build. They don't have a width limit.

I mainly need this is for a freebuild, so using zones with limited dimensions wouldn't be very foolproof (people running out of room inside of the zone and getting pushed out).
Yeah, I could technically just make a series of huge zones, but that would be less convenient, and just doesn't seem like as elegant of a solution to what I'm looking for.
« Last Edit: January 02, 2018, 01:22:53 PM by ArmyUnit »

that would be pretty sick :o

I had never seen that add-on. Nice!



Looks like GameConnection::pushEnvironment(%this, %environment) is the function you'll want to use. You could schedule a function run every few seconds to check for each player's height, and update their environment accordingly. For example,

Code: [Select]
$caveEnv = Environment();
$groundEnv = Environment();
$spaceEnv = Environment();

// Do something to load in the proper environment for each variable

function updateAllEnvs() {
%clientCnt = ClientGroup.getCount()
for(%i = 0; %i < %clientCnt; %i++) {
%client = ClientGroup.getObject(%i);
%z = getWord(%client.position, 2);
if (%z < 1000)
%client.pushEnvironment($caveEnv);
else if (%z >= 1000 && %z < 2000)
%client.pushEnvironment($groundEnv);
else if (%z >= 2000)
%client.pushEnvironment($spaceEnv);
}

Do you know how to code? If not, I could flesh this out a bit more and package it up for you.

If I do package it for you, I'll need an environment file for each level. You can save your current environment by running saveEnvironment(%filename). Afterward, just upload them here as attachments.
« Last Edit: January 04, 2018, 06:56:29 AM by Platypi »

- after you use pushEnvironment to add the new one, use popEnvironment to remove the previous height zone from the stack
- you should be able to edit the environments by just using the admin env gui while inside it

I had never seen that add-on. Nice!



Looks like GameConnection::pushEnvironment(%this, %environment) is the function you'll want to use. You could schedule a function run every few seconds to check for each player's height, and update their environment accordingly. For example,

Code: [Select]
$caveEnv = Environment();
$groundEnv = Environment();
$spaceEnv = Environment();

// Do something to load in the proper environment for each variable

function updateAllEnvs() {
%clientCnt = ClientGroup.getCount()
for(%i = 0; %i < %clientCnt; %i++) {
%client = ClientGroup.getObject(%i);
%z = getWord(%client.position, 3);
if (%z < 1000)
%client.pushEnvironment($caveEnv);
else if (%z >= 1000 && z < 2000)
%client.pushEnvironment($groundEnv);
else if (%z >= 2000)
%client.pushEnvironment($spaceEnv);
}

Do you know how to code? If not, I could flesh this out a bit more and package it up for you.

If I do package it for you, I'll need an environment file for each level. You can save your current environment by running saveEnvironment(%filename). Afterward, just upload them here as attachments.

Nice thanks!
I can code, but there's a huge amount of information that I still need to learn.
I could try and flesh out the script if I have time, but it would help me a ton if you or someone else did instead.

I don't really need anything too specific for the environment settings. The cave environment can just be the default with darker lighting, and the space one can just be a transition to the slate skybox or something. I know enough code that I could probably just tweak it to what I need, really. It's just the script as a whole that's a little beyond my current understanding.

Either that, or you could implement what Zeblote suggested:

- you should be able to edit the environments by just using the admin env gui while inside it

Since I'm a little hard pressed on time, I wouldn't mind hardcoded environment settings for now. But I think it would be more useful in the long run if the settings could be edited ingame.

Should also figure out how to save them too, seeing how they don't have zones or names.

Quick update: I'm currently working on the add-on. Just want to make sure no one else starts on something.

I'm having some trouble getting the DLL to actually work. I might have to put the project on hold, as I have other things I need to do at the moment. Here's what I have so far, if anyone want to pick up where I left off

Code: [Select]
if (forceRequiredAddOn("Server_EnvironmentZones") == $Error::AddOn_NotFound) {
error("Server_EnvironmentZones not found! Height Environments will not be loaded");
return;
}

function HEN::loadEnv(%fn) {
// TODO
}

function GameConnection::HEN_updateEnv(%this) {
%z = getWord(%client.position, 2);
if (%z < $HEN::dist)
%newEnv = $HEN::caveEnv;
else if (%z >= $HEN::dist && %z < 2 * $HEN::dist)
%newEnv = $HEN::groundEnv;
else if (%z >= 2 * $HEN::dist)
%newEnv = $HEN::spaceEnv;

if (%client.HEN_curEnv != %newEnv) {
%client.popEnvironment(%client.HEN_curEnv);
%client.pushEnvironment(%newEnv);
%client.HEN_curEnv = %newEnv;
}
}

function HEN_updateLoop() {
%clientCnt = ClientGroup.getCount()
for(%i = 0; %i < %clientCnt; %i++) {
%client = ClientGroup.getObject(%i);
%client.HEN_updateEnv();
}
schedule($HEN::elapse * 1000, 0, HEN_updateLoop);
}

package HeightEnvironmentPackage
{
GameConnection::onClientEnterGame(%this) {
Parent::onClientEnterGame(%this);

%this.HEN_curEnv = $caveEnv;
}

GameConnection::spawnPlayer(%this) {
Parent::spawnPlayer(%this);

%this.HEN_updateEnv();
}
};

activatePackage(HeightEnvironmentPackage);

$caveEnv = HEN::loadEnv($HEN::envPath @ "cave.env");
$groundEnv = HEN::loadEnv($HEN::envPath @ "ground.env");
$spaceEnv = HEN::loadEnv($HEN::envPath @ "space.env");


// Set preferences

if(forceRequiredAddOn("System_BlocklandGlass") != $Error::AddOn_NotFound) {
// Blockland Glass support
registerPref("Height Environments", "General", "Distance Between Environments", "num", "$HEN::dist", "Server_HeightEnvironments", 32, "0 1000 1", "", 0, 0, 0);
registerPref("Height Environments", "General", "Time Between Updates (in seconds)", "num", "$HEN::elapse", "Server_HeightEnvironments", 2, "0 10 1", "", 0, 0, 0);
}

if ($HEN::dist $= "")
$HEN::dist = 32;
if ($HEN::elapse $= "")
$HEN::elapse = 2;


// Start loop

HEN_updateLoop();

I haven't tested anything yet, as I haven't gotten the DLL to work. Also, as you can see in the code, I'm still not sure how to properly handle loading in environments. For one thing, I'm not sure whether to use the files generate by saveEnvironment() or the .ez file generated by exportEnvironmentZones(). The latter seems like the best option, but I haven't messed with it much yet.
« Last Edit: January 04, 2018, 09:33:35 AM by Platypi »