Duke Nukem-like medikit item.

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!
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!)
User avatar
Ahpiox
Posts: 98
Joined: Fri Dec 22, 2017 1:52 am

Duke Nukem-like medikit item.

Post by Ahpiox »

Now i trying to make Duke-like medikit. This medikit have 100 HP, and when used, just transferring his points to player.
But "Use" state just don't wanna do it properly, and even small tricks don't help at all. Help please

Code: Select all

ACTOR Nuking_Medik : CustomInventory replaces Medikit
{
  +COUNTITEM
  Inventory.MaxAmount 1
  Scale 0.5
  Inventory.PickupMessage "Portable Medikit"
  States
  {
  Spawn:
    0018 C -1
    Loop
  Pickup:
	TNT1 A 0 A_JumpIf(CountInv("Nuking_MedikCount") > 0, "Stopp")
	TNT1 A 0 A_GiveInventory("Nuking_MedikCount", 100)
	Stop
  Stopp:
	Stop
  }
}

ACTOR Nuking_MedikCount : CustomInventory
{
  +COUNTITEM
  +INVENTORY.ALWAYSPICKUP
  +INVENTORY.INVBAR
  Inventory.MaxAmount 100
  Scale 0.5
  States
  {
  Spawn:
    0018 C -1
    Loop
  Use:
  HealthyLoop:
	TNT1 A 0 A_JumpIf(CountInv("Nuking_MedikCount") == 0, "End")
	TNT1 A 0 A_GiveInventory("Health",1)
	TNT1 A 0 A_Jump(256,"Use")
	Stop
  End:
	Stop
  }
}
User avatar
ramon.dexter
Posts: 1562
Joined: Tue Oct 20, 2015 12:50 pm
Graphics Processor: nVidia with Vulkan support
Location: Kozolupy, Bohemia

Re: Duke Nukem-like medikit item.

Post by ramon.dexter »

So, this cannot be done in plain decorate, because CustomInventory items cannot have loops in use state. Its just impossible.

But, it is achievable in zscript with quite ease.

Take a look at this example. It's a healing powerup that provides regeneration while active. Uses the CustomInventory item as an 'ammo' or resource.

Code: Select all

class regenModule_Item : CustomInventory
{
	int rgnModSwitch;
	
	Default
	{
		//$Category "SoA/Items"
		//$Color 9
		//$Title "Regeneration Module"
		
		+INVENTORY.INVBAR
		+INVENTORY.ALWAYSPICKUP
		-SOLID
		
		Tag "$T_RGNMDL";
		radius 8;
		height 24;
		scale 1;
		inventory.icon "I_RGNM";
		inventory.amount 100;
		inventory.maxamount 200;
		inventory.interhubamount 200;
		inventory.PickupMessage "$F_RGNMDL";
	}
	
	States
	{
		Spawn:
			RGNM AB 8;
			Loop;
		
		Use:
			TNT1 A 0
			{
				if(invoker.rgnModSwitch == 0) {return ResolveState("Activate");}
				if(invoker.rgnModSwitch == 1) {return ResolveState("Deactivate");}
				return ResolveState(null);
			}
		Activate:
			TNT1 A 0
			{
				invoker.rgnModSwitch = 1;
				A_Giveinventory("RegenModuleActive", 1);
				A_Giveinventory("regenModuleActiveToken", 1);
			}
			Stop;
		Deactivate:
			TNT1 A 0
			{
				invoker.rgnModSwitch = 0;
				A_TakeInventory("PowerRegenModule");
				A_TakeInventory("RegenModuleActive");
				A_TakeInventory("regenModuleActiveToken");
			
			}
			Stop;
	}

}

//==--------------------------------------------------------------------------==
//mechanics
//==--------------------------------------------------------------------------==
class regenModuleActiveToken : Inventory
{
	Default
	{
		-INVENTORY.INVBAR

		inventory.amount 1;
		inventory.maxamount 1;
		inventory.interhubamount 1;
	}

}
class PowerRegenModule : PowerRegeneration
{
	int regnModCount; 

    override void attachtoowner(actor user)
    {
        regnModCount = 0;
        super.attachtoowner(user);
    }

    override void doeffect()
    {
		Super.doEffect();
        
		if(owner.countinv("regenModule_Item") <= 1) 
        {
            owner.takeinventory("RegenModuleActive", 1);
			owner.takeinventory("regenModuleActiveToken", 1);
			self.destroy();
			return;
		}

        regnModCount++;

        if(regnModCount == 35)
        {
            owner.takeinventory("regenModule_Item", 1);
            regnModCount = 0;
		
        }

    }
	
	Default
	{
		powerup.duration 0x7FFFFFFD;
		powerup.strength 2;
		inventory.icon "I_BLNK";
	}
}



class RegenModuleActive : PowerupGiver
{
	Default
	{
		+INVENTORY.AUTOACTIVATE
		+INVENTORY.FANCYPICKUPSOUND
		+Inventory.PickupFlash
		
		powerup.duration 0x7FFFFFFD;
		powerup.Type "PowerRegenModule";
		powerup.color "A70000", 0.3;
		inventory.pickupmessage "Regeneration!!";
		inventory.maxamount 0;
		inventory.usesound "pickups/slowmo";
	}
	
	States
	{
		Spawn:
			RGNM AB 8;
			Loop;
	}

}
//==--------------------------------------------------------------------------==


User avatar
Ahpiox
Posts: 98
Joined: Fri Dec 22, 2017 1:52 am

Re: Duke Nukem-like medikit item.

Post by Ahpiox »

Thanks for reply, also i will try to find more easy way.
User avatar
wildweasel
Posts: 21706
Joined: Tue Jul 15, 2003 7:33 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): A lot of them
Graphics Processor: Not Listed

Re: Duke Nukem-like medikit item.

Post by wildweasel »

ramon.dexter wrote:So, this cannot be done in plain decorate, because CustomInventory items cannot have loops in use state. Its just impossible.
Absolutely untrue; here is DECORATE code from ww-cola3 that has a loop in its use state and accomplishes what Ahpiox wants in much, MUCH less code:

Code: Select all

ACTOR WaterFlask : CustomInventory replaces HealthBonus
{
	Inventory.Icon "BON1ICON"
	Inventory.InterHubAmount 0x7fffffff
	Inventory.MaxAmount 100
	Inventory.Amount 2
	Inventory.PickupMessage "PortaCola - \"Cola you can take with you!\""
	Inventory.PickupSound "portacola/pickup"
	Tag "PortaCola Flask"
	+INVENTORY.INVBAR
	+INVENTORY.UNDROPPABLE
	//+INVENTORY.KEEPDEPLETED
	+INVENTORY.UNTOSSABLE
	States
	{
	Spawn:
		BON1 A -1
		Stop
	Use:
		TNT1 A 0 A_JumpIf(health >= 100, "DontDrinkNoNoise")
	UseLoop:
		TNT1 A 0 A_JumpIf(health >= 100, "DontDrink")
		TNT1 A 0 A_TakeInventory("WaterFlask", 1)
		TNT1 A 0 A_GiveInventory("Health", 1)
		TNT1 A 0 A_JumpIfInventory("WaterFlask", 1, "UseLoop")
	FlaskEmpty:
		TNT1 A 0 A_PlaySound("portacola/drink", CHAN_ITEM)
		Fail
	DontDrink:
		TNT1 A 0 A_PlaySound("portacola/drink", CHAN_ITEM)
		Fail
	DontDrinkNoNoise:
		TNT1 A 0 A_Print("Can't drink, health already full!")
		Fail
	}
}
User avatar
Ahpiox
Posts: 98
Joined: Fri Dec 22, 2017 1:52 am

Re: Duke Nukem-like medikit item.

Post by Ahpiox »

Such thanks for code! I need to give credit for someone?
User avatar
wildweasel
Posts: 21706
Joined: Tue Jul 15, 2003 7:33 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): A lot of them
Graphics Processor: Not Listed

Re: Duke Nukem-like medikit item.

Post by wildweasel »

Ahpiox wrote:Such thanks for code! I need to give credit for someone?
Just me. :D
User avatar
ramon.dexter
Posts: 1562
Joined: Tue Oct 20, 2015 12:50 pm
Graphics Processor: nVidia with Vulkan support
Location: Kozolupy, Bohemia

Re: Duke Nukem-like medikit item.

Post by ramon.dexter »

Oh, my bad. CustomInventory cannot have duration in use.

Return to “Scripting”