UGX-Mods Login

or login with an authentication provider below
Sign In with Google
Sign In with Twitter
Sign In with Discord
Sign In with Steam
Sign In with Facebook
Sign In with Twitch

General Help

broken avatar :(
Created 5 years ago
by dabro
0 Members and 1 Guest are viewing this topic.
2,376 views
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 14 March 2013
Last active: 2 years ago
Posts
26
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
dabro's Groups
dabro's Contact & Social Links
Hello, I recently got back into waw mapping and I'm having a few issues.

The first issue I'm having is that zombies are going to windows they shouldn't open yet. My map layout is a house with an up and down stairs, you start in the up stairs, but the zombies are breaking down the down stairs windows first. Is there a way to set certain zombies to open certain windows? Like Start_Zone zombies, can only break down Start_Zone windows?

My second issue, is if the zombies do go to the upstairs windows, they don't break down the window at all, they just try to attack me. The only thing I can think of is because it's on a roof and it's slanted it could be causing issues, does anyone know of any solution to fix this? My friend suggested using caulk to make the ground flat, but it's doesn't allow the player to shoot the zombies at the down stairs windows.

I appericate any suggestions that are given, thanks.

Update: To avoid making multiple post, I'm just going to keep using this one if that is ok. I have a few questions in the near future.
I'm currently trying to figure out the moving mystery box, if anyone can help me with that. I followed this tutorial
https://zombiemodding.com/index.php?topic=3206.0
, except I only need 4 boxes, not all 6 of them. The box keeps spawning in the same place.
Last Edit: May 02, 2019, 12:23:07 am by dabro
broken avatar :(
×
broken avatar :(
Location: alDurrës
Date Registered: 6 June 2017
Last active: 9 months ago
Posts
222
Respect
Forum Rank
Mr. Elemental
Primary Group
Donator ♥
My Groups
More
My Contact & Social Links
More
Signature
My published cod maps:

Mansion of the Undead
Buros Der Toten
Minions by k3nt
×
klevi's Groups
Donator ♥ Benevolent Soul who has our eternal gratitude and exclusive access to betas and the donator section of the forum.
For that 1st issue, im 100% sure that already is a tutorial(at least a post) on making zombies to spawn only in the area that you're currently in. As for your 2nd issue, what do you really mean with ``
 they don't break down the window at all, they just try to attack me``. Do you mean that they pass the window without breaking it(i don't think so) or they just try to attack but stay outside. If it's the 2nd issue try to check how it's placed your prefab but i cannot say anything for sure. But yeah, 1 suggestion: We would really appreciate if you get at least 1 screenshot!!!
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 14 March 2013
Last active: 2 years ago
Posts
26
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
dabro's Groups
dabro's Contact & Social Links
So, my first issue isn't about the incorrect zombies spawning, I only have 2 zombie spawners right now for the start zone. It's that they are going to windows that I current don't have access to, and it might be because the pathnodes go close enough to those windows and I was wanting to know if there was a way to make it were only certain zombies go to certain windows.
In the image, those 3 bottom windows, most of the zombies keep going to them, and as you can see I'm just trying to see if I can get the zombies to jump on the roof to break down those two windows on the second floor. Is there any solution for that? Here are pictures of that window up close, from both the inside and outside.



As of the second issue, yes they keep trying to attack, but stay outside, I want to say the slope of the roof is causing the issue, but they can walk all the way to the window, so I'm not sure. Also, none of the zombies go to the path nodes on the left side of the screen, they only come in this general direction, any ideas?
For that 1st issue, im 100% sure that already is a tutorial(at least a post) on making zombies to spawn only in the area that you're currently in. As for your 2nd issue, what do you really mean with ``
 they don't break down the window at all, they just try to attack me``. Do you mean that they pass the window without breaking it(i don't think so) or they just try to attack but stay outside. If it's the 2nd issue try to check how it's placed your prefab but i cannot say anything for sure. But yeah, 1 suggestion: We would really appreciate if you get at least 1 screenshot!!!

Double Post Merge: April 25, 2019, 10:28:09 pm
I couldn't add these pictures in my last post, so I'm going to put them here. These show the inside and outside pictures of the windows. I see the traverse thing is in the roof a bit, but is that going to prevent them from breaking down my window? I'm only curious because the other window isn't like that and they won't break that down either.


Last Edit: April 25, 2019, 10:28:11 pm by dabro
broken avatar :(
×
broken avatar :(
Location: alDurrës
Date Registered: 6 June 2017
Last active: 9 months ago
Posts
222
Respect
Forum Rank
Mr. Elemental
Primary Group
Donator ♥
My Groups
More
My Contact & Social Links
More
×
klevi's Groups
Donator ♥ Benevolent Soul who has our eternal gratitude and exclusive access to betas and the donator section of the forum.
As for the pathnodes i can say that you need to put them with a bit distance from each other and other things too such as brushes or modelshttps://imgur.com/a/ZIFNJWUAs for the window on the 2nd floor, isn't it a bit small?https://imgur.com/a/79cNtS3i can't say it for sure but also the roof does look like a bit sloped.
Last Edit: April 26, 2019, 12:37:06 pm by klevi
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 14 March 2013
Last active: 2 years ago
Posts
26
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
dabro's Groups
dabro's Contact & Social Links
As for the pathnodes i can say that you need to put them with a bit distance from each other and other things too such as brushes or models(Image removed from quote.)https://imgur.com/a/ZIFNJWUAs for the window on the 2nd floor, isn't it a bit small?https://imgur.com/a/79cNtS3i can't say it for sure but also the roof does look like a bit sloped.


Sorry for the long delay, I was going through finals and didn't have time to work on it. I was able to get it working. If I placed the zombies on the roof, they would go straight for the window, so I just decided to do that instead.

Now the issue I'm having is the random box. I followed this tutorial 
https://zombiemodding.com/index.php?topic=3206.0
and I did everything it said except, I don't need all 6 of the boxes, I only need 4 of them. What can I do to make this work. Before when I made my original map, I just used Sniperbolts tutorial, but I couldn't seem to find that anymore, as well as Tom_BMXs Music box. If you happen to know where I can download that again, I would appericate it.
broken avatar :(
×
broken avatar :(
Location: nl
Date Registered: 20 September 2013
Last active: 4 days ago
Posts
645
Respect
Forum Rank
Zombie Enslaver
Primary Group
Community Scripter
My Groups
More
My Contact & Social Links
More
Personal Quote
No code is bug free
Signature
My published cod maps:

Subzero
Djinncaves
Enclosed (a.k.a baconcube)
Bayern
Snowblind
Furtrelock

Black Ops Perks: https://www.ugx-mods.com/forum/scripts/55/call-of-duty-world-at-war-black-ops-perks/22180/
×
gympie6's Groups
Community Scripter Has shown effort and knowledge in the area of scripting while being a part of the UGX-Mods community.
gympie6's Contact & Social LinksTheRevenantSkullTeffrieTeffrieGympie5#5971
Sorry for the long delay, I was going through finals and didn't have time to work on it. I was able to get it working. If I placed the zombies on the roof, they would go straight for the window, so I just decided to do that instead.

Now the issue I'm having is the random box. I followed this tutorial
https://zombiemodding.com/index.php?topic=3206.0
and I did everything it said except, I don't need all 6 of the boxes, I only need 4 of them. What can I do to make this work. Before when I made my original map, I just used Sniperbolts tutorial, but I couldn't seem to find that anymore, as well as Tom_BMXs Music box. If you happen to know where I can download that again, I would appericate it.
Just remove a line instead of adding a new one:
 
Code Snippet
Plaintext
// Magic Boxes -- The Script_Noteworthy Value Names On Purchase Trigger In Radiant
boxArray = ;
boxArray = "start_chest";
boxArray = "chest1";
boxArray = "chest2";
boxArray = "chest3";
level.DLC3.PandoraBoxes = boxArray;
Sniperbolt tutorial uploaded by me: http://www.mediafire.com/file/zt32yz3kgvj2xyq/nazi_zombie_tutorial+v2.0+%28SNIPER+BOLT%29.zip
Good luck :)
Last Edit: May 02, 2019, 05:45:30 pm by gympie6
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 14 March 2013
Last active: 2 years ago
Posts
26
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
dabro's Groups
dabro's Contact & Social Links
Just remove a line instead of adding a new one:

Code Snippet
Plaintext
// Magic Boxes -- The Script_Noteworthy Value Names On Purchase Trigger In Radiant
boxArray = ;
boxArray = "start_chest";
boxArray = "chest1";
boxArray = "chest2";
boxArray = "chest3";
level.DLC3.PandoraBoxes = boxArray;
Sniperbolt tutorial uploaded by me: http://www.mediafire.com/file/zt32yz3kgvj2xyq/nazi_zombie_tutorial+v2.0+%28SNIPER+BOLT%29.zip
Good luck :)
Thanks for the response and thanks for the tutorial! I did go and add in the prefabs and I'm still having the same issue where the box keeps spawning in the same location. Any ideas?
Also, when I copied and pasted that code you sent, it would cause a syntax error for me.

Here is a picture of one of the boxes in game, this is the start box and it keeps going back to this one.
Last Edit: May 02, 2019, 06:26:18 pm by dabro
broken avatar :(
×
broken avatar :(
Location: nl
Date Registered: 20 September 2013
Last active: 4 days ago
Posts
645
Respect
Forum Rank
Zombie Enslaver
Primary Group
Community Scripter
My Groups
More
My Contact & Social Links
More
Personal Quote
No code is bug free
×
gympie6's Groups
Community Scripter Has shown effort and knowledge in the area of scripting while being a part of the UGX-Mods community.
gympie6's Contact & Social LinksTheRevenantSkullTeffrieTeffrieGympie5#5971
Thanks for the response and thanks for the tutorial! I did go and add in the prefabs and I'm still having the same issue where the box keeps spawning in the same location. Any ideas?
Also, when I copied and pasted that code you sent, it would cause a syntax error for me.
(Image removed from quote.)
Here is a picture of one of the boxes in game, this is the start box and it keeps going back to this one.
(Image removed from quote.)
I haven't done anything with random boxes before because I always place the prefabs and works without any problems.
Maybe it is different on your side:

openup dlc3 _code.gsc and look for this: magic_box_init()
Code Snippet
Plaintext
magic_box_init()
{
level.open_chest_location = [];

for( x = 0 ; x < level.DLC3.PandoraBoxes.size ; x++ )
{
level.open_chest_location[ x ] = level.DLC3.PandoraBoxes[ x ];
}
}
is this the same as yours?
then openup zombiemode_weapons.gsc and look for this: verify_chest_is_open()
Code Snippet
Plaintext
verify_chest_is_open()
{

//for(i = 0; i < 5; i++)
//PI CHANGE - altered so that there can be more than 5 valid chest locations
for (i = 0; i < level.open_chest_location.size; i++)
{
if(isdefined(level.open_chest_location[i]))
{
if(level.open_chest_location[i] == level.chests[level.chest_index].script_noteworthy)
{
level.verify_chest = true;
return;
}
}

}

level.verify_chest = false;


}
is this also same as yours?
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 14 March 2013
Last active: 2 years ago
Posts
26
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
dabro's Groups
dabro's Contact & Social Links
I haven't done anything with random boxes before because I always place the prefabs and works without any problems.
Maybe it is different on your side:

openup dlc3 _code.gsc and look for this: magic_box_init()
Code Snippet
Plaintext
magic_box_init()
{
level.open_chest_location = ;

for( x = 0 ; x < level.DLC3.PandoraBoxes.size ; x++ )
{
level.open_chest_location = level.DLC3.PandoraBoxes;
}
}
is this the same as yours?
then openup zombiemode_weapons.gsc and look for this: verify_chest_is_open()
Code Snippet
Plaintext
verify_chest_is_open()
{

//for(i = 0; i < 5; i++)
//PI CHANGE - altered so that there can be more than 5 valid chest locations
for (i = 0; i < level.open_chest_location.size; i++)
{
if(isdefined(level.open_chest_location[i]))
{
if(level.open_chest_location[i] == level.chests[level.chest_index].script_noteworthy)
{
level.verify_chest = true;
return;
}
}

}

level.verify_chest = false;


}
is this also same as yours?
 Yep, I double checked, I even put in the dlc3_code.gsc in my map folder and recompiled with the same result. I know what you mean though, the last time I made a map, all I did was use sniperbolts tutorial and it just worked.
broken avatar :(
×
broken avatar :(
Location: nl
Date Registered: 20 September 2013
Last active: 4 days ago
Posts
645
Respect
Forum Rank
Zombie Enslaver
Primary Group
Community Scripter
My Groups
More
My Contact & Social Links
More
Personal Quote
No code is bug free
×
gympie6's Groups
Community Scripter Has shown effort and knowledge in the area of scripting while being a part of the UGX-Mods community.
gympie6's Contact & Social LinksTheRevenantSkullTeffrieTeffrieGympie5#5971
Yep, I double checked, I even put in the dlc3_code.gsc in my map folder and recompiled with the same result. I know what you mean though, the last time I made a map, all I did was use sniperbolts tutorial and it just worked.
From what I see in code you need to place your "start_chest" to let it work.
Otherwise you can use the sniperbolts prefabs to make it work.  O0
Last Edit: May 02, 2019, 07:19:42 pm by gympie6
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 14 March 2013
Last active: 2 years ago
Posts
26
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
dabro's Groups
dabro's Contact & Social Links
From what I see in code you need to place your "start_chest" to let it work.Otherwise you can use the sniperbolts scripts to make it work.  O0
I have the start chest placed, in the sniperbolt prefab they are just called "treasure_chest_begin", but the script notworthy says "start_chest" in his tutorial, so I'm assuming they are the same. Where are the sniperbolt scripts located, I couldn't seem to find them.
broken avatar :(
×
broken avatar :(
Location: nl
Date Registered: 20 September 2013
Last active: 4 days ago
Posts
645
Respect
Forum Rank
Zombie Enslaver
Primary Group
Community Scripter
My Groups
More
My Contact & Social Links
More
Personal Quote
No code is bug free
×
gympie6's Groups
Community Scripter Has shown effort and knowledge in the area of scripting while being a part of the UGX-Mods community.
gympie6's Contact & Social LinksTheRevenantSkullTeffrieTeffrieGympie5#5971
I have the start chest placed, in the sniperbolt prefab they are just called "treasure_chest_begin", but the script notworthy says "start_chest" in his tutorial, so I'm assuming they are the same. Where are the sniperbolt scripts located, I couldn't seem to find them.
Yes,
The scripts should be located in raw/maps

 
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 14 March 2013
Last active: 2 years ago
Posts
26
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
dabro's Groups
dabro's Contact & Social Links
Yes,
The scripts should be located in raw/maps


Thank you for that. I'm going to be comparing the code over the next couple of days and will message back with an update. Thank you for your help!
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 14 March 2013
Last active: 2 years ago
Posts
26
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
dabro's Groups
dabro's Contact & Social Links
I wanted to make an update on the situation I had. So, I went back and forth between all of the files between Sniperbolts Tutorial and my own, and I couldn't really see anything besides minor stuff here and there. Today, I went through a post on an old thread that said, taking the _zombiemode_weapons files from Sniperbolts Tutorial and using it for yours should work. In my case it did, so if any one in the future has any issues with that, make a copy of your _zombiesmode_weapons file and put this into it, these are directly from the Sniperbolt Tutorial.

Code Snippet
Plaintext
#include maps\_utility; 
#include common_scripts\utility;
#include maps\_zombiemode_utility;

init()
{
init_weapons();
init_weapon_upgrade();
init_pay_turret();
init_weapon_cabinet();
treasure_chest_init();
level thread add_limited_tesla_gun();
level.box_moved = false;
}

add_zombie_weapon( weapon_name, hint, cost, weaponVO, variation_count, ammo_cost  )
{
if( IsDefined( level.zombie_include_weapons ) && !IsDefined( level.zombie_include_weapons[weapon_name] ) )
{
return;
}
 
add_weapon_to_sound_array(weaponVO,variation_count);

// Check the table first
table = "mp/zombiemode.csv";
table_cost = TableLookUp( table, 0, weapon_name, 1 );
table_ammo_cost = TableLookUp( table, 0, weapon_name, 2 );

if( IsDefined( table_cost ) && table_cost != "" )
{
cost = round_up_to_ten( int( table_cost ) );
}

if( IsDefined( table_ammo_cost ) && table_ammo_cost != "" )
{
ammo_cost = round_up_to_ten( int( table_ammo_cost ) );
}

PrecacheItem( weapon_name );
PrecacheString( hint );

struct = SpawnStruct();

if( !IsDefined( level.zombie_weapons ) )
{
level.zombie_weapons = ;
}

struct.weapon_name = weapon_name;
struct.weapon_classname = "weapon_" + weapon_name;
struct.hint = hint;
struct.cost = cost;
struct.sound = weaponVO;
struct.variation_count = variation_count;
struct.is_in_box = level.zombie_include_weapons[weapon_name];

if( !IsDefined( ammo_cost ) )
{
ammo_cost = round_up_to_ten( int( cost * 0.5 ) );
}

struct.ammo_cost = ammo_cost;

level.zombie_weapons[weapon_name] = struct;
}

default_weighting_func()
{
return 1;
}

default_tesla_weighting_func()
{
num_to_add = 1;
if( isDefined( level.pulls_since_last_tesla_gun ) )
{
// player has dropped the tesla for another weapon, so we set all future polls to 20%
if( isDefined(level.player_drops_tesla_gun) && level.player_drops_tesla_gun == true )
{
num_to_add += int(.2 * level.zombie_include_weapons.size);
}
 
// player has not seen tesla gun in late rounds
if( !isDefined(level.player_seen_tesla_gun) || level.player_seen_tesla_gun == false )
{
// after round 10 the Tesla gun percentage increases to 20%
if( level.round_number > 10 )
{
num_to_add += int(.2 * level.zombie_include_weapons.size);
}
// after round 5 the Tesla gun percentage increases to 15%
else if( level.round_number > 5 )
{
// calculate the number of times we have to add it to the array to get the desired percent
num_to_add += int(.15 * level.zombie_include_weapons.size);
}
}
}
return num_to_add;
}

default_ray_gun_weighting_func()
{
if( level.box_moved == true )
{
num_to_add = 1;
// increase the percentage of ray gun
if( isDefined( level.pulls_since_last_ray_gun ) )
{
// after 12 pulls the ray gun percentage increases to 15%
if( level.pulls_since_last_ray_gun > 11 )
{
num_to_add += int(level.zombie_include_weapons.size*0.15);
}
// after 8 pulls the Ray Gun percentage increases to 10%
else if( level.pulls_since_last_ray_gun > 7 )
{
num_to_add += int(.1 * level.zombie_include_weapons.size);
}
}
return num_to_add;
}
else
{
return 0;
}
}


//
// Slightly elevate the chance to get it until someone has it, then make it even
default_cymbal_monkey_weighting_func()
{
players = get_players();
count = 0;
for( i = 0; i < players.size; i++ )
{
if( players[i] has_weapon_or_upgrade( "zombie_cymbal_monkey" ) )
{
count++;
}
}
if ( count > 0 )
{
return 1;
}
else
{
if( level.round_number < 10 )
{
return 3;
}
else
{
return 5;
}
}
}


include_zombie_weapon( weapon_name, in_box, weighting_func )
{
if( !IsDefined( level.zombie_include_weapons ) )
{
level.zombie_include_weapons = ;
}
if( !isDefined( in_box ) )
{
in_box = true;
}

level.zombie_include_weapons[weapon_name] = in_box;
 
if( !isDefined( weighting_func ) )
{
level.weapon_weighting_funcs[weapon_name] = maps\_zombiemode_weapons::default_weighting_func;
}
else
{
level.weapon_weighting_funcs[weapon_name] = weighting_func;
}
}

init_weapons()
{
iprintln("init_weapons");
// Zombify
PrecacheItem( "zombie_melee" );


// Pistols
add_zombie_weapon( "colt", &"ZOMBIE_WEAPON_COLT_50", 50, "vox_crappy", 8 );
add_zombie_weapon( "colt_dirty_harry", &"ZOMBIE_WEAPON_COLT_DH_100", 100, "vox_357", 5 );
add_zombie_weapon( "zombie_sw_357", &"ZOMBIE_WEAPON_SW357_100", 100, "vox_357", 5 );
add_zombie_weapon( "zombie_sw_357_upgraded", &"ZOMBIE_WEAPON_SW357_100", 100, "vox_357", 5 );
add_zombie_weapon( "zombie_colt", &"ZOMBIE_WEAPON_ZOMBIECOLT_25", 25, "vox_crappy", 8 );
add_zombie_weapon( "zombie_colt_upgraded", &"ZOMBIE_WEAPON_ZOMBIECOLT_25", 25, "vox_crappy", 8 );

// Bolt Action                                     
add_zombie_weapon( "zombie_kar98k", &"ZOMBIE_WEAPON_KAR98K_200", 200, "", 0);
add_zombie_weapon( "zombie_kar98k_upgraded", &"ZOMBIE_WEAPON_KAR98K_200", 200, "", 0);
add_zombie_weapon( "zombie_springfield", &"ZOMBIE_WEAPON_SPRINGFIELD_200", 200, "", 0 );
add_zombie_weapon( "zombie_type99_rifle", &"ZOMBIE_WEAPON_TYPE99_200", 200, "", 0 );
add_zombie_weapon( "zombie_type99_rifle_upgraded", &"ZOMBIE_WEAPON_TYPE99_200", 200, "", 0 );
// Semi Auto                                       
add_zombie_weapon( "zombie_gewehr43", &"ZOMBIE_WEAPON_GEWEHR43_600", 600, "" , 0 );
add_zombie_weapon( "zombie_gewehr43_upgraded", &"ZOMBIE_WEAPON_GEWEHR43_600", 600, "" , 0 );
add_zombie_weapon( "zombie_m1carbine", &"ZOMBIE_WEAPON_M1CARBINE_600", 600, "" , 0 );
add_zombie_weapon( "zombie_m1carbine_upgraded", &"ZOMBIE_WEAPON_M1CARBINE_600", 600, "" , 0 );
add_zombie_weapon( "zombie_m1garand", &"ZOMBIE_WEAPON_M1GARAND_600", 600, "" , 0 );
add_zombie_weapon( "zombie_m1garand_upgraded", &"ZOMBIE_WEAPON_M1GARAND_600", 600, "" , 0 );

// Grenades                                         
add_zombie_weapon( "fraggrenade", &"ZOMBIE_WEAPON_FRAGGRENADE_250", 250, "" , 0 );
add_zombie_weapon( "molotov", &"ZOMBIE_WEAPON_MOLOTOV_200", 200, "vox_crappy", 8 );
add_zombie_weapon( "molotov_zombie", &"ZOMBIE_WEAPON_MOLOTOV_200", 200, "vox_crappy", 8 );
add_zombie_weapon( "stielhandgranate", &"ZOMBIE_WEAPON_STIELHANDGRANATE_250", 250, "" , 0, 250 );

// Scoped
add_zombie_weapon( "kar98k_scoped_zombie", &"ZOMBIE_WEAPON_KAR98K_S_750", 750, "vox_ppsh", 5);
add_zombie_weapon( "ptrs41_zombie", &"ZOMBIE_WEAPON_PTRS41_750", 750, "vox_ppsh", 5);
add_zombie_weapon( "ptrs41_zombie_upgraded", &"ZOMBIE_WEAPON_PTRS41_750", 750, "vox_ppsh", 5);

// Full Auto                                                                               
add_zombie_weapon( "zombie_mp40", &"ZOMBIE_WEAPON_MP40_1000", 1000, "vox_mp40", 2 );
add_zombie_weapon( "zombie_mp40_upgraded", &"ZOMBIE_WEAPON_MP40_1000", 1000, "vox_mp40", 2 );
add_zombie_weapon( "zombie_ppsh", &"ZOMBIE_WEAPON_PPSH_2000", 2000, "vox_ppsh", 5 );
add_zombie_weapon( "zombie_ppsh_upgraded", &"ZOMBIE_WEAPON_PPSH_2000", 2000, "vox_ppsh", 5 );
add_zombie_weapon( "zombie_stg44", &"ZOMBIE_WEAPON_STG44_1200", 1200, "vox_mg", 9 );
add_zombie_weapon( "zombie_stg44_upgraded", &"ZOMBIE_WEAPON_STG44_1200", 1200, "vox_mg", 9 );
add_zombie_weapon( "zombie_thompson", &"ZOMBIE_WEAPON_THOMPSON_1200", 1200, "", 0 );
add_zombie_weapon( "zombie_thompson_upgraded", &"ZOMBIE_WEAPON_THOMPSON_1200", 1200, "", 0 );
add_zombie_weapon( "zombie_type100_smg", &"ZOMBIE_WEAPON_TYPE100_1000", 1000, "", 0 );
add_zombie_weapon( "zombie_type100_smg_upgraded", &"ZOMBIE_WEAPON_TYPE100_1000", 1000, "", 0 );

// Shotguns                                         
add_zombie_weapon( "zombie_doublebarrel", &"ZOMBIE_WEAPON_DOUBLEBARREL_1200", 1200, "vox_shotgun", 6);
add_zombie_weapon( "zombie_doublebarrel_upgraded", &"ZOMBIE_WEAPON_DOUBLEBARREL_1200", 1200, "vox_shotgun", 6);
add_zombie_weapon( "zombie_doublebarrel_sawed", &"ZOMBIE_WEAPON_DOUBLEBARREL_SAWED_1200", 1200, "vox_shotgun", 6);
add_zombie_weapon( "zombie_doublebarrel_sawed_upgraded", &"ZOMBIE_WEAPON_DOUBLEBARREL_SAWED_1200", 1200, "vox_shotgun", 6);
add_zombie_weapon( "zombie_shotgun", &"ZOMBIE_WEAPON_SHOTGUN_1500", 1500, "vox_shotgun", 6);
add_zombie_weapon( "zombie_shotgun_upgraded", &"ZOMBIE_WEAPON_SHOTGUN_1500", 1500, "vox_shotgun", 6);

// Heavy Machineguns                               
add_zombie_weapon( "zombie_30cal", &"ZOMBIE_WEAPON_30CAL_3000", 3000, "vox_mg", 9 );
add_zombie_weapon( "zombie_30cal_upgraded", &"ZOMBIE_WEAPON_30CAL_3000", 3000, "vox_mg", 9 );
add_zombie_weapon( "zombie_bar", &"ZOMBIE_WEAPON_BAR_1800", 1800, "vox_bar", 5 );
add_zombie_weapon( "zombie_bar_upgraded", &"ZOMBIE_WEAPON_BAR_1800", 1800, "vox_bar", 5 );
add_zombie_weapon( "zombie_fg42", &"ZOMBIE_WEAPON_FG42_1500", 1500, "vox_mg" , 9 );
add_zombie_weapon( "zombie_fg42_upgraded", &"ZOMBIE_WEAPON_FG42_1500", 1500, "vox_mg" , 9 );
add_zombie_weapon( "zombie_mg42", &"ZOMBIE_WEAPON_MG42_3000", 3000, "vox_mg" , 9 );
add_zombie_weapon( "zombie_mg42_upgraded", &"ZOMBIE_WEAPON_MG42_3000", 3000, "vox_mg" , 9 );

// Grenade Launcher                                 
add_zombie_weapon( "m1garand_gl_zombie", &"ZOMBIE_WEAPON_M1GARAND_GL_1500", 1500, "", 0 );
add_zombie_weapon( "m1garand_gl_zombie_upgraded", &"ZOMBIE_WEAPON_M1GARAND_GL_1500", 1500, "", 0 );

// Rocket Launchers
add_zombie_weapon( "panzerschrek_zombie", &"ZOMBIE_WEAPON_PANZERSCHREK_2000", 2000, "vox_panzer", 5 );
add_zombie_weapon( "panzerschrek_zombie_upgraded", &"ZOMBIE_WEAPON_PANZERSCHREK_2000", 2000, "vox_panzer", 5 );

// Flamethrower                                     
add_zombie_weapon( "m2_flamethrower_zombie", &"ZOMBIE_WEAPON_M2_FLAMETHROWER_3000", 3000, "vox_flame", 7);
add_zombie_weapon( "m2_flamethrower_zombie_upgraded", &"ZOMBIE_WEAPON_M2_FLAMETHROWER_3000", 3000, "vox_flame", 7);

// Special                                         
add_zombie_weapon( "mine_bouncing_betty", &"ZOMBIE_WEAPON_SATCHEL_2000", 2000, "" );
add_zombie_weapon( "zombie_cymbal_monkey", &"ZOMBIE_WEAPON_SATCHEL_2000", 2000, "vox_monkey", 3 );
add_zombie_weapon( "ray_gun", &"ZOMBIE_WEAPON_RAYGUN_10000", 10000, "vox_raygun", 6 );
add_zombie_weapon( "ray_gun_upgraded", &"ZOMBIE_WEAPON_RAYGUN_10000", 10000, "vox_raygun", 6 );
add_zombie_weapon( "tesla_gun", &"ZOMBIE_BUY_TESLA", 10, "vox_tesla", 5 );
add_zombie_weapon( "tesla_gun_upgraded", &"ZOMBIE_BUY_TESLA", 10, "vox_tesla", 5 );

if(level.script != "nazi_zombie_prototype")
{
Precachemodel("zombie_teddybear");
}
// ONLY 1 OF THE BELOW SHOULD BE ALLOWED
add_limited_weapon( "m2_flamethrower_zombie", 1 );
add_limited_weapon( "tesla_gun", 1);
}   

//remove this function and whenever it's call for production. this is only for testing purpose.
add_limited_tesla_gun()
{

weapon_spawns = GetEntArray( "weapon_upgrade", "targetname" );

for( i = 0; i < weapon_spawns.size; i++ )
{
hint_string = weapon_spawns[i].zombie_weapon_upgrade;
if(hint_string == "tesla_gun")
{
weapon_spawns[i] waittill("trigger");
weapon_spawns[i] trigger_off();
break;

}
 
}

}


add_limited_weapon( weapon_name, amount )
{
if( !IsDefined( level.limited_weapons ) )
{
level.limited_weapons = ;
}

level.limited_weapons[weapon_name] = amount;
}                                         

// For pay turrets
init_pay_turret()
{
pay_turrets = ;
pay_turrets = GetEntArray( "pay_turret", "targetname" );
 
for( i = 0; i < pay_turrets.size; i++ )
{
cost = level.pay_turret_cost;
if( !isDefined( cost ) )
{
cost = 1000;
}
pay_turrets[i] SetHintString( &"ZOMBIE_PAY_TURRET", cost );
pay_turrets[i] SetCursorHint( "HINT_NOICON" );
pay_turrets[i] UseTriggerRequireLookAt();
 
pay_turrets[i] thread pay_turret_think( cost );
}
}

// For buying weapon upgrades in the environment
init_weapon_upgrade()
{
weapon_spawns = ;
weapon_spawns = GetEntArray( "weapon_upgrade", "targetname" );

for( i = 0; i < weapon_spawns.size; i++ )
{
hint_string = get_weapon_hint( weapon_spawns[i].zombie_weapon_upgrade );

weapon_spawns[i] SetHintString( hint_string );
weapon_spawns[i] setCursorHint( "HINT_NOICON" );
weapon_spawns[i] UseTriggerRequireLookAt();

weapon_spawns[i] thread weapon_spawn_think();
model = getent( weapon_spawns[i].target, "targetname" );
model hide();
}
}

// weapon cabinets which open on use
init_weapon_cabinet()
{
// the triggers which are targeted at doors
weapon_cabs = GetEntArray( "weapon_cabinet_use", "targetname" );

for( i = 0; i < weapon_cabs.size; i++ )
{

weapon_cabs[i] SetHintString( &"ZOMBIE_CABINET_OPEN_1500" );
weapon_cabs[i] setCursorHint( "HINT_NOICON" );
weapon_cabs[i] UseTriggerRequireLookAt();
}

array_thread( weapon_cabs, ::weapon_cabinet_think );
}

// returns the trigger hint string for the given weapon
get_weapon_hint( weapon_name )
{
AssertEx( IsDefined( level.zombie_weapons[weapon_name] ), weapon_name + " was not included or is not part of the zombie weapon list." );

return level.zombie_weapons[weapon_name].hint;
}

get_weapon_cost( weapon_name )
{
AssertEx( IsDefined( level.zombie_weapons[weapon_name] ), weapon_name + " was not included or is not part of the zombie weapon list." );

return level.zombie_weapons[weapon_name].cost;
}

get_ammo_cost( weapon_name )
{
AssertEx( IsDefined( level.zombie_weapons[weapon_name] ), weapon_name + " was not included or is not part of the zombie weapon list." );

return level.zombie_weapons[weapon_name].ammo_cost;
}

get_is_in_box( weapon_name )
{
AssertEx( IsDefined( level.zombie_weapons[weapon_name] ), weapon_name + " was not included or is not part of the zombie weapon list." );
 
return level.zombie_weapons[weapon_name].is_in_box;
}

is_weapon_upgraded( weaponname )
{
if( !isdefined( weaponname ) )
{
return false;
}

weaponname = ToLower( weaponname );

upgraded = issubstr( weaponname, "_upgraded" );

return upgraded;

}

has_upgrade( weaponname )
{
has_upgrade = false;
if( IsDefined( level.zombie_include_weapons[weaponname+"_upgraded"] ) )
{
has_upgrade = self HasWeapon( weaponname+"_upgraded" );
}
return has_upgrade;
}

has_weapon_or_upgrade( weaponname )
{
has_weapon = false;
if (self maps\_laststand::player_is_in_laststand())
{
for( m = 0; m < self.weaponInventory.size; m++ )
{
if (self.weaponInventory[m] == weaponname || self.weaponInventory[m] == weaponname+"_upgraded" )
{
has_weapon = true;
}
}
}
else
{
// If the weapon you're checking doesn't exist, it will return undefined
if( IsDefined( level.zombie_include_weapons[weaponname] ) )
{
has_weapon = self HasWeapon( weaponname );
}
 
if( !has_weapon && isdefined( level.zombie_include_weapons[weaponname+"_upgraded"] ) )
{
has_weapon = self HasWeapon( weaponname+"_upgraded" );
}
}

return has_weapon;
}

using_weapon_or_upgrade( weaponname )
{
if( self GetCurrentWeapon() == weaponname || self GetCurrentWeapon() == weaponname+"_upgraded" )
{
return true;
}
return false;
}

// for the random weapon chest
treasure_chest_init()
{
flag_init("moving_chest_enabled");
flag_init("moving_chest_now");
 
 
level.chests = GetEntArray( "treasure_chest_use", "targetname" );

if (level.chests.size > 1)
{

flag_set("moving_chest_enabled");
 
while ( 1 )
{
level.chests = array_randomize(level.chests);

if( isdefined( level.random_pandora_box_start ) )
break;
   
if ( !IsDefined( level.chests[0].script_noteworthy ) || ( level.chests[0].script_noteworthy != "start_chest" ) )
{
break;
}

}
 
level.chest_index = 0;

while(level.chest_index < level.chests.size)
{
 
if( isdefined( level.random_pandora_box_start ) )
break;

            if(level.chests[level.chest_index].script_noteworthy == "start_chest")
            {
                 break;
            }
           
            level.chest_index++;     
      }

//init time chest accessed amount.
 
if(level.script != "nazi_zombie_prototype")
{
level.chest_accessed = 0;
}

if(isDefined(level.DLC3.usePandoraBoxLight) && level.DLC3.usePandoraBoxLight)
{
// Anchor target will grab the weapon spawn point inside the box, so the fx will be centered on it too
anchor = GetEnt(level.chests[level.chest_index].target, "targetname");
anchorTarget = GetEnt(anchor.target, "targetname");

level.pandora_light = Spawn( "script_model", anchorTarget.origin );
level.pandora_light.angles = anchorTarget.angles + (-90, 0, 0);
//temp_fx_origin rotateto((-90, (box_origin.angles[1] * -1), 0), 0.05);
level.pandora_light SetModel( "tag_origin" );
playfxontag(level._effect["lght_marker"], level.pandora_light, "tag_origin");
}
// DCS: we need a smaller light in the catacombs for paris, the generic one fills the area under the tower.
else if(level.script == "nazi_zombie_paris")
{
// Anchor target will grab the weapon spawn point inside the box, so the fx will be centered on it too
anchor = GetEnt(level.chests[level.chest_index].target, "targetname");
anchorTarget = GetEnt(anchor.target, "targetname");

level.pandora_light = Spawn( "script_model", anchorTarget.origin );
level.pandora_light.angles = (-90, 0, 0);
level.pandora_light SetModel( "tag_origin" );
//playfxontag(level._effect["lght_marker"], level.pandora_light, "tag_origin");
}
 
//determine magic box starting location at random or normal
init_starting_chest_location();
 
}

array_thread( level.chests, ::treasure_chest_think );

}

init_starting_chest_location()
{

for( i = 0; i < level.chests.size; i++ )
{

if( isdefined( level.random_pandora_box_start ) && level.random_pandora_box_start == true )
{
if( i != 0 )
{
level.chests[i] hide_chest();
}
else
{
level.chest_index = i;
unhide_magic_box( i );
}

}
else
{
if ( !IsDefined(level.chests[i].script_noteworthy ) || ( level.chests[i].script_noteworthy != "start_chest" ) )
{
level.chests[i] hide_chest();
}
else
{
level.chest_index = i;
unhide_magic_box( i );
}
}
}


}

unhide_magic_box( index )
{
 
//PI CHANGE - altered to allow for more than one piece of rubble
rubble = getentarray( level.chests[index].script_noteworthy + "_rubble", "script_noteworthy" );
if ( IsDefined( rubble ) )
{
for ( x = 0; x < rubble.size; x++ )
{
rubble[x] hide();
}
//END PI CHANGE
}
else
{
println( "^3Warning: No rubble found for magic box" );
}
}

set_treasure_chest_cost( cost )
{
level.zombie_treasure_chest_cost = cost;
}

hide_chest()
{
pieces = self get_chest_pieces();

for(i=0;i<pieces.size;i++)
{
pieces[i] disable_trigger();
pieces[i] hide();
}
}

get_chest_pieces()
{
// self = trigger

lid = GetEnt(self.target, "targetname");
org = GetEnt(lid.target, "targetname");
box = GetEnt(org.target, "targetname");

pieces = ;
pieces[pieces.size] = self;
pieces[pieces.size] = lid;
pieces[pieces.size] = org;
pieces[pieces.size] = box;

return pieces;
}

play_crazi_sound()
{
self playlocalsound("laugh_child");
}

show_magic_box()
{
pieces = self get_chest_pieces();
for(i=0;i<pieces.size;i++)
{
pieces[i] enable_trigger();
}
 
// PI_CHANGE_BEGIN - JMA - we want to play another effect on swamp
anchor = GetEnt(self.target, "targetname");
anchorTarget = GetEnt(anchor.target, "targetname");

if(isDefined(level.DLC3.usePandoraBoxLight) && level.DLC3.usePandoraBoxLight != true )
{
playfx( level._effect["poltergeist"],pieces[0].origin);
}
else
{
level.pandora_light.angles = (-90, anchorTarget.angles[1] + 180, 0);
level.pandora_light moveto(anchorTarget.origin, 0.05);
wait(1);
playfx( level._effect["lght_marker_flare"],level.pandora_light.origin );
// playfxontag(level._effect["lght_marker_flare"], level.pandora_light, "tag_origin");
}
// PI_CHANGE_END
 
playsoundatposition( "box_poof", pieces[0].origin );
wait(.5);
for(i=0;i<pieces.size;i++)
{
if( pieces[i].classname != "trigger_use" )
{
pieces[i] show();
}
}
pieces[0] playsound ( "box_poof_land" );
pieces[0] playsound( "couch_slam" );
}

treasure_chest_think()
{
cost = 950;
if( IsDefined( level.zombie_treasure_chest_cost ) )
{
cost = level.zombie_treasure_chest_cost;
}
else
{
cost = self.zombie_cost;
}

self set_hint_string( self, "default_treasure_chest_" + cost );
self setCursorHint( "HINT_NOICON" );

//self thread decide_hide_show_chest_hint( "move_imminent" );

// waittill someuses uses this
user = undefined;
while( 1 )
{
self waittill( "trigger", user );

if( user in_revive_trigger() )
{
wait( 0.1 );
continue;
}

// make sure the user is a player, and that they can afford it
if( is_player_valid( user ) && user.score >= cost )
{
user maps\_zombiemode_score::minus_to_player_score( cost );
break;
}
else if ( user.score < cost )
{
user thread maps\_zombiemode_perks::play_no_money_perk_dialog();
continue;
}

wait 0.05;
}

// trigger_use->script_brushmodel lid->script_origin in radiant
lid = getent( self.target, "targetname" );
weapon_spawn_org = getent( lid.target, "targetname" );

//open the lid
lid thread treasure_chest_lid_open();

// SRS 9/3/2008: added to help other functions know if we timed out on grabbing the item
self.timedOut = false;

// mario kart style weapon spawning
weapon_spawn_org thread treasure_chest_weapon_spawn( self, user );

// the glowfx
weapon_spawn_org thread treasure_chest_glowfx();

// take away usability until model is done randomizing
self disable_trigger();

weapon_spawn_org waittill( "randomization_done" );

if (flag("moving_chest_now"))
{
user thread treasure_chest_move_vo();
self treasure_chest_move(lid);

}
else
{
// Let the player grab the weapon and re-enable the box //
self.grab_weapon_hint = true;
self.chest_user = user;
self sethintstring( &"ZOMBIE_TRADE_WEAPONS" );
self setCursorHint( "HINT_NOICON" );
self setvisibletoplayer( user );

// Limit its visibility to the player who bought the box
self enable_trigger();
self thread treasure_chest_timeout();

// make sure the guy that spent the money gets the item
// SRS 9/3/2008: ...or item goes back into the box if we time out
while( 1 )
{
self waittill( "trigger", grabber );

if( grabber == user || grabber == level )
{


if( grabber == user && is_player_valid( user ) && user GetCurrentWeapon() != "mine_bouncing_betty" )
{
bbPrint( "zombie_uses: playername %s playerscore %d round %d cost %d name %s x %f y %f z %f type magic_accept",
user.playername, user.score, level.round_number, cost, weapon_spawn_org.weapon_string, self.origin );
self notify( "user_grabbed_weapon" );
user thread treasure_chest_give_weapon( weapon_spawn_org.weapon_string );
break;
}
else if( grabber == level )
{
// it timed out
self.timedOut = true;
bbPrint( "zombie_uses: playername %s playerscore %d round %d cost %d name %s x %f y %f z %f type magic_reject",
user.playername, user.score, level.round_number, cost, weapon_spawn_org.weapon_string, self.origin );
break;
}
}

wait 0.05;
}

self.grab_weapon_hint = false;
self.chest_user = undefined;

weapon_spawn_org notify( "weapon_grabbed" );

//increase counter of amount of time weapon grabbed.
if(level.script != "nazi_zombie_prototype")
{
level.chest_accessed += 1;
 
// PI_CHANGE_BEGIN
// JMA - we only update counters when it's available
if( isDefined(level.DLC3.useChestPulls) && level.DLC3.useChestPulls )
{
level.pulls_since_last_ray_gun += 1;
}
 
if( isDefined(level.DLC3.useChestPulls) && level.DLC3.useChestPulls )
{
level.pulls_since_last_tesla_gun += 1;
}
// PI_CHANGE_END
}
self disable_trigger();

// spend cash here...
// give weapon here...
lid thread treasure_chest_lid_close( self.timedOut );

//Chris_P
//magic box dissapears and moves to a new spot after a predetermined number of uses

wait 3;
self enable_trigger();
self setvisibletoall();
}

flag_clear("moving_chest_now");
self thread treasure_chest_think();
}


//
// Disable trigger if can't buy weapon and also if someone else is using the chest
decide_hide_show_chest_hint( endon_notify )
{
if( isDefined( endon_notify ) )
{
self endon( endon_notify );
}

while( true )
{
players = get_players();
for( i = 0; i < players.size; i++ )
{
// chest_user defined if someone bought a weapon spin, false when chest closed
if ( (IsDefined(self.chest_user) && players[i] != self.chest_user ) ||
!players[i] can_buy_weapon() )
{
self SetInvisibleToPlayer( players[i], true );
}
else
{
self SetInvisibleToPlayer( players[i], false );
}
}
wait( 0.1 );
}
}

decide_hide_show_hint( endon_notify )
{
if( isDefined( endon_notify ) )
{
self endon( endon_notify );
}

while( true )
{
players = get_players();
for( i = 0; i < players.size; i++ )
{
if( players[i] can_buy_weapon() )
{
self SetInvisibleToPlayer( players[i], false );
}
else
{
self SetInvisibleToPlayer( players[i], true );
}
}
wait( 0.1 );
}
}

can_buy_weapon()
{
if( isDefined( self.is_drinking ) && self.is_drinking )
{
return false;
}
if( self GetCurrentWeapon() == "mine_bouncing_betty" )
{
return false;
}
if( self in_revive_trigger() )
{
return false;
}
 
return true;
}

treasure_chest_move_vo()
{

self endon("disconnect");

index = maps\_zombiemode_weapons::get_player_index(self);
sound = undefined;

if(!isdefined (level.player_is_speaking))
{
level.player_is_speaking = 0;
}
variation_count = 5;
sound = "plr_" + index + "_vox_box_move" + "_" + randomintrange(0, variation_count);


//This keeps multiple voice overs from playing on the same player (both killstreaks and headshots).
if (level.player_is_speaking != 1 && isDefined(sound))
{
level.player_is_speaking = 1;
self playsound(sound, "sound_done");
self waittill("sound_done");
level.player_is_speaking = 0;
}

}


treasure_chest_move(lid)
{
level waittill("weapon_fly_away_start");

players = get_players();
 
array_thread(players, ::play_crazi_sound);

level waittill("weapon_fly_away_end");

lid thread treasure_chest_lid_close(false);
self setvisibletoall();

fake_pieces = ;
pieces = self get_chest_pieces();

for(i=0;i<pieces.size;i++)
{
if(pieces[i].classname == "script_model")
{
fake_pieces[fake_pieces.size] = spawn("script_model",pieces[i].origin);
fake_pieces[fake_pieces.size - 1].angles = pieces[i].angles;
fake_pieces[fake_pieces.size - 1] setmodel(pieces[i].model);
pieces[i] disable_trigger();
pieces[i] hide();
}
else
{
pieces[i] disable_trigger();
pieces[i] hide();
}
}

anchor = spawn("script_origin",fake_pieces[0].origin);
soundpoint = spawn("script_origin", anchor.origin);
    playfx( level._effect["poltergeist"],anchor.origin);

anchor playsound("box_move");
for(i=0;i<fake_pieces.size;i++)
{
fake_pieces[i] linkto(anchor);
}

playsoundatposition ("whoosh", soundpoint.origin );
playsoundatposition ("ann_vox_magicbox", soundpoint.origin );


anchor moveto(anchor.origin + (0,0,50),5);
//anchor rotateyaw(360 * 10,5,5);
if(level.chests[level.chest_index].script_noteworthy == "magic_box_south" || level.chests[level.chest_index].script_noteworthy == "magic_box_bathroom" || level.chests[level.chest_index].script_noteworthy == "magic_box_hallway")
{
anchor Vibrate( (50, 0, 0), 10, 0.5, 5 );
}
else if(level.script != "nazi_zombie_sumpf")
{
anchor Vibrate( (0, 50, 0), 10, 0.5, 5 );
}
else
{
   //Get the normal of the box using the positional data of the box and lid
   direction = pieces[3].origin - pieces[1].origin;
   direction = (direction[1], direction[0], 0);
   
   if(direction[1] < 0 || (direction[0] > 0 && direction[1] > 0))
   {
            direction = (direction[0], direction[1] * -1, 0);
       }
       else if(direction[0] < 0)
       {
            direction = (direction[0] * -1, direction[1], 0);
       }
   
        anchor Vibrate( direction, 10, 0.5, 5);
}
 
//anchor thread rotateroll_box();
anchor waittill("movedone");
//players = get_players();
//array_thread(players, ::play_crazi_sound);
//wait(3.9);
 
playfx(level._effect["poltergeist"], anchor.origin);
 
//TUEY - Play the 'disappear' sound
playsoundatposition ("box_poof", soundpoint.origin);
for(i=0;i<fake_pieces.size;i++)
{
fake_pieces[i] delete();
}


//gzheng-Show the rubble
//PI CHANGE - allow for more than one object of rubble per box
rubble = getentarray(self.script_noteworthy + "_rubble", "script_noteworthy");
 
if ( IsDefined( rubble ) )
{
for (i = 0; i < rubble.size; i++)
{
rubble[i] show();
}
}
else
{
println( "^3Warning: No rubble found for magic box" );
}

wait(0.1);
anchor delete();
soundpoint delete();

old_chest_index = level.chest_index;

wait(5);

//chest moving logic
//PI CHANGE - for sumpf, this doesn't work because chest_index is always incremented twice (here and line 724) - while this would work with an odd number of chests,
//      with an even number it skips half of the chest locations in the map

level.verify_chest = false;
//wait(3);
//make sure level is asylum, factory, or sumpf and make magic box only appear in location player have open, it's off by default
//also make sure box doesn't respawn in old location.
//PI WJB: removed check on "magic_box_explore_only" dvar because it is only ever used here and when it is set in _zombiemode.gsc line 446
// where it is declared and set to 0, causing this while loop to never happen because the check was to see if it was equal to 1
if( isDefined(level.DLC3.useChestMoves) && level.DLC3.useChestMoves)
{
level.chest_index++;

/* while(level.chests[level.chest_index].origin == level.chests[old_chest_index].origin)
{
level.chest_index++;
}*/

if (level.chest_index >= level.chests.size)
{
//PI CHANGE - this way the chests won't move in the same order the second time around
temp_chest_name = level.chests[level.chest_index - 1].script_noteworthy;
level.chest_index = 0;
level.chests = array_randomize(level.chests);
//in case it happens to randomize in such a way that the chest_index now points to the same location
// JMA - want to avoid an infinite loop, so we use an if statement
if (temp_chest_name == level.chests[level.chest_index].script_noteworthy)
{
level.chest_index++;
}
//END PI CHANGE
}

//verify_chest_is_open();
wait(0.01);
 
}
level.chests[level.chest_index] show_magic_box();
 
//turn off magic box light.
level notify("magic_box_light_switch");
//PI CHANGE - altered to allow for more than one object of rubble per box
unhide_magic_box( level.chest_index );
 
}

rotateroll_box()
{
angles = 40;
angles2 = 0;
//self endon("movedone");
while(isdefined(self))
{
self RotateRoll(angles + angles2, 0.5);
wait(0.7);
angles2 = 40;
self RotateRoll(angles * -2, 0.5);
wait(0.7);
}
 


}
//verify if that magic box is open to players or not.
verify_chest_is_open()
{

//for(i = 0; i < 5; i++)
//PI CHANGE - altered so that there can be more than 5 valid chest locations
for (i = 0; i < level.open_chest_location.size; i++)
{
if(isdefined(level.open_chest_location[i]))
{
if(level.open_chest_location[i] == level.chests[level.chest_index].script_noteworthy)
{
level.verify_chest = true;
return;
}
}

}

level.verify_chest = false;


}


treasure_chest_timeout()
{
self endon( "user_grabbed_weapon" );

wait( 12 );
self notify( "trigger", level );
}

treasure_chest_lid_open()
{
openRoll = 105;
openTime = 0.5;

self RotateRoll( 105, openTime, ( openTime * 0.5 ) );

play_sound_at_pos( "open_chest", self.origin );
play_sound_at_pos( "music_chest", self.origin );
}

treasure_chest_lid_close( timedOut )
{
closeRoll = -105;
closeTime = 0.5;

self RotateRoll( closeRoll, closeTime, ( closeTime * 0.5 ) );
play_sound_at_pos( "close_chest", self.origin );
}

treasure_chest_ChooseRandomWeapon( player )
{

keys = GetArrayKeys( level.zombie_weapons );

// Filter out any weapons the player already has
filtered = ;
for( i = 0; i < keys.size; i++ )
{
if( !get_is_in_box( keys[i] ) )
{
continue;
}
 
if( player has_weapon_or_upgrade( keys[i] ) )
{
continue;
}

if( !IsDefined( keys[i] ) )
{
continue;
}

filtered[filtered.size] = keys[i];
}
 
// Filter out the limited weapons
if( IsDefined( level.limited_weapons ) )
{
keys2 = GetArrayKeys( level.limited_weapons );
players = get_players();
pap_triggers = GetEntArray("zombie_vending_upgrade", "targetname");
for( q = 0; q < keys2.size; q++ )
{
count = 0;
for( i = 0; i < players.size; i++ )
{
if( players[i] has_weapon_or_upgrade( keys2[q] ) )
{
count++;
}
}

// Check the pack a punch machines to see if they are holding what we're looking for
for ( k=0; k<pap_triggers.size; k++ )
{
if ( IsDefined(pap_triggers[k].current_weapon) && pap_triggers[k].current_weapon == keys2[q] )
{
count++;
}
}

if( count >= level.limited_weapons[keys2[q]] )
{
filtered = array_remove( filtered, keys2[q] );
}
}
}

return filtered[RandomInt( filtered.size )];
}

treasure_chest_ChooseWeightedRandomWeapon( player )
{

keys = GetArrayKeys( level.zombie_weapons );

// Filter out any weapons the player already has
filtered = ;
for( i = 0; i < keys.size; i++ )
{
if( !get_is_in_box( keys[i] ) )
{
continue;
}
 
if( player has_weapon_or_upgrade( keys[i] ) )
{
continue;
}

if( !IsDefined( keys[i] ) )
{
continue;
}

num_entries = [[ level.weapon_weighting_funcs[keys[i]] ]]();
 
for( j = 0; j < num_entries; j++ )
{
filtered[filtered.size] = keys[i];
}
}
 
// Filter out the limited weapons
if( IsDefined( level.limited_weapons ) )
{
keys2 = GetArrayKeys( level.limited_weapons );
players = get_players();
pap_triggers = GetEntArray("zombie_vending_upgrade", "targetname");
for( q = 0; q < keys2.size; q++ )
{
count = 0;
for( i = 0; i < players.size; i++ )
{
if( players[i] has_weapon_or_upgrade( keys2[q] ) )
{
count++;
}
}

// Check the pack a punch machines to see if they are holding what we're looking for
for ( k=0; k<pap_triggers.size; k++ )
{
if ( IsDefined(pap_triggers[k].current_weapon) && pap_triggers[k].current_weapon == keys2[q] )
{
count++;
}
}

if( count >= level.limited_weapons[keys2[q]] )
{
filtered = array_remove( filtered, keys2[q] );
}
}
}
 
return filtered[RandomInt( filtered.size )];
}

treasure_chest_weapon_spawn( chest, player )
{
assert(IsDefined(player));
// spawn the model
model = spawn( "script_model", self.origin );
model.angles = self.angles +( 0, 90, 0 );

floatHeight = 40;

//move it up
model moveto( model.origin +( 0, 0, floatHeight ), 3, 2, 0.9 );

// rotation would go here

// make with the mario kart
modelname = undefined;
rand = undefined;
number_cycles = 40;
for( i = 0; i < number_cycles; i++ )
{

if( i < 20 )
{
wait( 0.05 );
}
else if( i < 30 )
{
wait( 0.1 );
}
else if( i < 35 )
{
wait( 0.2 );
}
else if( i < 38 )
{
wait( 0.3 );
}

if( i+1 < number_cycles )
{
rand = treasure_chest_ChooseRandomWeapon( player );
}
else
{
rand = treasure_chest_ChooseWeightedRandomWeapon( player );
}

/#
if( maps\_zombiemode_tesla::tesla_gun_exists() )
{
if ( i == 39 && GetDvar( "scr_spawn_tesla" ) != "" )
{
SetDvar( "scr_spawn_tesla", "" );
rand = "tesla_gun";
}
}
#/

modelname = GetWeaponModel( rand );
model setmodel( modelname );


}

self.weapon_string = rand; // here's where the org get it's weapon type for the give function

// random change of getting the joker that moves the box
random = Randomint(100);

if( !isdefined( level.chest_min_move_usage ) )
{
level.chest_min_move_usage = 4;
}

//increase the chance of joker appearing from 0-100 based on amount of the time chest has been opened.
if(level.script != "nazi_zombie_prototype" && getdvar("magic_chest_movable") == "1")
{

if(level.chest_accessed < level.chest_min_move_usage)
{
// PI_CHANGE_BEGIN - JMA - RandomInt(100) can return a number between 0-99.  If it's zero and chance_of_joker is zero
// we can possibly have a teddy bear one after another.
chance_of_joker = -1;
// PI_CHANGE_END
}
else
{
chance_of_joker = level.chest_accessed + 20;
 
// make sure teddy bear appears on the 8th pull if it hasn't moved from the initial spot
if( (!isDefined(level.magic_box_first_move) || level.magic_box_first_move == false ) && level.chest_accessed >= 8)
{
chance_of_joker = 100;
}
 
// pulls 4 thru 8, there is a 15% chance of getting the teddy bear
// NOTE:  this happens in all cases
if( level.chest_accessed >= 4 && level.chest_accessed < 8 )
{
if( random < 15 )
{
chance_of_joker = 100;
}
else
{
chance_of_joker = -1;
}
}
 
// after the first magic box move the teddy bear percentages changes
if( isDefined(level.magic_box_first_move) && level.magic_box_first_move == true )
{
// between pulls 8 thru 12, the teddy bear percent is 30%
if( level.chest_accessed >= 8 && level.chest_accessed < 13 )
{
if( random < 30 )
{
chance_of_joker = 100;
}
else
{
chance_of_joker = -1;
}
}
 
// after 12th pull, the teddy bear percent is 50%
if( level.chest_accessed >= 13 )
{
if( random < 50 )
{
chance_of_joker = 100;
}
else
{
chance_of_joker = -1;
}
}
}
}

if (random <= chance_of_joker)
{
model SetModel("zombie_teddybear");
// model rotateto(level.chests[level.chest_index].angles, 0.01);
//wait(1);
model.angles = self.angles;
wait 1;
flag_set("moving_chest_now");
self notify( "move_imminent" );
level.chest_accessed = 0;

player maps\_zombiemode_score::add_to_player_score( 950 );

//allow power weapon to be accessed.
level.box_moved = true;
}
}

self notify( "randomization_done" );

if (flag("moving_chest_now"))
{
wait .5; // we need a wait here before this notify
level notify("weapon_fly_away_start");
wait 2;
model MoveZ(500, 4, 3);
model waittill("movedone");
model delete();
self notify( "box_moving" );
level notify("weapon_fly_away_end");
}
else
{

//turn off power weapon, since player just got one
if( rand == "tesla_gun" || rand == "ray_gun" )
{
// PI_CHANGE_BEGIN - JMA - reset the counters for tesla gun and ray gun pulls
if(isDefined(level.DLC3.useWeaponSpawn) && level.DLC3.useWeaponSpawn )
{
if( rand == "ray_gun" )
{
level.box_moved = false;
level.pulls_since_last_ray_gun = 0;
}
 
if( rand == "tesla_gun" )
{
level.pulls_since_last_tesla_gun = 0;
level.player_seen_tesla_gun = true;
}
}
else
{
level.box_moved = false;
}
// PI_CHANGE_END
}

model thread timer_til_despawn(floatHeight);
self waittill( "weapon_grabbed" );

if( !chest.timedOut )
{
model Delete();
}


}
}
timer_til_despawn(floatHeight)
{


// SRS 9/3/2008: if we timed out, move the weapon back into the box instead of deleting it
putBackTime = 12;
self MoveTo( self.origin - ( 0, 0, floatHeight ), putBackTime, ( putBackTime * 0.5 ) );
wait( putBackTime );

if(isdefined(self))
{
self Delete();
}
}

treasure_chest_glowfx()
{
fxObj = spawn( "script_model", self.origin +( 0, 0, 0 ) );
fxobj setmodel( "tag_origin" );
fxobj.angles = self.angles +( 90, 0, 0 );

playfxontag( level._effect["chest_light"], fxObj, "tag_origin"  );

self waittill_any( "weapon_grabbed", "box_moving" );

fxobj delete();
}

// self is the player string comes from the randomization function
treasure_chest_give_weapon( weapon_string )
{
primaryWeapons = self GetWeaponsListPrimaries();
current_weapon = undefined;

if( self HasWeapon( weapon_string ) )
{
self GiveMaxAmmo( weapon_string );
self SwitchToWeapon( weapon_string );
return;
}

// This should never be true for the first time.
if( primaryWeapons.size >= 2 ) // he has two weapons
{
current_weapon = self getCurrentWeapon(); // get hiss current weapon

if ( current_weapon == "mine_bouncing_betty" )
{
current_weapon = undefined;
}

if( isdefined( current_weapon ) )
{
if( !( weapon_string == "fraggrenade" || weapon_string == "stielhandgranate" || weapon_string == "molotov" || weapon_string == "zombie_cymbal_monkey" ) )
{
// PI_CHANGE_BEGIN
// JMA - player dropped the tesla gun
if( isDefined(level.DLC3.useGiveWeapon) && level.DLC3.useGiveWeapon)
{
if( current_weapon == "tesla_gun" )
{
level.player_drops_tesla_gun = true;
}
}
// PI_CHANGE_END
 
self TakeWeapon( current_weapon );
}
}
}

if( IsDefined( primaryWeapons ) && !isDefined( current_weapon ) )
{
for( i = 0; i < primaryWeapons.size; i++ )
{
if( primaryWeapons[i] == "zombie_colt" )
{
continue;
}

if( weapon_string != "fraggrenade" && weapon_string != "stielhandgranate" && weapon_string != "molotov" && weapon_string != "zombie_cymbal_monkey" )
{
// PI_CHANGE_BEGIN
// JMA - player dropped the tesla gun
if( isDefined(level.DLC3.useGiveWeapon) && level.DLC3.useGiveWeapon )
{
if( primaryWeapons[i] == "tesla_gun" )
{
level.player_drops_tesla_gun = true;
}
}
// PI_CHANGE_END
 
self TakeWeapon( primaryWeapons[i] );
}
}
}

self play_sound_on_ent( "purchase" );

if( weapon_string == "molotov" || weapon_string == "molotov_zombie" )
{
// PI_CHANGE_BEGIN
// JMA 051409 sanity check to see if we have the weapon before we remove it
has_weapon = self HasWeapon( "zombie_cymbal_monkey" );
if( isDefined(has_weapon) && has_weapon )
{
self TakeWeapon( "zombie_cymbal_monkey" );
}
// PI_CHANGE_END
}
if( weapon_string == "zombie_cymbal_monkey" )
{
// PI_CHANGE_BEGIN
// JMA 051409 sanity check to see if we have the weapon before we remove it
has_weapon = self HasWeapon( "molotov" );
if( isDefined(has_weapon) && has_weapon )
{
self TakeWeapon( "molotov" );
}

if( isDefined(level.zombie_weapons) && isDefined(level.zombie_weapons["molotov_zombie"]) )
{
has_weapon = self HasWeapon( "molotov_zombie" );
if( isDefined(has_weapon) && has_weapon )
{
self TakeWeapon( "molotov_zombie" );
}
}
// PI_CHANGE_END
 
self maps\_zombiemode_cymbal_monkey::player_give_cymbal_monkey();
play_weapon_vo(weapon_string);
return;
}

self GiveWeapon( weapon_string, 0 );
self GiveMaxAmmo( weapon_string );
self SwitchToWeapon( weapon_string );

play_weapon_vo(weapon_string);

// self playsound (level.zombie_weapons[weapon_string].sound);
}

weapon_cabinet_think()
{
weapons = getentarray( "cabinet_weapon", "targetname" );

doors = getentarray( self.target, "targetname" );
for( i = 0; i < doors.size; i++ )
{
doors[i] NotSolid();
}

self.has_been_used_once = false;

self thread decide_hide_show_hint();

while( 1 )
{
self waittill( "trigger", player );

if( !player can_buy_weapon() )
{
wait( 0.1 );
continue;
}

cost = 1500;
if( self.has_been_used_once )
{
cost = get_weapon_cost( self.zombie_weapon_upgrade );
}
else
{
if( IsDefined( self.zombie_cost ) )
{
cost = self.zombie_cost;
}
}

ammo_cost = get_ammo_cost( self.zombie_weapon_upgrade );

if( !is_player_valid( player ) )
{
player thread ignore_triggers( 0.5 );
continue;
}

if( self.has_been_used_once )
{
player_has_weapon = player has_weapon_or_upgrade( self.zombie_weapon_upgrade );
/*
player_has_weapon = false;
weapons = player GetWeaponsList();
if( IsDefined( weapons ) )
{
for( i = 0; i < weapons.size; i++ )
{
if( weapons[i] == self.zombie_weapon_upgrade )
{
player_has_weapon = true;
}
}
}
*/

if( !player_has_weapon )
{
if( player.score >= cost )
{
self play_sound_on_ent( "purchase" );
player maps\_zombiemode_score::minus_to_player_score( cost );
player weapon_give( self.zombie_weapon_upgrade );
}
else // not enough money
{
play_sound_on_ent( "no_purchase" );
player thread maps\_zombiemode_perks::play_no_money_perk_dialog();
}
}
else if ( player.score >= ammo_cost )
{
ammo_given = player ammo_give( self.zombie_weapon_upgrade );
if( ammo_given )
{
self play_sound_on_ent( "purchase" );
player maps\_zombiemode_score::minus_to_player_score( ammo_cost ); // this give him ammo to early
}
}
else // not enough money
{
play_sound_on_ent( "no_purchase" );
player thread maps\_zombiemode_perks::play_no_money_perk_dialog();
}
}
else if( player.score >= cost ) // First time the player opens the cabinet
{
self.has_been_used_once = true;

self play_sound_on_ent( "purchase" );

self SetHintString( &"ZOMBIE_WEAPONCOSTAMMO", cost, ammo_cost );
// self SetHintString( get_weapon_hint( self.zombie_weapon_upgrade ) );
self setCursorHint( "HINT_NOICON" );
player maps\_zombiemode_score::minus_to_player_score( self.zombie_cost );

doors = getentarray( self.target, "targetname" );

for( i = 0; i < doors.size; i++ )
{
if( doors[i].model == "dest_test_cabinet_ldoor_dmg0" )
{
doors[i] thread weapon_cabinet_door_open( "left" );
}
else if( doors[i].model == "dest_test_cabinet_rdoor_dmg0" )
{
doors[i] thread weapon_cabinet_door_open( "right" );
}
}

player_has_weapon = player has_weapon_or_upgrade( self.zombie_weapon_upgrade );
/*
player_has_weapon = false;
weapons = player GetWeaponsList();
if( IsDefined( weapons ) )
{
for( i = 0; i < weapons.size; i++ )
{
if( weapons[i] == self.zombie_weapon_upgrade )
{
player_has_weapon = true;
}
}
}
*/

if( !player_has_weapon )
{
player weapon_give( self.zombie_weapon_upgrade );
}
else
{
if( player has_upgrade( self.zombie_weapon_upgrade ) )
{
player ammo_give( self.zombie_weapon_upgrade+"_upgraded" );
}
else
{
player ammo_give( self.zombie_weapon_upgrade );
}
}
}
else // not enough money
{
play_sound_on_ent( "no_purchase" );
player thread maps\_zombiemode_perks::play_no_money_perk_dialog();
}
}
}

pay_turret_think( cost )
{
if( !isDefined( self.target ) )
{
return;
}
turret = GetEnt( self.target, "targetname" );
 
if( !isDefined( turret ) )
{
return;
}
 
turret makeTurretUnusable();
 
while( true )
{
self waittill( "trigger", player );
 
if( !is_player_valid( player ) )
{
player thread ignore_triggers( 0.5 );
continue;
}

if( player in_revive_trigger() )
{
wait( 0.1 );
continue;
}

if(isdefined(player.is_drinking))
{
wait(0.1);
continue;
}
 
if( player.score >= cost )
{
player maps\_zombiemode_score::minus_to_player_score( cost );
turret makeTurretUsable();
turret UseBy( player );
self disable_trigger();
 
player.curr_pay_turret = turret;
 
turret thread watch_for_laststand( player );
turret thread watch_for_fake_death( player );
if( isDefined( level.turret_timer ) )
{
turret thread watch_for_timeout( player, level.turret_timer );
}
 
while( isDefined( turret getTurretOwner() ) && turret getTurretOwner() == player )
{
wait( 0.05 );
}
 
turret notify( "stop watching" );
 
player.curr_pay_turret = undefined;
 
turret makeTurretUnusable();
self enable_trigger();
}
else // not enough money
{
play_sound_on_ent( "no_purchase" );
player thread maps\_zombiemode_perks::play_no_money_perk_dialog();
}
}
}

watch_for_laststand( player )
{
self endon( "stop watching" );
 
while( !player maps\_laststand::player_is_in_laststand() )
{
if( isDefined( level.intermission ) && level.intermission )
{
intermission = true;
}
wait( 0.05 );
}
 
if( isDefined( self getTurretOwner() ) && self getTurretOwner() == player )
{
self UseBy( player );
}
}

watch_for_fake_death( player )
{
self endon( "stop watching" );
 
player waittill( "fake_death" );
 
if( isDefined( self getTurretOwner() ) && self getTurretOwner() == player )
{
self UseBy( player )
Last Edit: May 06, 2019, 10:38:05 pm by dabro

 
Loading ...