Skip to content

Commit

Permalink
Merge branch 'master' of github.com:forcecore/KWReplayAutoSaver
Browse files Browse the repository at this point in the history
  • Loading branch information
jdj@legion committed Jan 3, 2015
2 parents 8f79b56 + 5a4196d commit f97bfd4
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 36 deletions.
251 changes: 227 additions & 24 deletions analyzer.py

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
'#ff7f00', # Orange
'#00ffff', # Cyan
'#ff7fff', # Pink
'#ffffff', # White
]

BLDG_COLORS = [
Expand All @@ -31,6 +32,7 @@
'#7f3f00', # Orange
'#007f7f', # Cyan
'#7f667f', # Pink
'#7f7f7f', # White
]


Expand Down Expand Up @@ -1133,6 +1135,7 @@ def make_timelines( self ) :

def load( self, kwr ) :
self.kwr = kwr
self.kwr.fix_pid()
assert len( kwr.replay_body.chunks ) > 0
# +1 second so that we can see the END of the replay.
self.length = int( kwr.replay_body.chunks[-1].time_code/15 ) + 1
Expand Down
32 changes: 30 additions & 2 deletions chunks.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,12 +381,13 @@ def decode_reverse_move_cmd( self ) :



def decode_placedown_cmd( self, UNITNAMES, UNITCOST ) :
def decode_placedown_cmd( self, UNITNAMES, UNITCOST, FREEUNITS ) :
self.cmd_ty = Command.PLACEDOWN
data = self.payload
self.building_type = uint42int( data[6:10] )
self.substructure_cnt = data[10]
self.substructures = []
self.free_unit = None # harvesters.

# substructure X and Y decoding.
pos = 11
Expand All @@ -402,6 +403,9 @@ def decode_placedown_cmd( self, UNITNAMES, UNITCOST ) :
self.cost = UNITCOST[ self.building_type ]

if self.building_type in UNITNAMES :
if self.building_type in FREEUNITS :
self.free_unit = FREEUNITS[ self.building_type ]
self.free_unit = UNITNAMES[ self.free_unit ]
self.building_type = UNITNAMES[ self.building_type ]
else :
self.building_type = "Bldg 0x%08X" % self.building_type
Expand Down Expand Up @@ -920,7 +924,31 @@ def read_footer( self, f ) :
print( "final_time_code:", self.final_time_code )
print( "footer_data:", self.footer_data )
print()




# Sometimes, we get invalid player_id in some commands for unknown reason.
# See cornercases/big_player_id for example.
# Why do I do this? cos I work with pid as array indexes a lot.
def fix_pid( self ) :
discarded = 0
for chunk in self.replay_body.chunks :

# keep valid commands
commands = []
for cmd in chunk.commands :
# invalid player id!
if cmd.player_id < len( self.players ) :
commands.append( cmd )

if len( commands ) != len( chunk.commands ) :
discarded += len( chunk.commands ) - len( commands )
chunk.commands = commands

print( discarded, "commands with invalid player discarded" )



def loadFromFile( self, fname ) :
self.guess_game( fname )
f = open( fname, 'rb' )
Expand Down
Binary file added cornercases/big_player_id.KWReplay
Binary file not shown.
9 changes: 6 additions & 3 deletions gnuplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def ylabel( self, s ) :
self.write( 'set ylabel "%s"\n' % s )

def legend( self, labels ) :
self.write( 'set key outside bottom center horizontal\n' )
self.labels = labels

def plot( self, xs, ys ) :
Expand All @@ -45,13 +46,15 @@ def show( self ) :
#self.linestyle_id += 1
#self.write( 'set style line %d \n' % self.data_id )

self.write( 'set key outside bottom center horizontal\n' )

self.write( 'plot \\\n' )
# now a stub command... for use with other useful plottings.
self.data_plot_command()

def data_plot_command( self ) :
assert len( self.xss ) == len( self.yss )
data_str = []
for i in range( len( self.xss ) ) :
data_str.append( '"-" using 1:2 with %s title "%s"' % ( self.style, self.labels[i] ) )
data_str.append( '"-" using 1:2 with %s title "%s" linecolor %d' % ( self.style, self.labels[i], i+1 ) )
data_str = ", ".join( data_str )
self.write( data_str )
self.write( "\n" )
Expand Down
15 changes: 14 additions & 1 deletion kwchunks.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
0x2D: "queue/resume production",
0x2E: "hold/cancel/cancel_all production",
0x2F: "Start building construction",
0x30: "Hold/Cancel construction",
0x31: "Place down building",
0x34: "sell",
0x3D: "attack",
Expand Down Expand Up @@ -276,6 +277,18 @@
0x4FCCDACF: "Traveller engine",
}

FREEUNITS = {
0xB5D275B6: 0x3A3D109A, # Nod ref & harv
0x16A86D68: 0x0D258354, # GDI
0x4C2E2C25: 0xF52AEEDF, # ST
0x05F6FA50: 0x21661DFB, # BH
0x40DCA116: 0xC3785BFE, # MoK
0x0CA58AEF: 0x14E34DE2, # Sc
0x7E291858: 0xC37F7227, # R17
0xF4E73A51: 0x998395BF, # T59
0xBA62677D: 0xC23B3A15, # ZCM
}

UNITNAMES = {
0xA333C6A8: "Nod power plant",
0x72407A4F: "Nod barracks",
Expand Down Expand Up @@ -1131,7 +1144,7 @@ def resolve_known( self, cmd ) :

def decode_cmd( self, cmd ) :
if cmd.cmd_id == 0x31 :
cmd.decode_placedown_cmd( UNITNAMES, UNITCOST )
cmd.decode_placedown_cmd( UNITNAMES, UNITCOST, FREEUNITS )
elif cmd.cmd_id == 0x26 :
cmd.decode_skill_targetless( POWERNAMES, POWERCOST )
elif cmd.cmd_id == 0x27 :
Expand Down
9 changes: 8 additions & 1 deletion ra3chunks.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
0x83D5A86B, # Century bomber
]

FREEUNITS = {
0xC45AAEAB: 0xF6DAC2A4, # soviet ref
0x8ECE261C: 0x2A196E71, # allied ref
0xFF4A8B60: 0x92CDE50F, # empire ref
"E Ref core": "E Ore collector", # empire ref
}

UNITNAMES = {
0xA01D437D: "S Crane",
0xCF8D9F20: "S Reactor",
Expand Down Expand Up @@ -421,7 +428,7 @@ def decode_cmd( self, cmd ) :
cmd.cmd_ty = chunks.Command.HIDDEN # lets forbid this from showing.

if cmd.cmd_id == 0x09 :
cmd.decode_placedown_cmd( UNITNAMES, UNITCOST )
cmd.decode_placedown_cmd( UNITNAMES, UNITCOST, FREEUNITS )
elif cmd.cmd_id == 0x05 :
cmd.decode_ra3_queue_cmd( UNITNAMES, AFLD_UNITS, UNITCOST )
elif cmd.cmd_id == 0x06 :
Expand Down
11 changes: 6 additions & 5 deletions twchunks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
###

import chunks
from kwchunks import UNITNAMES, UNITCOST, AFLD_UNITS, POWERNAMES, UPGRADENAMES, POWERCOST, UPGRADECOST
from kwchunks import UNITNAMES, UNITCOST, AFLD_UNITS, POWERNAMES, UPGRADENAMES, POWERCOST, UPGRADECOST, FREEUNITS



Expand All @@ -16,8 +16,9 @@
0x1D: "Skill (with 1 target pos)",
0x21: "Upgrade",
0x23: "Queue a unit production",
0x24: "Hold a unit production",
0x25: "Start construction of a structure",
0x26: "Hold",
0x26: "Hold/cancel construction of a structure",
0x27: "Place down a structure",
0x2A: "Sell",
0x2D: "GG",
Expand All @@ -30,7 +31,7 @@
0xF8: "Deselect units",
}

BO_COMMANDS = [ 0x1C, 0x1D, 0x23, 0x27, 0x80, 0x21, 0x26, 0x2A, 0x2D ]
BO_COMMANDS = [ 0x1C, 0x1D, 0x23, 0x24, 0x27, 0x80, 0x21, 0x2A, 0x2D ]



Expand All @@ -48,7 +49,7 @@ def resolve_known( self, cmd ) :
# Decode decodable commands
def decode_cmd( self, cmd ) :
if cmd.cmd_id == 0x27 :
cmd.decode_placedown_cmd( UNITNAMES, UNITCOST )
cmd.decode_placedown_cmd( UNITNAMES, UNITCOST, FREEUNITS )
elif cmd.cmd_id == 0x23 :
cmd.decode_queue_cmd( UNITNAMES, AFLD_UNITS, UNITCOST )
elif cmd.cmd_id == 0x1C :
Expand All @@ -59,7 +60,7 @@ def decode_cmd( self, cmd ) :
cmd.decode_skill_2xy( POWERNAMES, POWERCOST )
elif cmd.cmd_id == 0x21 :
cmd.decode_upgrade_cmd( UPGRADENAMES, UPGRADECOST )
elif cmd.cmd_id == 0x26 :
elif cmd.cmd_id == 0x24 :
cmd.decode_hold_cmd( UNITNAMES )
elif cmd.cmd_id == 0x2A :
cmd.decode_sell_cmd()
Expand Down

0 comments on commit f97bfd4

Please sign in to comment.