UGX-Mods

Call of Duty 5: World at War => Downloadable Items for Mappers => Custom Maps, Mods & Tools => Scripts => Topic started by: buttkicker845 on July 07, 2016, 11:12:50 pm

Title: Doors that requires keys to open
Post by: buttkicker845 on July 07, 2016, 11:12:50 pm
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 (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
Code Snippet
Plaintext
script_vector
an integer value such as 2
           Step 2: once youre door is made select the trigger and change the targetname kvp to
Code Snippet
Plaintext
targetname
key_door
            Step 3: place script model or script brush and give it the kvp
Code Snippet
Plaintext
targetname
door_key
Script:
            Step 1: open your mapname.gsc and place the line before _zombiemode::main();
Code Snippet
Plaintext
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
Code Snippet
Plaintext
if(isDefined(self.script_noteworthy) && self.script_noteworthy == "electric_door")
{
flag_wait( "electricity_on" );
}
else
{
and replace it with this
Code Snippet
Plaintext
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

www.mediafire.com

If you use this please give me credit and please report any bugs or problems you may encounter

Images in game:
Spoiler: click to open...
Text for picking up key
(https://s31.postimg.org/xbhhky4jf/shot0005.jpg)

Notification to all players when key has been picked up
(https://s32.postimg.org/jsh8gg3h1/shot0009.jpg)

Text on door when door is locked, is dynamic for how many keys are still needed to be found to open
(https://s31.postimg.org/6wef46vgb/shot0010.jpg)

Text on door when door can be unlocked
(https://s31.postimg.org/fdmqy8x8b/shot0006.jpg)

Source code in case the link ever becomes broken:
Spoiler: click to open...
Code Snippet
Plaintext
/**
/////////////////////////////////////////////////
///////// 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

Title: Re: Doors that requires keys to open
Post by: muliteman on August 21, 2016, 10:28:41 pm
cool thx man :)
Title: Re: Doors that requires keys to open
Post by: Sebra on August 22, 2016, 05:54:58 am
Thanks man i really needed that! +1
Title: Re: Doors that requires keys to open
Post by: PlutoBro on August 22, 2016, 07:06:08 am
dude I was just designing something that would require a certain amount of items triggered to unlock, this is perfect!!

Will give it a go tonight  :D
Title: Re: Doors that requires keys to open
Post by: buttkicker845 on August 24, 2016, 05:14:24 pm
glad you guys can use it, let me know if there are any problems :)
Title: Re: Doors that requires keys to open
Post by: Ping998 on September 03, 2016, 07:26:55 pm
glad you guys can use it, let me know if there are any problems :)

Sometimes the hintstring breaks and shows a wrong number
Title: Re: Doors that requires keys to open
Post by: IamTIMMEHHH on May 03, 2017, 06:53:31 pm
I followed the script twice but i still dont get a ''press f to pick up key'' hintstring also cant pick it up.
Title: Re: Doors that requires keys to open
Post by: Deer2014 on January 14, 2018, 09:56:38 pm
Guys, does anybody work random key position?

I have a door, the door trigger kvp is:
targetname -> key_door

I have 5 script model (keys), the kvp of 5 script model:
targetname -> door_key

the script init() variables:
Code Snippet
Plaintext
level.useRandomKeyLocations = true;
level.numberOfKeysInWorld = 5;
level.numberOfKeysRequiredGlobal = 1;
level.distanceFromKey = 55;

The mapname.gsc:
Code Snippet
Plaintext
level thread maps\key_door::init();
maps\_zombiemode::main();

In the game I can see the 5 keys, I picking up one, then script delete all and open the door.
But I just want to see 1 key in different locations each game. Is possible? What did I ruin it?

Can anyone help me?
Thx.
Title: Re: Doors that requires keys to open
Post by: BluntStuffy on January 14, 2018, 10:18:45 pm
Quote
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


set this to 1:
Code Snippet
Plaintext
level.numberOfKeysInWorld = 5; 

Title: Re: Doors that requires keys to open
Post by: Deer2014 on January 15, 2018, 12:09:26 am
Ohh, I was careless. :-\
Thanks BluntStuffy.  ;)

Title: Re: Doors that requires keys to open
Post by: Deer2014 on January 16, 2018, 12:46:55 pm
Hi guys,

I tried the above "no cost" script modification and I get the script compile error (syntax error).
I found the cause of the problem. On line 5 the less equal relation signal is wrong.

Wrong script detail:
Code Snippet
Plaintext
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
{

Correct script detail:
Code Snippet
Plaintext
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
{
Title: Re: Doors that requires keys to open
Post by: buttkicker845 on January 16, 2018, 01:28:27 pm
Hi guys,

I tried the above "no cost" script modification and I get the script compile error (syntax error).
I found the cause of the problem. On line 5 the less equal relation signal is wrong.

Thank you for catching that!  :D When I wrote the documentation i re-wrote it rather than copying it straight from the script. I have updated the original post
Title: Re: Doors that requires keys to open
Post by: Deer2014 on March 13, 2018, 03:09:31 pm
Hi,

I would like to ask some help.

I have more doors in my map.
I want to hide at least 3 keys for each door randomly.
And I want to open each door with 1 key, which can be accessed in 3 different places.

Now I have two doors and I have set trigger_use for both doors:
targetname = key_door, but when I find the key, I can open both doors, it is not good for me. :(
So, I want to set 1 key to the other door, which is also in 3 different locations.

It is possible? How to do it?

Thx.
Title: Re: Doors that requires keys to open
Post by: Fancygamer1738 on March 25, 2018, 04:55:43 pm
Exactly what I needed for my map! Thanks a ton! :nyan: