Macro handlers and how to add them

Discuss coding questions, pull requests, and implementation details.
Post Reply
User avatar
Hazelnut
Posts: 589
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Macro handlers and how to add them

Post by Hazelnut » Mon Sep 04, 2017 4:05 pm

As you may have seen on Interkarma's twitter feed, I've created a macro handling system to deal with %abc style text macros that Daggerfall uses in the following files: arena2\text.rsc, fall.exe, and arena2\*.qrc. My aim when creating the system is that it's easy for anyone to add macro handlers in the future without needing to worry about how the system works. I think this is important because there are 160 macros in Daggerfall (according to http://www.dfworkshop.net/static_files/ ... qrcsymbols) and the handling of them often has to wait for the appropriate game system to be in place first.


Messages that are not yet handled will show up in game as %abc[tag]. The tag will tell you what is missing to be able to replace the macro with the correct value, as shown in the list below:

%abc[undefined] -> Macro needs adding to the list of macroHandlers found in MacroHelper class.
%abc[unhandled] -> Macro requires a handler method to be defined in MacroHelper class and the name adding to macroHandlers mapping.
%abc[srcDataUnknown] -> Macro needs an appropriate handler method adding to the relevant context provider class.


What complicates macro handling is that some need contextual information which can be based on an object instance (e.g. item), or based on previous macro expansions (e.g. person pronouns). If a message has contextual macros DaggerfallMessageBox has to be setup using the baseic 2 param constructor and then call the required set methods. SetText methods accept an option macro context provider. So there are two sets of steps given below, one for simple macros whose value is globally availiable, and the other for macros that need context of some sort. (note that steps 1 & 2 are common)


Process for adding new macro handlers:

Open the class DaggerfallWorkshop.Utility.MacroHelper.
Does the macro need an object instance to provide context? (e.g. item, quest, stats)

If no context required:
1) Find the macro in macroHandlers dictionary, if the macro isn't in the list then add it at the bottom. e.g. "%gns"
2) Define the handler method name, replacing 'null' with it. e.g. 'GreatNewStuff'
3) Add a suitable handler method to the code region marked "Global macro handlers". (Note that the mcp param will be null so don't try and use it) e.g.

Code: Select all

private static string GreatNewStuff(IMacroContextProvider mcp)
{   // %gns
    return GameManager.Instance.PlayerEntity.NewStuff.GreatStuff;
}

If context required:
1) Find the macro in macroHandlers dictionary, if the macro isn't in the list then add it at the bottom. e.g. '%gns'
2) Define the handler method name, replacing 'null' with it. e.g. 'GreatNewStuff'
3) Add a suitable handler method that delegates to the same method in a MacroDataSource (provided by the passed IMacroContextProvider) to the code region marked "Contextual macro handlers". e.g.

Code: Select all

public static string GreatNewStuff(IMacroContextProvider mcp)
{   // %gns
    return mcp.GetMacroDataSource().GreatNewStuff();
}
4) Add an unimplemented exception method to the MacroDataSource base class. (this ensures only has to be implemented by data sources where it's relevant) e.g.

Code: Select all

public virtual string GreatNewStuff()
{   // %gns
    throw new NotImplementedException();
}
5) Find the class that will provide the required context data and override the handler method. (convention is the macro data source implementation lives in a file of the same name but using suffix 'MCP') The variable 'parent' provides access to the context providing class. e.g.

Code: Select all

public override string GreatNewStuff()
{
    return (parent.LastStuff != null) ? parent.LastStuff.GreatStuff : parent.NewStuff.GreatStuff;
}
If you need a new macro data source, copy one of the existing ones: QuestMCP, DaggerfallUnityItemMCP, DaggerfallStatsMCP. (MCP = Macro Context Provider)

Hope this make sense.

User avatar
AXO
Posts: 76
Joined: Mon May 14, 2018 4:19 am
Location: Italy

Re: Macro handlers and how to add them

Post by AXO » Thu Jun 28, 2018 3:16 pm

I do not understand anything about programming, and maybe I even posted this in the wrong place in any case
for the list of macros, I found it very useful to understand what I'm translating on, I noticed that the macro %hpw is it marked with " ? " , I found it in the 4130 string of biographies:
You spent most of your childhood roaming the %hpw with<0xFC>
your mother,
and I think it refers to the place chosen in the creation of the character.
I do not know if this kind of information can be useful, or even how to verify it but
i hope it is useful, otherwise say it and i'm stop writing about every little thing I discover :lol:

User avatar
Hazelnut
Posts: 589
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Re: Macro handlers and how to add them

Post by Hazelnut » Thu Jun 28, 2018 4:50 pm

Here's as good a place as any. Many macros we still don't know what they mean. The acronyms are quite cryptic!

hpw maybe is "home province world"? :roll:

The main way to figure them out is to get evidence of one or more actual replacements from classic. Usually the meaning can then be inferred from 1, 2 or more data points in context.

Al-Khwarizmi
Posts: 94
Joined: Sun Mar 22, 2015 9:52 am

Re: Macro handlers and how to add them

Post by Al-Khwarizmi » Thu Jun 28, 2018 6:16 pm

"Home province wilderness" (which could resolve to forest, swamps, desert, tundra, mountains, etc.) could make sense there.

User avatar
AXO
Posts: 76
Joined: Mon May 14, 2018 4:19 am
Location: Italy

Re: Macro handlers and how to add them

Post by AXO » Sun Jul 01, 2018 3:11 pm

Al-Khwarizmi wrote:
Thu Jun 28, 2018 6:16 pm
"Home province wilderness" (which could resolve to forest, swamps, desert, tundra, mountains, etc.) could make sense there.
yes , this sound good

by the way , maybe , i find macro which is not listed, wen you enter in the dark brother : %dbp

From this moment on, your codeword will be<0xFD>
%dbp. You are now considered a<0xFD>

I think talking about the moral code or stuff like that

User avatar
InconsolableCellist
Posts: 88
Joined: Mon Mar 23, 2015 6:00 am

Re: Macro handlers and how to add them

Post by InconsolableCellist » Sun Jul 01, 2018 3:14 pm

This might be a very basic question, but what exactly is a macro in the context of Daggerfall? What could be accomplished if we create our own?

User avatar
Hazelnut
Posts: 589
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Re: Macro handlers and how to add them

Post by Hazelnut » Mon Jul 02, 2018 7:33 am

In this context they are simply variable replacement symbols for text, in the form of a % followed by 1-3 letters. Interkarma calls them macros.

We can define our own and a couple have already been added.

Post Reply