Gcc was my first thought, being one the most common preprocessors, and that's what I went with.
Some example snippets:
BAF
Code: Select all
IF
See(NearestEnemyOf(Myself))
Global("abi_dalzim","LOCALS",0)
LevelGT(LastSeenBy(Myself),15) // Level 16+
!GlobalTimerNotExpired("delay","LOCALS")
THEN
RESPONSE #100
SetGlobalTimer("delay","LOCALS",6)
IncrementGlobal("doomed","LOCALS",1)
IncrementGlobal("abi_dalzim","LOCALS",1)
ReallyForceSpell(NearestEnemyOf(Myself),WIZARD_ABI_DALZIMS_HORRID_WILTING)
END
IF
See(NearestEnemyOf(Myself))
Global("efreeti","LOCALS",0)
LevelGT(LastSeenBy(Myself),15) // Level 16+
!GlobalTimerNotExpired("delay","LOCALS")
THEN
RESPONSE #100
SetGlobalTimer("delay","LOCALS",6)
IncrementGlobal("doomed","LOCALS",1)
IncrementGlobal("efreeti","LOCALS",1)
ReallyForceSpell(Myself,WIZARD_SUMMON_EFREET)
END
IF
See(NearestEnemyOf(Myself)
Global("sunfire","LOCALS",0)
LevelGT(LastSeenBy(Myself),15) // Level 16+
!GlobalTimerNotExpired("delay","LOCALS")
THEN
RESPONSE #100
SetGlobalTimer("delay","LOCALS",6)
IncrementGlobal("doomed","LOCALS",1)
IncrementGlobal("sunfire","LOCALS",1)
ReallyForceSpell(NearestEnemyOf(Myself),WIZARD_SUN_FIRE)
END
gcc equivalent
Code: Select all
#define HASH1 # // special character shenanigans
#define HASH2(x) x
#define cast_spell_level(SYMBOL, TARGET, SPELL_VAR, MIN_LEVEL) \
IF \
See(NearestEnemyOf(Myself)) \
Global(#SPELL_VAR,"LOCALS",0) \
LevelGT(LastSeenBy(Myself),MIN_LEVEL) \
!GlobalTimerNotExpired("delay","LOCALS") \
THEN \
RESPONSE HASH2(HASH1)100 \
SetGlobalTimer("delay","LOCALS",6) \
IncrementGlobal("doomed","LOCALS",1) \
IncrementGlobal(#SPELL_VAR,"LOCALS",1) \
ReallyForceSpell(SYMBOL, TARGET) \
END
cast_spell_level(WIZARD_ABI_DALZIMS_HORRID_WILTING, NearestEnemyOf(Myself), abi_dalzim, 15)
cast_spell_level(WIZARD_SUMMON_EFREET, Myself, efreeti, 15)
cast_spell_level(WIZARD_SUN_FIRE, Myself, sunfire, 15)
Of course, complex baf is already dominated by SSL, so this is mostly useful in less complex scripts.
But on the other hand, the applications are not limited to baf.
Code: Select all
// never again confuse "GLOBAL" and "LOCALS" types
#define LocalGT(x,y) GlobalGT(x, "LOCALS", y)
IF
LocalGT("my_var", value)
...
TP2
Code: Select all
// just because I'm tired of typing COPY_EXISING_REGEXP all the time
#define copy_er COPY_EXISING_REGEXP
copy_er GLOB ~*.itm~ ~override~
Code: Select all
// or take it further
#include header.h
// header.h:
#define POUND1 $ // more shenanigans
#define POUND2(x,y) x ## y
#define POUND3(x,y) POUND2(x,y)
#define POUND_APPEND(x) POUND3(x,POUND1)
#define copy_erg(FILE_EXT) COPY_EXISTING_REGEXP GLOB ~^.+\.POUND_APPEND(FILE_EXT)~ ~override~
// end header.h
// actual code
copy_erg(dlg)
DECOMPILE_AND_PATCH BEGIN x = 0 END
BUT_ONLY
D
Code: Select all
// this is too long...
IF ~~ study1
SAY @14
IF ~OR(2) Global("wm_book_spell","LOCALS",0) Global("wm_book_spell","LOCALS",1)~ REPLY @20 GOTO 00 // -> +6 = 6/7
IF ~OR(2) Global("wm_book_spell","LOCALS",0) Global("wm_book_spell","LOCALS",6)~ REPLY @22 GOTO 02 // -> +1 = 1/7
IF ~OR(2) Global("wm_book_spell","LOCALS",7) Global("wm_book_spell","LOCALS",8)~ REPLY @23 GOTO 03 // -> +2 = 9/10
IF ~OR(2) Global("wm_book_spell","LOCALS",7) Global("wm_book_spell","LOCALS",9)~ REPLY @24 GOTO 04 // -> +1 = 8/10
// how about this
#define if_node(value1, value2, tra, goto) \
IF ~OR(2) Global("wm_book_spell","LOCALS",value1) Global("wm_book_spell","LOCALS",value2)~ REPLY tra GOTO goto
IF ~~ study1
SAY @14
if_node(0,1,@20,00)
if_node(0,6,@22,02)
if_node(7,8,@23,03)
if_node(7,9,@20,04)
Technically, all this already can be done manually with command line. But with some glue code in various places it could be automated similarly to how SSL works.
To be clear, gcc with its c++ heritage is not "great" for weidu. But weidu syntaxes are unique and diverse enough that according to my analysis, there's no preprocessor or templating engine that is "great". The reason to choose it is that it's very common, simple to use, has lots of documentation and examples, and easy to implement too. That makes it a good starting point, from which the feature can improve.
So, I added rudimentary support for gcc preprocessing to MLS. To make use of it, add ".tpl" extension to the file (".baf.tpl", ".tpa.tpl", etc). Press CTRL+R to preprocess and parse. "test.baf.tpl" will be preprocessed into "test.baf", then test.baf will be parsed with weidu normally.
Of course, this is still pretty manual - each file has to be preprocessed separately. But it's just a start. It can be improved later with various techniques.
(Also, you need gcc in system PATH for this to work).
This feature is tech preview. It may get changed or removed later on. I'm entertaining various ideas, and welcome feedback, help moreso.