by gramps » Thu Nov 22, 2018 12:18 pm
Hmm, thanks, that looks a lot like one of my earlier attempts (except I think I went with SectorSound).
Hard-coding all this stuff seems inflexible, but some of that can be mitigated with script args...
What I've done for now is stick a bunch of data in custom UDMF fields, on the line with the switch. So the UDMF looks like this:
Code: Select all
linedef {
v1=...; v2=...; sidefront=...;
blocking=true; playeruse=true;
special=80; // ACS_Execute
id=1;
arg0str="lights on";
user_light_things=2;
user_dark_things=1;
user_light_sector_1=1;
user_light_sector_2=3;
user_volumetric_sector_1=3;
}
Then I wrote a little script that'll iterate over UDMF user fields named like foo_1, foo_2, foo_3, calling a named script and passing each value to it (we don't have first-class functions, right?).
Code: Select all
function void IterateLineUDMFInt(int tag, str field, str scriptname, int a, int b) {
int i = 0;
int sid = GetLineUDMFInt(tag, strparam(s:"user_", s:field, s:"_", i:++i));
while (sid > 0) {
ACS_NamedExecuteAlways(scriptname, 0, sid, a, b);
sid = GetLineUDMFInt(tag, strparam(s:"user_", s:field, s:"_", i:++i));
}
}
Then the rest of my code looks like this:
Code: Select all
script "flicker" (int sid) {
Light_Stop(sid);
Light_Strobe(sid, 96, 80, 1, 3);
}
script "fade" (int sid) {
Light_Stop(sid);
Light_ChangeToValue(sid, 96);
Light_Fade(sid, 128, 30);
}
script "haze" (int sid, int value) {
Sector_SetFade(sid, value, value, value);
}
script "dim" (int sid) {
Light_Stop(sid);
Light_ChangeToValue(sid, 64);
}
script "lights on" (void) {
ACS_NamedTerminate("lights off", 0);
SetLineSpecial(1, ACS_NamedExecute, "lights off");
Thing_Activate(GetLineUDMFInt(1, "user_light_things"));
Thing_Deactivate(GetLineUDMFInt(1, "user_dark_things"));
IterateLineUDMFInt(1, "light_sector", "flicker", 0, 0);
delay(30);
IterateLineUDMFInt(1, "light_sector", "fade", 0, 0);
IterateLineUDMFInt(1, "volumetric_sector", "haze", 255, 0);
}
script "lights off" (void) {
ACS_NamedTerminate("lights on", 0);
SetLineSpecial(1, ACS_NamedExecute, "lights on");
Thing_Activate(GetLineUDMFInt(1, "user_dark_things"));
Thing_Deactivate(GetLineUDMFInt(1, "user_light_things"));
IterateLineUDMFInt(1, "volumetric_sector", "haze", 0, 0);
IterateLineUDMFInt(1, "light_sector", "dim", 0, 0);
}
The huge glaring problem here is "lights on" has some warmup time -- a flicker and then a fade -- so "lights off" needs to terminate it. That's enough to pretty much kill any chance of reuse (I can't have "lights off" kill the "lights on" happening in another room).
I guess I'm mainly trying to figure out how to achieve some level of encapsulation/reuse at this point (although it would still be great if there were some kind of "switches stay put" line flag).
Hmm, thanks, that looks a lot like one of my earlier attempts (except I think I went with SectorSound).
Hard-coding all this stuff seems inflexible, but some of that can be mitigated with script args...
What I've done for now is stick a bunch of data in custom UDMF fields, on the line with the switch. So the UDMF looks like this:
[code]linedef {
v1=...; v2=...; sidefront=...;
blocking=true; playeruse=true;
special=80; // ACS_Execute
id=1;
arg0str="lights on";
user_light_things=2;
user_dark_things=1;
user_light_sector_1=1;
user_light_sector_2=3;
user_volumetric_sector_1=3;
}[/code]
Then I wrote a little script that'll iterate over UDMF user fields named like foo_1, foo_2, foo_3, calling a named script and passing each value to it (we don't have first-class functions, right?).
[code]function void IterateLineUDMFInt(int tag, str field, str scriptname, int a, int b) {
int i = 0;
int sid = GetLineUDMFInt(tag, strparam(s:"user_", s:field, s:"_", i:++i));
while (sid > 0) {
ACS_NamedExecuteAlways(scriptname, 0, sid, a, b);
sid = GetLineUDMFInt(tag, strparam(s:"user_", s:field, s:"_", i:++i));
}
}[/code]
Then the rest of my code looks like this:
[code]script "flicker" (int sid) {
Light_Stop(sid);
Light_Strobe(sid, 96, 80, 1, 3);
}
script "fade" (int sid) {
Light_Stop(sid);
Light_ChangeToValue(sid, 96);
Light_Fade(sid, 128, 30);
}
script "haze" (int sid, int value) {
Sector_SetFade(sid, value, value, value);
}
script "dim" (int sid) {
Light_Stop(sid);
Light_ChangeToValue(sid, 64);
}
script "lights on" (void) {
ACS_NamedTerminate("lights off", 0);
SetLineSpecial(1, ACS_NamedExecute, "lights off");
Thing_Activate(GetLineUDMFInt(1, "user_light_things"));
Thing_Deactivate(GetLineUDMFInt(1, "user_dark_things"));
IterateLineUDMFInt(1, "light_sector", "flicker", 0, 0);
delay(30);
IterateLineUDMFInt(1, "light_sector", "fade", 0, 0);
IterateLineUDMFInt(1, "volumetric_sector", "haze", 255, 0);
}
script "lights off" (void) {
ACS_NamedTerminate("lights on", 0);
SetLineSpecial(1, ACS_NamedExecute, "lights on");
Thing_Activate(GetLineUDMFInt(1, "user_dark_things"));
Thing_Deactivate(GetLineUDMFInt(1, "user_light_things"));
IterateLineUDMFInt(1, "volumetric_sector", "haze", 0, 0);
IterateLineUDMFInt(1, "light_sector", "dim", 0, 0);
}[/code]
The huge glaring problem here is "lights on" has some warmup time -- a flicker and then a fade -- so "lights off" needs to terminate it. That's enough to pretty much kill any chance of reuse (I can't have "lights off" kill the "lights on" happening in another room).
I guess I'm mainly trying to figure out how to achieve some level of encapsulation/reuse at this point (although it would still be great if there were some kind of "switches stay put" line flag).