JaMiT's list of questions & cool macros
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.
- Elvish_Hunter
- Posts: 1600
- Joined: September 4th, 2009, 2:39 pm
- Location: Lintanir Forest...
Re: JaMiT's laundry list of WML questions
I looked again, but it seems like Lua cannot access the scrolling information, or evalutate if a certain hex is visible on the screen or is off-screen. The most similar things that I think can be done are:mattsc wrote:I'd add my vote to that. Since I wrote that last night, I've been wondering if you could do this in Lua. It'd be trivial to write a [message_right] tag. Whether you could do it automatically would depend on whether the scroll status of the screen is accessible in Lua. I don't know that off the top of my head, maybe one of the Lua experts can chime in here. If it is, it would be easy to redefine the message tag to auto-flip the image when the unit is in the left half of the screen.
- checking the unit's facing, and then use a line like:
Code: Select all
if unit.facing=="nw" or unit.facing=="sw" then
image = unit.__cfg.profile .. "~FL()~RIGHT()"
Code: Select all
local w, h, b = wesnoth.get_map_size()
if unit.x > math.floor( w / 2 ) then
image = unit.__cfg.profile .. "~FL()~RIGHT()"
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
Re: JaMiT's laundry list of WML questions
Reminds me of a line from a movie -- it goes something like "Why build one when you can build two for twice the price?"mattsc wrote:You've solved the problem at least 3 different ways in your post.

Since someone other than me endorses it, sure. (Not right away, but probably within a week or two.)and wrote:That's a nice example of a Formula AI CA you have there. Would you mind posting that on the wiki page? Especially since there are currently very few FAI examples.
I guess I'll add it to the bug tracker once 1.10 is released and the feature freeze ends (unless a developer would like it submitted sooner or never). It is looking like WML and Lua can at best do approximations that will likely be wrong too often for my likes.and wrote:I'd add my vote to that.JaMiT wrote:Maybe a feature request for 1.11?
____
Since it looks like I will be editing the wiki eventually, a few questions that are really asking for confirmation of things I've deduced:
- The SingleUnitWML wiki page claims that a unit's
id
key "is not displayed to the player", but a leader's ID is displayed in the "scenario settings" panel of the status table (hit the "more" button), right? Is there another value that can be shown here? - In an
[item]
, why should someone useimage=
instead ofhalo=
? I know you would usehalo=
instead ofimage=
if the image is larger than a hex or is to be animated, but why not usehalo=
all the time? One thing I discovered is thatimage=
gets displayed under units, whilehalo=
gets displayed on top of units (which is a good reason for usingimage=
). Is that it? (And related: in order to get an animation below units, it would have to be done with[terrain_graphics]
?) - When are spaces in WML significant? I took a look at a few saved games, and it looks like:
- Spaces inside a tag or key name are forbidden (this much is already mentioned in the wiki).
- Spaces within a tag's brackets are ignored (if not inside the tag name).
- Spaces at the beginning and end of a line ignored.
- Spaces adjacent to the equals sign in a "key=value" line are ignored.
- Spaces between the underscore and quote (indicating a translatable string) are ignored.
- Spaces adjacent to operators (e.g. '+' for string concatenation) are ignored.
- Consecutive spaces are treated as a single space unless they are within quotes.
- Spaces within quotes are preserved.
-
- Inactive Developer
- Posts: 2461
- Joined: August 15th, 2008, 8:46 pm
- Location: Germany
Re: JaMiT's laundry list of WML questions
Contact ?JaMiT wrote:Reminds me of a line from a movie -- it goes something like "Why build one when you can build two for twice the price?"

What's shown there is the "current_player" attribute, which is the (untranslatable) save_id of that leader's side if not set, which is that side's leader's id if not set.JaMiT wrote:The SingleUnitWML wiki page claims that a unit's id key "is not displayed to the player", but a leader's ID is displayed in the "scenario settings" panel of the status table (hit the "more" button), right?
As for spaces, I suggest to not use trailing whitespace in attribute values since it's not ignored in the lua-implemented tags (leading one is).
In
key= val1, val2,val3, val4 , val5
it will be read as "val4 " (while the others are ok).
I don't think there should be documented when and where spaces are used/ignored, because the engine doesn't handle it consistently.
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
Re: JaMiT's laundry list of WML questions
Guess I am not the only one who finds that scene (and the movie) memorable.Anonymissimus wrote:Contact ?JaMiT wrote:Reminds me of a line from a movie -- it goes something like "Why build one when you can build two for twice the price?"![]()

Oh right, I overlooked that part in the [side] specs. (It is still a slight inaccuracy under SingleUnitWML though.) So, would it be correct to surmise that "current_player" should be set for all sides (in a single-player campaign; human sides might be skippable in multiplayer) so that it can be translated? (For some reason I had not been setting it, and I do not know why.)Anonymissimus wrote:What's shown there is the "current_player" attribute, which is the (untranslatable) save_id of that leader's side if not set, which is that side's leader's id if not set.JaMiT wrote:The SingleUnitWML wiki page claims that a unit's id key "is not displayed to the player", but a leader's ID is displayed in the "scenario settings" panel of the status table (hit the "more" button), right?
I see; that can be a problem for documentation. I'll think about this some more. My thought was to provide some reassurance for people who notice small details like spaces, but that reassurance certainly should not be false.Anonymissimus wrote:I don't think there should be documented when and where spaces are used/ignored, because the engine doesn't handle it consistently.
Re: JaMiT's laundry list of WML questions
[wiki=Formula AI Code Library]Done[/wiki].mattsc wrote:Would you mind posting that on the wiki page? Especially since there are currently very few FAI examples.
Also started an idea topic for the mirroring of message images. Getting through a backlog of things to do slowly, but surely. I guess it helped that I hit a bit of writer's block for my campaign.

Resizing maps
Hmm... I mentioned sharing some of my WML creations, but never got around to it. Here is one I think I have finished adding to. It expands upon the resizing map macros from LoW, providing additional support for map resizing. What these are intended to do is make it easier to have a map that can shrink or grow in the middle of a scenario. The idea is that you would have a large .map file, but at any given time only part of the full map might be shown. All map coordinates given to these macros are in terms of coordinates of what is in the map file (which I hope are easier to obtain than the coordinates a player would see).
Setup:
In scenarios using these macros, there will be two variables defined for you to reference (but not change, under penalty of Bad Things Happening). The variables are $map_offset and $map_extent, each a container variable with fields x and y. You can use these to determine which submap is currently being used. The former is useful for converting between current coordinates (as reported by WML) and full map coordinates, while the latter is useful for... not sure, but having it available seems like a Good Idea.
Macros:
USE_RESIZING_MAP
This macro initializes the system (and schedules variable cleanup at the end of the scenario). It is used instead of specifying
RESIZED_MAP_REPLACE
Did I say you would have a large .map file? I understated. You can have more than one. This macro replaces the current file with another, using the same left, right, top, and bottom coordinates. It takes one parameter -- the name of the new .map file.
RESIZED_MAP_REPLACE_AND_SHIFT
Your two .map's are not aligned? This macro is like RESIZED_MAP_REPLACE, but takes three parameters -- the name of the new .map file and new left and top coordinates for what will be shown to the player. (The result will still be the same size; if you want a new map, new offset, and a new size, use this macro followed by one that will extend the map down and to the right.)
Warning: This macro might break pending events that filter on map coordinates. (I forget why I did not make it more robust.)
GROW_MAP
This is for relative changes to the map size. It takes four parameters -- left, right, up, and down -- and the map will be extended by that many hexes in those directions.
RESIZE_MAP
This is for absolute changes to the map size. It takes four parameters -- left, right, top, and bottom -- specifying the coordinates (in the full map) of the corresponding sides of the portion of the map that will be shown to the player.
RESIZING_PLACE_IMAGE
Instead of using an
RESIZING_REMOVE_IMAGE
Use this to remove an image placed with RESIZING_PLACE_IMAGE. It takes two parameters -- the x- and y- coordinates where the image was placed.
RESIZING_XY
This macro is an aid to events that filter on map coordinates. It has some limitations though, most notably that you can only specify a single hex; coordinate ranges are not supported. However, it will allow an event filter to automatically adjust to the map being resized, keeping the trigger location in the same hex. This macro takes three parameters -- the x- and y- coordinates, plus a third parameter that should be left empty unless you turn off delayed variable substitution. If you are making use of non-delayed variable substitution, use a string of pipe characters (|) as the third parameter, with the number of pipes equal to the number of times variable substitution was not delayed (going back to the top-level event this is part of). Do not enclose the parameters in quotes, even if you use formulas for the coordinates.
- Make the attached file accessible by your campaign (e.g. placing it in your campaign's
utils
directory. - In your campaign's
_main.cfg
, #define CAMPAIGN_DIR to be your campaign's directory (e.g. "add-ons/my_campaign"). - Copy
replace_map.lua
from the LoW campaign to thelua
subdirectory of your campaign's directory. (Cannot assume that LoW is installed when the campaign is played.) - In the scenario that will have a resizing map, use the USE_RESIZING_MAP macro instead of specifying
mapdata=
.
In scenarios using these macros, there will be two variables defined for you to reference (but not change, under penalty of Bad Things Happening). The variables are $map_offset and $map_extent, each a container variable with fields x and y. You can use these to determine which submap is currently being used. The former is useful for converting between current coordinates (as reported by WML) and full map coordinates, while the latter is useful for... not sure, but having it available seems like a Good Idea.

Macros:
USE_RESIZING_MAP
This macro initializes the system (and schedules variable cleanup at the end of the scenario). It is used instead of specifying
mapdata=
within a [scenario]
tag. It takes five parameters -- the name of the map file (not the map data; the file name without surrounding braces) and the left, right, top, and bottom coordinates of what will be shown to the player.RESIZED_MAP_REPLACE
Did I say you would have a large .map file? I understated. You can have more than one. This macro replaces the current file with another, using the same left, right, top, and bottom coordinates. It takes one parameter -- the name of the new .map file.
RESIZED_MAP_REPLACE_AND_SHIFT
Your two .map's are not aligned? This macro is like RESIZED_MAP_REPLACE, but takes three parameters -- the name of the new .map file and new left and top coordinates for what will be shown to the player. (The result will still be the same size; if you want a new map, new offset, and a new size, use this macro followed by one that will extend the map down and to the right.)
Warning: This macro might break pending events that filter on map coordinates. (I forget why I did not make it more robust.)
GROW_MAP
This is for relative changes to the map size. It takes four parameters -- left, right, up, and down -- and the map will be extended by that many hexes in those directions.
RESIZE_MAP
This is for absolute changes to the map size. It takes four parameters -- left, right, top, and bottom -- specifying the coordinates (in the full map) of the corresponding sides of the portion of the map that will be shown to the player.
RESIZING_PLACE_IMAGE
Instead of using an
[item]
tag or the (core) PLACE_IMAGE macro to place an image, use this macro so that the image will remain in the correct hex after resizing the map. This macro takes four parameters -- the image name, x-coordinate, y-coordinate, and halo name. (The two names are the same as what would be supplied to those keys in the [item]
tag. The coordinates are from the full map, as usual.)RESIZING_REMOVE_IMAGE
Use this to remove an image placed with RESIZING_PLACE_IMAGE. It takes two parameters -- the x- and y- coordinates where the image was placed.
RESIZING_XY
This macro is an aid to events that filter on map coordinates. It has some limitations though, most notably that you can only specify a single hex; coordinate ranges are not supported. However, it will allow an event filter to automatically adjust to the map being resized, keeping the trigger location in the same hex. This macro takes three parameters -- the x- and y- coordinates, plus a third parameter that should be left empty unless you turn off delayed variable substitution. If you are making use of non-delayed variable substitution, use a string of pipe characters (|) as the third parameter, with the number of pipes equal to the number of times variable substitution was not delayed (going back to the top-level event this is part of). Do not enclose the parameters in quotes, even if you use formulas for the coordinates.
Tracking map macros
Here is another group of macros. These deal with the journeys often displayed on a tracking map before a scenario starts (those maps showing where each scenario takes place). The idea here is to reduce the amount of redundant information in the .cfg files, which in theory should make maintenance easier.
Setup:
Scenario files:
In your scenario files, the interface to this system is rather simple. When you come to a [story] [part] that should display a stage of the journey, the [part] would look something likeAs I already mentioned. "HttT2" is the example name I am using for journey/campaign names. Change that to whatever you decided to use.
The '4' in the macro name would change depending on the scenario (more precisely, the journey stage). This number indicates how many stages will be displayed; all but the last will be displayed as "old" (white) journeys, while the last will be a "new" (red) journey. The system as written supports up to 20 stages, but this can be easily extended. (Extending the system just takes copy, paste, edit the macro name, change a "NEW" to "OLD", and add a line. It's probably obvious what to do if you look at the file.)
Definition files:
The definition file is where you record all your hard work in deciding where exactly the dots of the journey should appear. There are two types of macros that go in this file.
*_TRACKING_MAP_IMAGE
This macro, whose name will start with your journey/campaign name, must be defined to be the name of the background image (the map). So, for example, this might be defined as
*_MAP_STAGE_*
These macro names start with your journey/campaign name, and end with the number of the stage they define. (As mentioned earlier, stages 1 through 20 are supported, but additional support can be easily gained by editing the attached file.) Each of these macros defines just one stage; earlier stages are automatically called first. The layout of these macros is probably easiest to explain by example:
The JOURNEY lines produce dots at the specified X and Y coordinates. The BATTLE lines produce the crossed swords typical of scenario locations. The REST lines produce the flag often indicating a non-combat scenario. Adding QUESTION_ before REST or BATTLE is a little variant that produces a red question mark when the stage is "new" and the crossed swords or flag when the stage is "old". (I recall encountering the idea in these forums, but I forget where.) Oh, the red question mark is a custom file I better attach. It goes in your campaign's
Choices:
A complication arises when a campaign gives a choice of which path to follow. There are a few ways this system can accommodate that. Possibly the "best" option is to use an [if] tag within the macros defining stages. Another option is to define different journeys for each option. These journeys could either be complete, with most stages copied (more precisely, using an example, the contents of the macro HttT3_MAP_STAGE_3 could be
Sorry if that explanation is not clear. I did intend to support branching campaigns, but I don't yet actually have a use for them. The goal is to keep things simple, so I think using an [if] clause is probably the way to go. It requires no special tricks and is standard WML for within a [part].
Setup:
- Make the attached file accessible by your campaign (e.g. placing it in your campaign's utils directory.
- Create a file to hold the definitions for your journeys.
- Use the TRACKING_MAP_* macros in
[story][part]
s as needed.
Scenario files:
In your scenario files, the interface to this system is rather simple. When you come to a [story] [part] that should display a stage of the journey, the [part] would look something like
Code: Select all
[part]
show_title=yes
{TRACKING_MAP_4 HttT2}
[/part]
The '4' in the macro name would change depending on the scenario (more precisely, the journey stage). This number indicates how many stages will be displayed; all but the last will be displayed as "old" (white) journeys, while the last will be a "new" (red) journey. The system as written supports up to 20 stages, but this can be easily extended. (Extending the system just takes copy, paste, edit the macro name, change a "NEW" to "OLD", and add a line. It's probably obvious what to do if you look at the file.)
Definition files:
The definition file is where you record all your hard work in deciding where exactly the dots of the journey should appear. There are two types of macros that go in this file.
*_TRACKING_MAP_IMAGE
This macro, whose name will start with your journey/campaign name, must be defined to be the name of the background image (the map). So, for example, this might be defined as
Code: Select all
#define HttT2_TRACKING_MAP_IMAGE
maps/wesnoth.png#enddef
These macro names start with your journey/campaign name, and end with the number of the stage they define. (As mentioned earlier, stages 1 through 20 are supported, but additional support can be easily gained by editing the attached file.) Each of these macros defines just one stage; earlier stages are automatically called first. The layout of these macros is probably easiest to explain by example:
Code: Select all
#define HttT2_MAP_STAGE_1 OLD_NEW
{{OLD_NEW}_BATTLE 426 194}
#enddef
#define HttT2_MAP_STAGE_2 OLD_NEW
{{OLD_NEW}_JOURNEY 450 200}
{{OLD_NEW}_QUESTION_REST 478 202}
# enddef
# define HttT2_MAP_STAGE_3 OLD_NEW
{{OLD_NEW}_JOURNEY 497 194}
{{OLD_NEW}_JOURNEY 517 190}
{{OLD_NEW}_JOURNEY 535 183}
{{OLD_NEW}_REST 529 167}
#enddef
images/misc
directory.Choices:
A complication arises when a campaign gives a choice of which path to follow. There are a few ways this system can accommodate that. Possibly the "best" option is to use an [if] tag within the macros defining stages. Another option is to define different journeys for each option. These journeys could either be complete, with most stages copied (more precisely, using an example, the contents of the macro HttT3_MAP_STAGE_3 could be
{HttT2_MAP_STAGE_3 {OLD_NEW}}
). Or the journeys could consist of just the stages that are different, with an empty stage at the end, then the needed MAP_STAGE macro could be invoked next to TRACKING_MAP_* in the scenario file.Sorry if that explanation is not clear. I did intend to support branching campaigns, but I don't yet actually have a use for them. The goal is to keep things simple, so I think using an [if] clause is probably the way to go. It requires no special tricks and is standard WML for within a [part].