Soulbox

This is a soulbox script that is made to work mostly in radiant, with as little GSC as possible to use.

```
/\*
Created by Cardigan
\*/

#using scripts\codescripts\struct;

#using scripts\shared\flag\_shared;
#using scripts\shared\array\_shared;
#using scripts\shared\util\_shared;

#using scripts\zm\\_zm\_audio;

#define SOULBOX\_KILL\_FX "dlc5/zmhd/fx\_quad\_teleport\_out"
#define SOULBOX\_SOUL\_TRAIL\_FX "dlc1/castle/fx\_rune\_arrow\_reveal\_trail"
#define SOULBOX\_SOUL\_FX "dlc4/genesis/fx\_corrupteng\_zombie\_soul\_115"
#define SOULBOX\_ARRIVE\_FX "dlc2/zmb\_weapon/fx\_mirg\_spore\_pop\_sm"

#precache( "fx", SOULBOX\_KILL\_FX );
#precache( "fx", SOULBOX\_SOUL\_TRAIL\_FX );
#precache( "fx", SOULBOX\_SOUL\_FX );
#precache( "fx", SOULBOX\_ARRIVE\_FX );

#define DEBUG 0
#define MOVE\_TIME 1

#namespace zm\_soulbox;

// self = struct
function new\_box(finish\_flag) {
 SetupEffects ();

 self.needed\_kills = self.count;
 self.enemy\_type = self.script\_string;
 if(DEBUG == 1){
 if(isdefined(self.target)){
 IPrintLnBold("target\_trigger: " + self.target);
 }

 if(isdefined(self.needed\_kills)){
 IPrintLnBold("needed\_kills: " + self.needed\_kills);
 }

 if(isdefined(self.enemy\_type)){
 IPrintLnBold("enemy\_type: " + self.enemy\_type);
 }
 }

 self.trigger = getent(self.target, "targetname");
 self.current\_kills = 0;
 self.filled = false;

 self thread TrackZombies();

 while(!self.filled){
 wait (.1);
 }

 wait MOVE\_TIME; // waiting for move time

 self.trigger Delete();
 level notify(finish\_flag);
}

function SetupEffects () {
 level.Soulboxes\_KillEffects = [];
 level.Soulboxes\_SoulEffects = [];
 level.Soulboxes\_BoxArriveEffects = [];

 level.Soulboxes\_KillEffects[0] = SOULBOX\_KILL\_FX;
 level.Soulboxes\_SoulEffects[0] = SOULBOX\_SOUL\_TRAIL\_FX;
 level.Soulboxes\_SoulEffects[1] = SOULBOX\_SOUL\_FX;
 level.Soulboxes\_BoxArriveEffects[0] = SOULBOX\_ARRIVE\_FX;
}

// self = struct
function TrackZombies(){
 while(self.filled == false)
 {
 zombies = GetAiSpeciesArray( "all" );
 for(i=0;i<zombies.size;i++)
 {
 if(isdefined(zombies[i].soulready))
 {
 continue;
 }
 else
 {
 zombies[i] thread wait\_till\_death(self);
 }
 }
 wait(.1);
 }
}

function wait\_till\_death (soulbox) {

 if(isdefined(self))
 {
 self.soulready = true;
 }
 else
 {
 return;
 }
 self waittill("death");

 if((self isTouching(soulbox.trigger)) == true && soulbox.filled == false){
 if(soulbox.enemy\_type == self.animName){
 soulbox.current\_kills += 1;
 if(DEBUG == 1){
 IPrintLnBold("Zombie killed. " + soulbox.current\_kills + " / " + soulbox.needed\_kills);
 }
 thread playdeathfx( self.origin, soulbox);

 if(soulbox.current\_kills >= soulbox.needed\_kills){
 soulbox.filled = true;
 // soulbox thread PlayBoxFilledEffect();
 }
 } else {
 if(DEBUG == 1){
 IPrintlnbold("Incorrect type: " + self.animName);
 IPrintlnbold("Required type: " + soulbox.enemy\_type);
 }
 }
 }
 else{
 if(DEBUG == 1) IPrintLnBold("Died outside of soulbox trigger");
 }
}

function playdeathfx( location, soulb){

 //Spawn model
 zombie\_kill\_fx = spawn("script\_model", location + (0,0,40));
 zombie\_kill\_fx SetModel("tag\_origin");
 // zombie\_kill\_fx playSound("soulrelease");

 //Play effects
 foreach(effect in level.Soulboxes\_KillEffects){
 playFx(effect, zombie\_kill\_fx.origin);
 }
 foreach(effect in level.Soulboxes\_SoulEffects){
 playFxOnTag(effect, zombie\_kill\_fx, "tag\_origin");
 }

 zombie\_kill\_fx moveto(soulb.origin, MOVE\_TIME);
 wait(MOVE\_TIME);

 foreach(effect in level.Soulboxes\_BoxArriveEffects){
 playFx(effect, soulb.origin);
 }
 zombie\_kill\_fx Delete();
}

```

## Usage

Include the file in your .zone and .gsc files.

In radiant, create a script\_struct with the kvps:

* count: zombies\_to\_fill
* script\_string: type\_of\_zombie (ex. "zombie")
* target: targetname\_of\_trigger\_for\_soulbox\_collection\_zone

Once you've done this, you can init the soulbox in your script with

```
GetEnt("soulbox\_name", "targetname") zm\_soulbox::new\_box("flag\_to\_notify\_level\_when\_done");

```
Feel free to edit the code to your liking and use the FX you want.

## Notes

Be sure to include the fx in your zone with `fx,the/location/of\_the\_file.efx`.