JaMiT's list of questions & cool macros

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
Elvish_Hunter
Posts: 1600
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: JaMiT's laundry list of WML questions

Post by Elvish_Hunter »

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.
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:
- 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()"
- compare the speaker's position with the map, and if it is in a certain location flip the portrait:

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)
JaMiT
Inactive Developer
Posts: 511
Joined: January 22nd, 2012, 12:38 am

Re: JaMiT's laundry list of WML questions

Post by JaMiT »

mattsc wrote:You've solved the problem at least 3 different ways in your post. :)
Reminds me of a line from a movie -- it goes something like "Why build one when you can build two for twice the price?" :)
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.
Since someone other than me endorses it, sure. (Not right away, but probably within a week or two.)
and wrote:
JaMiT wrote:Maybe a feature request for 1.11?
I'd add my vote to that.
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.

____

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 use image= instead of halo=? I know you would use halo= instead of image= if the image is larger than a hex or is to be animated, but why not use halo= all the time? One thing I discovered is that image= gets displayed under units, while halo= gets displayed on top of units (which is a good reason for using image=). 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:
    1. Spaces inside a tag or key name are forbidden (this much is already mentioned in the wiki).
    2. Spaces within a tag's brackets are ignored (if not inside the tag name).
    3. Spaces at the beginning and end of a line ignored.
    4. Spaces adjacent to the equals sign in a "key=value" line are ignored.
    5. Spaces between the underscore and quote (indicating a translatable string) are ignored.
    6. Spaces adjacent to operators (e.g. '+' for string concatenation) are ignored.
    7. Consecutive spaces are treated as a single space unless they are within quotes.
    8. Spaces within quotes are preserved.
    So basically, spaces can be used to separate elements of the language, but they are not required (aside from separating macro parameters), and multiple (consecutive) spaces are equivalent to a single space (unless inside quotes). Authors can use spaces as needed to improve readability, but should avoid consecutive spaces within quoted values (with quoted formulas as a possible exception). Is that the basic gist?
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: JaMiT's laundry list of WML questions

Post by Anonymissimus »

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?" :)
Contact ? :mrgreen:
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?
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.

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 startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
JaMiT
Inactive Developer
Posts: 511
Joined: January 22nd, 2012, 12:38 am

Re: JaMiT's laundry list of WML questions

Post by JaMiT »

Anonymissimus wrote:
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?" :)
Contact ? :mrgreen:
Guess I am not the only one who finds that scene (and the movie) memorable. :)
Anonymissimus wrote:
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?
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.
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:I don't think there should be documented when and where spaces are used/ignored, because the engine doesn't handle it consistently.
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.
JaMiT
Inactive Developer
Posts: 511
Joined: January 22nd, 2012, 12:38 am

Re: JaMiT's laundry list of WML questions

Post by JaMiT »

mattsc wrote:Would you mind posting that on the wiki page? Especially since there are currently very few FAI examples.
[wiki=Formula AI Code Library]Done[/wiki].

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. :) Maybe I should extract some other potentially useful pieces of WML from that so they can be shared before the campaign is done.
JaMiT
Inactive Developer
Posts: 511
Joined: January 22nd, 2012, 12:38 am

Resizing maps

Post by JaMiT »

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).
map-resizing.cfg
macros to help with map resizing
(15.76 KiB) Downloaded 128 times
Setup:
  1. Make the attached file accessible by your campaign (e.g. placing it in your campaign's utils directory.
  2. In your campaign's _main.cfg, #define CAMPAIGN_DIR to be your campaign's directory (e.g. "add-ons/my_campaign").
  3. Copy replace_map.lua from the LoW campaign to the lua subdirectory of your campaign's directory. (Cannot assume that LoW is installed when the campaign is played.)
  4. In the scenario that will have a resizing map, use the USE_RESIZING_MAP macro instead of specifying mapdata=.
Variables:
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.
JaMiT
Inactive Developer
Posts: 511
Joined: January 22nd, 2012, 12:38 am

Tracking map macros

Post by JaMiT »

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.
tracking-map.cfg
Generic macro file for this system.
(12.13 KiB) Downloaded 136 times
Extra graphic file used by QUESTION_BATTLE and QUESTION_REST; it goes in images/misc
Extra graphic file used by QUESTION_BATTLE and QUESTION_REST; it goes in images/misc
qmark-red.png (318 Bytes) Viewed 1688 times
Setup:
  1. Make the attached file accessible by your campaign (e.g. placing it in your campaign's utils directory.
  2. Create a file to hold the definitions for your journeys.
  3. Use the TRACKING_MAP_* macros in [story][part]s as needed.
A key part of this system is the use of a name for the journey, which includes all parts/stages that will/could eventually appear on the map at the same time. This name is just a prefix used for some macro names, so there is a lot of freedom in choosing it. For examples, I will use the name "HttT2". (If your campaign has just one journey map, it would probably make the most sense to use the abbreviation for your campaign name as the journey name. For more complex campaigns, the abbreviation followed by a number might work better.)


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]
As 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

Code: Select all

#define HttT2_TRACKING_MAP_IMAGE
maps/wesnoth.png#enddef
*_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:

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
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 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].
Post Reply