unit variables, arrays, and turns oh my

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
impyre
Posts: 9
Joined: December 14th, 2010, 7:24 pm

unit variables, arrays, and turns oh my

Post by impyre »

Please forgive me if I'm re-posting. The search tool here doesn't really play nicely with WML, and I've searched the wiki up and down. I'll start by describing what I'm doing and my problems, then I'll post some snippets.

I'm trying to mod the ANL map/scenario and build a toolset for what I call "Battlecraft" (in honor of certain old-school RTS's). I've written up a new unit called "Heavy Barracks" which is race=building. I've defined the race in unit.cfg. The Heavy Barracks building can "produce" units on the field. I'm trying to implement two features regarding these buildings.

1) buildings can be upgraded once certain criteria are met (gold primarily) to produce higher level units (and maybe some more specialized units).
2) upgrading buildings (and producing higher level units) is a process that should occur over multiple turns. IE: it starts on turn 5 and completes on turn 8.
2a) buildings can't be used to produce units while in upgrade-mode
2b) any combination of buildings should be able to be in upgrade state at the same time

Here's some code i've used.

Code: Select all

# OPTION TO PRODUCE SHOCKTROOPER
[option]
message= {MENU_IMG_TXT2 "units/human-loyalists/shocktrooper.png" ("<span color='green'>" + _"Shock Trooper - Lvl 2" + "</span>") ("<span size='small'>" +_"Cost: 35g" + "</span>")}
{ANL_SHOW_IF ("Heavy Barracks","Advanced Heavy Barracks") "Gg^Vh,Aa^Vha,Wog,Wo,Wot,Wwg,Ww,Wwt,Wwf,Wwr,Ss,Sm,Gg,Gs,Gd,Gll,Rb,Re,Rd,Rr,Rrc,Rp,Ai,Aa,Dd,Ds,Dd^Do,Dd^Dc,Gg^Gvs"}
	[command]
		[if]
		{CONDITION worker.gold greater_than_equal_to 35}
			[then]
				[if]
				{CONDITION unit.building_upgrading not_equals yes}
					[then]
						{COMPLETE_ACTION (-30)}
						{GENERIC_UNIT 1 "Shock Trooper" $x1 $y1}
          					{BUILD_SOUND_1}
					[/then]
				[/if]
			[/then]
		[/if]
{VARIABLE finished yes} 
	[/command]
[/option]
# OPTION TO PRODUCE IRON MAULER
[option]
message= {MENU_IMG_TXT2 "units/human-loyalists/siegetrooper-attack-1.png" ("<span color='green'>" + _"Shock Trooper - Lvl 3" + "</span>") ("<span size='small'>" +_"Cost: 50g" + "</span>")}
{ANL_SHOW_IF ("Advanced Heavy Barracks") "Gg^Vh,Aa^Vha,Wog,Wo,Wot,Wwg,Ww,Wwt,Wwf,Wwr,Ss,Sm,Gg,Gs,Gd,Gll,Rb,Re,Rd,Rr,Rrc,Rp,Ai,Aa,Dd,Ds,Dd^Do,Dd^Dc,Gg^Gvs"}
	[command]
		[if]
		{CONDITION worker.gold greater_than_equal_to 50}
			[then]
				[if]
				{CONDITION unit.building_upgrading not_equals yes}
					[then]
						{COMPLETE_ACTION (-30)}
						{GENERIC_UNIT 1 "Iron Mauler" $x1 $y1}
          					{BUILD_SOUND_1}
					[/then]
				[/if]
			[/then]
		[/if]
{VARIABLE finished yes} 
	[/command]
[/option]
# OPTION TO UPGRADE CURRENT BUILDING
[option]
message= {MENU_IMG_TXT2 "units/human-loyalists/siegetrooper-attack-1.png" ("<span color='green'>" + _"Upgrade to Advanced Heavy Barracks" + "</span>") ("<span size='small'>" +_"Cost: 150g" + "</span>")}
{ANL_SHOW_IF ("Heavy Barracks") "Gg^Vh,Aa^Vha,Wog,Wo,Wot,Wwg,Ww,Wwt,Wwf,Wwr,Ss,Sm,Gg,Gs,Gd,Gll,Rb,Re,Rd,Rr,Rrc,Rp,Ai,Aa,Dd,Ds,Dd^Do,Dd^Dc,Gg^Gvs"}
	[command]
		[if]
		{CONDITION worker.gold greater_than_equal_to 150}
			[then]
				[store_unit]
					[filter]
						[filter_location]
							x,y=$x1,$y1
						[/filter_location]
					[/filter]
					variable=building
					kill=no
					mode=replace
				[/store_unit]
				{COMPLETE_ACTION (-150)}
				{VARIABLE building.building_upgrading yes}
          			{BUILD_SOUND_1}
			[/then]

		[/if]
{VARIABLE finished yes} 
	[/command]

[/option]

[/message]
	[message]
		message= _ "Building_upgrading = $building.building_upgrading"
	[/message]
So ideally speaking the option to upgrade the building sets a variable on the heavy barracks "unit" of building_upgrading=yes. (I also tried building.status.building_upgrading=yes)

The code is inserted in the scenario like this:

Code: Select all

[event]
        name=side turn
        first_time_only=no
        [if]
            {CONDITION side_number less_than_equal_to 1}
            [then]
			{BUILDING_UPGRADES}
            [/then]
        [/if]
[/event]
And here is the BUILDING_UPGRADES macro:

Code: Select all

#define BUILDING_UPGRADES
[store_unit]
	[filter]
		race="building"
		side="$side_number"
	[/filter]
	variable=buildings
	kill=no
	mode=replace
[/store_unit]

[command]
	{DEBUG_MSG $buildings.length|}
[/command]

{FOREACH buildings i}
	[command]
		{VARIABLE_OP xp add 10}
		{DEBUG_MSG $buildings[$i].building_upgrading}
	[/command]
	[unstore_unit]
		variable=buildings[$i]
	[/unstore_unit]
{NEXT i}

#enddef
Right now, the building_upgrades macro is written more in a debug format because i've been trying to figure out what's going wrong. My code is running and loading. All resources and locations are correct. As this code is written, the result i'm expecting is that at the beginning of each turn it will go through each "building" unit I have, and add 10 XP (which it isn't... probably because XP is the wrong variable or my syntax is wrong) and also tell me the contents of the building_upgrading variable... which always comes back empty. I tried inserting a debug_msg in the "option" to upgrade the building, and it works... so I know the variable gets assigned at some point... it just either gets cleared, dropped, or doesn't behave as I'm expecting. Any help with any of these problems would be appreciated. Also, if you can see any way to improve or clean up some of the code... I also welcome that advice. (I know my massive terrain filter above is probably not the most elegant way to accomplish that goal... it's just that some options are filtered by terrain type... just that one option shouldn't be filtered by terrain type.)
impyre
Posts: 9
Joined: December 14th, 2010, 7:24 pm

Re: unit variables, arrays, and turns oh my

Post by impyre »

I intend on using experience to control the building upgrade process, but I've also considered setting a separate variable on the unit based on the number of turns, and just adding one for each turn that passes... and upgrading the building after a threshold (but i figured XP was simpler... and I can't get the rest of it to work yet, one hurdle at a time.) If there are any suggestions on how I should do that, please feel free to share.
silene
Posts: 1109
Joined: August 28th, 2004, 10:02 pm

Re: unit variables, arrays, and turns oh my

Post by silene »

impyre wrote:I intend on using experience to control the building upgrade process, but I've also considered setting a separate variable on the unit based on the number of turns, and just adding one for each turn that passes... and upgrading the building after a threshold (but i figured XP was simpler... and I can't get the rest of it to work yet, one hurdle at a time.) If there are any suggestions on how I should do that, please feel free to share.
Overall, the concept is sane. Whether you are using experience or a unit variable doesn't make much difference (except that experience allows for visual feedback, which is always good.) You should post more precise questions if you have troubles with some specific details. A quick glance at your code tells you should rather use the following for increasing experience:

Code: Select all

{VARIABLE_OP buildings[$i].experience add 10}
Also, you tend to like the [command] tag a lot. While it is mandatory for [option], elsewhere it is just noise.
impyre
Posts: 9
Joined: December 14th, 2010, 7:24 pm

Re: unit variables, arrays, and turns oh my

Post by impyre »

Thanks for the quick response, I will give that a try.
My biggest problem is that the building_upgrading variable doesn't seem to stick.
Without that variable as a "flag", I have no way to filter out which buildings I should be modifying.
silene
Posts: 1109
Joined: August 28th, 2004, 10:02 pm

Re: unit variables, arrays, and turns oh my

Post by silene »

impyre wrote:My biggest problem is that the building_upgrading variable doesn't seem to stick.
Custom unit variables go into the "variables" part of a unit, so try "whatever.variables.building_upgrading" instead of "whatever.building_upgrading".
impyre
Posts: 9
Joined: December 14th, 2010, 7:24 pm

Re: unit variables, arrays, and turns oh my

Post by impyre »

ooohhhh... anyone ever tell you that you're awesome?
thanks!
impyre
Posts: 9
Joined: December 14th, 2010, 7:24 pm

Re: unit variables, arrays, and turns oh my

Post by impyre »

Now I'm getting the variable to stick, but it seems to be applying to all buildings rather than just the specific building that i chose to upgrade.
impyre
Posts: 9
Joined: December 14th, 2010, 7:24 pm

Re: unit variables, arrays, and turns oh my

Post by impyre »

nvm, I figured it out. I was trying to do

Code: Select all

[filter]
    [filter_wml]
        [variables]
            building_upgrading=yes
        [/variables]
    [/filter_wml]
[/filter]
But that syntax wasn't filtering out the non-upgrading buildings. I changed the filter to just filter by race=building and did a
[if]
{CONDITION building[$i].variables.building_upgrading equals yes}
in my FOREACH loop.

Thanks for all your help so far.
Post Reply