Xudo questions about WML.

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
Xudo
Posts: 563
Joined: April 3rd, 2009, 5:26 pm

Re: Xudo questions about WML.

Post by Xudo »

Yeah.
Invalid WML found: [unit_type] not supported

Code: Select all

	[set_variables]
		name = test_unit_container
		mode = append
		[literal]
			id=Elvish Archer123
			name= _ "Elvish Archer"
			race=elf
			gender=male,female
			image="units/elves-wood/archer.png"
			{MAGENTA_IS_THE_TEAM_COLOR}
			profile="portraits/elves/archer.png"
			hitpoints=29
			movement_type=woodland
			movement=6
			experience=44
			level=1
			alignment=neutral
			advances_to=Elvish Ranger,Elvish Marksman
			cost=17
			usage=archer
			description= _ "Elves have always had a reputation for archery, a skill that, for many reasons, comes naturally to them. Even the frail of body can be deadly with a bow in hand, and in times of war, many will take up this weapon. Though their relative inexperience with combat leaves them somewhat vulnerable, their natural grace ensures that they can best any of humanity’s fresh recruits."
			die_sound={SOUND_LIST:ELF_HIT}
			[portrait]
				size=400
				side="left"
				mirror="false"
				image="portraits/elves/transparent/archer.png"
			[/portrait]
			[portrait]
				size=400
				side="right"
				mirror="true"
				image="portraits/elves/transparent/archer.png"
			[/portrait]
			[attack]
				name=sword
				description=_"sword"
				icon=attacks/sword-elven.png
				type=blade
				range=melee
				damage=5
				number=2
			[/attack]
			[attack]
				name=bow
				description=_"bow"
				icon=attacks/bow-elven.png
				type=pierce
				range=ranged
				damage=5
				number=4
			[/attack]
		[/literal]
	[/set_variables]
	{GLOBAL_VARIABLE "Tales_of_Irdya" test_unit_container test_unit_container 1}
	[insert_tag]
		name = unit_type
		variable = test_unit_container
	[/insert_tag]
Looks like I will need to handle recruit event instead.
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: Xudo questions about WML.

Post by tekelili »

I am not 100% sure, but I would say [unit_type] can not be used inside event, and in general, can not be used in same context where [insert_tag] is supported.
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
User avatar
Dugi
Posts: 4961
Joined: July 22nd, 2010, 10:29 am
Location: Carpathian Mountains
Contact:

Re: Xudo questions about WML.

Post by Dugi »

As zookeeper said, unit_type can't be used as ActionWML, thus doesn't work inside event. You can't define unit_type dynamically. They are defined when loading. You can use store_unit_type or wesnoth.unit_types to read them, but there is no tool to modify them.

However, the situation isn't so desperate. You can modify a lot of properties of a unit when unstoring it (or using [insert_tag] with name=unit, that one is sometimes better than unstore_unit), including race, health, damage, level, weapon specials, maximum attacks per turn and also appearance to some extent. The things that cannot be changed are type (and thus type name displayed) and AMLA. As far as I know, you don't wanna use the in-game experience as a way to level-up, so AMLA immutability will not matter. This is very close to an ability to create dynamic unit types (you aren't gonna create dynamically unit type names, right?).

Changing everything except graphics can be done simply via set_variable, graphics are a bit tricky but I'll explain that if you'll want.
User avatar
Xudo
Posts: 563
Joined: April 3rd, 2009, 5:26 pm

Re: Xudo questions about WML.

Post by Xudo »

I want to use default AI recruitment behavior to spawn enemies constantly.
It is very convenient. You can easily manage rate of spawning (by giving gold/modifying income) or recruitment pattern, or quantity of recruited enemies per turn. In addition, players can kill enemy leader and spawning will stop.
It is possible to create it all by wml/lua, but I don't want to bother reinventing the wheel.

Using event=recruit I can apply random predefined template to recruit unit, so the problem is partially solved.
User avatar
Dugi
Posts: 4961
Joined: July 22nd, 2010, 10:29 am
Location: Carpathian Mountains
Contact:

Re: Xudo questions about WML.

Post by Dugi »

With a project like the one you're planning, it will be quite unpleasant to let the AI pick what is recruited. AI may find your hero's weakness and recruit almost solely the units that are good against him. Characters whose weakness isn't found by the AI recruiter (or those whose weakness is found wrongly, AI can't consider some right-click menu options) would be in advantage with characters whose AI is found by it. If you just used recruitment_pattern with a shorter list of possible units, it would be no different from random spawning in the IftU style.

Enough philosophy.

I think that you'll have to let it recruit some template units and use a prerecall event that will assign right properties to them.
User avatar
Xudo
Posts: 563
Joined: April 3rd, 2009, 5:26 pm

Re: Xudo questions about WML.

Post by Xudo »

When I trying to apply the pattern, I get strange error. I found the solution, but I don't understand what was wrong. May be it helps someone in the future, because there is no info about this error on forums.

Battle for Wesnoth version 1.11.16

I'm overriding properties of unit at prerecruit event using this code:

Code: Select all

[event]
		name = prerecruit
		first_time_only=no
		[filter]
			type=ToI_Minion
		[/filter]
		[store_unit]
			[filter]
				x,y = $unit.x,$unit.y
			[/filter]
			variable = recruited_minion
			kill = yes
		[/store_unit]
		{ALGORITHM_NEW_LVL0}
		
		{VARIABLE recruited_minion.max_hitpoints $lvl0_hp}
		{VARIABLE recruited_minion.hitpoints $lvl0_hp}
		[set_variables]
			name = recruited_minion.attack
			[value]
				description = _ "Description of new attack"
				name = _ "New attack"
				type = impact
				range = _ "contact"
				damage = $lvl0_attack
				number = 1
			[/value]
		[/set_variables]

		[unstore_unit]
			variable = recruited_minion
			find_vacant = yes #HERE
			animate = no
		[/unstore_unit]
	[/event]
I get this error and no unit appears at all.
Trying to add - ToI_Minion-18 at an invalid location; Discarding.
I have tried to set x and y explicitly, but it didn't help.

I have changed find_vacant value to "no" and problem gone. Can someone explain me what went wrong?
User avatar
Xudo
Posts: 563
Joined: April 3rd, 2009, 5:26 pm

Re: Xudo questions about WML.

Post by Xudo »

And there is other question appeared for me now. Is there any way to iterate over unit_types, available for creating?
User avatar
Ravana
Forum Moderator
Posts: 3078
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: Xudo questions about WML.

Post by Ravana »

I used

Code: Select all

	[event]
		name=
		first_time_only=no
		[store_unit_type_ids]
			variable=unit_types
		[/store_unit_type_ids]
		[set_variables]
			name=split_list
			mode=replace
			[split]
				list=$unit_types
				key=id
				separator=,
				remove_empty=yes
			[/split]
		[/set_variables]
....
to place them into array for manipulation, and used

Code: Select all

      [unit]
			type=$output
			x=10
			y=10
			side=1
		[/unit]
to create lua error to make wesnoth write it to file for easy copying.

You can use [store_unit_type_ids] within real scenario too but usually that isnt too good idea, it gets all units across all addons.

Full event I used is http://pastebin.com/Tda6dxC6
User avatar
Xudo
Posts: 563
Joined: April 3rd, 2009, 5:26 pm

Re: Xudo questions about WML.

Post by Xudo »

Dugi wrote:Changing everything except graphics can be done simply via set_variable, graphics are a bit tricky but I'll explain that if you'll want.
I want. Though, it will be enough, if you say: did you succeed in World of Wesnoth (or image_test) in changing graphics?
User avatar
Dugi
Posts: 4961
Joined: July 22nd, 2010, 10:29 am
Location: Carpathian Mountains
Contact:

Re: Xudo questions about WML.

Post by Dugi »

We did it in World of Wesnoth. Your unit had weapons and armour according to inventory, head according to race and gender and some accessories according to some skills (furthermore some armour and weapons had special colours), its graphics fused together into a single sprite with thousands and possible combinations. I failed to do the animations there, but I managed to add custom animations through in LotI.

Now, how to do it:
1. Set misc/blank-hex.png as the unit's sprite.
2. Compose every frame from parts using ImagePathFunctionWML's ~BLIT function, using something like armour.png~BLIT(head.png)~BLIT(weapon.png)
3a. If you don't care about animations, you can apply the sprite to it by adding an [object] (there is absolutely no way to do it without inserting stuff into [modifications]) to it with its effect apply_to=image_mod that adds the frame using BLIT (result would be someting like BLIT(armour.png~BLIT(head.png)~BLIT(weapon.png))); this is the temporary solution used in World of Wesnoth (animations aren't drawn yet anyway)
3b. If you care about animations, compose them into WML tables and add them via [object] (again, no way to do this without altering [modifications]) and for the ones you haven't drawn, add the animations made only of the baseframe (that means that you must add all animations in any case (there isn't so many of them and you'll do that with code anyway), because you want the unchangeable baseframe to be never visible). This is what I got working in LotI, but failed in World of Wesnoth somehow.

If you want just to change colours and such, using [object] with apply_to=image_mod is enough.
User avatar
Xudo
Posts: 563
Joined: April 3rd, 2009, 5:26 pm

Re: Xudo questions about WML.

Post by Xudo »

Is it important to use [object] to apply animation?
I always thought it is same as I just store-change-unstore unit.
I failed to create animation with unstoring anyway. Thats why I'm asking.
I end up with structure, which looks right, but animation is ignored.

Code: Select all

[recruited_minion]
		advances_to=""
		alignment="neutral"
		alpha=256
		attacks_left=0
		cost=1
		description="This is a test stamp with only two attacks: halberd and spear."
		die_sound="human-die-[1~3].ogg"
		experience=0
		extra_recruit=""
		facing="ne"
		flag_rgb="magenta"
		gender="male"
		generate_name=no
		goto_x=-999
		goto_y=-999
		healed_sound=""
		hitpoints=35
		id="ToI_Minion-22"
		image="units/undead/zombie.png"
		jamming=0
		language_name=_"Minion"
		level=0
		max_attacks=1
		max_experience=466
		max_hitpoints=35
		max_moves=5
		moves=0
		name="Human unit stamp"
		overlays=""
		profile="units/undead/zombie.png"
		race=""
		random_traits=no
		resting=no
		role=""
		side=1
		small_profile="units/undead/zombie.png"
		type="ToI_Minion"
		undead_variation=""
		underlying_id=22
		unrenamable=no
		upkeep="full"
		usage="minion"
		variation=""
		vision=-1
		x=24
		y=4
		zoc=no
		[variables]
		[/variables]
		[filter_recall]
		[/filter_recall]
		[status]
		[/status]
		[modifications]
		[/modifications]
		[attack]
			damage=16.8518
			description="Spear"
			icon="weapons/spear/icon.png"
			name="spear"
			number=1
			range="contact"
			type="pierce"
		[/attack]
		[attack_anim]
			start_time=-150
			[filter_attack]
				name="spear"
			[/filter_attack]
			[frame]
				duration=50
				image="units/human/twohanded/thrust/frame0.png"
			[/frame]
			[frame]
				duration=50
				image="units/human/twohanded/thrust/frame1.png"
			[/frame]
			[frame]
				duration=50
				image="units/human/twohanded/thrust/frame2.png"
			[/frame]
		[/attack_anim]
	[/recruited_minion]
User avatar
Dugi
Posts: 4961
Joined: July 22nd, 2010, 10:29 am
Location: Carpathian Mountains
Contact:

Re: Xudo questions about WML.

Post by Dugi »

That's the point, man. You can't add animations in the classical store/unstore way, the changes will be discarded (this was to allow artists to be able to apply changes into animations simply by loading a save file, without having to recreate the unit). You must add them with something with an [effect] that adds animations (apply_to=new_animation).
User avatar
Xudo
Posts: 563
Joined: April 3rd, 2009, 5:26 pm

Re: Xudo questions about WML.

Post by Xudo »

Thanks for help.
I' ended up with this. This is relevant part of the WML macro, which adds animations to stored unit (which is {UNIT})
When fight is on armslength distance, then units are stands on their places. In case of contact distance, attacker moves to defender.
The difference in one empty [missile_frame].
I also used progressive animation strings and image path functions ~BLIT.

Code: Select all

{VARIABLE last_frame_index ${ASTAMP}.frames}
{VARIABLE_OP last_frame_index sub 1}
{VARIABLE frame_string "frame[0~$last_frame_index|].png"}

{VARIABLE iaap_timer -50}
{VARIABLE_OP iaap_timer multiply ${A_STAMP}.frames}
{VARIABLE {UNIT}.modifications.object.effect.apply_to "new_animation"}
[set_variables]
	name = {UNIT}.modifications.object.effect.standing_anim
	mode = append
	[value]
		[frame]
			image=$iaap_unitframe_path| + "/standing.png" + "~BLIT($iaap_weaponframe_path|/standing.png)"
		[/frame]
	[/value]
[/set_variables]
[if]
	{VARIABLE_CONDITIONAL {A_STAMP}.range equals "armslength"}
	[then]
		[set_variables]
			name = {UNIT}.modifications.object.effect.attack_anim
			mode = append
			[value]
				missile_start_time = $iaap_timer
				start_time = $iaap_timer
				[missile_frame]
					image="misc/blank-hex.png"
				[/missile_frame]
				[frame]
					image=$iaap_unitframe_path| + "/$frame_string" + "~BLIT($iaap_weaponframe_path|/$frame_string)" + ":50"
				[/frame]
			[/value]
		[/set_variables]
	[/then]
[/if]
[if]
	{VARIABLE_CONDITIONAL {A_STAMP}.range equals "contact"}
	[then]
		[set_variables]
			name = {UNIT}.modifications.object.effect.attack_anim
			mode = append
			[value]
				start_time = $iaap_timer
				[frame]
					image=$iaap_unitframe_path| + "/$frame_string" + "~BLIT($iaap_weaponframe_path|/$frame_string)" + ":50"
				[/frame]
			[/value]
		[/set_variables]
	[/then]
[/if]
I want to note, that duration of frame should be set after image path functions. I found it is not obvious.

Code: Select all

#right
image=$iaap_unitframe_path| + "/$frame_string" + "~BLIT($iaap_weaponframe_path|/$frame_string)" + ":50"
#wrong
image=$iaap_unitframe_path| + "/$frame_string" + ":50" + "~BLIT($iaap_weaponframe_path|/$frame_string)"
I hope this help if someone else will going to repeat it.
User avatar
Dugi
Posts: 4961
Joined: July 22nd, 2010, 10:29 am
Location: Carpathian Mountains
Contact:

Re: Xudo questions about WML.

Post by Dugi »

Congrats for making it.

There is one possible technical diffuculty with it, how many times are you invoking that macro? Because invoking a large macro more than a couple of times leads to all kinds of unexpected trouble.
User avatar
Xudo
Posts: 563
Joined: April 3rd, 2009, 5:26 pm

Re: Xudo questions about WML.

Post by Xudo »

Dugi wrote:There is one possible technical diffuculty with it, how many times are you invoking that macro?
I use it once on recruit and in loop on prestart to convert all units with specific type to playable enemies.
Post Reply