fix the lifting of attack [frame]s to [attack_anim]

This code block was actually producing some horrendous output, because key values were not reset to defaults at the closing [/attack] tag, even though many units have more than one attack. Also, the conversion was done when the first [frame] tag was encountered, although most authors put the [sound] block after [frame]s. So, what would typically happen is this:

* The first attack would be converted, usually without a soundpath. If there were any attributes after the [frame] sequence, the result would be non-functional, as the comment introducing this wmllint block warned (and wmllint would crash with an assertion error if "name=" happened to be one of them).

* Subsequent attacks would be converted, inheriting the sound and [attack_filter] from the soundpath and attackname of the *first* attack.

To fix these issues, I did the following:

* In order to do the conversion at a later stage, after the soundpath would normally have been picked up, the variable 'converting' was changed from a 0/1 value to a line index position.

* This enables the opportunity to move post-[frame] lines, for which purpose the new variables in_frame and postframe are created. When encountered, these lines are deleted and appended to postframe.

* When we get to [/attack], we still look to see if we are converting. If so, we go ahead with the replacement of lines[i], before the index position gets changed. Then we carry out the conversion that was originally carried out at the first [frame], using lines[converting] to do it at the same place.

* The lines in postframe are fed back in reverse order before the new closing [/attack] tag.

* Values are cleared to defaults, ready for the next [attack].

* It is no longer true that the frame sequence has to go last in [attack], so that part of the comment can be deleted.
This commit is contained in:
Groggy Dice 2013-07-13 15:24:49 -04:00
parent 411ec9d882
commit 29c9931c05

View file

@ -1313,12 +1313,12 @@ def hack_syntax(filename, lines):
elif converting and "[/animation]" in lines[i]:
lines[i] = lines[i].replace("animation", "attack_anim")
# Lift [frame] declarations directly within attacks
# Note: This assumes that the frame sequence goes last in the [attack] WML
# with nothing after it, and will fail if that is not true.
in_attack = False
attackname = None
soundpath = None
in_sound = False
in_frame = False
postframe = []
converting = 0
for i in range(len(lines)):
if "no-syntax-rewrite" in lines[i]:
@ -1327,24 +1327,33 @@ def hack_syntax(filename, lines):
in_attack = True
elif "[/attack]" in lines[i]:
if converting:
assert attackname != None
lines[i] = lines[i].replace("/attack", "/attack_anim")
print '"%s", line %d: converting frame in [attack]'%(filename, converting+1)
ws = leader(lines[converting])
outer = outdent(ws)
insertion = outer + "[/attack]\n" \
+ outer + "[attack_anim]\n" \
+ ws + "[attack_filter]\n" \
+ ws + baseindent + "name=" + attackname + "\n" \
+ ws + "[/attack_filter]\n"
lines[converting] = insertion + lines[converting]
if soundpath:
lines[converting] += ws + baseindent + "sound=" + soundpath + "\n"
postframe.reverse()
for preframe in postframe:
lines[converting] = preframe + lines[converting]
modcount += 1
converting = 0
in_attack = False
attackname = None
soundpath = None
in_sound = False
in_frame = False
postframe = []
elif ("[frame]" in lines[i] or "[missile_frame]" in lines[i]) and in_attack and converting == 0:
assert attackname != None
print '"%s", line %d: converting frame in [attack] '%(filename, i+1)
ws = leader(lines[i])
outer = outdent(ws)
insertion = outer + "[/attack]\n" \
+ outer + "[attack_anim]\n" \
+ ws + "[attack_filter]\n" \
+ ws + baseindent + "name=" + attackname + "\n" \
+ ws + "[/attack_filter]\n"
lines[i] = insertion + lines[i]
if soundpath:
lines[i] += ws + baseindent + "sound=" + soundpath + "\n"
converting += 1
modcount += 1
converting = i
in_frame = True
elif in_attack:
fields = lines[i].strip().split('#')
syntactic = fields[0]
@ -1365,6 +1374,15 @@ def hack_syntax(filename, lines):
in_sound = False
if in_sound:
lines[i] = ""
# Move post-frame lines up
if "[frame]" in lines[i] or "[missile_frame]" in lines[i]:
in_frame = True
elif "[/frame]" in lines[i] or "[/missile_frame]" in lines[i]:
in_frame = False
elif converting and not in_frame:
postframe.append(lines[i])
lines[i] = ""
modcount += 1
# Upconvert ancient ability declarations from 1.x
level = None
abilities = []