Page 1 of 1

Making a player lose points when damaged

Posted: Thu Mar 02, 2023 3:45 am
by giwake
Hello.
I'm currently working on a TC with a score system, and I'm trying to make it so that when the player is damaged they lose points.
Here's my code so far.

Decorate code

Code: Select all

ACTOR NewMarine : Doomplayer
{
    Player.StartItem "Clip", 24 //TODO: Replace clip with other ammo for 3d model support.
    Player.StartItem "Revolver"
    Player.StartItem "Kick" 
	States {
	Pain:
		PLAY G 4 A_GiveInventory("owie") //CULPRIT #1: Maybe this isn't actually giving the owie actor?
		PLAY G 4 A_Pain
		Goto Spawn
	
	}
}

ACTOR owie : CustomInventory
{
  Inventory.PickupMessage "owie" //TODO: remove when this shit works
  iNVENTORY.AMOUNT 1
  +AUTOACTIVATE
  States
  {
  Spawn:
    TNT1 A 1
    Loop
  PICKUP:
    TNT1 A 0
    Stop
  }
}
ACS code:

Code: Select all

Script "PAINCHECK" (void) //Player loses points when hit by enemies
{
	If(CheckInventory("owie")) //CULPRIT #2: Maybe this isn't finding the owie actor?
	{
		SetActorProperty(0, APROP_Score, (GetActorProperty(0, APROP_Score)-(Random(8,15))));
		print(s:"OWIE!");
		TakeInventory("owie", 1);

	}

}

The issue is that when the player loses health and enters the pain state, they don't actually lose points for some reason.
I've left some comments where I think some issues might be, but I'm not 100% certain on what could be causing this to not work.

Re: Making a player lose points when damaged

Posted: Thu Mar 02, 2023 4:32 am
by ramon.dexter
Okay, this could be executed even better in zscript. Try using this for your base marine class (untested, only to give basic idea on how to do it in zscript):

Code: Select all

class NewMarine : DoomPlayer {
	int score;
	Default {
		NewMarine.score 0; //if you want to pre-set some base value of score
	}
	Override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle) {
		int newdamage;
		
		let pawn = self.player;
		pawn.score--;
		Return Super.DamageMobj(inflictor,source,damage,mod);
	}
}

Re: Making a player lose points when damaged

Posted: Thu Mar 02, 2023 5:26 am
by Jarewill
As Ramon said, ZScript's DamageMobj will work better, although Score is already a property of Actor, so it will error out if you try to redefine it.
But as for the reason why your code doesn't work, I have two ideas:
First is that you don't call your ACS script from anywhere, it won't automatically run whenever the player takes damage, but I will for now assume you are calling this script from a sort of "master script" that's looping.
Second is seeing how you check for the owie item, it being a CustomInventory with +AUTOACTIVATE and no Use state might be the reason it's messing up, it might be worth to make it a simple Inventory item instead, like so:
ACTOR owie : Inventory { Inventory.MaxAmount 1 }

If the issue persists, it might be worth posting your project here so we can look inside it.

Edit: Looking closer at Ramon's code, I can see an issue.
Putting self.player will interpret the actor as PlayerInfo, which has a completely different set of variables and properties and as such won't read the Score variable.
So instead of using this:

Code: Select all

let pawn = self.player;
pawn.score--;
You can just use this: self.Score--;
And again, Score is already defined in the Actor class, so redefining it can lead to an error.

Re: Making a player lose points when damaged

Posted: Thu Mar 02, 2023 6:02 am
by giwake
I quickly slapped the ZScript into my mod, unfortunately I'm getting an error message.

Code: Select all

E:/SuperRad/Build/:zscript.zc, line 93: '@property@NewMarine.Score' is an unknown actor property.
My ZScript is this:

Code: Select all

class NewMarine : DoomPlayer {

	int score;
	Default {
		NewMarine.score 50; //if you want to pre-set some base value of score
		Player.StartItem "Clip", 24; //TODO: Replace clip with other ammo for 3d model support.
		Player.StartItem "Revolver";
		Player.StartItem "Kick";
	}
	Override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle) {
		int newdamage;
		
		self.Score--;
		Return Super.DamageMobj(inflictor,source,damage,mod);
	}
}
Is it score that might be causing the issue?

Re: Making a player lose points when damaged

Posted: Thu Mar 02, 2023 6:04 am
by giwake
Scratch that, I figured out an absolutely awful hack to fix it, but it works and at this point I'm just happy that my code works :V

I commented out the definition for newmarine.score and then made a script inside my map that sets the player's score to 50 at the start of the map.
I can only hope and pray that I never have to touch this code ever again.

Re: Making a player lose points when damaged

Posted: Thu Mar 02, 2023 11:00 am
by ramon.dexter
Jarewill wrote: Thu Mar 02, 2023 5:26 am As Ramon said, ZScript's DamageMobj will work better, although Score is already a property of Actor, so it will error out if you try to redefine it.
But as for the reason why your code doesn't work, I have two ideas:
First is that you don't call your ACS script from anywhere, it won't automatically run whenever the player takes damage, but I will for now assume you are calling this script from a sort of "master script" that's looping.
Second is seeing how you check for the owie item, it being a CustomInventory with +AUTOACTIVATE and no Use state might be the reason it's messing up, it might be worth to make it a simple Inventory item instead, like so:
ACTOR owie : Inventory { Inventory.MaxAmount 1 }

If the issue persists, it might be worth posting your project here so we can look inside it.

Edit: Looking closer at Ramon's code, I can see an issue.
Putting self.player will interpret the actor as PlayerInfo, which has a completely different set of variables and properties and as such won't read the Score variable.
So instead of using this:

Code: Select all

let pawn = self.player;
pawn.score--;
You can just use this: self.Score--;
And again, Score is already defined in the Actor class, so redefining it can lead to an error.
Sorry for the mistake, I didn't checked the actor class ;)