SHADOW WARRIOR MODDING TUTORIAL:
Turning Ninja Stars into the Duke3D expander weapon.
In this tutorial we will make it so enemies will grow very big and blow up when the ninja stars hit a enemy actor.
In Actor.cpp at the very end of the add the following code. 
 
void InitActorGrow(int spritenum, int scalex, int scaley)
{
	USERp u = User[spritenum];
	
	if (u == nullptr)
		return; 
	u->isGrowingTillDeath = true;
	u->growingTicTimer = 0;
	u->growScaleX = scalex;
	u->growScaleY = scaley;
}
bool DoGenericGrowCode(int spritenum)
{
	USERp u = User[spritenum];
	if (u == nullptr)
		return FALSE;
	if (!u->isGrowingTillDeath)
		return FALSE;
	SPRITEp sprite = u->SpriteP;
	if (u->growingTicTimer < 32)
	{
		sprite->xrepeat += ksgn(u->growScaleX);
		sprite->yrepeat += ksgn(u->growScaleX);
		u->growingTicTimer++;
	}
	else
	{
		// spawn explosion
		int explosion = SpawnSectorExp(spritenum);
		ASSERT(explosion >= 0);
		SPRITEp exp = &sprite[explosion];
		USERp eu = User[explosion];
		exp->xrepeat += (RANDOM_P2(32 << 8) >> 8) - 16;
		exp->yrepeat += (RANDOM_P2(32 << 8) >> 8) - 16;
		eu->xchange = MOVEx(92, exp->ang);
		eu->ychange = MOVEy(92, exp->ang);
		KillSprite(spritenum);
		return TRUE;
	}
	return FALSE;
}
The above code is our expander logic. The above logic is based on the expander logic in duke3d. 
In actor.h at the bottom of the header add the following code:
void InitActorGrow(int spritenum, int scalex, int scaley);
bool DoGenericGrowCode(int spritenum);
In game.h find the USER struct and add the following just above the filler variable:
 
        bool isGrowingTillDeath;
	int growingTicTimer;
	int growScaleX;
	int growScaleY;
In sprite.cpp just below #include "player.h" add the following:
#include "actor.h"
Also in sprite.cpp find the function SpriteControl just above the CloseToPlayer = FALSE; line(inside of the move bad guys around TRAVERSE_SPRITE_STAT) add the following code.
			if (DoGenericGrowCode(sp - sprite))
				continue;
Were executing our exploding logic here, there is probably a better place for it but we don't continue in the loop if DoGenericGrowCode has removed destroyed this actor.
Finally in weapon.cpp around line 6373(case STAR1/case CROSSBOLT) modify that condition from
case STAR1:
    case CROSSBOLT:
        damage = GetDamage(SpriteNum, Weapon, WPN_STAR);
        if (u->sop_parent)
        {
            break;
        }
        else if (u->PlayerP)
        {
            MONO_PRINT("Stat Hit Actor");
            // Is the player blocking?
            if (u->PlayerP->WpnKungFuMove == 3)
                damage /= 3;
            PlayerDamageSlide(u->PlayerP, damage, wp->ang);
            if (PlayerTakeDamage(u->PlayerP, Weapon))
            {
                PlayerUpdateHealth(u->PlayerP, damage);
                PlayerCheckDeath(u->PlayerP, Weapon);
            }
            if (u->PlayerP->Armor)
                PlaySound(DIGI_ARMORHIT,&u->PlayerP->posx,&u->PlayerP->posy,&
u->PlayerP->posz,v3df_dontpan|v3df_follow|v3df_doppler);
        }
        else
        {
            MONO_PRINT("Star Hit Actor");
            ActorHealth(SpriteNum, damage);
            ActorPain(SpriteNum);
            ActorStdMissile(SpriteNum, Weapon);
            ActorDamageSlide(SpriteNum, damage, wp->ang);
            ActorChooseDeath(SpriteNum, Weapon);
        }
        StarBlood(SpriteNum, Weapon);
        wu->ID = 0;
        SetSuicide(Weapon);
        break;
to
case STAR1:
		InitActorGrow(SpriteNum, 100, 100);
		StarBlood(SpriteNum, Weapon);
		wu->ID = 0;
		SetSuicide(Weapon);
		break;
    case CROSSBOLT:
        damage = GetDamage(SpriteNum, Weapon, WPN_STAR);
        if (u->sop_parent)
        {
            break;
        }
        else if (u->PlayerP)
        {
            MONO_PRINT("Stat Hit Actor");
            // Is the player blocking?
            if (u->PlayerP->WpnKungFuMove == 3)
                damage /= 3;
            PlayerDamageSlide(u->PlayerP, damage, wp->ang);
            if (PlayerTakeDamage(u->PlayerP, Weapon))
            {
                PlayerUpdateHealth(u->PlayerP, damage);
                PlayerCheckDeath(u->PlayerP, Weapon);
            }
            if (u->PlayerP->Armor)
                PlaySound(DIGI_ARMORHIT,&u->PlayerP->posx,&u->PlayerP->posy,&
u->PlayerP->posz,v3df_dontpan|v3df_follow|v3df_doppler);
        }
        else
        {
            MONO_PRINT("Star Hit Actor");
            ActorHealth(SpriteNum, damage);
            ActorPain(SpriteNum);
            ActorStdMissile(SpriteNum, Weapon);
            ActorDamageSlide(SpriteNum, damage, wp->ang);
            ActorChooseDeath(SpriteNum, Weapon);
        }
        StarBlood(SpriteNum, Weapon);
        wu->ID = 0;
        SetSuicide(Weapon);
        break;