#!/usr/bin/python import Tkinter, random, Pmw, os, copy, re, pprint, tkFileDialog Tk = Tkinter ################################################################################ margin = 40 tick = 1000 # ms zoom = 0.5 radius = 4 pause = 0 increment = 1 callback = None cluster = 0 # dis/en-able partioning code if cluster: from clason import calculate_partition ################################################################################ def read_position_data(datafile): global data, map_x0, map_y0, map_x1, map_y1, map_width, map_height, frames file = open( datafile ) data = [] currentTimeDictionary = {} map_name = file.readline(); map_type = file.readline(); map_display_name = file.readline(); map_display_type = file.readline(); map_x0, map_y0, map_width, map_height = map(float, file.readline().split()) map_x1, map_y1 = map_x0 + map_width, map_y0 + map_height map_y0, map_y1 = -map_y1, -map_y0 root.title("%s (%s)" % (map_display_name, map_display_type)) l = file.readline() while l != "\n" and l != "\r\n": l = l.strip("\r\n") team, type, block, name, x, y, z, desc = l.split(' ', 7) team, x, y, z = int(team), float(x), float(y), float(z) if type in ('SpawnSphere', 'InteriorInstance', 'AIObjective'): pass else: if type == 'WayPoint': map_item.append([x, -y, z, team, desc]) elif (type, block[:9]) == ('StaticShape', 'Generator'): map_item.append([x, -y, z, team, 'G']) elif (type, block) == ('StaticShape', 'StationInventory'): map_item.append([x, -y, z, team, 'I']) elif (type, block) == ('StaticShape', 'StationVehiclePad'): map_item.append([x, -y, z, team, 'V']) elif type == 'Turret': map_item.append([x, -y, z, team, 'T']) elif (type, block[:6]) == ('StaticShape', 'Sensor'): map_item.append([x, -y, z, team, 'S']) l = file.readline() carrier = [] l = file.readline() while l != '': if l == "\n" or l == "\r\n": data.append( currentTimeDictionary ) currentTimeDictionary = {} carrier = [] else: m = l.strip().split(' ', 5) # the file format is: "playerid team x y z name" playerID = m.pop(0) if playerID == 'flag': if len(m) == 2: # the flag is being carried carrier.append(m[1]) else: m.append('flag') playerID += m[0] if len(m) == 5 and m[1] != '': team = int(m[0]) x = float(m[1]) y = -float(m[2]) z = float(m[3]) name = m[4] currentTimeDictionary[playerID] = x, y, z, team, name, playerID in carrier l = file.readline() frames = len(data) print frames, "frames" ################################################################################ def move_to(time): global actor, data actor1 = {} nowData = data[time] for clientID in nowData.keys(): x, y, z, team, name, flag = nowData[clientID] x = (x - map_x0) * zoom y = (y - map_y0) * zoom colour = ('black', 'green', 'red')[team] if flag: colour, bcolour = 'black', colour rad = radius * 2 else: bcolour = 'black' rad = radius if actor.has_key( clientID ): dot, label = actor[clientID] del actor[clientID] canvas.coords(dot, x - rad, y - rad, x + rad, y + rad) canvas.coords(label, x, y) canvas.itemconfigure(dot, fill=colour, outline=bcolour) else: if team == 1: dot = canvas.create_oval(x - rad, y - rad, x + rad, y + rad, fill=colour, outline=bcolour) else: dot = canvas.create_rectangle(x - rad, y - rad, x + rad, y + rad, fill=colour, outline=bcolour) label = canvas.create_text(x, y, text=name) actor1[clientID] = (dot, label) # any dot left is dead or has left the game, so remove it for dot, label in actor.values(): canvas.delete(dot) canvas.delete(label) actor = actor1 if cluster: show_partition( calculate_partition( data, time, data[time].keys() ) ) status_bar.configure(text='%i / %i, zoom %.2f' % (time+1, frames, zoom)) def move(): global time, pause, increment, callback, current_partition, current_partition_cost, SWITCH_MULTIPLIER callback = None if increment > 0 and time == frames - 1: return elif increment < 0 and time == 0: return time += increment move_to(time) callback = root.after(int(tick), move) def show_partition( partition ): global rectangle for rect in rectangle: canvas.delete(rect) rectangle = [] for set in partition: x0, y0, x1, y1 = 1e10, 1e10, -1e10, -1e10 for player in set: x0 = min((x0, data[time][player][0])) y0 = min((y0, data[time][player][1])) x1 = max((x1, data[time][player][0])) y1 = max((y1, data[time][player][1])) rectangle.append(canvas.create_rectangle((x0 - map_x0) * zoom, (y0 - map_y0) * zoom, (x1 - map_x0) * zoom, (y1 - map_y0) * zoom)) ################################################################################ def zoom_in(event): global zoom zoom = zoom * 1.2 update_zoom() def zoom_out(event): global zoom zoom = zoom / 1.2 update_zoom() def update_zoom(): canvas.coords(bg_rect, 0, 0, map_width * zoom, map_height * zoom) for item in map_item: x, y, z, team, name, label = item x = (x - map_x0) * zoom y = (y - map_y0) * zoom canvas.coords(label, x, y) canvas.resizescrollregion() move_to(time) def unpause(): global pause if pause == 0: return pause = 0 move() def setpause(): global pause, callback if pause == 1: return pause = 1 if callback is not None: root.after_cancel(callback) callback = None def button_handler(event): global pause, increment, time, tick, partition_index if event == '|<': setpause() time = 0 move_to(time) increment = 1 tick = 1000 elif event == '<': unpause() if increment == 1: increment = -1 tick = 1000 else: tick = tick * 0.8 elif event == '||<': setpause() if time > 0: time -= 1 move_to(time) elif event == '||': if pause: unpause() else: setpause() elif event == '>||': setpause() if time < frames - 1: time += 1 move_to(time) elif event == '>': unpause() if increment == -1: increment = 1 tick = 1000 else: tick = tick * 0.8 elif event == '>|': setpause() time = frames - 1 move_to(time) increment = -1 tick = 1000 elif event == 'partition': show_partition( calculate_partition(data, time, data[time].keys()) ) ############################################################################### root = Tk.Tk() root.withdraw() Pmw.initialise() actor = {} map_item = [] rectangle = [] time = 0 datafile = tkFileDialog.askopenfilename() read_position_data(datafile) toolbar = Tk.Frame(root) button = {} event_list = ['|<', '<', '||<', '||', '>||', '>', '>|'] if cluster: event_list += ['partition'] for event in event_list: button[event] = Tk.Button(toolbar, text=event, command=lambda x=event: button_handler(x)) button[event].pack(side=Tk.LEFT, anchor=Tk.W) status_bar = Tk.Label(toolbar, text='') status_bar.pack(side=Tk.LEFT, anchor=Tk.W) toolbar.pack(side=Tk.TOP, anchor=Tk.W) canvas = Pmw.ScrolledCanvas(root, hull_width=5000, hull_height=5000, usehullsize=1, canvasmargin=margin) bg_rect = canvas.create_rectangle(0, 0, map_width * zoom, map_height * zoom, outline='black', fill='white') for item in map_item: x, y, z, team, name = item x = (x - map_x0) * zoom y = (y - map_y0) * zoom colour = ('black', 'darkgreen', 'red')[team] label = canvas.create_text(x, y, text=name, fill=colour) item.append(label) canvas.pack(side=Tk.TOP) canvas.resizescrollregion() Tk.Widget.bind(canvas.component('canvas'), '', zoom_in) Tk.Widget.bind(canvas.component('canvas'), '', zoom_out) move() w, h = root.winfo_screenwidth(), root.winfo_screenheight() root.geometry('=%ix%i+%i+%i' % (w * 0.8, h * 0.8, w * 0.1, h * 0.1)) root.wm_deiconify() root.mainloop()