Need Help with Unmaker Code

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
PhoenixCyanFire
Posts: 35
Joined: Fri Jul 07, 2023 12:00 pm
Preferred Pronouns: She/Her
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia (Modern GZDoom)

Need Help with Unmaker Code

Post by PhoenixCyanFire »

so I have a unmaker mod, but like

Here is the issue.


The lasers dont spawn from the muzzle of the unmaker, it spawns from above the player or below the player, and moves weirdly when the player moves.


Does anyone know what the issue is?

Code: Select all

class Unmaykr : Doomweapon
{
    const CHAN_HUM = 14;
    Default
	{
	    //$Color 14
        //$NotAngled
        //$Title "Unmaykr"
        //$Category "Weapons"
		Weapon.Slotnumber 8;
		Weapon.SlotPriority 0;
		
		Weapon.SelectionOrder 2900;
		Weapon.AmmoUse 1;
		Weapon.AmmoUse2 30;
		Weapon.AmmoGive 80;
		Weapon.AmmoType "Cell";
		Weapon.AmmoType2 "Cell";
		+WEAPON.NOAUTOFIRE;
		+WEAPON.BFG;
		+DONTGIB;
		
		Obituary "%o was unmade by %k.";
		Weapon.UpSound "Weapons/UnmaykrUp";
		Inventory.Pickupmessage "\cgWhat the \ca!@#%* \cgis this?!";
		Inventory.PickupSound "Weapons/UnmaykrPickup";
        //AttackSound "Weapons/UnmaykrFire";
		Inventory.Icon "LSGRA0";
		Tag "Unmaykr";
		Weapon.BobSpeed 1.2;
        Weapon.BobRangeX 0.5;
        Weapon.BobRangeY 1.0;
	}
	States
	{
	Ready:
		TNT1 A 0 A_JumpIfInventory("DemonKeyCount", 3, "NewReady");
		TNT1 A 0 A_SetCrosshair (96);
		TNT1 A 0 A_ZoomFactor(1.0);
		TNT1 A 0;
        TNT1 AAAAA 0;
		TNT1 A 0 A_StartSound("unmaykr/hum", CHAN_HUM, CHANF_LOOPING|CHANF_OVERLAP, 0.25, ATTN_NORM, 0, 0);
		UNMK A 1 A_WeaponReady();
		Loop;
		
	NewReady:
		TNT1 A 0;
        TNT1 AAAAA 0;
		TNT1 A 0 A_SetCrosshair (96);
		TNT1 A 0 A_ZoomFactor(1.0);
		UMYK A 1 A_UnmaykrReady();
		TNT1 A 0 A_StartSound("unmaykr/hum", CHAN_HUM, CHANF_LOOPING|CHANF_OVERLAP, 0.5, ATTN_NORM, 0, 0);
		UMYK "##" 1 A_WeaponReady();
		Loop;
		
		
	Deselect:
		UNMK A 0 A_JumpIfInventory("DemonKeyCount", 3, "NewDeselect");
		TNT1 A 0 A_SetCrosshair (96);
		TNT1 A 0 A_ZoomFactor(1.0);
        TNT1 A 0 A_StopSound(CHAN_HUM);
        UNMK A 1 A_Lower();
        wait;
		
	NewDeselect:
		TNT1 A 0 A_SetCrosshair (96);
		TNT1 A 0 A_ZoomFactor(1.0);
		TNT1 A 0 A_StopSound(CHAN_HUM);
		UMYK A 1 A_Lower();
		Wait;
		
		
	Select:
		UNMK A 0 A_JumpIfInventory("DemonKeyCount", 3, "NewDeselect");
		TNT1 A 0 A_SetCrosshair (96);
		TNT1 A 0 A_ZoomFactor(1.0);
		UNMK A 1 A_Raise();
		Wait;
		
	NewSelect:
		TNT1 A 0 A_SetCrosshair (96);
		TNT1 A 0 A_ZoomFactor(1.0);
	    UMYK A 1 A_Raise();
		Wait;
	
	
    Fire:
		UNMK A 0 A_JumpIfInventory("DemonKeyCount", 1, "FireUpgradeOne");
		UNMK B 9 Bright
		{
			invoker.A_FireLaser();
		}
		UNMK A 4 A_ReFire();
		Goto Ready;
		
		FireUpgradeOne:
			UNMK A 0 A_JumpIfInventory("DemonKeyCount", 2, "FireUpgradeTwo");
			UNMK B 6 Bright
			{
				invoker.A_FireLaser();
			}
			UNMK A 3 A_ReFire();
			Goto Ready;
			
		FireUpgradeTwo:
			UNMK A 0 A_JumpIfInventory("DemonKeyCount", 3, "FireUpgradeThree");
			UNMK B 5 Bright
			{
				invoker.A_FireLaser(2, -1);
			}
			UNMK A 3 A_ReFire();
			Goto Ready;
		
		FireUpgradeThree:
			UMYK J 5 Bright
			{
				invoker.A_FireLaser(3, -3, true);
			}
			UMYK A 3 A_ReFire("Hold1");
			Goto NewReady;
		Hold1:
			UMYK J 5 Bright
			{
				invoker.A_FireLaser(3, -6, true);
			}
			UMYK A 3 A_ReFire("Hold2");
			Goto NewReady;
		Hold2:
			UMYK J 5 Bright
			{
				invoker.A_FireLaser(3, -9, true);
			}
			UMYK A 3 A_ReFire("Hold3");
			Goto NewReady;
		Hold3:
			UMYK J 5 Bright
			{
				invoker.A_FireLaser(3, -12, true);
			}
			UMYK A 3 A_ReFire();
			Goto NewReady;

	Flash:
	    TNT1 A 3 A_Light(Random(4,5));
		TNT1 A 1 A_Light(3);
	    TNT1 A 1 A_Light(2);
		TNT1 A 1 A_Light(1);
		Goto LightDone;
 	Spawn:
	    LSGR A -1;
	    Stop;
	}

	// Performs a hitscan attack and draws a laser to the location hit (based on puff spawn)
	//		amount - the number of hitscan attacks to perform (also determines ammo used)
	//		angOfs - the angle to offset the hitscan attack relative to the player
	//		additiveOfs - if true, subtracts angOfs from the angle offset for the next hitscan attack
	//					  if false, mirrors the angle offset for the next hitscan attack
	void A_FireLaser(int amount = 1, double angOfs = 0, bool additiveOfs = false)
	{
		if (!owner)
			return;
			
		// Make sure we have enough ammo to fire it first
		Weapon weap = owner.player.ReadyWeapon;
		int ammo = owner.CountInv("Cell");
		if (weap != null && self == weap)
		{
			if (ammo < amount)
			{
				owner.player.mo.PickNewWeapon(null);
				return;
			}
			
			// Play the weapon's Flash state
			owner.player.SetPsprite(PSP_FLASH, weap.FindState('Flash'), true);
		}
		
		owner.A_TakeInventory("Cell", amount, TIF_NOTAKEINFINITE);
		owner.A_StartSound("weapons/unmaykrfire", CHAN_AUTO, CHANF_DEFAULT, 0.8, ATTN_NORM, 0, 0);
		owner.player.mo.PlayAttacking2();
		
		FTranslatedLineTarget data;
		double ang = angOfs;
		double slope;
		int damage;
		Actor puff;
		
		// Start performing the hitscan attacks
		for (int i = 0; i < amount; i++)
		{
			slope = owner.AimLineAttack(owner.angle+ang, 4096);
			damage = random(1,8)*10;
			
			puff = owner.LineAttack(owner.angle+ang, 4096, slope, damage, 'Hitscan', "LaserPuff", LAF_NORANDOMPUFFZ, data);
			if (puff)
				DrawLaser(puff.pos);
				
			// Only offset the angle if we didn't hit an enemy
			if (!data.linetarget)
			{
				if (additiveOfs)
					ang -= angOfs;
				else
					ang *= -1;
			}
		}
	}
	
	// Draws the Unmaykr laser trail starting from the player and ending at targLoc
	//		targLoc - 3D coordinate that marks where the laser should end
	void DrawLaser(Vector3 targLoc)
	{
		if (!owner)
			return;
			
		// Offset the starting point of the laser based on where the player is looking
		// Forward offset of 30 and height offset of 40 are based on Doom 64 EX's data
		Vector2 looking;
		if (owner.pitch <= 0)
			looking = AngleToVector(owner.angle, 30);
		else
		{
			// We need to move it backwards when looking down to prevent weird visual issues
			double offset = owner.pitch*2 / 3;
			looking = AngleToVector(owner.angle, abs(30-offset));
			if (offset > 30)
				looking *= -1;
		}
		
		// Get the direction from the player to the puff
		Vector3 origin = owner.pos + (looking.x,looking.y,40);
		Vector3 base = targLoc - origin;
		Vector3 dir = base.Unit();
		double length = base.Length();
		
		int l = 0; // Used for keeping track of when to spawn a light source in the trail
		int dur = 1; // How long a group of sprites should stay alive in tics (35 is one second)
		bool increaseDur = false; // Whether to increase the duration for the next group of sprites
		
		// Traverse down the path while spawning sprites
		UnmaykrLaserTrailFix trail;
		Vector3 spos;
		for (int i = 0; i < length; i++)
		{
			spos = origin + dir*i;
			
			if (l == 32)
			{
				trail = UnmaykrLaserTrailFix(Spawn("UnmaykrLaserTrailFix2", spos, ALLOW_REPLACE));
				l = 0;
				
				if (increaseDur)
				{
					dur++;
					increaseDur = false;
				}
				else
					increaseDur = true;
			}
			else
				trail = UnmaykrLaserTrailFix(Spawn("UnmaykrLaserTrailFix", spos, ALLOW_REPLACE));
				
			trail.deathTimer = dur;
			l++;
		}
	}

	action void A_UnmaykrReady()
	{
		if(random(0,35) == 0)
		{
			Players[consoleplayer].psprites.frame = random(1,8);
			A_StartSound("world/spark", CHAN_WEAPON, CHANF_OVERLAP, 0.250);
		}
		else if(level.totaltime % 16 == 0)
		{
			Players[consoleplayer].psprites.frame = 0;
			A_StopSound(CHAN_WEAPON);
		}
		A_WeaponReady();
	}
}

Class FullUnmaykr : CustomInventory 
{
	Default
	{
	    Inventory.PickupMessage "";
	}
	States
	{
	Spawn:
		LSGR A -1 Bright;
		Stop;
	Pickup:
		TNT1 A 0 A_GiveInventory("DemonKeyCount", 3);
		TNT1 A 0 A_GiveInventory("Unmaykr", 1);
		TNT1 A 0 A_GiveInventory("OrangeKeyIcon", 1);
		TNT1 A 0 A_GiveInventory("PurpleKeyIcon", 1);
		TNT1 A 0 A_GiveInventory("CyanKeyIcon", 1);
		TNT1 A 0 A_GiveInventory("Backpack", 1);
		TNT1 A 0 A_GiveInventory("Cell", 600);
		TNT1 A 0 A_Print("\cgYou shall forever be Eternally damned, Cheater!");
		Stop;
	}
}

class LaserPuff : BulletPuff
{
	Default
	{
		Alpha 1;
		VSpeed 0;
	
		+PUFFONACTORS
		+ALWAYSPUFF
		+FORCEXYBILLBOARD
		+NOINTERACTION
	}
	
	States
	{
		Spawn:
			LPUF AB 3 BRIGHT A_FadeOut(0.10);
			Loop;
		Melee:
			Stop;
	}
}

class UnmaykrLaserTrailFix : Actor
{
	int deathTimer;
	int i;
	
	Default
	{
		Radius 1;
		Height 2;
		Scale 0.6;
	
		+NOINTERACTION;
		+FORCEXYBILLBOARD;
	}
	
	States
	{
		Spawn:
			UNML A 1 BRIGHT
			{
				if (i == deathTimer)
					SetState(null);
				else
					i++;
			}
			Loop;
	}
}

// Used for light source
class UnmaykrLaserTrailFix2 : UnmaykrLaserTrailFix {}
User avatar
Enjay
 
 
Posts: 27115
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Need Help with Unmaker Code

Post by Enjay »

Please stop bumping this thread with one word posts that add nothing. (Relevant posts have been moved.)

Your first bump was after just a few hours. We are quite a quiet forum these days, and we are international. You could easily have posted while someone who could help was in bed, and they could still have been there when you bumped!

What you are asking requires some specialist knowledge. Your weapon code is a little more complicated than a standard weapon mod.

Perhaps someone with the necessary skills hasn't come along. Perhaps someone has seen it, but hasn't had the time to reply. Perhaps no one who has seen it knows the answer.

You may or may not get an answer in time (I hope you do) but bumping the thread will not help, and it's against the forum rules.

viewtopic.php?t=27644
Patience is a virtue! If nobody's replied to your project thread within half an hour, don't just make another post and complain about how slow we are. Generally you'll want to wait a week (or until your thread drops off the first page) to bump it, if it's something important. Not everybody lives on the forums, and ZDoom isn't nearly as fast-paced as other message boards - it could take upwards of a couple days before anybody notices your thread, so count on waiting a while.
Post Reply

Return to “Scripting”