this is a script for a power-up that randomizes and stays forever until its picked up, like in Mob Of The Dead on bo2 or Shadows Of Evil in bo3. there can be as many locations as you like and will pick between max ammo, double points and insta-kill. they will stay untill picked up
first go into your _zombiemode.gsc inside of your mod and under this line:
Code Snippet
Plaintext
level thread players_playing();
place
Code Snippet
Plaintext
level thread free_powerup();
then at the bottom of the GSC place this
Code Snippet
Plaintext
free_powerup() { level._effect["powerup_grabbed"] = loadfx( "misc/fx_zombie_powerup_grab" ); free_powerup = GetEntArray("free_powerup", "targetname"); if ( !isDefined( free_powerup ) || free_powerup.size < 1 ) { iPrintLnBold( "YOU HAVENT PLACED THE POWER UP IN RADIANT OR ITS KVPS ARE WRONG" ); return; } else for (i = 0; i < free_powerup.size; i++) { free_pow = spawn("script_model",free_powerup[i].origin); free_pow thread wait_for_powerup(); } } wait_for_powerup() { self endon( "collected" ); rand = randomInt(3); if (rand == 0) modl = "zombie_ammocan"; //max ammo else if (rand == 1) modl = "zombie_skull"; //insta else modl = "zombie_x2_icon";//double points self setmodel(modl); self thread maps\_zombiemode_powerups::powerup_wobble(); while(1) { players = get_players(); for (i = 0; i < players.size; i++) { if(distance(players[i].origin,self.origin) < 64) { playfx (level._effect["powerup_grabbed"], self.origin); if (modl == "zombie_skull"){players[i] thread maps\_zombiemode_powerups::insta_kill_powerup();} if (modl == "zombie_x2_icon"){players[i] thread maps\_zombiemode_powerups::double_points_powerup();} if (modl == "zombie_ammocan"){players[i] thread maps\_zombiemode_powerups::full_ammo_powerup();} playfx (level._effect["powerup_grabbed"], self.origin); self delete(); self notify( "collected" ); break; } } wait .1; } }
lastly open up your map in radiant and right click on the 2D view and go script->origin give it the targetname
Code Snippet
Plaintext
free_powerup
copy this as many times as you want to, this is where a power-up will spawn
have fun, please credit if used
Last Edit: December 16, 2015, 05:30:06 am by Harry Bo21
If you want scripts / features made for you, then contact me by PM or email / skype etc it will cost you tho so if you have no intention of reciprocating don't even waste my time
// here if ( !isDefined( free_powerup ) || free_powerup.size < 1 ) { iPrintLnBold( "YOU HAVENT PLACED THE POWER UP IN RADIANT OR ITS KVPS ARE WRONG" ); }
for (i = 0; i < free_powerup.size; i++) { free_pow = spawn("script_model",free_powerup[i].origin); free_pow thread wait_for_powerup(); }
So it "doesnt" crash the game and still explains the issue
Also i dont understand why you are "spawning" a model, when you could just have the user place models in radiant and use them? the model it uses can still be changed like this, with no need to spawn anything
Code Snippet
Plaintext
self.exists = true; while(self.exists == true) {
This is irrelevent, its "always" set to true right before, even though you set this to false, the thread is killed anyway by the endon?
Code Snippet
Plaintext
rand = randomIntRange(1,4); if (rand == 1){modl = "zombie_ammocan";}//max ammo if (rand == 2){modl = "zombie_skull";}//insta if (rand == 3){modl = "zombie_x2_icon";}//double points
should really be
Code Snippet
Plaintext
rand = randomIntRange( 3 ); if (rand == 0) modl = "zombie_ammocan"; //max ammo else if (rand == 1) modl = "zombie_skull"; //insta else modl = "zombie_x2_icon";//double points
You could also have just "spawned" a power up, and killed the "timeout" thread, which would have saved 75% of this code, as its already written
nice work, but i think theres still some things you need to consider in future
* PS * Unless already done so, you should also be "precaching" the models. These will prob be loaded by the powerups script anyway, but that may not be the case for all users
Code Snippet
Plaintext
PrecacheModel( "" ); // Called BEFORE zombiemode::main();
and no need to declare things undefined if you are declaring them in the very next line
Code Snippet
Plaintext
modl = undefined;
** EDIT ** and another, your calling something on something you deleted just beforehand....
// here if ( !isDefined( free_powerup ) || free_powerup.size < 1 ) { iPrintLnBold( "YOU HAVENT PLACED THE POWER UP IN RADIANT OR ITS KVPS ARE WRONG" ); }
for (i = 0; i < free_powerup.size; i++) { free_pow = spawn("script_model",free_powerup[i].origin); free_pow thread wait_for_powerup(); }
So it "doesnt" crash the game and still explains the issue
That will still crash the game or cause a bunch of errors unless you return it:
Code Snippet
Plaintext
if ( !isDefined( free_powerup ) || free_powerup.size < 1 ) { iPrintLnBold( "YOU HAVENT PLACED THE POWER UP IN RADIANT OR ITS KVPS ARE WRONG" ); return; }
I have to disagree about that being "good practice" though. When it comes to these type of things, Treyarch and Infinity Ward both use the assert functions as they not only stop the map and give you whatever message you pass them, it also gives a stack trace(error log) in console so its easier to debug.
if you use developer, which im guessing by this he doesnt - nor will most of the people who download this, so i posted what i thought was "appropriate", but yes there should have been a return
and in either case the "good practice" was referring to "putting a handle in for a potential error rather than just leaving it to crash the game with no explination", which is pretty much what you yourself posted anyway DD...
Last Edit: December 16, 2015, 04:23:08 am by Harry Bo21
it works either way, i call this "clean up". I often go back through my work multiple times after its finished and find the same kind of mistakes
a lot of the extra stuff was kinda a fail safe cause when testing i had multiple problems, like the model not disappearing and the power-up function running forever, but i'll see if i can make it all work better
a lot of the extra stuff was kinda a fail safe cause when testing i had multiple problems, like the model not disappearing and the power-up function running forever, but i'll see if i can make it all work better
remember some of it is prob just coding preference
I like to leave a "default" path, for if other checks failed. thats why i changed that last statement from if 1 2 3 to
if 0 or 1 or "any other"
then even if a bad value gets passed, should still default
learned a lot about this kind of thing with case statements
remember some of it is prob just coding preference
I like to leave a "default" path, for if other checks failed. thats why i changed that last statement from if 1 2 3 to
if 0 or 1 or "any other"
then even if a bad value gets passed, should still default
learned a lot about this kind of thing with case statements
also a little problem on your end, you had the random range with 1 number, but luckily i picked up on that, anyway the new script works a little better then the last one. also for PrecacheModel, they should already be called in _zombiemode_powerups, so there shouldnt be a need to do it again, which i found through testing
also a little problem on your end, you had the random range with 1 number, but luckily i picked up on that, anyway the new script works a little better then the last one. also for PrecacheModel, they should already be called in _zombiemode_powerups, so there shouldnt be a need to do it again, which i found through testing
pretty sure the first defaults to 0 if left empty, but you only need this anyway
Code Snippet
Plaintext
randomInt( 3 )
that will return 0, 1 or 2
you dont need range, you just need a random number up to a certain value
also the model i meant, if people have ported say the BO3 insta kill model ( or just felt like being fancy and changed it to some other model, i dunno, people are weird lol ), yours wont work. So "I" precache whats needed in my scripts at the top, and people can comment it out if they want ( although they should not need to )
its "defo gonna work" vs "should work assuming the user hasnt messed with something at some point so things are not as they should be"
to ensure this i thread it in zombiemode along with the tesla etc that treyarch did, because that is "at" the precache stage, so anything added to your scripts "init", is valid for precache. Also easy to find as all treyarchs important scripts are threaded there
then I thread off that ( if i need to ) and flag_wait( "all_players_connected" ); for anything i wanted to run after zombiemode::main()
Last Edit: December 16, 2015, 05:08:57 am by Harry Bo21
rand = randomIntRange( 3 ); if (rand == 0) modl = "zombie_ammocan"; //max ammo else if (rand == 1) modl = "zombie_skull"; //insta else modl = "zombie_x2_icon";//double points
[/quote] what i meant is you said to use range by mistake, and i picked up on that and fixed it, otherwise it will always be 0 which makes it always max ammo
rand = randomIntRange( 3 ); if (rand == 0) modl = "zombie_ammocan"; //max ammo else if (rand == 1) modl = "zombie_skull"; //insta else modl = "zombie_x2_icon";//double points
what i meant is you said to use range by mistake, and i picked up on that and fixed it, otherwise it will always be 0 which makes it always max ammo
yea i know (coz i copy pasted and adjust yours and missed it lol ), I thought puting one value in made it "assume" the first value is 0, pretty sure it does, as unless specified, cant go lower.
anyway, despite this, just need randomInt instead, your range will never vary into negatives
P.S, added the return that was missing that was mentioned earlier
I se youve cleaned it up, still one ( very minor and could be ignored completely, i mention only coz its good to mention lol )
Code Snippet
Plaintext
self delete(); self notify( "collected" ); break;
you dont need the break, for two reasons
firstly, the break wont be breaking from the while() loop, itll be breaking from the players loop, so the while loop would continue and run the player loop again anyway
if you do need to break from a loop, from within another loop youd do something like this
Code Snippet
Plaintext
early_break = false; // variable we will use to pass something to kill the other loop while( 1 ) { for ( i = 0; i < players.size; i++ ) { if ( i == 1 ) { early_break = true; break; } } if ( isDefined( early_break ) && early_break ) break; // break again, so you break from the parent loop }
but secondly
the notify is killing the thread anyway, so that line doesnt even get read
next you should look into "weighting", so it has a higher chance of being a certain one, than others. If you need a few pointers for that let me know, but its pretty interesting to come up with your own way of weighting, as the practice can carry over to anything else you do that you want to "weight"
Last Edit: December 16, 2015, 05:39:24 am by Harry Bo21