3 questions: to_location; chaining events ; store_unit

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.
User avatar
Helmet
Posts: 331
Joined: December 19th, 2006, 5:28 pm
Location: Florida, USA

Re: 3 questions: to_location; chaining events ; store_unit

Post by Helmet »

beetlenaut wrote: January 2nd, 2021, 4:34 pm [have_unit] is just a standard unit filter when it's used inside an [if] tag. (So it works the same as [filter] in an event.)
Ohhh. That's perfect. I thought it had different rules. I finally 'get' have_unit. Thanks.
WhiteWolf wrote: January 2nd, 2021, 5:24 pm As beetlenaut says, so the standard unit filter keys are recognized.

Otherwise you could just use a formula for this.

Code: Select all

[have_unit]
    id=Moho
    formula="level < 2"
[/have_unit]
I almost never think about formulas, but that looks pretty easy. I'm mentally adding formulas to my toolkit of solutions.
WhiteWolf wrote: January 2nd, 2021, 5:24 pm There is a level key, but I don't know if would accept a comma separated list of level=0,1. (You could test it so that the wiki can be amended with the result info).
I tested your idea and level=0,1 works. Yay. Thanks.

Code: Select all

[event]
	name=turn 3	
	[if]
		[have_unit]
			id=Moho
			level=0,1
		[/have_unit]
		[then]
			[message]
				speaker=Moho
				message= _ "Hi, I am level 0 or level 1."
			[/message]
		[/then]	
		[else]			
			[message]
				speaker=Moho
				message= _ "Hi, I am NOT level 0 or level 1."
			[/message]
		[/else]				
	[/if]
[/event]		

User avatar
WhiteWolf
Forum Moderator
Posts: 739
Joined: September 22nd, 2009, 7:48 pm
Location: Hungary

Re: 3 questions: to_location; chaining events ; store_unit

Post by WhiteWolf »

Helmet wrote: January 2nd, 2021, 6:59 pm I finally 'get' have_unit. Thanks.
For future reference, it also has an option to search on a recall lists as well, and you can even specify the count for the number of units that must match the filter. Neat tools to use.
level=0,1 works. Yay. Thanks.
Thanks, I added the info that it accepts comma separated lists to the wiki :)
Author of the Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny
Standalone works: The Ravagers - now for 1.14, with new bugs!
User avatar
Helmet
Posts: 331
Joined: December 19th, 2006, 5:28 pm
Location: Florida, USA

Re: 3 questions: to_location; chaining events ; store_unit

Post by Helmet »

I spoke too soon. Evidently I still don't 'get' have_unit.

A unit (id=ShroomkinLeader) is injured. When he is fully healed (61 hitpoints) he will speak a message. The code does not work. The message fires the first turn, even though he has fewer than 61 hitpoints.

Code: Select all

[event]
	name=side 2 turn
	first_time_only=yes
	[if]
		[have_unit]
			id=ShroomkinLeader
			hitpoints=61
		[/have_unit]		
		[then]
			[message]
Oh, I found another hitpoint problem during playtesting. A corrupted unit is not receiving their hitpoint bonus.

Code: Select all

#define CORRUPTED_VIA_UNIT
    name= _ "Corrupted"
	[status]
		corrupted=yes
	[/status]
	side=2
	upkeep=free
	hitpoints = "$($this_unit.hitpoints + 2)" # 			temporary hitpoints
# 	etc.	

CORRUPTED_VIA_UNIT is used when a unit is created.

CORRUPTED_VIA_MODIFY_UNIT is almost identical, but is only used within modify_unit. What's strange is that "$($this_unit.hitpoints + 2)" works inside CORRUPTED_VIA_MODIFY_UNIT, but not CORRUPTED_VIA_UNIT.

Thanks for any light that you can shine on these mysteries.
User avatar
WhiteWolf
Forum Moderator
Posts: 739
Joined: September 22nd, 2009, 7:48 pm
Location: Hungary

Re: 3 questions: to_location; chaining events ; store_unit

Post by WhiteWolf »

Helmet wrote: January 2nd, 2021, 10:19 pm I spoke too soon. Evidently I still don't 'get' have_unit.

A unit (id=ShroomkinLeader) is injured. When he is fully healed (61 hitpoints) he will speak a message. The code does not work. The message fires the first turn, even though he has fewer than 61 hitpoints.
Standard Unit Filter has no hitpoints key. Use the wiki when you don't know if a key is supported or not :) Anything that is not listed is unsupported.
Easiest way for this is a formula again. formula="hitpoints = 61". Alternatively you can use [filter_wml] to filter for wml attributes of units:

Code: Select all

[have_unit]
    [filter_wml]
        hitpoints=61
    [/filter_wml]
[/have_unit]
But keep in mind that [filter_wml] is marked as a slow method by the wiki, so I just recommend using the formula.
Also, I think the event is currently very bug-prone. It will always fire since it has no filters, and you specifically set first_time_only to yes, so the event will be used up and won't fire again if the unit is not yet fully healed. I recommend moving the condition to a filter so that the event doesn't get used up prematurely by any means.

Code: Select all

[event]
    name=side 2 turn
    first_time_only=yes   # (edited - previously i accidentaly set it to no, sorry.)
    [filter_condition]
        [have_unit]
            id=ShroomkinLeader
            formula="hitpoints = 61"
        [/have_unit]
    [/filter_condition]
    
    # contents of your [then]
CORRUPTED_VIA_MODIFY_UNIT is almost identical, but is only used within modify_unit. What's strange is that "$($this_unit.hitpoints + 2)" works inside CORRUPTED_VIA_MODIFY_UNIT, but not CORRUPTED_VIA_UNIT.
This is because $this_unit is supported for [modify_unit], but it is not for unit creation. I don't think that a unit that is just being created has its hitpoints defined (I mean, it is not stored in $this_unit, otherwise it equals the max_hitpoints. The hitpoints key is a valid modifier, but the variable doesn't exist), so for that reason I don't think it's even possible to implement [unit] to support $this_unit. Just create the unit, and modify the hitpoints right after creation when the unit already exists.
Author of the Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny
Standalone works: The Ravagers - now for 1.14, with new bugs!
User avatar
Helmet
Posts: 331
Joined: December 19th, 2006, 5:28 pm
Location: Florida, USA

Re: 3 questions: to_location; chaining events ; store_unit

Post by Helmet »

WhiteWolf wrote: January 2nd, 2021, 10:41 pm Standard Unit Filter has no hitpoints key. Use the wiki when you don't know if a key is supported or not :) Anything that is not listed is unsupported.
I thought I had verified it in the Wiki as acceptable, but what I had been looking at was Unit State. It's probably a common mistake. After all, they both have the word "unit" in them.

Ha ha, joking.

Sort of.
WhiteWolf wrote: January 2nd, 2021, 10:41 pm Easiest way for this is a formula again...
But keep in mind that [filter_wml] is marked as a slow method by the wiki, so I just recommend using the formula.
Also, I think the event is currently very bug-prone. It will always fire since it has no filters, and you specifically set first_time_only to yes, so the event will be used up and won't fire again if the unit is not yet fully healed. I recommend moving the condition to a filter so that the event doesn't get used up prematurely by any means.
That bug-filled event was very important. I'm relieved its working now. Thanks.

I originally had only 1 corruption macro, but it didn't work all the time. The problem, I discovered, was that modify_unit and modifications didn't work the same way. So I made two versions of corruption, one for modify_unit and one for modifications. That helped a lot, but it was still flawed when it came to hitpoints. I'll do what you suggested and just use modify_unit for all the corruptions.
User avatar
WhiteWolf
Forum Moderator
Posts: 739
Joined: September 22nd, 2009, 7:48 pm
Location: Hungary

Re: 3 questions: to_location; chaining events ; store_unit

Post by WhiteWolf »

Helmet wrote: January 3rd, 2021, 12:47 am So I made two versions of corruption, one for modify_unit and one for modifications. That helped a lot, but it was still flawed when it came to hitpoints. I'll do what you suggested and just use modify_unit for all the corruptions.
If you want to stick to your current layout with the macros, it's actually quite possible, using the tag-amendment syntax ;)

Code: Select all

#define CORRUPTED_VIA_UNIT ID
    name= _ "Corrupted"
	[status]
		corrupted=yes
	[/status]
	side=2
	upkeep=free
	[/unit]
	[modify_unit]
	    [filter]
	        id={ID}
	    [/filter]
	    hitpoints = "$($this_unit.hitpoints + 2)" # 			temporary hitpoints
	[/modify_unit]
	[+unit]
# 	etc.	
#enddef
Note that the id, type, side and x,y values should be in the initial [unit] tag before it's ended by the macro for it to be valid:

Code: Select all

[unit]
    type=its_type
    x,y=6,7
    id=corrupted_53
    {CORRUPTED_VIA_UNIT corrupted_53}
[/unit]
This should work, but it might also be just a better idea to put the whole thing into a macro like the core unit placement macros and just use that, it makes the code even tidier (and keeps in-line with house conventions):

Code: Select all

#define CORRUPTED_UNIT SIDE TYPE X Y WML
    {UNIT {SIDE} {TYPE} {X} {Y} {WML}}
    [+unit]
        [status]
		corrupted=yes
	[/status]
	upkeep=free # but note my comment at the end
    [/unit]
    [modify_unit]
        [filter]
            id={ID}
        [/filter]
        hitpoints= "$($this_unit.hitpoints + 2)" 
    [/modify_unit]
#enddef
Then placing a corrupted unit in action wml is just:

Code: Select all

{CORRUPTED_UNIT 2 your_type x y ()}
One more thing I noticed - be wary of upkeep inside [unit], it's value won't persist when certain things are performed by the engine. (But wasn't this already discussed in another topic?) Anyway, giving it an invisible loyal [effect] is the preferable way for this.
Author of the Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny
Standalone works: The Ravagers - now for 1.14, with new bugs!
User avatar
Helmet
Posts: 331
Joined: December 19th, 2006, 5:28 pm
Location: Florida, USA

Re: 3 questions: to_location; chaining events ; store_unit

Post by Helmet »

WhiteWolf wrote: January 3rd, 2021, 9:46 am If you want to stick to your current layout with the macros, it's actually quite possible, using the tag-amendment syntax ;)
Oh no! Tag amendment syntax! :shock:
WhiteWolf wrote: January 3rd, 2021, 9:46 am
Spoiler:
Then placing a corrupted unit in action wml is just:

Code: Select all

{CORRUPTED_UNIT 2 your_type x y ()}
All that code looks amazing. I wish I had checked this post before I already changed everything! I streamlined the corruption process to one macro which uses modify_unit, like you suggested. It worked great. I am tempted to implement the above nifty code...but...there's the old saying, "If it ain't broke, don't fix it."
WhiteWolf wrote: January 3rd, 2021, 9:46 am One more thing I noticed - be wary of upkeep inside [unit], it's value won't persist when certain things are performed by the engine. (But wasn't this already discussed in another topic?) Anyway, giving it an invisible loyal [effect] is the preferable way for this.
Oh, thanks for catching that. I had removed upkeep=free elsewhere in the campaign, but that one slipped by me.
Post Reply