Rewards per soul collector can be randomized or collector specific. - script_string kvp on the collector will override level settings - Can change weapons rewarded or level reward without randomization Can play a looping animation of collectors - optional, requires uncommenting of a few lines Includes prefabs to get you started Only setup for one set of soul collectors and one final reward on a map Many level vars to edit, including fx and sounds (be sure to add fx to precache and zone if adding more fx)
v 1.1 - Added level var option to not grow - Added level vars to reward on completion the following: - gun - door - buyable ending
v1.2 - Fixed developer 2 errors
v1.3 - Added multiple soul collector support with multiple reward support, and individual sizing with script_noteworthy
v1.3.1 - Find player.cost and replace it with player.score to fix buyable ending
v1.4 - Added rotating door prefab, updated normal door prefab, fixed endgame trigger, and updated endgame text
Instructions
Code Snippet
Plaintext
MakeCents v1.4 Updated 12-20-16
Prefabs - in multiple folders (each folder is a different system with different kvps) grow_soul_complete - everything you need with gun reward grow_soul_complete_door - everything you need with door reward grow_soul_complete_ending - everything you need with end game reward grow_soul - just one of the soul collectors grow_soul_door - just the door reward grow_soul_ending - just the end game reward grow_soul_with_clip - jus one of the soul collectors with a clip grow_soul_door_rotate - door that rotates, script_string controls angle
To make this work you can use one of the complete prefabs, stamp once, and then chose the soul collector with a clip or without and delete the other. Next copy the soul collector you kept around where you want them and place the reward where you want it - end game trigger, door, or gun structs
Then in the script there are notes at the top.
This goes in your main function in your mapname.gsc grow_soul::init( );
This goes in your mapname.gsc with the other using's #using scripts\zm\growing_soulbox;
This goes in your zone file: scriptparsetree,scripts/zm/growing_soulbox.gsc fx,zombie/fx_ritual_pap_energy_trail
1.3.1 fixes end game score
1.4 adds more prefabs, rotating door, updates normal door, edits endgame text
To make multiple systems work, do the same you did for the first system, but select from another folder. In these other folders each item has a different kvp. You can add more if you like, I provided 3 systems.
Last Edit: December 20, 2016, 03:50:32 pm by MakeCents
Hello, I was editing your script for the soul collectors and I ran into some problems that only you, the creator, might know how to fix. What I wanted to do was make it so that every time a soul collector was finished (in my case they are 4 different colored rocks) the rock of that soul collector would move to its pedestal, as well as the light that made them look glowing. This is currently my script:
/* ##################### by: M.A.K.E C E N T S ##################### Script: v1.1 //MAKE SURE ALL ENTITIES ARE PRESENT IN RADIANT!//
scriptparsetree,scripts/zm/growing_soulbox.gsc fx,zombie/fx_ritual_pap_energy_trail //fx,any other fx you add //the following is optional for anims xanim,youranimhere//your anim here rawfile,animtrees/youranimtreename.atr//your animtree here
//#using_animtree( "youranimtreename" );//your animtree here
function init() { level.post_blue_light = GetEnt( "post_blue_light", "targetname"); level.post_green_light = GetEnt( "post_green_light", "targetname"); level.post_yellow_light = GetEnt( "post_yellow_light", "targetname"); level.post_red_light = GetEnt( "post_red_light", "targetname"); level.post_blue_light Hide(); level.post_green_light Hide(); level.post_yellow_light Hide(); level.post_red_light Hide(); //vars for growing and reward level.grow_soul_grow = true;//true to grow, and false to not grow level.grow_soul_final_reward = "door";//options: gun, ending, door level.grow_soul_start_scale = 0.75;//starting scale of model level.grow_soul_anim = undefined;//set to true to play an anim, define down in PlayMyAnim function, and uncomment anim related lines level.grow_soulallreward = "raygun_mark3"; level.grow_soul_explode = true; level.grow_soulfx_limit = 5; level.grow_soul_growth = 0.05;//growth per zombie level.grow_soul_size = 1;//how big you want it to get scale wise level.grow_souldistance = 300;//how far away they can be level.growspeed = .015;//how fast to grow level.grow_soul_scaler = .001;//how much it grows during growspeed level.soul_speed_divider = 200;//the higher the number the faster it travels level.grow_soul_reward = "random_weapon";//can also be other things, random_weapon, tesla, minigun, and so on level.grow_soul_rand_rewards = array("random_weapon");//can add other powerups also level.grow_soul_rand_weapons = array( "ar_damage", "lmg_cqb", "shotgun_pump", "smg_versatile" );//added for the weapons to randomly reward level.grow_soul_randomize = true;//make false or undefined to not randomize rewards //vars for fx and sounds level.grow_soulsoulfx = "zombie/fx_ritual_pap_energy_trail";//fx for the soul to travel level.grow_soulenterfx = "zombie/fx_powerup_grab_red_zmb";//fx for when the soul gets to the box level.grow_soulexplode = "zombie/fx_powerup_off_green_zmb";//fx for exploding level.grow_soulentersound = "evt_nuked";//play sound for soul to box level.grow_soulrewardsound = "zmb_couch_slam";//sound to play when box is level.grow_soul_idlefx = undefined;//"zombie/fx_powerup_on_green_zmb";// fx for model while idle
//start it up grow_souls = GetEntArray("grow_soul","targetname"); array::thread_all(grow_souls, &MonitorGrowSouls); level.grow_souls = grow_souls.size; thread WatchZombies(); thread SetUpReward(); }
function GrowSoulEnding() { self SetCursorHint("HINT_NOICON"); self SetHintString("You may not leave until you finish collecting my souls."); level waittill("allgrowsouls"); IPrintLnBold("You may now escape, if you can."); self Show(); cost = 50000; if(isdefined(self.zombie_cost)) { cost = self.zombie_cost; } self SetCursorHint("HINT_NOICON"); self SetHintString("Press & hold [{+activate}] for buyable ending [Cost: " + cost + "]."); while(1) { self waittill("trigger", player); if(player.cost+5<cost) { player PlayLocalSound("zmb_no_cha_ching"); continue; } player PlayLocalSound("zmb_cha_ching"); IPrintLnBold("Congratulations! You escaped in " + level.round_number + " rounds."); level notify("end_game"); } }
function GrowSoulDoor() { self SetCursorHint("HINT_NOICON"); self SetHintString("It is too soon. Collect the Four Stones First"); if(isdefined(self.script_flag) && self.script_flag!="") { flag::init(self.script_flag); } self thread HandlePaths(false); level waittill("allgrowsouls"); IPrintLnBold("You Sense an Awakening"); self SetHintString(""); self thread HandlePaths(); if(isdefined(self.script_flag)) { flag::set(self.script_flag); } wait(1); self delete(); }
function HandlePaths(connect = true) { if(isdefined(self.target)) { doors = GetEntArray(self.target,"targetname"); foreach(door in doors) { if(!isdefined(door.model)) { if(connect) { door NotSolid(); door ConnectPaths(); } else { door DisconnectPaths(); } } if(connect) { if(isdefined(door.script_noteworthy) && door.script_noteworthy=="clip") { door Delete(); } else { if(isdefined(door.script_vector)) { vector = VectorScale( door.script_vector, 1 ); IPrintLnBold("move door"); IPrintLnBold(self.origin + vector); door MoveTo(self.origin + vector,1); } if(isdefined(door.script_sound)) { door PlaySound(door.script_sound); } } } if(isdefined(door)) { door thread HandlePaths(connect); } } } }
if(level.closest == blue) { blue_light Delete(); blue MoveZ( -50, 3); blue MoveTo( pre_blue_origin, 0.05); blue MoveTo( blue_origin, 5); level.post_blue_light show(); } else if(level.closest == green) { green_light Delete(); green MoveZ( -50, 3); green MoveTo( pre_green_origin, 0.05); green MoveTo( green_origin, 5); level.post_green_light show(); } else if(level.closest == yellow) { yellow_light Delete(); yellow MoveZ( -50, 3); yellow MoveTo( pre_yellow_origin, 0.05); yellow MoveTo( yellow_origin, 5); level.post_yellow_light show(); } else { red_light Delete(); red MoveZ( -50, 3); red MoveTo( pre_red_origin, 0.05); red MoveTo( red_origin, 5); level.post_red_light show(); }
}
I think the reason it doesn't work may be due to level.closest not actually being the closest soul collector. I looked through your script and I was fairly confused, being new to scripting and all, and I couldn't find a variable defined for the single soul collector the player has completed. I appreciate any help.
Well your working off 1.1, some additions have been made since. such as multiple soul box systems. I'm up to 1.4 now.
It sounds like you could achieve this by just spawning the rock back and moving it. You could also change level.grow_soul_explode to false, and then in the MonitorGrowSouls function, add an else like this:
Code Snippet
Plaintext
//up top change level.grow_soul_explode = true; to level.grow_soul_explode = false; if(isdefined(self) && isdefined(level.grow_soul_explode) && level.grow_soul_explode) { self thread BlowUpGrowSoul(system); } else { if(isdefined(self.target))//stamp prefab and select model and then struct, that is where you want it to move to { struct = struct::get(self.target, "targetname"); if(isdefined(struct)) { self MoveTo(struct.origin,2); } } }
You could decide where to move the rock by distance or maybe even setting up a target of a struct, getting the struct, and moving it do that origin.
If you have an level.grow_soul_idlefx playing on the model, you can modify the
I appreciate your quick response, its very helpful, but I am a little confused. I inserted the script in MonitorGrowSouls and set level.grow_soul_explode to false, but I am a little confused where to put the struct and what KVPs it should have. Also, I don't have an FX for the rocks, but I do have a different colored light for each one of them that I would like to move with them, or at least delete themselves and then reappear at the end. I am know somewhat how to script but as you could see before, not very well. I'm just a little confused whats going on in the script right now, and if could explain it that would be awesome, and would help me become a better scripter in the long run.
What I proposed, you would make the struct the target of the model. Select the prefab, stamp it, if necessary, then select the rock, then select the struct and press w. Then move the struct where you want the rock to end up. You can select one and then the other, enter the origin kvp and hit enter to line things up. Depending which you select first, depends which will go to the others origin. That's just for assignment purposes. Move the rock back once you have the struct aligned.
As far as the light. I've seen gsc scripting options on lights, but hasn't tried it yet. If you can get a light by target name, I would try linking it to the rock, our just moving it yourself, maybe to the struct + 0 0 30, or whatever. Or you can put the light in an fx, and do the play fx on tag thing I said.
I have a tut on script too radiant relationship on my YouTube, if you haven't seen it, check it out. I plan on adding two more parts before the end of next week.
Last Edit: December 22, 2016, 09:53:47 pm by MakeCents
So I put in the script, set the level.grow_soul_explode to false, and created a struct where I want the rock to end up. I selected the rock (which has the targetname "grow_souls" like it should, and is a script model) and then selected the struct and pressed W, created a line with an arrow pointing from the rock to the struct. The problem is, when I go in game the rocks are all just where they end up, at the script struct, from the beginning, And you can't collect any souls. The magical door doesn't even open up.
So I put in the script, set the level.grow_soul_explode to false, and created a struct where I want the rock to end up. I selected the rock (which has the targetname "grow_souls" like it should, and is a script model) and then selected the struct and pressed W, created a line with an arrow pointing from the rock to the struct. The problem is, when I go in game the rocks are all just where they end up, at the script struct, from the beginning, And you can't collect any souls. The magical door doesn't even open up.
Alright I got the collectors to collect souls again. They collect souls, then move to the correct pedestal. Everything works except for the door. It doesn't open and the hintstring doesn't change.
Alright I got the collectors to collect souls again. They collect souls, then move to the correct pedestal. Everything works except for the door. It doesn't open and the hintstring doesn't change.
Well, it sounds like either that ee is not complete, or maybe there is a string typo or something like that. You can add prints to see where it is getting hung up at.
Well, it sounds like either that ee is not complete, or maybe there is a string typo or something like that. You can add prints to see where it is getting hung up at.
You know, I've been wondering how you call the script using:
Code Snippet
Plaintext
grow_soul::init( );
despite the name of the file being growing_soulbox.gsc.
I'm trying to add a second growing soulbox script (yes it has to be in its own .gsc to work) but I don't know how to reference it. Using:
Code Snippet
Plaintext
growing_soulbox_2::init( );
does not work.
My system supports multiple soul box systems already, Just by adding the prefabs, and the line of script. But the reason I call it with that is because of name spaces. If a script declares a name space, you use that instead of the scripts name.
ah , I understand now. I hadn't seen namespaces used yet. I need to have multiple .gsc's though because the level vars have to be different for the other set (as well as some extra script things I need to add in).