Prerequisities:
- your own zforms build
- your own menu background & button graphics ... maybe I'll make a proper pk3 containing some graphics ...
Usage:
Place the ACS scripts into the map's scripts.
The universalPolyDoor and universalPolyDoorBase are my main polydoor control scripts. You can freely use them, as the require only three arguments - poly is polyobject nukmber, right1left2 is to control swing direction and speed ...well..controls opening speed. It's nice addition.
To use the locked door menu, just call the "menu_lockedDoor" (int poly, int right1left2, int stats) from the door or polyobject door, just the speed argument is changed to stats argument, which is used as condition to unlock the door. You can set-up your own arguments to open the door, I'm, using just built-in strife stats, which perfectly fit my needs.
Code:
Code: Select all
////////////////////////////////////////////////////////////////////////////////
// zscript locked door menu ////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// credits: Agent_Ash, Gutawer, ramon.dexter
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// ZSCRIPT /////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// menu code ///////////////////////////////////////////////////////////////////
class DoorController play {
int playerNumber;
int poly;
int right1left2;
int stats;
static void OpenDoorMenu(Actor activator, int poly, int right1left2, int stats) {
if (activator.player && activator.player == players[consoleplayer]) {
let handler = argentEventHandler(EventHandler.Find("argentEventHandler"));
if (handler) {
let dc = New('DoorController');
dc.playerNumber = activator.PlayerNumber();
dc.poly = poly;
dc.right1left2 = right1left2;
dc.stats = stats;
// store a pointer to an instane of this in an event handler:
handler.d_controllers[dc.playerNumber] = dc;
Menu.SetMenu("lockedDoorMenu");
}
}
}
}
class lockedDoorHandler : soa_ZF_Handler {
lockedDoorMenu menu;
override void buttonClickCommand(soa_ZF_Button caller, string command) {
if ( command == "cmd_ld_odemknout" ) {
//Console.Printf("cmd: odemknout");
// do things ///////////////////////////////////////////////////////
let lockedhandler = argentEventHandler(EventHandler.Find("argentEventHandler"));
let dc = lockedhandler.d_controllers[consoleplayer];
argentEventHandler.SendNetworkEvent("unlockDoor", dc.poly, dc.right1left2, dc.stats);
////////////////////////////////////////////////////////////////////
// close menu //////////////////////////////////////////////////////
let curmenu = Menu.GetCurrentMenu();
if (curmenu != null) curmenu.Close();
// close menu //////////////////////////////////////////////////////
} else if ( command == "cmd_ld_vypacit" ) {
//Console.Printf("cmd: vypacit");
// do things ///////////////////////////////////////////////////////
let lockedhandler = argentEventHandler(EventHandler.Find("argentEventHandler"));
let dc = lockedhandler.d_controllers[consoleplayer];
argentEventHandler.SendNetworkEvent("breakDoor", dc.poly, dc.right1left2, dc.stats);
////////////////////////////////////////////////////////////////////
// close menu //////////////////////////////////////////////////////
let curmenu = Menu.GetCurrentMenu();
if (curmenu != null) curmenu.Close();
// close menu //////////////////////////////////////////////////////
} else if ( command == "cmd_ld_exit" ) {
//Console.Printf("cmd: exit");
// close menu //////////////////////////////////////////////////////
let curmenu = Menu.GetCurrentMenu();
if (curmenu != null) curmenu.Close();
// close menu //////////////////////////////////////////////////////
}
}
}
class lockedDoorMenu : soa_ZF_GenericMenu {
lockedDoorHandler handler;
DoorController d_controller;
// vars definition /////////////////////////////////////////////////////////
font smallfont;
soa_ZF_Image img_background;
soa_ZF_Label ldm_lbl_title;
soa_ZF_Label ldm_lbl_odemknout;
soa_ZF_Label ldm_lbl_vypacit;
soa_ZF_Label ldm_lbl_exit;
soa_ZF_Button ldm_btn_odemknout;
soa_ZF_Button ldm_btn_vypacit;
soa_ZF_Button ldm_btn_exit;
////////////////////////////////////////////////////////////////////////////
override void Init(menu parent) {
////////////////////////////////////////////////////////////////////////
// overall init ////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
Vector2 baseRes = (320, 200); //set base resolution to work with
Super.Init(parent); // Call GenericMenu's 'Init' function to do some required initialization.
// doorcontroller //////////////////////////////////////////////////////
let lockedhandler = argentEventHandler(EventHandler.Find("argentEventHandler"));
if (lockedhandler)
{
let dc = lockedhandler.d_controllers[consoleplayer];
if (dc)
{
d_controller = dc;
}
}
////////////////////////////////////////////////////////////////////////
SetBaseResolution(baseRes);
smallfont = "smallfont";
handler = new("lockedDoorHandler"); // Create an instance of the handler.
handler.menu = self; // Set the handler's "link" pointer to us.
////////////////////////////////////////////////////////////////////////
// play sound on menu open /////////////////////////////////////////////
Menu.MenuSound("sounds/journalUse");
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// create background ///////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
img_background = soa_ZF_Image.Create ( // Add a background.
(0, 0),//position
(320, 200), //size
"graphics/soaMenu/menuBack2.png",//image path/name
soa_ZF_Image.AlignType_TopLeft
);
img_background.Pack(mainFrame); // Add the image element into the main frame.
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// add buttons /////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// create the button's textures ////////////////////////////////////////
let smallbuttonIdle = soa_ZF_BoxTextures.CreateSingleTexture("graphics/soaMenu/smallButtonIdle.png", true);
let smallbuttonHover = soa_ZF_BoxTextures.CreateSingleTexture("graphics/soaMenu/smallButtonHover.png", false);
let smallbuttonClick = soa_ZF_BoxTextures.CreateSingleTexture("graphics/soaMenu/smallButtonClick.png", false);
// odemknout ///////////////////////////////////////////////////////////
ldm_btn_odemknout = soa_ZF_Button.Create(
(((baseRes.X - 32.0) / 2.0) - 40, ((baseRes.Y - 16.0) / 2.0) + 0),//position
(9, 9), //size
cmdHandler : handler, //command handler
command : "cmd_ld_odemknout", //command string for button
inactive: smallbuttonIdle,
hover: smallbuttonHover,
click: smallbuttonClick
);
ldm_btn_odemknout.pack(mainframe);
// vypacit /////////////////////////////////////////////////////////////
ldm_btn_vypacit = soa_ZF_Button.Create(
(((baseRes.X - 32.0) / 2.0) - 40, ((baseRes.Y - 16.0) / 2.0) + 15),//position
(9, 9), //size
cmdHandler : handler, //command handler
command : "cmd_ld_vypacit", //command string for button
inactive: smallbuttonIdle,
hover: smallbuttonHover,
click: smallbuttonClick
);
ldm_btn_vypacit.pack(mainframe);
// exit ////////////////////////////////////////////////////////////////
ldm_btn_exit = soa_ZF_Button.Create(
(((baseRes.X - 32.0) / 2.0) - 40, ((baseRes.Y - 16.0) / 2.0) + 30),//position
(9, 9), //size
cmdHandler : handler, //command handler
command : "cmd_ld_exit", //command string for button
inactive: smallbuttonIdle,
hover: smallbuttonHover,
click: smallbuttonClick
);
ldm_btn_exit.pack(mainframe);
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// ADD LABELS //////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// title ///////////////////////////////////////////////////////////////
ldm_lbl_title = soa_ZF_Label.Create(
(0, ldm_btn_odemknout.GetPosY() + ldm_btn_odemknout.GetHeight() - 30),
(0, smallFont.GetHeight()),
text: "$M_lockeddoorMenu_title", //label's text: [ Bedroll Menu ]
fnt: smallfont, //font !string! to use > if 'null', uses default smallfont
wrap: false, //auto text wrap
autoSize: true, //auto resize elements
textColor: Font.CR_FIRE //text color
);
//soaLabel_nadpis.SetPosX(baseRes.X - smallFont.stringWidth (soaLabel_nadpis.GetText ()) / 2.0);
ldm_lbl_title.SetPosX((baseRes.X / 2.0) - (smallFont.stringWidth(ldm_lbl_title.GetText ()) / 2.0));
ldm_lbl_title.Pack(mainFrame); //add element to mainframe
// odemknout ///////////////////////////////////////////////////////////
ldm_lbl_odemknout = soa_ZF_Label.Create(
(0, ldm_btn_odemknout.GetPosY() + ldm_btn_odemknout.GetHeight() - 10),
(0, smallFont.GetHeight()),
text: "$M_lockeddoorMenu_btn_odemknout", //label's text: [ Bedroll Menu ]
fnt: smallfont, //font !string! to use > if 'null', uses default smallfont
wrap: false, //auto text wrap
autoSize: true, //auto resize elements
textColor: Font.CR_FIRE //text color
);
ldm_lbl_odemknout.SetPosX((baseRes.X / 2.0) - (smallFont.stringWidth(ldm_lbl_odemknout.GetText ()) / 2.0));
ldm_lbl_odemknout.Pack(mainFrame); //add element to mainframe
// vypacit /////////////////////////////////////////////////////////////
ldm_lbl_vypacit = soa_ZF_Label.Create(
(0, ldm_btn_vypacit.GetPosY() + ldm_btn_vypacit.GetHeight() - 10),
(0, smallFont.GetHeight()),
text: "$M_lockeddoorMenu_btn_vypacit", //label's text: [ Bedroll Menu ]
fnt: smallfont, //font !string! to use > if 'null', uses default smallfont
wrap: false, //auto text wrap
autoSize: true, //auto resize elements
textColor: Font.CR_FIRE //text color
);
ldm_lbl_vypacit.SetPosX((baseRes.X / 2.0) - (smallFont.stringWidth(ldm_lbl_vypacit.GetText ()) / 2.0));
ldm_lbl_vypacit.Pack(mainFrame); //add element to mainframe
// exit ////////////////////////////////////////////////////////////////
ldm_lbl_exit = soa_ZF_Label.Create(
(0, ldm_btn_exit.GetPosY() + ldm_btn_exit.GetHeight() - 10),
(0, smallFont.GetHeight()),
text: "$M_lockeddoorMenu_btn_exit", //label's text: [ Bedroll Menu ]
fnt: smallfont, //font !string! to use > if 'null', uses default smallfont
wrap: false, //auto text wrap
autoSize: true, //auto resize elements
textColor: Font.CR_FIRE //text color
);
ldm_lbl_exit.SetPosX((baseRes.X / 2.0) - (smallFont.stringWidth(ldm_lbl_exit.GetText ()) / 2.0));
ldm_lbl_exit.Pack(mainFrame); //add element to mainframe
}
}
////////////////////////////////////////////////////////////////////////////////
// eventhandler ////////////////////////////////////////////////////////////////
class lockedDoorEventHandler : EventHandler {
DoorController d_controllers[MAXPLAYERS];
override void NetworkProcess(ConsoleEvent e) {
let pawn = <YourPlayerClass>(players[e.Player].mo);
if ( e.Name ~== "unlockDoor" ) {
let dc = d_controllers[e.Player];
if (dc) {
// dc.tag is now your door tag
pawn.ACS_NamedExecuteAlways("unlockDoor", 0, dc.poly, dc.right1left2, dc.stats);
}
} else if ( e.Name ~== "breakDoor" ) {
let dc = d_controllers[e.Player];
if (dc) {
// dc.tag is now your door tag
pawn.ACS_NamedExecuteAlways("breakDoor", 0, dc.poly, dc.right1left2, dc.stats);
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// ACS /////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// polyobject door control scripts /////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#define MAX_SWINGING_DOORS 1000
bool polyDoor[MAX_SWINGING_DOORS]; //'dynamic' variable = array
////////////////////////////////////////////////////////////////////////////////
// newest iteration, universal script for right/left opened doors //////////////
script "universalPolyDoorBase" (int poly, int spd, int right1Left2) {
if ( right1Left2 == 1 ) { //right
if ( !polyDoor[poly] ) {
Polyobj_RotateRight(poly, spd, 64);
if(spd < 16) {
AmbientSound("sounds/DoorCreak", 127);
}
else if(spd >= 16) {
AmbientSound("sounds/officeDopen", 127);
}
PolyWait(poly);
polyDoor[poly] = true;
} else if ( polyDoor[poly] ) {
Polyobj_RotateLeft(poly, spd, 64);
if(spd < 16) {
AmbientSound("sounds/DoorCreak", 127);
}
else if(spd >= 16) {
AmbientSound("sounds/officeDclose", 127);
}
PolyWait(poly);
polyDoor[poly] = false;
}
} else if ( right1Left2 == 2 ) { //left
if ( !polyDoor[poly] ) {
Polyobj_RotateLeft(poly, spd, 64);
if(spd < 16) {
AmbientSound("sounds/DoorCreak", 127);
}
else if(spd >= 16) {
AmbientSound("sounds/officeDopen", 127);
}
PolyWait(poly);
polyDoor[poly] = true;
} else if ( polyDoor[poly] ) {
Polyobj_RotateRight(poly, spd, 64);
if(spd < 16) {
AmbientSound("sounds/DoorCreak", 127);
}
else if(spd >= 16) {
AmbientSound("sounds/officeDclose", 127);
}
PolyWait(poly);
polyDoor[poly] = false;
}
}
}
// to make it behave as a built in function > run the script in separate VM ////
script "universalPolyDoor" (int poly, int spd, int right1Left2) {
ACS_NamedExecuteAlways("universalPolyDoorBase", 0, poly, spd, right1Left2);
}
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// zscript locked door menu ////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#define MAX_LOCKEDDOORS 1000
bool lockedDoor[MAX_LOCKEDDOORS];
script "menu_lockedDoor" (int poly, int right1left2, int stats) {
if ( !lockedDoor[poly] ) {
ScriptCall("DoorController", "OpenDoorMenu", poly, right1left2, stats);
} else {
ACS_NamedExecute("universalPolyDoor", 0, poly, 16, right1left2);
}
}
script "unlockDoor" (int poly, int right1left2, int stats) {
if ( !lockedDoor[poly] ) {
// here the condition should be ANYTHING, I'm using player's strife stats here, as they're built-in (==lazy)
int playerAccuracy = ScriptCall("wielder", "getplayerAccuracy");
int desiredAccuracy = stats*10;
if ( playerAccuracy >= desiredAccuracy ) {
Log(l:"$TXT_unlockeddoor");
ACS_NamedExecute("universalPolyDoor", 0, poly, 16, right1left2);
lockedDoor[poly] = true;
} else {
Log(l:"TXT_required", i:desiredAccuracy, l:"TXT_accuracy2unlock");
}
} else {
ACS_NamedExecute("universalPolyDoor", 0, poly, 16, right1left2);
}
}
script "breakDoor" (int poly, int right1left2, int stats) {
if ( !lockedDoor[poly] ) {
// here the condition should be ANYTHING, I'm using player's strife stats here, as they're built-in (==lazy)
int playerStamina = ScriptCall("wielder", "getplayerStamina");
int desiredStamina = stats*10;
if ( playerStamina >= desiredStamina ) {
Log(l:"$TXT_brokendoor");
ACS_NamedExecute("universalPolyDoor", 0, poly, 16, right1left2);
lockedDoor[poly] = true;
} else {
Log(l:"TXT_required", i:desiredStamina, l:"TXT_stamina2unlock");
}
} else {
ACS_NamedExecute("universalPolyDoor", 0, poly, 16, right1left2);
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////