Ability damage %HP owner help needed

The place to post your WML questions and answers.

Moderator: Forum Moderators

Forum rules
  • Please use [code] BBCode tags in your posts for embedding WML snippets.
  • To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
Post Reply
Soshen_
Posts: 13
Joined: May 12th, 2020, 12:01 pm

Ability damage %HP owner help needed

Post by Soshen_ »

Hi I try to build an ability who deal adjacent damage at the end the of turn, based on the owner current HP.
With my event i have an error message in the game debug console when the event triggers (and match filters) :
"attempt to perform arithmetic on a nil value (local 'base_damage')"

But i don't understand the error, what is a "nil" value ?
Can you help me to solve my problem please ?


My ability definition :

Code: Select all

	[ability]
    id=cold
    name= _ "cold"
    description= _ "At the end of the turn all surrounding units receive 60% of your curent HP in cold damage and get slowed. This ability in and of itself does not kill."
	[/ability]
My ability event

Code: Select all

[event]			# COLD EFFECT
	name=side turn end
	first_time_only=no
	[filter_condition]
		[have_unit]
			side=$side_number
			ability=cold
		[/have_unit]
	[/filter_condition]
	[harm_unit]
		[filter]
			[filter_adjacent]
				side=$side_number
				is_enemy=yes
			[/filter_adjacent]
			[not]
				trait=immune_to_specials
			[/not]
		[/filter]
		amount="$($self.hitpoints*0.6)"             <-------- THE PROBLEM I WANT TO SOLVE
		damage_type=cold
		alignment=neutral
		animate=yes
		slowed=no
		kill=no
		fire_event=no
		experience=no
		delay=0
	[/harm_unit]
[/event]
User avatar
Ravana
Forum Moderator
Posts: 3018
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: Ability damage %HP owner help needed

Post by Ravana »

nil is Lua keyword for empty. You have not stored anything into $self, so amount evaluates to empty, and [harm_unit] is required to have amount.
Soshen_
Posts: 13
Joined: May 12th, 2020, 12:01 pm

Re: Ability damage %HP owner help needed

Post by Soshen_ »

Oh my apologize i clean the variable before where i include this... And don't mind to re store it Fatigue ^^" I go to sleep
User avatar
Celtic_Minstrel
Developer
Posts: 2241
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Ability damage %HP owner help needed

Post by Celtic_Minstrel »

Soshen_ wrote: April 2nd, 2024, 9:08 am amount="$($self.hitpoints*0.6)" <-------- THE PROBLEM I WANT TO SOLVE
That's wrong. Delete the $ signs and you should have it working.

What that actually does is look for a WML container variable called self which contains a variable called hitpoints. Failing to find one, it deletes the substitution, resulting in text amount="$(*0.6)". It then attempts to evaluate the string *0.6 as a WFL formula, but that's not valid syntax, so it returns null. I think that results in the string amount="", or possibly (even worse) amount="null()". It then tries to convert that string to a number. Since it's not a number, trying to convert it to a number returns the value nil, which raises the error you mentioned when it trie to use it as a number.

What you want it to do is not substitute any variables at all. If it is amount="(self.hitpoints*0.6)", then there are no variables to substitute, so that exact string is passed to the engine, which will then try to convert it to a number like before. However, this time, it will recognize that it begins and ends with parentheses, so in order to convert it to a number it'll parse the string into a formula and evaluate that formula on the unit that owns the ability. That means that self refers to said unit, so self.hitpoints is the unit's hitpoints, and multiplying a number by a number is fine, and it returns the result of that calculation.

The key difference there is that it evaluates the formula on the unit that owns the ability. Even if you had removed the first $ (so you had amount="$(self.hitpoints*0.6)", that remaining $ means the formula is evaluated on nothing, instead of on the unit in question. So, it'll find that self doesn't exist, which means that self.hitpoints doesn't exist, which means it's calculating null() * 0.6, which again yields null() (since anything you can do to null() just returns null() again).
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Ravana
Forum Moderator
Posts: 3018
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: Ability damage %HP owner help needed

Post by Ravana »

The way I understood use was, $self was meant as unit with ability, not the unit being harmed.
User avatar
lhybrideur
Posts: 369
Joined: July 9th, 2019, 1:46 pm

Re: Ability damage %HP owner help needed

Post by lhybrideur »

What you would need would be to use a store_unit instead of the harm_unit with the same filter, then do a foreach on the store_unit variable with a harm_unit id=$this_item.id in it. This would let you access to the unit hitpoints with $this_item.hitpoints.
Please someone correct me if I am wrong.
User avatar
Celtic_Minstrel
Developer
Posts: 2241
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Ability damage %HP owner help needed

Post by Celtic_Minstrel »

Ravana wrote: April 11th, 2024, 7:49 am The way I understood use was, $self was meant as unit with ability, not the unit being harmed.
Hmm, you're right. I saw that this was about an ability and thought we were talking about an ability formula and missed the fact that, in fact, there was a [harm_unit] tag involved.

So, I think changing the ability to this would almost work:

Code: Select all

[heals]
    id=cold
    name= _ "cold"
    description= _ "At the end of the turn all surrounding units receive 60% of your curent HP in cold damage and get slowed. This ability in and of itself does not kill."
    value="(self.hitpoints*-0.6)"
    # possibly more stuff here, like filter_adjacent or something
[/heals]
However, when it comes to making your specific line in your actual code work, I think the only thing you would need to do is replace self with unit (instead of removing the $ signs).
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
lhybrideur
Posts: 369
Joined: July 9th, 2019, 1:46 pm

Re: Ability damage %HP owner help needed

Post by lhybrideur »

Just trying to understand here. What would be filling in the unit variable? Harm_unit filter?
User avatar
Celtic_Minstrel
Developer
Posts: 2241
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Ability damage %HP owner help needed

Post by Celtic_Minstrel »

That's a good question, and it made me realize that you want $this_unit (which is indeed filled in by [harm_unit]) rather than $unit (which is filled in by the event, but in your case would be blank since it's a turn event).
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
lhybrideur
Posts: 369
Joined: July 9th, 2019, 1:46 pm

Re: Ability damage %HP owner help needed

Post by lhybrideur »

Checking VariableWML, I discover that [filter] fills in this_unit. That is a valuable piece of info.
User avatar
Celtic_Minstrel
Developer
Posts: 2241
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Ability damage %HP owner help needed

Post by Celtic_Minstrel »

Yes, but that doesn't help your specific use-case here, because the filter clears harm_unit once it's done filtering. The key is that harm_unit also fills in this_unit.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
Post Reply