History of script: This is a script that i started writing over a year ago, i got side tracked and forgot about it. I recently saw someone on the forum request something similar and gave me the idea to just go ahead and finish the script.
Description of the script: Its a simple script that makes it so the players have to find and pick up keys before they are allowed to open the door. there can be unlimited doors and each one can have a different number of keys required. the door can also still require points to open if you so choose
it also DOESN'T require you to use a trigger for the keys saving you half of the script entities that would normally be used for having keys to pick up
Features: The script can be customized 4 different ways in order to make it work how you wish
- These modifications include if the key location will be randomly selected in the world
- how many keys should be kept in the world
- the distance the player must be from the key in order to pick it up
- the default value for how many keys each door requires to open, this can be overridden for each door by placing script_vector on your door trigger
There are instructions included in the file but i will place them here as well for ease of access: Radiant: Step 1: make a normal door, if you dont know how to make a door go to
https://confluence.ugx-mods.com/display/UGXMODS/Creating+a+Moving+Door+Blocker Optional Step: if you dont want your door to cost anything then either delete the kvp zombie_cost or set it equal to 0
Note: if you delete the zombie_cost kvp you will need to do the optional step in the script section!
Optional Step: To Specify how many keys the current door will require give it the kvp
script_vector an integer value such as 2
Step 2: once youre door is made select the trigger and change the targetname kvp to
targetname key_door
Step 3: place script model or script brush and give it the kvp
targetname door_key
Script: Step 1: open your mapname.gsc and place the line before _zombiemode::main();
level thread maps\key_door::init();
Optional Step: open up_zombiemode_blockers_new.gsc and find the section that looks like this, around line 136
if(isDefined(self.script_noteworthy) && self.script_noteworthy == "electric_door") { flag_wait( "electricity_on" ); } else {
and replace it with this
if(isDefined(self.script_noteworthy) && self.script_noteworthy == "electric_door") { flag_wait( "electricity_on" ); } else if(isDefined(self.targetname) && self.targetname == "key_door" && (!isDefined(self.zombie_cost) || self.zombie_cost <= 0)) { } else {
Note: if you did the optional step to remove zombie_cost you will have to complete this step otherwise your door will still cost 1000 points
If you use this please give me credit and please report any bugs or problems you may encounter
Images in game: Text for picking up key
Notification to all players when key has been picked up
Text on door when door is locked, is dynamic for how many keys are still needed to be found to open
Text on door when door can be unlocked
Source code in case the link ever becomes broken: /** ///////////////////////////////////////////////// ///////// Written by buttkicker845/////////////// ///////// Date Created: 2/7/2015///////////////// ///////// Date Modified: 7/7/2016//////////////// ///////////////////////////////////////////////// Discription of features: The point of this script is for doors that require the player to find a specified number of keys before being able to open the door. How to set up key entry door: Radiant: Step 1: make a door like normal, if you dont know how to make a normal door visit the UGX wiki at: [url]https://confluence.ugx-mods.com/display/UGXMODS/Creating+a+Moving+Door+Blocker[/url] Step 2: once your door is made, select the trigger on the door and change the targetname kvp from zombie_door to key_door Step 3: right click on the 2D window and select script if you have a model for your key, then select model if you made your key out of a brush or multiple brushes then select the brush/es and then select script and then select brush Step 4: once you have your key placed in the world select it and press N to bring up the entity window, in here you will give your key the kvp of targetname of door_key Optional Step: while the door trigger is still selected and the entity window is open give the trigger the kvp of script_vector to specify how many keys must be found to open the door That is it for radiant! Script: Step 1: open up mods/modname/maps if the folder doesnt exist create it, and place this script in there Step 2: open up your mapname.gsc, if you dont know where it is located then look in either raw/maps or in mods/modname/maps depending on the script placer you used Step 3: search for the line maps\_zombiemode::main(); Step 4: right above the maps\_zombiemode::main(); line place the line maps\key_door::init(); Optional Modifications to the door functionality! Step 1: find the function names init() and change the level.variables you would like to modify Step 2: the useRandomKeyLocations will randomly delete key locations in order to have the keys be in different locations each game Step 3: the numberOfKeysInWorld will modify how many keys will remain in the world after the useRandomKeyLocations is used, only effects if useRandomKeyLocations is true Step 4: the numberOfKeysRequiredGlobal specifies how many keys are required to open all doors in the world, this can be overridden by using the kvp script_vector on the door trigger Optional Step! The door can still have a specified cost like normal doors or they can free after unlocking the door using the keys that were found A free door can be achieved by either setting teh zombie_cost kvp to 0 or by using this script modification to _zombiemode_blockers_new on line 136 or by searching for : if(isDefined(self.script_noteworthy) && self.script_noteworthy == "electric_door") if(isDefined(self.script_noteworthy) && self.script_noteworthy == "electric_door") { flag_wait( "electricity_on" ); } else if(isDefined(self.targetname) && self.targetname == "key_door" && (!isDefined(self.zombie_cost) || self.zombie_cost <= 0)) { } else { Thats it! If you fallowed the steps correctly you should now have doors that will require the players to find keys before they can open the door */ #include common_scripts\utility; #include maps\_zombiemode_utility; #include maps\_utility; init() { //you can modify these variables level.useRandomKeyLocations = true;// this will randomly spawn the keys in the world based on the locations placed in radiant, (set true of false) level.numberOfKeysInWorld = 2; // number of keys that will be in the game, the number of keys placed in radiant must be equal to or greater than this number! level.numberOfKeysRequiredGlobal = 1; // number of keys required to open a door, can be overridden by the kvp script_vector on the door trigger level.distanceFromKey = 75; // the distance from the key a player has to be in order to pick it up //dont modify these variables! level.keysFound = 0;// it is required to count how many keys the players have found this game level.maxNumberOfKeysRequired = level.numberOfKeysRequiredGlobal; //the max amount of keys that is required by any door in the world level thread main(); } main() { //gets all the keys in the world keys = getEntArray("door_key", "targetname"); //if the level.useRandomKeyLocations is true the script will randomly spawn delete keys in the world, this is to keep the players guessing if(level.useRandomKeyLocations) { //create two arrays in order to keep track of the keys that will be left in the world and to modify the array of keys without messing with the original array keysKept = []; temp = []; //makes deep copy of keys array for minipulation of keys array for(i = 0; i < keys.size; i++) { temp[i] = keys[i]; } //finds random keys up to the number of keys set by level.numberOfKeysInWorld for(i = 0; i < level.numberOfKeysInWorld; i++) { location = getRandomLocation(temp); keysKept[keysKept.size] = location; temp = array_remove(temp,location); } //removes the rest of the keys in the world for(i = 0; i < temp.size; i++) { temp[i] delete(); } //recollects the keys after the extras have been deleted keys = getEntArray("door_key", "targetname"); } else { for(i = level.numberOfKeysInWorld; i < keys.size; i++) { keys[i] delete(); } } //threads the key_init funciton on each key in the world for(i = 0; i < keys.size; i++) { keys[i] thread key_init(); } //collects all the doors in the world and threads the door_init function on them keyDoors = getEntArray("key_door", "targetname"); for(i = 0; i < keyDoors.size; i++) { keyDoors[i] thread key_door_init(); } } key_door_init() { keysRequiredCount = level.numberOfKeysRequiredGlobal; //checks if the door trigger overrides the global key requirement if(isDefined(self.script_vector)) { keysRequiredCount = self.script_vector; //if the keys required for this door is if(keysRequiredCount > level.numberOfKeysInWorld) { keysRequiredCount = level.numberOfKeysInWorld; println("Key_Door at location: " + self.origin + " requires more keys to open than there are in the world"); } //if this door requires more keys than the current max amount required update the current max amount required if(level.maxNumberOfKeysRequired < keysRequiredCount) { level.maxNumberOfKeysRequired = keysRequiredCount; } } //set the trigger hintstring and remove the hand icon self.keysRequiredCount = keysRequiredCount; self thread setDoorHint(); while(1) { self waittill("trigger",player); //if there are enough keys found to opent this door, then unlock it if(self.keysRequiredCount <= level.keysFound) { self notify("door_opened"); //now that the door is unlocked make it act like a normal door self thread maps\_zombiemode_blockers_new::door_init(); break; } wait(.05); } } setDoorHint() { self endon("door_opened"); //runs until the door has been opened self SetCursorHint( "HINT_NOICON" ); while(1) { //creates the remain amount of keys that need to be found in order to unlock the door cost = self.keysRequiredCount - level.keysFound; //if the player has enough keys they can unlock the door if(cost <= 0) { self setHintString("Press and hold &&1 to unlock the door"); } //otherwise display how many more must be found to unlock the door else { self setHintString("Keys required to unlock door: [" + cost + "]"); } wait(.05); } } key_init() { //threads the functions that will set the hint string for the key as well as wait for the player to pick up the key self thread setKeyHint(); self thread keyWaitForTrigger(); } setKeyHint() { dist = level.distanceFromKey; //runs as long as the current key is defined in the world while(isDefined(self)) { players = getPlayers(); //itterates through all the players and checks if they are valid and if they are close enough to pick up the key for(i = 0; i < players.size; i++) { if(is_player_valid(players[i])) { if(distance(self.origin, players[i].origin) < dist) { //displays a message on screen for the player to press and hold use to pick up the key self thread printDisplay(self, players[i], "Press and hold [{+activate}] to pick up key", dist); } } } wait(.05); } } //waits for a player to be close enough to the key and to be pressing the use button to pick the key up keyWaitForTrigger() { //sets the distance for the check to the global distance dist = level.distanceFromKey; //runs as long as the key is defined while(isDefined(self)) { players = getPlayers(); for(i = 0; i < players.size; i++) { //checks if the current is player is a valid player and if they are close enough to the key and if they are currently pressing the use button if(is_player_valid(players[i]) && distance(self.origin, players[i].origin) < dist && players[i] useButtonPressed()) { //deletes the current key self delete(); //increase the amount of keys found by all players level.keysFound++; //notify all other players that a key was found notifyAllPlayersOfKeyPickUp(players[i]); //if the players have found enough keys to open all doors then its safe to delete the rest if(level.keysFound >= level.maxNumberOfKeysRequired) { deleteAllKeysRemaining(); } } } wait(.05); } } //displays a message at the top left of the screen letting all players know a player found a key notifyAllPlayersOfKeyPickUp(pickUpPlayer) { players = getPlayers(); for(i = 0; i < players.size; i++) { players[i] iPrintln(pickUpPlayer.playername + " has found a key!"); } } //deletes all the remaining keys in the world once the players have found enough keys to open all doors deleteAllKeysRemaining() { keys = getEntArray("door_key", "targetname"); for(i = 0; i < keys.size; i++) { if(keys[i] != undefined) { keys[i] delete(); } } } //will create a hud element for the player with the text that is passed in the parameter, will display the hud element as long as the player is close enough to see it printDisplay(ent,player,message,dist) { //if the thread is called again stops the previous running thread player notify("setting_hint"); player endon("setting_hint"); //if either the ent to display the message for or the player is undefined then stop the thread if(!isDefined(ent) || !isDefined(player)) return; //if there isnt a message passed then present a warning instead of the message if(!isDefined(message)) message = "hint string for enity " + ent.targetname + " is not defined in printDisplay"; //if the destance for how close the player must be isnt set then use default distance if(!isDefined(dist)) dist = 100; //if the hud element isnt defined then create a new one and set its position in the middle of the screen if(!isDefined(player.trigText)) { player.trigText = NewClientHudElem( player ); player.trigText.alignX = "center"; player.trigText.alignY = "middle"; player.trigText.horzAlign = "center"; player.trigText.vertAlign = "middle"; player.trigText.y += 100; player.trigText.foreground = true; player.trigText.fontScale = 1.5; player.trigText.alpha = 1; player.trigText.color = ( 1.0, 1.0, 1.0 ); } //if the element is defined then set the text to the message passed if(isDefined(player.trigText)) { player.trigText SetText( message ); } //if the entity passed is a trigger of some kind then set the hint cursor to nothing if(isDefined(ent.classname) && isSubStr(ent.classname, "trigger")) ent SetCursorHint( "HINT_NOICON" ); //keep the hud element as long as the entity is defined, the player is valid and as long as the player is close enough while(isDefined(ent) && isDefined(player) && is_player_valid(player) && distance(ent.origin, player.origin) < dist) { wait(.05); } //if the hud element is still defined destroy it from the screen if(isDefined(player.trigText)) player.trigText destroy(); }//end printDisplay //will return a random value in from the array passed getRandomLocation(array){ //if the array is empty dont return anything if(array.size <= 0) return undefined; //remove all undefined values in the array array = array_removeundefined(array); //return the random value return array[randomInt(array.size)]; }//end getRandomLocation