[ZS] Changing weapon sprite with script

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!)
User avatar
Virathas
Posts: 220
Joined: Thu Aug 10, 2017 9:38 am

[ZS] Changing weapon sprite with script

Post by Virathas »

Hey everybody!

I have been lately refactoring some code, making it way more compact thanks to the almighty power of ZScipt. Yet, while I can do a lot by now, i still am somtimes stumped with some features.

I am working on a weapon, that is a wrapper of many potential weapon (consolidiating over 100 actual weapons into one). While everything works as I would like, i still need to have a few different varieties of how the weapon looks (depending on meta-data)

So the main question is: How do you change a weapon sprite via script? I am able to change a projectile sprite with code like this:

Code: Select all

Sprite = GetSpriteIndex("COOL");
And then referencing sprites in states with ####.

However, this does not work with weapons. I'd wager, that there is a different variable than sprite for that, but I was unable to find it.
User avatar
Virathas
Posts: 220
Joined: Thu Aug 10, 2017 9:38 am

Re: [ZS] Changing weapon sprite with script

Post by Virathas »

I don't know if I am cursed, but as soon as I asked the question here I found my answer:
For anyone looking to do so:

Code: Select all


let psp = Invoker.Owner.player.FindPSprite(PSP_WEAPON);
psp.Sprite = GetSpriteIndex("COOL");

User avatar
Sir Robin
Posts: 392
Joined: Wed Dec 22, 2021 7:02 pm
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: Intel (Modern GZDoom)
Location: Medellin, Colombia

Re: [ZS] Changing weapon sprite with script

Post by Sir Robin »

Virathas wrote:I don't know if I am cursed, but as soon as I asked the question here I found my answer:
For anyone looking to do so:

Code: Select all


let psp = Invoker.Owner.player.FindPSprite(PSP_WEAPON);
psp.Sprite = GetSpriteIndex("COOL");

Could you explain this a little bit please? I have a similar thing where I have my weapons defined and working but I have several sprite sets to use (depending on if the player is left or right handed, skin color, glove color, etc) so I want to swap out sprites without changing anything else in the weapon definition. All the animations for a single weapon fit in the 29 frames of a single 4-character sprite set so I just need to swap one sprite base set for another.
User avatar
Virathas
Posts: 220
Joined: Thu Aug 10, 2017 9:38 am

Re: [ZS] Changing weapon sprite with script

Post by Virathas »

Sure thing!
The best way to explain is to show some code:

Code: Select all

Select:
	TNT1 A 0;
	#### A 0 A_SetWeaponGraphics();
ContinueSelect:
    #### A 1 A_Raise;
    Loop;
Deselect:
	#### A 1 A_Lower;
        Loop;
Ready:
	TNT1 A 0 A_SetWeaponGraphics();
    #### A 1 A_WeaponReady;
    Loop;
Fire: 
	#### ABC 0;
        #### D 0 A_FireSomethingGood();
        #### EFG 0;
	Goto Ready;
This is simple weapon states, the #### sprite means "use the last spirte used". Since we only provide sprite frame, the sprite is "last", but the frame of the sprite is the letter. You could use something like "#### # 1" which would use the last sprite and frame.
The other important parts, is the first state of Select and Ready - it needs to be something defined, or else the item will be considered invalid (I think Spawn state also requires this).
The A_SetWeaponGraphics() is the function that does the sprite changing magic:

Code: Select all

action void A_SetWeaponGraphics ()
{
	let psp = Invoker.Owner.player.FindPSprite(PSP_WEAPON);
		switch (Invoker.Material)
		{
		case 1:
		{
			
			psp.Sprite = getspriteindex("HUBW");
			break;
		}
		case 2:
		{
			psp.Sprite = getspriteindex("IMBW");
			break;
		}
                }
}
Since i did copy paste from my implementation, it uses meta data from the weapon (Material). But it could be anything, you could have like "Owner.CountInv("ItemForSomeStuffCheck");".

Hope it clears up stuff more than it confuses :)
User avatar
Sir Robin
Posts: 392
Joined: Wed Dec 22, 2021 7:02 pm
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: Intel (Modern GZDoom)
Location: Medellin, Colombia

Re: [ZS] Changing weapon sprite with script

Post by Sir Robin »

So if I'm understanding this correctly, that psp.Sprite is what gets used whenever there is a "####" in the state code?
User avatar
Virathas
Posts: 220
Joined: Thu Aug 10, 2017 9:38 am

Re: [ZS] Changing weapon sprite with script

Post by Virathas »

#### uses the last sprite, but since we are setting the sprite manually with the function it will be last. If at any time you use anything else than #### in state, it will use a different. in example:

Code: Select all

#### A 1 A_ChangeGFX(); // We use the function to set graphics of STAR
#### ABC 1; // It displays STAR ABC
NWGF DEF 1; // displays NWGF DEF
#### GH 1; // displays NWGF GH
Technically using somethign like
NWGF A 1 A A_ChangeGFX();
woudl still display what the A_ChangeGFX change the sprite to

Return to “Scripting”