More broken WML: two Die events

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
Steelclad Brian
Posts: 110
Joined: November 15th, 2005, 5:26 am

More broken WML: two Die events

Post by Steelclad Brian »

The scenario I'm working on has been a real bear to debug, but I seem to have gotten 99% of the WML working. The only part that isn't is a seemingly very simple event that just won't fire. Really, it's a pair of events, but neither works.

Whats supposed to happen is once the attack gets under way, any time a human unit dies, it is supposed to be replaced by a walking corpse as long as a specific necromancer unit is still alive. There are two events: the first is to do the actual placing of the zombie, the second occurs when the first successful human ressurection takes place and gives some commentary via [message]. Unfortunately, nothing happens. I've gotten the other Die event to work, so I'm a bit mystified as to why this isn't working.

Code: Select all

#this event replaces dead units with walking corpses while necro
#is alive
[event]
	name=die
	first_time_only=no
	[filter]
		race=human
	[/filter]
		[if]
			[have_unit]
				description="The Oathbreaker"
			[/have_unit]
		[/if]
		[then]
			{ZOMBIE x1 y1}
		[/then]
[/event]

# inform the player of the effect of the necromancer
[event]
	name=die
	first_time_only=no
	[filter]
		race=human
	[/filter]
		[if]
			[have_unit]
				description=The Oathbreaker
			[/have_unit]
			[variable]
				name=undead_seen
				equals=0
			[/variable]
		[/if]
		[then]
			[message]
				speaker=narrator
				message= _ "To your horror, the corpse rises almost immediately after death. There must be some terrible magic at work."
			[/message]
			{VARIABLE_OP undead_seen add 1}
		[/then]
[/event]
and the ZOMBIE macro:

Code: Select all

#define ZOMBIE X Y
	[unit]
		type=Walking Corpse
		side=3
		x={X}
		y={Y}
	[/unit]
#enddef
User avatar
Tomsik
Posts: 1401
Joined: February 7th, 2005, 7:04 am
Location: Poland

Post by Tomsik »

Don't you need side=x in [have_unit]? (IIRC it uses side=1 by default)
User avatar
zookeeper
WML Wizard
Posts: 9742
Joined: September 11th, 2004, 10:40 pm
Location: Finland

Post by zookeeper »

[then] comes inside an [if], not after it.

You have:

Code: Select all

      [if]
         [have_unit]
            description="The Oathbreaker"
         [/have_unit]
      [/if]
      [then]
         {ZOMBIE x1 y1}
      [/then]
You need:

Code: Select all

    [if]
        [have_unit]
            description="The Oathbreaker"
        [/have_unit]
        [then]
            {ZOMBIE x1 y1}
        [/then]
    [/if]
(the other event has the same issue)
User avatar
Ranger M
Art Contributor
Posts: 1965
Joined: December 8th, 2005, 9:13 pm
Location: England

Post by Ranger M »

also the macro is named

Code: Select all

ZOMBIE X Y
and in the code you put

Code: Select all

{ZOMBIE x1 y1}
User avatar
zookeeper
WML Wizard
Posts: 9742
Joined: September 11th, 2004, 10:40 pm
Location: Finland

Post by zookeeper »

Ranger M wrote:

Code: Select all

{ZOMBIE x1 y1}
I wonder how I missed that...but yes, of course you need to use "{ZOMBIE $x1 $y1}" there.
scott
Posts: 5243
Joined: May 12th, 2004, 12:35 am
Location: San Pedro, CA

Post by scott »

In the [variable] tag, replace equals= with numerical_equals=
Hope springs eternal.
Wesnoth acronym guide.
Steelclad Brian
Posts: 110
Joined: November 15th, 2005, 5:26 am

Post by Steelclad Brian »

Tomsik wrote:Don't you need side=x in [have_unit]? (IIRC it uses side=1 by default)
It apparently works without a side specified. [have_unit] appears to just check whether a unit exists at all.

I made all the changes you guys indicated and it works fine, thanks, with one minor problem. When a human unit dies, it is indeed replaced by a walking corpse, but the walking corpse's placement is offset as if you had tried to place a unit where there already was one. I suppose the timing of the death event is such that the dying unit is still considered to be there, and so it gets placed in an adjacent hex.

I was thinking that I'd try and remedy that by placing a kill event before the unit placement event, although I'm not sure what happens when you kill a dead unit.

Thanks.
User avatar
zookeeper
WML Wizard
Posts: 9742
Joined: September 11th, 2004, 10:40 pm
Location: Finland

Post by zookeeper »

Steelclad Brian wrote:I was thinking that I'd try and remedy that by placing a kill event before the unit placement event, although I'm not sure what happens when you kill a dead unit.
That should work all right, I think, at least if you meant what I think you did. That is, [kill] the unit before you place the corpse, in the same [then] (not in a separate event).
Steelclad Brian
Posts: 110
Joined: November 15th, 2005, 5:26 am

Post by Steelclad Brian »

That is exactly what I plan to do, but I'm having a small problem. I've placed a [kill] event right before the unit creation macro, but I don't know how to filter to the unit I want. I know that primary_unit and secondary_unit get stored and about x1,y1 and x2,y2, but what should I be filtering to get primary_unit in this case? What kind of variables are primary_unit and secondary_unit?

I did this, assuming they were like pointers to a unit object:

Code: Select all

[then]
				[kill]
					description=$primary_unit.description
					animate=yes
					fire_event=no
				[/kill]
				{ZOMBIE $x1 $y1}
			[/then]
The results were rather apocalyptic. As soon as a single human died, every unit in the level was killed. :shock:

I've used primary_unit before with [message] tabs and speaker, but I'm not sure what it's looking for. Perhaps role? I'll try that next and see if I bring about the end-times again. I suppose I'll also try description, although I don't understand how that could work.

EDIT: Well, nothing I've tried has worked 100% so far.

I tried filtering by description and the placement was still wrong
I tried filtering by role and the placement was again, still wrong.
I tried filtering like this, using x1 and y1:

Code: Select all

[event]
	name=die
	first_time_only=no
	[filter]
		race=human
	[/filter]
		[if]
			[have_unit]
				description="The Oathbreaker"
			[/have_unit]
			[then]
				[kill]
					[filter]
						x=$x1
						y=$y1
					[/filter]
					animate=yes
					fire_event=no
				[/kill]
				{ZOMBIE $x1 $y1}
			[/then]
		[/if]
[/event]
And every unit in the level was killed, but the placement was correct! So now I'm just confused. :(
User avatar
zookeeper
WML Wizard
Posts: 9742
Joined: September 11th, 2004, 10:40 pm
Location: Finland

Post by zookeeper »

Steelclad Brian wrote:That is exactly what I plan to do, but I'm having a small problem. I've placed a [kill] event right before the unit creation macro, but I don't know how to filter to the unit I want. I know that primary_unit and secondary_unit get stored and about x1,y1 and x2,y2, but what should I be filtering to get primary_unit in this case? What kind of variables are primary_unit and secondary_unit?
Filtering by the location of the primary unit would be easiest. The coordinates of the primary unit are in variables x1 and y1. Try:

Code: Select all

[kill]
    x=$x1
    y=$y1
    animate=yes
    fire_event=no
[/kill]
primary_unit and secondary_unit are not variables. They're just convenient means to point to the units directly involved in the event in [message]s. x1,y1,x2 and y2 on the other hand are variables (which get set before the event is processed) that you can use with the dollar sign. However, you probably want to put animate=no instead, since the unit death animation has already been shown once (just before the event triggered).

If you had, for example, stored the primary_unit (with [store_unit] into a variable called xyz, you could give [kill] the kind of filter you suggested (description=$xyz.description) although it wouldn't be very reliable, since not all units have a unique description (most probably don't). It's usually best to filter with the coordinates.

EDIT: Your latest was exactly right (the same as my example above), but you put a [filter] tag into [kill], which takes the standard unit filter keys directly inside it, not encapsulated inside a [filter] tag.
Post Reply