Introduction (500 words, followed by an OPTIONAL changelog w/ all the details)
I had a break (kind of). After which I've decided to rebuild the box scripts for WM2 and while at it check them for fundamental issues. (bit of ground research as a side-benefit – or possibly main-benefit...).
Which then resulted in several weeks working on nothing but these scripts (i.e. looking for bugs, fixing them, experimenting w/ ideas, full test sessions, learning about the engine and so on). Got a bit out of proportion.
Anyway, I think I'm finished with it for now... and as the scripts have reached a kind of finished state it seemed like I should share them.
https://easyupload.io/9ocpcx
[Temporary link to the files (so far), if interested, These are updated templates of the default Containr & Door source of Fo2 (1.02d).
The two ssl files have a lot of comments. Should all be self-explanatory.]
I think the best part of these scripts is that they allow to adjust the settings for every door individually. If you want a fridge that closes after opened, but cannot be lockpicked or destroyed you can set that at the beginning: CLOSE, NO_LOCK, NON_DESTROY. If you want a door that closes and opens automatically, can be destroyed by two charges of dynamite and lockpicked with electronic & crowbar items (only), you can set that, too: [BOTH WAYS, METAL, DOOR STRENGTH 1, NO_LOCK_ELEVATOR.]
This being individually changeable for every door is probably the best part of it. In fact, the adjustable sections has many options -> combinations. Use what works best for you. Should be easy enough to toggle.
Plus bug fixes and some improvements like auto-doors (see next & changelog).
Rat Maze (using EcRobber) to test auto-doors.
I also made versions of this maze with quadruped critters, multiple critters and one I've send Vic through. The main purpose was not only to test auto-door functions but also if critters & companions can disarm traps (correctly), which is a new feature in door.ssl.
Anyway, I believe these default Fo2 scripts should be all correct now. Rest is expanding on it.
Do mind that ANY other vanilla 1.02d script that was based on these templates may still be bugged, e.g. ZiLckDor is missing the damage type check, so any damage takes it down, while ZiWodDor decided, for some reason, to do w/o the "locked variable" and consequently required script stunts all over the script – bit bizarre. Not sure what to make of it. Btw, DiDoor is basically ZiWodDor. And last but not least the party.h macro that added "procedure checkPartyMembersNearDoor" to 1400+ scripts, but is really only needed by 20, tops. Was getting on my nerves a bit, tbh.
500 words
Rest is a full rundown of changes.
DONE, 2500 words, sue me.
I had a break (kind of). After which I've decided to rebuild the box scripts for WM2 and while at it check them for fundamental issues. (bit of ground research as a side-benefit – or possibly main-benefit...).
Which then resulted in several weeks working on nothing but these scripts (i.e. looking for bugs, fixing them, experimenting w/ ideas, full test sessions, learning about the engine and so on). Got a bit out of proportion.
Anyway, I think I'm finished with it for now... and as the scripts have reached a kind of finished state it seemed like I should share them.
https://easyupload.io/9ocpcx
[Temporary link to the files (so far), if interested, These are updated templates of the default Containr & Door source of Fo2 (1.02d).
The two ssl files have a lot of comments. Should all be self-explanatory.]
I think the best part of these scripts is that they allow to adjust the settings for every door individually. If you want a fridge that closes after opened, but cannot be lockpicked or destroyed you can set that at the beginning: CLOSE, NO_LOCK, NON_DESTROY. If you want a door that closes and opens automatically, can be destroyed by two charges of dynamite and lockpicked with electronic & crowbar items (only), you can set that, too: [BOTH WAYS, METAL, DOOR STRENGTH 1, NO_LOCK_ELEVATOR.]
This being individually changeable for every door is probably the best part of it. In fact, the adjustable sections has many options -> combinations. Use what works best for you. Should be easy enough to toggle.
Plus bug fixes and some improvements like auto-doors (see next & changelog).
Rat Maze (using EcRobber) to test auto-doors.
I also made versions of this maze with quadruped critters, multiple critters and one I've send Vic through. The main purpose was not only to test auto-door functions but also if critters & companions can disarm traps (correctly), which is a new feature in door.ssl.
Anyway, I believe these default Fo2 scripts should be all correct now. Rest is expanding on it.
Do mind that ANY other vanilla 1.02d script that was based on these templates may still be bugged, e.g. ZiLckDor is missing the damage type check, so any damage takes it down, while ZiWodDor decided, for some reason, to do w/o the "locked variable" and consequently required script stunts all over the script – bit bizarre. Not sure what to make of it. Btw, DiDoor is basically ZiWodDor. And last but not least the party.h macro that added "procedure checkPartyMembersNearDoor" to 1400+ scripts, but is really only needed by 20, tops. Was getting on my nerves a bit, tbh.
500 words
Rest is a full rundown of changes.
List of changes w/ code examples
macros & defines
-allowed Script_<Name> to be set normally and moved the generic msg (door/containr) to its own macro. This should make it easier to use it as a template.
-expanded/fixed defines to allow toggling all script functions and options :
-added full explanations to the define section, to make adjusting the script easier.
use proc
-added missing obj_name to line 205
-[Door only] New Feature: critters & companions use a new check which allows them to disarm traps they've spotted. (before this they would only "spot" traps over and over until setting them off)
-expanded the auto door check, it has now 4 settings: off (), close (after opening), open (when approaching) & on (closes & opens automatically). Macro is called in various places. See timed event for extra notes.
pickup proc
-[Container only] does not call use proc anymore : new fix (see use skill proc)
use skill proc
-added script_overrides
-added New Option to disable lockpick skill
-added a new Steal check, as the pickup proc fix would open the inventory screen when a trap goes off
-New Feature: option to call Examine Checks through Science skill
use obj proc
-removed "else" checks as they blocked (crowbar & explosives) usage
-added script_overrides
-expanded and added status checks
-[Container only] added super lockpicks (standard & electronic)
-pry door checks if door is locked
damage proc
-damage proc checks for damage type (door only)
-fixed the fridge & non-destroy variable dupe/conflict (containr only)
-[Container only] New feature: if not destroyed, the objects opens (like "blowing a safe open"), nice visual with some containers; (Door script needs to enable it)
-fixed the explosion loop of metal containers
-added message that damage was done
-[Door only] added message for indestructible state
look_<X>
-made bonuses definable (this makes spotting traps consistent, i.e. same modifier throughout)
look_traps
-added the missing "set trap found" checks (4x)
disarm traps
-added missing obj_name to line 199
-moved XP from spotted to disarmed, as it was inconsistent (many options to spot a trap in the script, only one gave XP)
-added missing 198 line for the dude, goes with 202
super lockpick lock
-moved proc for better structure
lock door
-added that the object closes when locking it (new feature)
set trap
-explosives are only removed on success and critical failure, not on every attempt (fix, imo)
pry door
-added missing obj_name to line: 181, 182/183, 186/187 & 185
-added XP gain, same as lockpick but can be defined separately
timed event
-expanded on the Door.ssl auto door function to support all 4 options
set timer
-added Set Timer proc; which sets timers for auto door function,
-and called it in use, use skill, use obj and map enter.
Bonus:
If tired of global procs:
This fix should also allow to define party_close_distance in the door & containr template scripts (currently disabled).
macros & defines
-allowed Script_<Name> to be set normally and moved the generic msg (door/containr) to its own macro. This should make it easier to use it as a template.
Code:
/* You can define your script name in the following as usual */
#define NAME SCRIPT_
/* If you want to call the generic door/box msg then define it here: */
#define DOOR_NAME SCRIPT_CONTAINR // SCRIPT_DOOR (if object is a door)
/* and use : display_msg(door_mstr(204)); : instead : display_msg(mstr(204)); */
Code:
...these already exist...
#define STATE_WOOD (0)
#define STATE_METAL (1)
#define STATE_NON_DESTROY (2)
...these already exist...
#define STATE_STANDARD_LOCK (0) //allows basic
#define STATE_ELECTRIC_LOCK (1) //allows electronic
...new...
#define STATE_NO_LOCK_CRATE (2) //allows crowbar (only)
#define STATE_NO_LOCK_ELEVATOR (3) //allows electronic & crowbar
#define STATE_STANDARD_CROWBAR (4) //allows basic & crowbar
#define STATE_LOCK_ONLY (5) //allows basic & electronic
#define STATE_UNIVERSAL_LOCK (6) //allows all
#define STATE_NO_LOCK (7) //blocks skill and items
...these already exist...
#define STATE_DOOR_NOCLOSE (0)
#define STATE_DOOR_CLOSE (1) //doors close (distance)
...new...
#define STATE_DOOR_OPEN (2) //doors open (nearness)
#define STATE_DOOR_BOTH_WAYS (3) //doors close & open auto.
use proc
-added missing obj_name to line 205
-[Door only] New Feature: critters & companions use a new check which allows them to disarm traps they've spotted. (before this they would only "spot" traps over and over until setting them off)
Code:
if (source_obj == dude_obj) then begin // ADDED for NEW critter check
<old check>
end
/* NEW CRITTER CHECK FOR critters AND companions */
else begin
/* Originally, companions (and critters) who ran into a trapped door would spot the trap, then keep using the door until triggering it, now they have a chance to disarm it. */
/* Notes: */
/* critters do treat "locked" doors as blocked tiles and will never interact with a locked (or open) door */
/* quadruped critters (like dog companions) are blocked from using doors... only biped (includes floaters, btw) and robotic critters can use doors */ //exception: silver & gold geckos are biped, but can't use doors (must be hard-coded)
/* party control companions : are treated as the dude, never goes into this check. */
if (local_var(LVAR_Trapped) == STATE_ACTIVE) then begin
if (is_success(Traps_Roll)) then begin
script_overrides;
/* Critters don't need to set LVAR_Found_Trap,1; they either disarm or trigger the traps they've spotted */
display_msg(obj_name(source_obj)+door_mstr(205));
if not combat_is_initialized then begin // no disarm or skill use in combat, normal engine behaviour : ofc, the player will not use a door after spotting a trap, while critters/companions will be back to using the door till they trigger it; that said, one may decide to remove this check and allow critters/companions to disarm in combat : OPTION
Traps_Roll:=roll_vs_skill(source_obj,SKILL_TRAPS,Trap_Bonus);
if (is_success(Traps_Roll)) then begin
set_local_var(LVAR_Trapped,STATE_INACTIVE);
set_local_var(LVAR_Found_Trap,1); //else it would still trigger for the dude, despite the object not being trapped anymore
obj_open(self_obj); //I removed "reg_anim_clear(source_obj);" as critters have no magic hands, but added this, as it seemed to help the critter to move smoother
display_msg(obj_name(source_obj)+door_mstr(201));
end
else begin
call Damage_Critter;
end
end
end
else begin
call Damage_Critter;
end
end
/* Spam of "The doorway seems to be blocked" messages. Caused by a critter opening a door that is mid open animation.
Most commonly caused by two critters opening the same door OR a companion opening an auto door. The slower the door's swing animation the more likely it is to trigger.
The following blocks it. */
if (obj_is_open(self_obj)) then begin
script_overrides;
end
end // End of NEW CRITTER CHECK FOR critters AND companions
pickup proc
-[Container only] does not call use proc anymore : new fix (see use skill proc)
use skill proc
-added script_overrides
-added New Option to disable lockpick skill
-added a new Steal check, as the pickup proc fix would open the inventory screen when a trap goes off
Code:
/* Skill_Steal */
/* The engine allows to steal from a container when it is open. It also allows to steal from containers* that can't be opened. */ // *edit: actually any item, not just containers -.-
/* This behaviour enables to circumvent traps (on objects like bookshelves) and locked states (on objects like workbenches) */
/* A way to fix this was to call use proc in pickup proc. However, this has a downside: If a trap goes off on an object w/o an
open state (like a workbench), or an object in the open state (like a locker), the inventory screen does not get cancelled
and the player explodes with the screen open. */
/* So I used the following instead: */
else if (Skill_Used == SKILL_STEAL) then begin
if (local_var(LVAR_Locked) == STATE_ACTIVE) then begin // added to emulate engine behaviour; it checks for locked first, if true, action cancelled
script_overrides;
display_msg(door_mstr(203));
end
else begin
/* this should check for "obj_is_open", if true then, but this check returns as false for objects w/o an open state like shelves and workbenches */
if (local_var(LVAR_Trapped) == STATE_ACTIVE) then begin
script_overrides; // remove this and it has the same bug as pickup proc (inventory screen comes up while trap explodes)
call use_p_proc; // (detect or explode) : this allows Steal to trigger use proc on a "closed" locker, which it normally can't (should get cancelled)
end
/* else : nothing, allow Steal */
/* else : this should play an engine message saying ("The container isn't open."), but it doesn't exist. */
end
end // End of Skill_Steal
use obj proc
-removed "else" checks as they blocked (crowbar & explosives) usage
-added script_overrides
-expanded and added status checks
-[Container only] added super lockpicks (standard & electronic)
-pry door checks if door is locked
damage proc
-damage proc checks for damage type (door only)
-fixed the fridge & non-destroy variable dupe/conflict (containr only)
-[Container only] New feature: if not destroyed, the objects opens (like "blowing a safe open"), nice visual with some containers; (Door script needs to enable it)
-fixed the explosion loop of metal containers
-added message that damage was done
-[Door only] added message for indestructible state
look_<X>
-made bonuses definable (this makes spotting traps consistent, i.e. same modifier throughout)
look_traps
-added the missing "set trap found" checks (4x)
disarm traps
-added missing obj_name to line 199
-moved XP from spotted to disarmed, as it was inconsistent (many options to spot a trap in the script, only one gave XP)
-added missing 198 line for the dude, goes with 202
super lockpick lock
-moved proc for better structure
lock door
-added that the object closes when locking it (new feature)
set trap
-explosives are only removed on success and critical failure, not on every attempt (fix, imo)
pry door
-added missing obj_name to line: 181, 182/183, 186/187 & 185
-added XP gain, same as lockpick but can be defined separately
timed event
-expanded on the Door.ssl auto door function to support all 4 options
set timer
-added Set Timer proc; which sets timers for auto door function,
-and called it in use, use skill, use obj and map enter.
-Name the door.ssl script DiDoor and make the settings you want.
-Test script in the Den w/ & w/o Vic (and all the wandering loser models).
*you may have to rest 10 minutes to kickstart them.
-Testing containers (dunno easy set up)... if you know a box script (based on the template) you may replace that temporarily, else you may just use desert1, put a container, assign it EcBox, then save containr.ssl as EcBox and make the settings you want.
Or (instead EcBox & Fo2) you may use WM2, which has 8 box scripts (!box1 to !box8), allowing to set up 8 different types on desert1 (that's what I did).
Otherwise you need to take another hurdle and adjust scripts.lst and so on.
[BEFORE YOU CALL IT A BUG:]
[quick notes from my documentation on "auto doors":
-the basic function is to step in front of the door/container – wait till it opens – then go through OR use Steal to access it – then walk away : [this is still slow, but some may prefer it to opening doors by walking into them]
-trapped doors are prevented from auto opening (-can look like a bug, but isn't-)
-the engine cannot open/close locked objects (-easy to forget-)
-the script can be used with "gl_autodoors" (a script that has the dude behave like a critter)
-setting a trap on an auto opening door requires to "lock" the door first. Then unlock the door again after setting the trap
-closing auto opening doors manually is a bit silly and you could consider to add script_overrides to block use proc when you use auto doors [but only override for the dude (better) and only if the door is not trapped (important)!]
-players are likely to flip when you set containers to auto open. - they can use Steal to access them, but expect to be yelled at first.
I hope these examples show how that this can change and mess up known mechanics, but still work by creating new ones. There are many variables → options. Try and experiment. Including using gl_autodoors with CLOSE, for example. Many options. You can even turn it all off; NOCLOSE.
Known Bugs (all considered minor):
- When a critter is scripted to stay next to a door (see orphans in the Den) it fails to close the door as "last object" is never out of range. [fixes itself by loading map]
- A door with a very slow close/open animation can trigger timed event before the door can be registered as closed/open and breaks sequence. [can fix itself]
- General Manhandling can Create Bugs (example; I managed to set a trap on an open door) [has to be done on purpose]
- And a few optimizations here and there [details]
-Long list of ideas and smaller improvements... nothing vital. [but I have a working prototype that allows companions to pry open a door, which is intriguing, but also a full job, and possibly stupid, maybe next time, plus some other mad ideas which are probably all going for bust anyway]
Options:
-Please note the commented out option "not to auto-open a door again after the player closed it" in Set Timer proc. This may help to enhance the OPEN option to something you may actually want.
-There is also an option in map enter "not to close objects on map enter". Also commented out, but something you may want with some doors (e.g. set to open in mapper).
You probably have to experiment a bit.
-Test script in the Den w/ & w/o Vic (and all the wandering loser models).
*you may have to rest 10 minutes to kickstart them.
-Testing containers (dunno easy set up)... if you know a box script (based on the template) you may replace that temporarily, else you may just use desert1, put a container, assign it EcBox, then save containr.ssl as EcBox and make the settings you want.
Or (instead EcBox & Fo2) you may use WM2, which has 8 box scripts (!box1 to !box8), allowing to set up 8 different types on desert1 (that's what I did).
Otherwise you need to take another hurdle and adjust scripts.lst and so on.
[BEFORE YOU CALL IT A BUG:]
[quick notes from my documentation on "auto doors":
-the basic function is to step in front of the door/container – wait till it opens – then go through OR use Steal to access it – then walk away : [this is still slow, but some may prefer it to opening doors by walking into them]
-trapped doors are prevented from auto opening (-can look like a bug, but isn't-)
-the engine cannot open/close locked objects (-easy to forget-)
-the script can be used with "gl_autodoors" (a script that has the dude behave like a critter)
-setting a trap on an auto opening door requires to "lock" the door first. Then unlock the door again after setting the trap
-closing auto opening doors manually is a bit silly and you could consider to add script_overrides to block use proc when you use auto doors [but only override for the dude (better) and only if the door is not trapped (important)!]
-players are likely to flip when you set containers to auto open. - they can use Steal to access them, but expect to be yelled at first.
I hope these examples show how that this can change and mess up known mechanics, but still work by creating new ones. There are many variables → options. Try and experiment. Including using gl_autodoors with CLOSE, for example. Many options. You can even turn it all off; NOCLOSE.
Known Bugs (all considered minor):
- When a critter is scripted to stay next to a door (see orphans in the Den) it fails to close the door as "last object" is never out of range. [fixes itself by loading map]
- A door with a very slow close/open animation can trigger timed event before the door can be registered as closed/open and breaks sequence. [can fix itself]
- General Manhandling can Create Bugs (example; I managed to set a trap on an open door) [has to be done on purpose]
- And a few optimizations here and there [details]
-Long list of ideas and smaller improvements... nothing vital. [but I have a working prototype that allows companions to pry open a door, which is intriguing, but also a full job, and possibly stupid, maybe next time, plus some other mad ideas which are probably all going for bust anyway]
Options:
-Please note the commented out option "not to auto-open a door again after the player closed it" in Set Timer proc. This may help to enhance the OPEN option to something you may actually want.
-There is also an option in map enter "not to close objects on map enter". Also commented out, but something you may want with some doors (e.g. set to open in mapper).
You probably have to experiment a bit.
Bonus:
If tired of global procs:
Code:
/* How far do party members have to be from the door before it closes */
#ifndef PARTY_CLOSE_DIST
#define PARTY_CLOSE_DIST (5)
#endif
#define CHECKMEMBERNEARDOOR(inparty, obj) \
if (inparty) then begin \
if (tile_distance_objs(self_obj, obj) <= PARTY_CLOSE_DIST) then begin \
return 1; \
end \
end
#define CHECK_PARTYMEMBERS_NEAR_DOOR CHECKMEMBERNEARDOOR(Vic_In_Party, Vic_Ptr) \
CHECKMEMBERNEARDOOR(Myron_In_Party, Myron_Ptr) \
CHECKMEMBERNEARDOOR(Marcus_In_Party, Marcus_Ptr) \
CHECKMEMBERNEARDOOR(MacRae_In_Party, MacRae_Ptr) \
CHECKMEMBERNEARDOOR(Sulik_In_Party, Sulik_Ptr) \
CHECKMEMBERNEARDOOR(Lenny_In_Party, Lenny_Ptr) \
CHECKMEMBERNEARDOOR(Cyberdog_In_Party, Cyberdog_Ptr) \
CHECKMEMBERNEARDOOR(Doc_In_Party, Doc_Ptr) \
CHECKMEMBERNEARDOOR(Goris_In_Party, Goris_Ptr) \
CHECKMEMBERNEARDOOR(Davin_In_Party, Davin_Ptr) \
CHECKMEMBERNEARDOOR(Miria_In_Party, Miria_Ptr) \
CHECKMEMBERNEARDOOR(Robobrain_In_Party, Robobrain_Ptr) \
CHECKMEMBERNEARDOOR(Laddie_In_Party, Laddie_Ptr) \
CHECKMEMBERNEARDOOR(Bess_In_Party, Bess_Ptr) \
CHECKMEMBERNEARDOOR(Chicken_In_Party, Chicken_Ptr) \
CHECKMEMBERNEARDOOR(Karl_In_Party, Karl_Ptr) \
CHECKMEMBERNEARDOOR(Jonny_In_Party, Jonny_Ptr) \
CHECKMEMBERNEARDOOR(Lloyd_In_Party, Lloyd_Ptr) \
CHECKMEMBERNEARDOOR(Dogmeat_In_Party, Dogmeat_Ptr) \
CHECKMEMBERNEARDOOR(Pariah_Dog_In_Party, Pariah_Dog_Ptr) \
return 0;
/*
create following proc:
procedure checkPartyMembersNearDoor begin
CHECK_PARTYMEMBERS_NEAR_DOOR
end
in every script that needs to call it
*/
Scripts that use it:
The ones in GENERIC (ZILCKDOR.SSL, ZIMTLDOR.SSL, ZIWODDOR.SSL) and TEMPLATE (DOOR.SSL) use this, plus;
MIDOOR.SSL, SIVDOR.SSL, IILOCKDR.SSL, RIJALDOR.SSL, RIVLTDOR.SSL, WILV1DOR.SSL, WIBAYDOR.SSL, WIBNKDOR.SSL, VIVLTDR2.SSL and VIVLTDR3.SSL.
The scripts DIDOOR.SSL, NIBASDOR.SSL and NIDOOR.SSL are updated through ZIMTLDOR & ZIWODDOR (need to be re-compiled).
That "could" be all in 1.02d...
and 1400+ scripts can shed a proc they don't need.
Plus, maybe, proper macro in SICLSDOR.SSL, SIKDOOR.SSL, SSFLXDOR.SSL, SSFRGDOR.SSL and SSGUNDOR.SSL. (not tested, but they don't check for Dogmeat & Pariah, plus, any new companions you may want to add to the list).
DONE, 2500 words, sue me.