Jump to content

ZScript - ClusterRocket Weapon Help


Wo0p

Recommended Posts

Hello forums! :)

 

I'm trying to make a rocket launcher that shoots a projectile which then splits into several smaller explosive grenades when in-flight. But I've tried several different avenues of approach and I either get a rocket that launches grenades AT THE PLAYER, spawns no additional grenades or spawns grenades that flies in the right direction but has no pitch adjustments (I.E vertical adjustment).

I understand that actor pointers are different depending on which actor they are attached to, but actor pointers is still a somewhat foggy subject to me. It's difficult to keep track of. Anyway, this code here is what I've come up with. I'm using:

A_FireBullets and FBF_PUFFTRACER

 

as a sort of invisible marker which I had thought should be enough for the secondary rocket spawn but it's not apparently. The A_FireBullets has the missile field filled out with the "MainRocket" projectile actor. I used AAPTR_TRACER to try and circumvent the automatic projectile pointer AAPTR_TARGET that's associated with the missile that spawned it. But to no avail as stated.

 

Anyway, here's the code:

 

Class CarpetBomber : Doomweapon
{
    Default
        {
        //$Category Weaponry
  Weapon.SelectionOrder 700;
  Weapon.Kickback 90;
  Weapon.BobStyle "InverseSmooth";
  Weapon.BobSpeed 2.0;
  Weapon.BobRangeY 0.6;
  Weapon.BobRangeX 1.2;
  Weapon.AmmoType1 "ImpactNadesMag";
  Weapon.AmmoUse1 0;
  Weapon.AmmoGive1 0;
  Weapon.AmmoType2 "ImpactNades";
  Weapon.AmmoUse2 0;
  Weapon.AmmoGive2 8;
  Weapon.ReadySound "Union/Up";
  +WEAPON.NO_AUTO_SWITCH
  +WEAPON.NOAUTOSWITCHTO
  +FORCEXYBILLBOARD
  Inventory.pickupmessage "\cfPicked up a Semi-Automatic High-Yield Mining Aide, lovingly nicknamed the \cgCarpet Bomber!";
  Inventory.Icon "CARPS0";
        }
        
    action void A_WeaponReadyReload(int flags = 0)
    {
        if (invoker.ammo1.amount < invoker.ammo1.maxamount && invoker.ammo2.amount >= invoker.ammouse1)
        {
            flags |= WRF_ALLOWRELOAD;
        }
        A_WeaponReady(flags);
    }
    action void A_MagazineReload()
    {
        while (invoker.ammo2.amount > 0 && invoker.ammo1.amount < invoker.ammo1.maxamount) 
        {
            TakeInventory(invoker.ammotype2, 1); //take 1 of AmmoType2
            GiveInventory(invoker.ammotype1, 1); //give 1 of AmmoType1
        }
    }
    
        States
        {
  Ready:
    TNT1 A 0;
    CARP A 1 A_WeaponReadyReload(WRF_ALLOWRELOAD);
    Loop;
  Deselect:
    TNT1 AA 0 A_Lower();
    CARP A 1 A_Lower();
    Goto Deselect+1;
  Select:
    TNT1 AA 0 A_Raise();
    CARP A 1 A_Raise();
    Goto Select+1;
  Fire:
    CARP A 0 A_WeaponReady(WRF_DISABLESWITCH|WRF_NOFIRE);
    CARP A 0 A_JumpIfNoAmmo("Reload");
    CARP A 0 A_JumpIfInventory("ImpactNadesMag", 1, 1);
    goto Dry;
    CARP A 0 A_StartSound("Union/Fire", CHAN_BODY, 0, 1,ATTN_NORM, 0, 0);
    CARP A 0 A_TakeInventory(invoker.ammotype1, 1);
    CARP B 2 
    {
    A_Quake(16, 8, 0, 16, "");
    A_Recoil(4);
    A_SpawnItemEx("BullpupSmoke", 6, 0, 32, 0, 1, 1);
    A_SpawnItemEx("BullpupSmoke", 4, 2, 32, 0, 1, 1);
    A_SpawnItemEx("BullpupSmoke", 4, -2, 32, 0, 1, 1);
    A_FireBullets(0, 0, 1, 0, "CBomberTargetPuff", FBF_EXPLICITANGLE|FBF_PUFFTRACER|FBF_NORANDOM, 4096, "MainRocket", 34, 2);
    }
    CARP B 4 A_SetPitch(pitch-2, 0, AAPTR_DEFAULT);
    CARP C 3 A_SetPitch(pitch+1, 0, AAPTR_DEFAULT);
    CARP D 2 A_SetPitch(pitch+1, 0, AAPTR_DEFAULT);
    CARP A 8 A_WeaponReadyReload(WRF_DISABLESWITCH);
    Carp A 8 A_Refire();
    goto Ready;
  Dry:
    CARP A 4 A_StartSound("Union/Dry", CHAN_WEAPON, 0,1,ATTN_NORM,0,0);
    Goto Reload;
  Reload:
    CARP A 0
    {
        if (CountInv("ImpactNades", AAPTR_DEFAULT) == 0 )
            { 
            return ResolveState("Ready");
            }
        return ResolveState(null);
    }
    CARP A 0 A_JumpIfInventory("ImpactNadesMag", 51, "Ready");
    CARP A 0 A_JumpIfInventory("ImpactNades", 1, 1);
    CARP A 0 A_JumpIfNoAmmo("Ready");
    CARP A 2 A_WeaponReadyReload(WRF_DISABLESWITCH|WRF_NOFIRE);
    CARP A 2 Offset(0,34);
    CARP A 2 Offset(0,38);
    CARP A 2 Offset(0,42);
    CARP A 2 A_StartSound("Union/Magout", CHAN_BODY, 0, 1,ATTN_NORM,0,0);
    CARP A 35;
    CARP A 0 A_MagazineReload();
    CARP A 6 A_StartSound("Union/Magin", CHAN_BODY, 0, 1,ATTN_NORM,0,0);
    CARP A 3 Offset(0,34);
    CARP A 3 Offset(0,33);
    CARP A 3 Offset(0,32);
    CARP A 2;
    CARP A 2;
    goto Ready;
  XMFlash:
    CARP D 2 BRIGHT A_Light2();
    CARP D 1 BRIGHT A_Light1();
    Goto LightDone;
  Spawn:
    CARP S -1 Bright;
    Stop;
        }
}

Class ImpactNadesMag : Ammo
{
	Default
	{
		Inventory.Amount 1;
		Inventory.Maxamount 4;
		+INVENTORY.IGNORESKILL
		Ammo.BackPackAmount 0;
		Ammo.BackPackMaxamount 4;
		Inventory.Icon "ROKKA0";
	}
}

Class ImpactNades : Ammo
{
	Default
	{
		//$Category Ammo
		XScale 0.9;
		YScale 1.0;
		Inventory.Amount 4;
		Inventory.Maxamount 16;
		Ammo.BackPackAmount 16;
		Ammo.BackPackMaxamount 32;
		Inventory.Icon "ROKKA0";
		+INVENTORY.IGNORESKILL
		Inventory.Pickupmessage "\cfPicked up a cluster of\cgImpact Grenades!";
		Inventory.Pickupsound "Union/Magout";
	}
		States
			{
			Spawn:
			ROKK A -1;
			Stop;
			}
}

Class MainRocket : Rocket
{
    Default
    {
        Radius 4;
        Height 2;
        Speed 46;
        +Ripper
        +BOUNCEONWALLS
        +BOUNCEONFLOORS
        +BOUNCEONCEILINGS
        BounceCount 2;
        DamageFunction 10;
        DamageType "Internal";
        DeathSound "Union/Shot";
        SeeSound "weapons/rocklf";
    }
    States
    {
    Spawn:
        MISL A 1 Bright;
        MISL A 1 Bright;
        MISL A 1 Bright;
        MISL A 1 Bright;
        MISL A 1 Bright;
        MISL A 1 Bright;
        MISL A 1 Bright;
        goto Death;
	Crash:
    Death:
        MISL B 0 Bright
        {
        A_SpawnProjectile("ImpactGrenade", 0, 0, 0, CMF_TRACKOWNER|CMF_AIMOFFSET|CMF_OFFSETPITCH|CMF_SAVEPITCH, 0, AAPTR_TRACER);
        A_SpawnProjectile("ImpactGrenade", 0, 0, 3, CMF_TRACKOWNER|CMF_AIMOFFSET|CMF_OFFSETPITCH|CMF_SAVEPITCH, 0, AAPTR_TRACER);
        A_SpawnProjectile("ImpactGrenade", 0, 0, 3, CMF_TRACKOWNER|CMF_AIMOFFSET|CMF_OFFSETPITCH|CMF_SAVEPITCH, 3, AAPTR_TRACER);
        A_SpawnProjectile("ImpactGrenade", 0, 0, 3, CMF_TRACKOWNER|CMF_AIMOFFSET|CMF_OFFSETPITCH|CMF_SAVEPITCH, -3, AAPTR_TRACER);
        A_SpawnProjectile("ImpactGrenade", 0, 0, -3, CMF_TRACKOWNER|CMF_AIMOFFSET|CMF_OFFSETPITCH|CMF_SAVEPITCH, 0, AAPTR_TRACER);
        A_SpawnProjectile("ImpactGrenade", 0, 0, -3, CMF_TRACKOWNER|CMF_AIMOFFSET|CMF_OFFSETPITCH|CMF_SAVEPITCH, 3, AAPTR_TRACER);
        A_SpawnProjectile("ImpactGrenade", 0, 0, -3, CMF_TRACKOWNER|CMF_AIMOFFSET|CMF_OFFSETPITCH|CMF_SAVEPITCH, -3, AAPTR_TRACER);
        A_SpawnProjectile("ImpactGrenade", 0, 0, 0, CMF_TRACKOWNER|CMF_AIMOFFSET|CMF_OFFSETPITCH|CMF_SAVEPITCH, 3, AAPTR_TRACER);
        A_SpawnProjectile("ImpactGrenade", 0, 0, 0, CMF_TRACKOWNER|CMF_AIMOFFSET|CMF_OFFSETPITCH|CMF_SAVEPITCH, -3, AAPTR_TRACER);
        }
        MISL B 4 Bright A_Explode(100, 128, XF_CIRCULAR|XF_THRUSTZ, false, 96, 0, 0, "Shotpuff", "Explosive");
        MISL C 3 Bright;
		MISL D 2 Bright;
        stop;
    }
}

Class ImpactGrenade : Rocket
{
    Default
    {
        Radius 8;
        Height 8;
        Scale 0.25;
        Speed 46;
        +NOGRAVITY
        +THRUSPECIES
        +MTHRUSPECIES
        +SEEKERMISSILE
        Species "Grenade";
        DeathSound "Union/Hit";
    }
    States
    {
        Spawn:
            MISL A 8 Bright A_SeekerMissile(1, 1, SMF_PRECISE, 0, 16);
            loop;
        Crash:
        Death:
            TMIS B 0 Bright A_SetScale(1.5, 1.5, AAPTR_DEFAULT);
            TMIS B 3 Bright A_Explode(100, 128, XF_CIRCULAR|XF_THRUSTZ, false, 96, 0, 0, "Shotpuff", "Explosive");
            TMIS C 3 Bright;
            TMIS D 3 Bright;
            Stop;
    }
}

Class CBomberTargetPuff : HitPuff
{
	Default
	{
		Renderstyle "Add";
		Alpha 0.1;
		Scale 0.1;
		Radius 0;
		Height 0;
		+NOGRAVITY
        +PUFFGETSOWNER
		Decal "";
		VSpeed 1;
		Mass 1;
	}
	States
	{
	Spawn:
		TNT1 A 1;
	Melee:
		TNT1 A 1;
		Stop;
    Death:
        TNT1 A 1;
        stop;
	}
}

 

Share this post


Link to post

From the code I can see that your target puff despawns (2 tics) before the missile splits (7 tics) so there is no tracer to aim at.

 

 

I think the splitting projectile spawning could be:

A_SpawnProjectile("ImpactGrenade", 0, 0, X, CMF_TRACKOWNER|CMF_AIMDIRECTION|CMF_SAVEPITCH, X+pitch);

(Change both X to 0 or 3 or -3 as it is in your code.)

This way it should not need any targeting puff.

Share this post


Link to post
53 minutes ago, jaeden said:

From the code I can see that your target puff despawns (2 tics) before the missile splits (7 tics) so there is no tracer to aim at.

 

 

I think the splitting projectile spawning could be:


A_SpawnProjectile("ImpactGrenade", 0, 0, X, CMF_TRACKOWNER|CMF_AIMDIRECTION|CMF_SAVEPITCH, X+pitch);

(Change both X to 0 or 3 or -3 as it is in your code.)

This way it should not need any targeting puff.

 

Once again you save my project. Thank you so much ^_^

 

I removed the targetpuff class like you suggested (And introduced your new formula) and the seekermissile flag from the impact grenade and it worked!

Edited by Wo0p

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...