class sheduleDialog(Dialog): def __init__(self, parent, title, rows): Dialog.__init__(self, parent) if hasattr(sys, "_MEIPASS"): ico_str = os.path.join(sys._MEIPASS, 'res/Clock.ico') else: ico_str = 'res/Clock.ico' ico = Path(ico_str) if ico.is_file(): ico = wx.Icon(ico_str, wx.BITMAP_TYPE_ICO) self.SetIcon(ico) else: print("Ico File Not Found") self.rows = rows self.timeSpin = wx.SpinButton(self, -1, style=wx.SP_VERTICAL) self.triggerTime = TimeCtrl(self, -1, format='24HHMM') self.triggerTime.BindSpinButton(self.timeSpin) self.GetSizer().GetItem(0).GetSizer().Add(self.triggerTime, 1, wx.ALL, 5) self.GetSizer().GetItem(0).GetSizer().Add(self.timeSpin, 0, wx.EXPAND, 5) self.SetTitle(title) def mdBtnAdd_Click(self, event): self.rows.append(self.triggerTime.GetValue()) self.rows.sort() # print(self.rows) # self.EndModal(self.rows) self.Close() def mdBtnCancel_Click(self, event): self.Close()
class RenderingConfigPanel: """ Description: Contains configuration options for the timeline """ def __init__(self, parent, control): self.control = control self.parent = parent #wx.Panel.__init__(self,parent,-1)#,style=wx.SUNKEN_BORDER) #wx.wizard.WizardPageSimple.__init__(self,parent) self.control.setTimelineConfig(self) self.sizer = wx.GridBagSizer(5, 5) self.fps = 25.00 self.secs = 10 self.parent = parent self.updated = 0 self.in_fps = 0 self.in_framecount = 0 self.outputsizer = wx.GridBagSizer(5, 5) box = wx.StaticBox(self.parent, wx.HORIZONTAL, "Rendering parameters") self.outputstaticbox = wx.StaticBoxSizer(box, wx.HORIZONTAL) self.outputstaticbox.Add(self.outputsizer) self.totalFramesLabel = wx.StaticText(self.parent, -1, "Frames:") self.durationLabel = wx.StaticText(self.parent, -1, "Duration:") self.totalFrames = wx.TextCtrl(self.parent, -1, "250", size=(50, -1), style=wx.TE_PROCESS_ENTER) self.spin = wx.SpinButton(self.parent, -1, style=wx.SP_VERTICAL, size=(-1, 25)) self.duration = TimeCtrl(self.parent, -1, "00:00:10", fmt24hr=True, size=(50, 25), style=wx.TE_PROCESS_ENTER, spinButton=self.spin) self.totalFrames.Bind(wx.EVT_TEXT, self.updateFrameCount) self.duration.Bind(wx.EVT_TEXT, self.updateDuration) self.followAspect = wx.CheckBox( self.parent, -1, "Don't resize preview, only use aspect ratio.") self.followAspect.SetForegroundColour(scripting.COLOR_EXPERIENCED) toolTip = wx.ToolTip( """If this box is checked, the rendering preview window will always be sized so that it fits into the screen and uses the aspect ratio of the final rendered frame. If this is unchecked, the preview window will be resized to be the same size as the final frame.""") self.followAspect.SetToolTip(toolTip) self.followAspect.SetValue(1) box = wx.BoxSizer(wx.HORIZONTAL) box.Add(self.duration) box.Add(self.spin) self.frameSizeLbl = wx.StaticText(self.parent, -1, "Frame size:") self.resLst = [(0, 0), (320, 240), (512, 512), (640, 480), (720, 576), (800, 600)] self.frameSize = wx.Choice(self.parent, -1, choices=[ "Custom", "320 x 240", "512 x 512", "640 x 480", "720x576 (PAL)", "720x480 (NTSC)", "800 x 600" ]) self.frameSize.SetSelection(4) self.frameSize.Bind(wx.EVT_CHOICE, self.onUpdateFrameSize) self.outputsizer.Add(self.durationLabel, (0, 0)) self.outputsizer.Add(box, (0, 1)) self.outputsizer.Add(self.totalFramesLabel, (1, 0)) self.outputsizer.Add(self.totalFrames, (1, 1)) #self.outputsizer.Add(self.fpsLabel,(2,1)) self.frameRateLbl = wx.StaticText(self.parent, -1, "Frame rate:") self.frameRate = wx.TextCtrl(self.parent, -1, "%.2f" % self.fps, style=wx.TE_PROCESS_ENTER) self.frameRate.Bind(wx.EVT_TEXT, self.updateFPS) self.outputsizer.Add(self.frameRateLbl, (2, 0)) self.outputsizer.Add(self.frameRate, (2, 1)) self.custLbl = wx.StaticText(self.parent, -1, "Custom size:") self.custXLbl = wx.StaticText(self.parent, -1, "x") self.custX = wx.TextCtrl(self.parent, -1, "512", size=(48, -1)) self.custY = wx.TextCtrl(self.parent, -1, "512", size=(48, -1)) self.custX.Enable(0) self.custY.Enable(0) box = wx.BoxSizer(wx.HORIZONTAL) box.Add(self.custX) box.Add(self.custXLbl) box.Add(self.custY) self.outputsizer.Add(self.frameSizeLbl, (3, 0)) self.outputsizer.Add(self.frameSize, (3, 1)) self.outputsizer.Add(self.custLbl, (4, 0)) self.outputsizer.Add(box, (4, 1)) self.outputsizer.Add(self.followAspect, (5, 0)) self.sizer.Add(self.outputstaticbox, (0, 0), flag=wx.EXPAND | wx.ALL) #self.sizer.Add(self.animationstaticbox,(0,1),flag=wx.EXPAND|wx.ALL) #self.sline=wx.StaticLine(self) #self.sizer.Add(self.sline,(4,0),flag=wx.EXPAND|wx.RIGHT|wx.LEFT) #self.sizer.Add(self.useButton,(5,0)) #self.SetSizer(self.sizer) #self.SetAutoLayout(1) #self.sizer.Fit(self) #self.updateFormat() self.useSettings() def onUpdateFrameSize(self, evt): """ A callback for when the user changes the frame size """ sel = evt.GetSelection() flag = (sel == 0) self.custX.Enable(flag) self.custY.Enable(flag) evt.Skip() def getFrameAmount(self): """ Return the number of frames selected """ try: n = int(self.totalFrames.GetValue()) return n except: return 0 def setFrames(self, n): """ Set the number of frames in the GUI """ self.totalFrames.SetValue(str(n)) self.useSettings() def setDuration(self, t): """ Set the duration in the GUI """ if type(t) != types.StringType: h = t / 3600 m = t / 60 s = t % 60 t = "%.2d:%.2d:%.2d" % (h, m, s) self.duration.SetValue(t) self.useSettings() def useSettings(self, event=None): """ Use the GUI settings """ duration = -1 frameCount = -1 try: # We get a string, but pylint doesn't know that (it thinks we get a wxDateTime) # so we cast this to str although it is already an str duration = str(self.duration.GetValue()) hh, mm, ss = map(int, duration.split(":")) print hh, mm, ss secs = hh * 3600 + mm * 60 + ss lib.messenger.send(None, "set_duration", secs) except: pass try: frameCount = self.totalFrames.GetValue() frameCount = int(frameCount) lib.messenger.send(None, "set_frames", frameCount) except: pass if duration != -1 and frameCount != -1: self.control.configureTimeline(secs, frameCount) x = -1 y = -1 try: sel = self.frameSize.GetSelection() if sel != 0: x, y = self.resLst[sel] else: try: x = int(self.custX.GetValue()) y = int(self.custY.GetValue()) except: return #x,y=size.split("x") #x=int(x) #y=int(y) keepAspect = self.followAspect.GetValue() except: pass if x != -1 and y != -1: self.control.setFrameSize(x, y) lib.messenger.send(None, "set_frame_size", (x, y), keepAspect) #self.control.configureTimeline(secs,frameCount) #self.parent.sizer.Fit(self.parent) def getDurationInSeconds(self): """ return the duration of the movie in seconds """ if not self.updated: return self.secs duration = str(self.duration.GetValue()) try: hh, mm, ss = map(int, duration.split(":")) except: return 0 secs = hh * 3600.0 + mm * 60.0 + ss self.secs = secs self.updated = 0 return secs def updateFPS(self, event): """ update the amount of frames based on the Frames Per Second variable """ if self.in_framecount: return self.in_fps = 1 secs = self.getDurationInSeconds() try: fps = float(self.frameRate.GetValue()) except: self.in_fps = 0 return newframes = secs * fps self.totalFrames.SetValue("%d" % newframes) self.in_fps = 0 def updateDuration(self, event): """ update the amount of frames based on the duration of the movie """ self.updated = 1 secs = self.getDurationInSeconds() if secs == 0: return newframes = self.fps * secs self.totalFrames.ChangeValue("%d" % newframes) #self.fpsLabel.SetLabel("%.2f / second"%newfps) def updateFrameCount(self, event): """ Update the frame rate based on the duration """ if self.in_fps: return self.in_framecount = 1 try: frameCount = int(self.totalFrames.GetValue()) except: self.in_framecount = 0 return if frameCount == 0: self.in_framecount = 0 return secs = self.getDurationInSeconds() self.fps = frameCount / float(secs) self.frameRate.SetValue("%.2f" % self.fps) #self.fpsLabel.SetLabel("%.2f / second"%newfps) self.in_framecount = 0
class GamemasterWindow(wx.Panel): def __init__(self, parent): #wx.Frame.__init__(self,None,title="QJM Game Master") wx.Panel.__init__(self, parent) self.Bind(wx.EVT_CLOSE, self.OnClose) self.SetMinSize((850, 400)) self.SetSize((800, 600)) frame_sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(frame_sizer) # create a panel main_panel = wx.ScrolledWindow(self) frame_sizer.Add(main_panel, 1, wx.ALL | wx.EXPAND) main_panel.SetScrollRate(0, 5) #main_panel = wx.Panel(self) main_sizer = wx.BoxSizer(wx.VERTICAL) side_sizer = wx.BoxSizer(wx.HORIZONTAL) main_sizer.Add(side_sizer, 1, wx.EXPAND | wx.ALL) main_panel.SetSizer(main_sizer) ### create a menu #menubar = wx.MenuBar() #filemenu = wx.Menu() #editmenu = wx.Menu() #reloadmenu = filemenu.Append(wx.ID_ANY,"&Load state") #filemenu.AppendSeparator() #quitmenu = filemenu.Append(wx.ID_EXIT, "&Quit", "Quit application") #dbmenu = editmenu.Append(wx.ID_ANY,"&Database Editor") #menubar.Append(filemenu,"&File") #menubar.Append(editmenu,"&Edit") #self.SetMenuBar(menubar) ## menu binds #self.Bind(wx.EVT_MENU,self.OnLoad,reloadmenu) #self.Bind(wx.EVT_MENU,self.OnClose,quitmenu) #self.Bind(wx.EVT_MENU,self.OnDbEdit,dbmenu) sides = ["", "NATO", "Warsaw Pact"] # attacker info attacker_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel, "Attacker:") side_sizer.Add(attacker_sizer, 1, wx.ALL | wx.EXPAND, 5) # attacker side selecton self.attacker_side = wx.Choice(main_panel, -1, choices=sides) self.attacker_side.Bind(wx.EVT_CHOICE, self.OnAttackerSide) attacker_sizer.Add(self.attacker_side, 0, wx.EXPAND, 3) # attacker listctrl self.attacker_list = CheckListCtrl(main_panel) attacker_sizer.Add(self.attacker_list, 1, wx.EXPAND, 3) self.attacker_list.InsertColumn(0, "Formation", width=180) self.attacker_list.InsertColumn(1, "Strength") self.attacker_list.Bind(EVT_CHECKLISTCTRL, self.OnAttackerCheck) # TLI output self.oli_atk = 0 # tracker self.attacker_oli = wx.StaticText( main_panel, -1, "Total attacker OLI: {:>9,.0f}".format(0), ) attacker_sizer.Add(self.attacker_oli, 0, wx.CENTRE | wx.EXPAND | wx.ALL, 3) # defender info defender_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel, "Defender:") side_sizer.Add(defender_sizer, 1, wx.ALL | wx.EXPAND, 5) # defender side selecton self.defender_side = wx.Choice(main_panel, -1, choices=sides) self.defender_side.Bind(wx.EVT_CHOICE, self.OnDefenderSide) defender_sizer.Add(self.defender_side, 0, wx.EXPAND, 3) # defender listctrl self.defender_list = CheckListCtrl(main_panel) defender_sizer.Add(self.defender_list, 1, wx.EXPAND, 3) self.defender_list.InsertColumn(0, "Formation", width=180) self.defender_list.InsertColumn(1, "Strength") self.defender_list.Bind(EVT_CHECKLISTCTRL, self.OnDefenderCheck) # TLI output self.oli_def = 0 # tracker self.defender_oli = wx.StaticText( main_panel, -1, "Total defender OLI: {:>9,.0f}".format(0), ) defender_sizer.Add(self.defender_oli, 0, wx.CENTRE | wx.EXPAND | wx.ALL, 3) # bind double click for SITREP self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.ShowSITREP, self.attacker_list) self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.ShowSITREP, self.defender_list) # battle data ######################### data_sizer = wx.BoxSizer(wx.HORIZONTAL) main_sizer.Add(data_sizer, 0, wx.EXPAND | wx.ALL) # duration duration_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel, "Duration (hrs):") self.duration = wx.SpinCtrl(main_panel, -1, min=4, max=48, initial=4) duration_sizer.Add(self.duration, 1, wx.EXPAND | wx.ALL, 3) data_sizer.Add(duration_sizer, 0, wx.EXPAND | wx.ALL, 5) # terrain terrain_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel, "Terrain:") roughness = [ "rugged, heavily wooded", "rugged, mixed", "rugged, bare", "rolling, heavily wooded", "rolling, mixed", "rolling, bare", "flat, heavily wooded", "flat, mixed", "flat, bare, hard", "flat, desert", "desert, sandy dunes", "swamp, jungled", "swamp, mixed or open", "urban" ] self.terrain = wx.Choice(main_panel, -1, choices=roughness) self.terrain.SetSelection(0) terrain_sizer.Add(self.terrain, 1, wx.EXPAND | wx.ALL, 3) data_sizer.Add(terrain_sizer, 1, wx.EXPAND | wx.ALL, 5) # weather weather_types = [ "dry, sunshine, extreme heat", "dry, sunshine, temperate", "dry, sunshine, extreme cold", "dry, overcast, extreme heat", "dry, overcast, temperate", "dry, overcast, extreme cold", "wet, light, extreme heat", "wet, light, temperate", "wet, light, extreme cold", "wet, heavy, extreme heat", "wet, heavy, temperate", "wet, heavy, extreme cold", ] weather_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel, "Weather:") self.weather = wx.Choice(main_panel, -1, choices=weather_types) self.weather.SetSelection(0) weather_sizer.Add(self.weather, 1, wx.EXPAND | wx.ALL, 3) data_sizer.Add(weather_sizer, 1, wx.EXPAND | wx.ALL, 5) # 2nd row datar2_sizer = wx.BoxSizer(wx.HORIZONTAL) main_sizer.Add(datar2_sizer, 0, wx.EXPAND | wx.ALL) # season season_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel, "Season:") season_choices = [ "winter, jungle", "winter, desert", "winter, temperate", "spring, jungle", "spring, desert", "spring, temperate", "summer, jungle", "summer, desert", "summer, temperate", "fall, jungle", "fall, desert", "fall, temperate" ] seasons_choices = ["spring", "summer", "fall", "winter"] seasonloc_choices = ["temperate", "jungle", "desert"] self.season = wx.Choice(main_panel, -1, choices=seasons_choices) self.seasonloc = wx.Choice(main_panel, -1, choices=seasonloc_choices) self.season.SetSelection(0) self.seasonloc.SetSelection(0) season_sizer.Add(self.season, 1, wx.EXPAND | wx.ALL, 3) season_sizer.Add(self.seasonloc, 1, wx.EXPAND | wx.ALL, 3) datar2_sizer.Add(season_sizer, 1, wx.EXPAND | wx.ALL, 5) # roads road_density_choices = [ "dense network", "medium network", "sparse network" ] road_quality_choices = ["good roads", "mediocre roads", "poor roads"] roads_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel, "Roads:") self.road_density = wx.Choice(main_panel, -1, choices=road_density_choices) self.road_density.SetSelection(0) self.road_quality = wx.Choice(main_panel, -1, choices=road_quality_choices) self.road_quality.SetSelection(0) roads_sizer.Add(self.road_density, 1, wx.EXPAND | wx.ALL, 3) roads_sizer.Add(self.road_quality, 1, wx.EXPAND | wx.ALL, 3) datar2_sizer.Add(roads_sizer, 1, wx.EXPAND | wx.ALL, 5) # posture def_pos_choices = ["hasty", "prepared", "fortified", "delay", "attack"] posture_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel, "Defender posture:") self.posture = wx.Choice(main_panel, -1, choices=def_pos_choices) self.posture.SetSelection(0) posture_sizer.Add(self.posture, 1, wx.EXPAND | wx.ALL, 3) datar2_sizer.Add(posture_sizer, 1, wx.EXPAND | wx.ALL, 5) # date and name mdata_sizer = wx.BoxSizer(wx.HORIZONTAL) main_sizer.Add(mdata_sizer, 0, wx.EXPAND | wx.ALL, 0) datesizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel, "Date and location:") self.date = DatePickerCtrl(main_panel, -1, style=wx.adv.DP_DROPDOWN) self.date.SetValue(wx.DateTime(1, 10, 1983)) # default is 1 Nov 1983 #self.time = TimePickerCtrl(main_panel,-1) self.time = TimeCtrl(main_panel, -1, value='00:00', format='24HHMM') self.location = wx.TextCtrl(main_panel, -1, "") datesizer.Add(self.date, 0, wx.EXPAND | wx.ALL, 3) datesizer.Add(self.time, 0, wx.EXPAND | wx.ALL, 3) datesizer.Add(self.location, 1, wx.EXPAND | wx.ALL, 3) mdata_sizer.Add(datesizer, 1, wx.EXPAND | wx.ALL, 3) # river river_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel, "River:") river_choices = [ "no river", "fordable, 20m", "fordable, 50m", "fordable, 100m", "fordable, 500m", "unfordable, 20m", "unfordable, 50m", "unfordable, 100m", "unfordable, 500m", ] self.river = wx.Choice(main_panel, -1, choices=river_choices) self.river.SetSelection(0) river_sizer.Add(self.river, 1, wx.EXPAND | wx.ALL, 3) mdata_sizer.Add(river_sizer, 1, wx.EXPAND | wx.ALL, 3) # frontage frontage_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel, "Frontage:") self.frontage = wx.Slider(main_panel, -1, 100, 0, 100, style=wx.SL_HORIZONTAL | wx.SL_LABELS) frontage_sizer.Add(self.frontage, 1, wx.EXPAND | wx.ALL, 3) mdata_sizer.Add(frontage_sizer, 1, wx.EXPAND | wx.ALL, 3) # buttons button_panel = wx.Panel(self, style=wx.BORDER_THEME) frame_sizer.Add(button_panel, 0, wx.ALL | wx.EXPAND) button_sizer = wx.BoxSizer(wx.HORIZONTAL) button_panel.SetSizer(button_sizer) #main_sizer.Add(button_sizer,0,wx.EXPAND|wx.ALL,) self.simulate_btn = wx.Button(button_panel, -1, "Simulate") self.simulate_btn.Bind(wx.EVT_BUTTON, self.OnSimulate) self.save_btn = wx.Button(button_panel, -1, "Save State") self.save_btn.Bind(wx.EVT_BUTTON, self.OnSave) self.load_btn = wx.Button(button_panel, -1, "Load State") self.load_btn.Bind(wx.EVT_BUTTON, self.OnLoad) button_sizer.Add(self.simulate_btn, 1, wx.EXPAND | wx.ALL, 3) button_sizer.Add(self.save_btn, 1, wx.EXPAND | wx.ALL, 3) button_sizer.Add(self.load_btn, 1, wx.EXPAND | wx.ALL, 3) def OnAttackerCheck(self, event): idx = event.idx name = self.attacker_list.GetItemText(idx, col=0) form = self.GetTopLevelParent().gdb.gm_forms_db.formation_by_name(name) flag = event.flg if flag: # if checked, add the OLI value self.oli_atk += form.OLI else: # if unchecked, remove it self.oli_atk += -form.OLI # update the OLI display self.attacker_oli.SetLabel("Total attacker OLI: {:>9,.0f}".format( self.oli_atk)) def OnDefenderCheck(self, event): idx = event.idx name = self.defender_list.GetItemText(idx, col=0) form = self.GetTopLevelParent().gdb.gm_forms_db.formation_by_name(name) flag = event.flg if flag: # if checked, add the OLI value self.oli_def += form.OLI else: # if unchecked, remove it self.oli_def += -form.OLI # update the OLI display self.defender_oli.SetLabel("Total defender OLI: {:>9,.0f}".format( self.oli_def)) def OnAttackerSide(self, event): # set both OLI values to zero self.attacker_oli.SetLabel("Total attacker OLI: {:>9,.0f}".format(0)) self.defender_oli.SetLabel("Total defender OLI: {:>9,.0f}".format(0)) self.attacker_list.DeleteAllItems() # clear items side = self.attacker_side.GetString(self.attacker_side.GetSelection()) if side == "": return faction_search = side_dict[side] formations = self.GetTopLevelParent().gdb.gm_forms_db.forms for form in formations: if form.faction in faction_search: entry = [form.name, "{:,.0f}".format(form.OLI)] self.attacker_list.Append(entry) def OnDefenderSide(self, event): self.defender_list.DeleteAllItems() # clear items side = self.defender_side.GetString(self.defender_side.GetSelection()) if side == "": return faction_search = side_dict[side] formations = self.GetTopLevelParent().gdb.gm_forms_db.forms for form in formations: if form.faction in faction_search: entry = [form.name, "{:,.0f}".format(form.OLI)] self.defender_list.Append(entry) def OnSimulate(self, event): # Multiply force strength by operational variables - overall forms a big ugly equation # force strength is shown by: # S = [(ws+Wmg+Whw)*rn]+(wgi*rn)+[(Wg+Wgy)*(rwg*hwg*zwg*wyg)]+(Wi*rwi*hwi)+ ... # ...(Wy*rwy*hwy*zyw*wyy) + Wgi + Wgy # note Wgi is included up to enemy armour OLI, then only half excess is added # same applies for Wfgy for air defense weapons, up to hostile Close Air Support (Wey) # Air firepower (Wy) over sum of all ground firepower is not fully effective # Wy > Ws + Wmy + Whw + Wgi + Wg + Wgy + Wi, only half of excess Wy is applied # maximum Wy is 3x ground weapons firepower # # operational factors are given by: # [Ma-(1-rm*hm)(Ma-1)]*le*t*o*b*us*ru*hu*zu*v # where v = 1-(N*uv/ru*(Se/Sf)**.5 * vy*vr)/Sf # Following are degredation factors # le: leadership - typically 1 # t: training/experience - typically 1 # o: morale - typically 1 # b: logistical capability - typically 1 # Get OLI values from checked attackers attackers = list() attackers_forms = list() for idx in range(self.attacker_list.GetItemCount()): if self.attacker_list.IsChecked(idx): attackers.append(self.attacker_list.GetItemText(idx)) for form in attackers: attackers_forms.append( self.GetTopLevelParent().gdb.gm_forms_db.formation_by_name( form)) attacker_oli = self.GetTopLevelParent().gdb.gm_forms_db.oli_by_names( attackers) N_attacker = self.GetTopLevelParent().gdb.gm_forms_db.pers_by_names( attackers) J_attacker = self.GetTopLevelParent( ).gdb.gm_forms_db.vehicles_by_names( attackers, self.GetTopLevelParent().gdb.equip_db) # Get OLI values from checked defenders defenders = list() defenders_forms = list() for idx in range(self.defender_list.GetItemCount()): if self.defender_list.IsChecked(idx): defenders.append(self.defender_list.GetItemText(idx)) defender_oli = self.GetTopLevelParent().gdb.gm_forms_db.oli_by_names( defenders) for form in defenders: defenders_forms.append( self.GetTopLevelParent().gdb.gm_forms_db.formation_by_name( form)) N_defender = self.GetTopLevelParent().gdb.gm_forms_db.pers_by_names( defenders) J_defender = self.GetTopLevelParent( ).gdb.gm_forms_db.vehicles_by_names( defenders, self.GetTopLevelParent().gdb.equip_db) # get environment data from the forms terrain = self.terrain.GetString(self.terrain.GetSelection()) weather = self.weather.GetString(self.weather.GetSelection()) season_sel = self.season.GetString(self.season.GetSelection()) season_locale = self.seasonloc.GetString(self.seasonloc.GetSelection()) river = self.river.GetString(self.river.GetSelection()) time_day = self.time.GetValue() print(time_day) # determine if it is day or night if time_day > "06:00" and time_day < "20:00": daytime = True else: daytime = False # get the frontage of the attack (% of defenders) frontage = self.frontage.GetValue() / 100 seasonstr = season_sel + ', ' + season_locale #print(seasonstr) # get the posture from the form def_posture = self.posture.GetString(self.posture.GetSelection()) # Terrain effectiveness values (r) and weather effectiveness (h) # infantry & antitank rn = mc.terrain(terrain, 'inf') # artillery & air defence rwg = mc.terrain(terrain, 'arty') hwg = mc.weather(weather, 'arty') zwg = mc.season(seasonstr, 'arty') # tanks rwi = mc.terrain(terrain, 'tank') hwi = mc.weather(weather, 'tank') # aircraft rwy = mc.terrain(terrain, 'air') hwy = mc.weather(weather, 'air') zwy = mc.season(seasonstr, 'air') # these constants are for air superiority wyg = 1 wyy = 1 print(attacker_oli.air, attacker_oli.ad) print(defender_oli.air, defender_oli.ad) # attacker data: Wain = attacker_oli.inf Waat = attacker_oli.at Watn = attacker_oli.afv Waar = attacker_oli.arty Waad = attacker_oli.ad Waai = attacker_oli.air # defender data Wdin = defender_oli.inf Wdat = defender_oli.at Wdtn = defender_oli.afv Wdar = defender_oli.arty Wdad = defender_oli.ad Wdai = defender_oli.air # deal with overmatches in at and ad OLIs Waat = overmatch(Waat, Wdtn) Wdat = overmatch(Wdat, Watn) Waad = overmatch(Waad, Wdai, cap=3) Wdad = overmatch(Wdad, Waai, cap=3) # using my "simplified" formula S_attacker = ((Wain + Waat) * rn + (Waar + Waad * wyg) * rwg * hwg * zwg + Watn * rwi * hwi + Waai * rwy * hwy * zwy * wyy) S_defender = ( (Wdin + Wdat) * rn + (Wdar + Wdad * wyg) * rwg * hwg * zwg + Wdtn * rwi * hwi + Wdai * rwy * hwy * zwy * wyy) * frontage # get the combat power Faj = 1 # judgement degrading factor for attacker Fdj = 1 # judgement degrading factor for defender uas = mc.stren_posture_factor('attack') # posture for attacker uds = mc.stren_posture_factor(def_posture) # posture for defender rau = 1 # terrain for attacker - attacker is always 1 rdu = mc.terrain( terrain, 'defpos') # terrain for defender - uses terrain defpos hau = mc.weather(weather, 'attack') # weather for attacker hdu = 1 # weather for defender - defender is always 1 zau = mc.season(seasonstr, 'attack') # season for attacker zdu = 1 # season for defender - defender is always 1 # mobility factors road_quality = self.road_quality.GetString( self.road_quality.GetSelection()) road_density = self.road_density.GetString( self.road_density.GetSelection()) rma = mc.terrain(terrain, 'mobility') hma = mc.weather(weather, 'mobility') mya = 1 # don't know what this factor is myd = 1 # don't know what this factor is either # vulnerability factors uav = mc.vuln_posture_factor('attack') udv = mc.vuln_posture_factor(def_posture) vay = 1 # air superiority vulnerability vdy = 1 # air superiority vulnerability var = 1 # shoreline vulnerability vdr = 1 # shoreline vulnerability # mobility MFactor = 12 # 20 for WWII M_attacker = (( (N_attacker + MFactor * J_attacker + Waar) * mya / N_attacker) / ((N_defender + MFactor * J_defender + Wdar) * myd / N_defender))**0.5 M_defender = 1 # always 1 ma_operational = M_attacker - (1 - rma * hma) * (M_attacker - 1) md_operational = M_defender # vulnerability Vuln_attacker = N_attacker * uav / rau * (S_defender / S_attacker)**0.5 * vay * var print("Vulnerability calcs:", N_attacker, uav, rau, S_defender, S_attacker, vay, var) Vuln_defender = N_defender * udv / rdu * (S_attacker / S_defender)**0.5 * vdy * vdr va_operational = (1 - Vuln_attacker / S_attacker) vd_operational = (1 - Vuln_defender / S_defender) if va_operational > 0.8: va_operational = 0.8 elif va_operational > 0.3: va_operational = 0.3 + 0.1 * (va_operational - 0.3) else: va_operational = 0.3 if vd_operational > 0.8: vd_operational = 0.8 elif vd_operational > 0.3: vd_operational = 0.3 + 0.1 * (vd_operational - 0.3) else: vd_operational = 0.3 # note that the CEV is already contained in the OLI output Op_attacker = Faj * uas * rau * hau * zau Op_defender = Fdj * uds * rdu * hdu * zdu P_attacker = S_attacker * ma_operational * Op_attacker * va_operational P_defender = S_defender * md_operational * Op_defender * vd_operational P_ratio = P_attacker / P_defender dateval = self.date.GetValue().FormatISODate() #timeval = self.time.GetValue().FormatISOTime() timeval = self.time.GetWxDateTime().FormatISOTime() location = self.location.GetValue() print("*** START REPORT ***\n") print("{} engages {}\n".format(attackers, defenders)) print( "Base OLI data: (W) || Attacker: {:9,.0f} | Defender: {:9,.0f} | Ratio {:.1f}" .format(attacker_oli.total, defender_oli.total, attacker_oli.total / defender_oli.total)) print( "Strength data (S): || Attacker: {:9,.0f} | Defender: {:9,.0f} | Ratio {:.1f}" .format(S_attacker, S_defender, S_attacker / S_defender)) print( "Combat Power (P): || Attacker: {:9,.0f} | Defender: {:9,.0f} | Ratio {:.1f}" .format(P_attacker, P_defender, P_attacker / P_defender)) print( "\n Key factors: | Attacker | Defender\n", "Strength | {:9,.0f} | {:9,.0f}\n".format( S_attacker, S_defender), "Mobility | {:9,.2f} | {:9,.2f}\n".format( M_attacker, M_defender), "Vulnerability| {:9,.0f} | {:9,.0f}\n".format( Vuln_attacker, Vuln_defender), "Op. Vuln | {:9,.3f} | {:9,.3f}\n".format( va_operational, vd_operational), ) # advance rate - probably need to run for each individual formation? for name in attackers: index = self.GetTopLevelParent().gdb.gm_forms_db.names.index(name) unittype = self.GetTopLevelParent( ).gdb.gm_forms_db.forms[index].type adv_base = mc.advance_rate_base(P_ratio, unittype, def_posture) adv_roads = mc.advance_rate_road(road_quality, road_density) adv_terr = mc.advance_rate_terr(terrain, unittype) adv_river = mc.river_obstacle_factor(river) adv_rate = adv_base * adv_roads * adv_terr * adv_river atk_losses = self.GetTopLevelParent( ).gdb.gm_forms_db.forms[index].casualties( P_ratio, 'attack', day=daytime, duration=self.duration.GetValue(), pers=N_attacker) print("{} advance rate: {:.1f} km/day".format( self.GetTopLevelParent().gdb.gm_forms_db.forms[index].name, adv_rate)) print("---") print(self.GetTopLevelParent().gdb.gm_forms_db.forms[index].SITREP( atk_losses, activity='Attacking', datestr="{} {}".format(dateval, timeval), location=location, writefolder=gmdir + "\\reports")) for name in defenders: index = self.GetTopLevelParent().gdb.gm_forms_db.names.index(name) def_losses = self.GetTopLevelParent( ).gdb.gm_forms_db.forms[index].casualties( P_ratio, def_posture, day=daytime, duration=self.duration.GetValue(), exposure=frontage, pers=N_defender) print("---") print(self.GetTopLevelParent().gdb.gm_forms_db.forms[index].SITREP( def_losses, activity=def_posture + ' defense', datestr="{} {}".format(dateval, timeval), location=location, writefolder=gmdir + "\\reports")) # finish the report print("*** END REPORT ***") def ShowSITREP(self, event): # get the list that was clicked formlist = event.GetEventObject() # get the item from the list item = formlist.GetItemText(event.GetIndex(), col=0) # print a sitrep for the item form = self.GetTopLevelParent().gdb.gm_forms_db.formation_by_name(item) infoframe = formation_info_form( self, form.SITREP(activity='None') + "\nNo TLI data for:\n{}".format(form.NoTLIData), item) infoframe.Show() def OnDbEdit(self, event): eqp = equip_gui.equipment_gui_frame() eqp.Show() def OnSave(self, event): dlg = wx.DirDialog(self, message="Master folder for formations to save", defaultPath=gmdir) result = dlg.ShowModal() path = dlg.GetPath() dlg.Destroy() if result == wx.ID_OK: for form in self.GetTopLevelParent().gdb.gm_forms_db.forms: form.output(path) def OnLoad(self, event): dlg = wx.DirDialog(self, message="Master folder for formations to load", defaultPath=gmdir) result = dlg.ShowModal() path = dlg.GetPath() dlg.Destroy() if result == wx.ID_OK: self.GetTopLevelParent().gdb.load_gm_formations(path) def OnClose(self, event): dlg = wx.MessageDialog(self, "Are you sure you want to close?", "Confirm exit", wx.OK | wx.CANCEL | wx.ICON_QUESTION) result = dlg.ShowModal() dlg.Destroy() if result == wx.ID_OK: self.Destroy()
class MainWindow(wx.Frame): def __init__(self, parent, title, sdb): wx.Frame.__init__(self, parent, title=title, size=(200, 100)) self.timeControl = TimeCtrl(self, -1, value='00:00:00', pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TE_PROCESS_TAB, validator=wx.DefaultValidator, name="time", format='HHMMSS', fmt24hr=True, displaySeconds=False, spinButton=None, min=None, max=None, limited=None, oob_color="Yellow") self.sizer = wx.GridSizer(rows=4, cols=1, hgap=0, vgap=0) self.timeControlSizer = wx.GridSizer(rows=1, cols=1, hgap=0, vgap=0) self.timeControlSizer.Add(self.timeControl, 0, wx.EXPAND) self.sizer.Add(self.timeControlSizer, 0, wx.ALIGN_CENTER) # Button to set alarm self.setButton = wx.Button(self, -1, "Set Alarm") self.setButton.Bind(wx.EVT_BUTTON, self.OnAlarm) # Button to reset alarm self.resetButton = wx.ToggleButton(self, wx.ID_ANY, "OFF") self.resetButton.SetBackgroundColour('RED') self.resetButton.SetValue(False) self.resetButton.Bind(wx.EVT_TOGGLEBUTTON, self.OnReset) self.alarmControlSizer = wx.GridSizer(rows=1, cols=2, hgap=0, vgap=0) self.alarmControlSizer.Add(self.setButton, 0, wx.EXPAND) self.alarmControlSizer.Add(self.resetButton, 0, wx.EXPAND) self.sizer.Add(self.alarmControlSizer, 0, wx.EXPAND) # Now Playing self.nowPlaying = wx.TextCtrl(self, wx.ID_ANY, NOW_PLAYING) self.nowPlaying.SetEditable(False) self.sizer.Add(self.nowPlaying, 0, wx.EXPAND) self.SetNowPlaying(sdbPlayer.CurrentSong.ArtistName, sdbPlayer.CurrentSong.Title) # Player Controls self.controlsSizer = wx.GridSizer(rows=1, cols=4, hgap=0, vgap=0) self.playButton = wx.Button(self, wx.ID_ANY, "> ||") self.playButton.Bind(wx.EVT_BUTTON, self.OnPressPlay) self.stopButton = wx.Button(self, wx.ID_ANY, "x") self.stopButton.Bind(wx.EVT_BUTTON, self.OnPressStop) self.nextButton = wx.Button(self, wx.ID_ANY, ">>") self.nextButton.Bind(wx.EVT_BUTTON, self.OnPressNext) self.prevButton = wx.Button(self, wx.ID_ANY, "<<") self.prevButton.Bind(wx.EVT_BUTTON, self.OnPressPrev) self.controlsSizer.Add(self.playButton, 0, wx.EXPAND) self.controlsSizer.Add(self.stopButton, 0, wx.EXPAND) self.controlsSizer.Add(self.prevButton, 0, wx.EXPAND) self.controlsSizer.Add(self.nextButton, 0, wx.EXPAND) self.sizer.Add(self.controlsSizer, 0, wx.EXPAND) self.SetBackgroundColour('WHITE') self.CreateStatusBar() # File Menu Set Up filemenu = wx.Menu() menuAbout = filemenu.Append( wx.ID_ABOUT, "&About", "An alarm clock that ties into Media Monkey and triggers\ a play on the now playing playlist.") self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout) menuExit = filemenu.Append(wx.ID_EXIT, "&Exit", "Terminate the Program") self.Bind(wx.EVT_MENU, self.OnExit, menuExit) # Create the Menu Bar. menuBar = wx.MenuBar() menuBar.Append(filemenu, "&File") self.SetMenuBar(menuBar) #Layout sizers self.SetSizer(self.sizer) self.SetAutoLayout(1) self.sizer.Fit(self) # Set the window to be visible. self.Show(True) def OnAbout(self, e): # A message dialog with OK button. dlg = wx.MessageDialog( self, "An alarm clock that ties into Media Monkey and triggers\ a play on the now playing playlist. \n\n Created by Natasha Dalal (2014).", "About", wx.OK) dlg.ShowModal() dlg.Destroy() # Destroy the window when it is finished. print('resetting') def OnExit(self, e): self.Close(True) def OnReset(self, e): self.ToggleReset() def ToggleReset(self): self.SetAlarmArmed(self.resetButton.GetValue()) def SetAlarmArmed(self, arm): self.resetButton.SetValue(arm) if not arm: self.resetButton.SetBackgroundColour('RED') self.resetButton.SetLabel("OFF") try: self.timer.Stop() print "Disarming Alarm" except: print "No timer currently set" else: print "Arming Alarm" self.resetButton.SetBackgroundColour('GREEN') self.resetButton.SetLabel("ON") def OnAlarm(self, e): try: self.timer.Stop() except: print "No timer currently set" # Get the current set alarm time: atTime = self.timeControl.GetValue(as_wxDateTime=True) # Set the date to the right date. atTime.SetDay(wx.DateTime.Today().GetDay()) atTime.SetMonth(wx.DateTime.Today().GetMonth()) atTime.SetYear(wx.DateTime.Today().GetYear()) # If the time specified has already passed, set it for # the provided time on the next day. now = wx.DateTime.Now() if atTime.IsEarlierThan(now): # Number of Days in the current month dim = wx.DateTime.GetNumberOfDaysInMonth(atTime.GetMonth()) if atTime.GetDay() == dim: atTime.SetDay(1) atTime.SetMonth(atTime.GetMonth() + 1) else: atTime.SetDay(atTime.GetDay() + 1) # At this point, atTime should be the right time and date. # The sleep time in seconds sleepTime = atTime.GetTicks() - now.GetTicks() self.timer = wx.Timer(self, -1) self.Bind(wx.EVT_TIMER, self.DoPlay) self.timer.Start(sleepTime * 1000, wx.TIMER_ONE_SHOT) self.SetAlarmArmed(True) def DoPlay(self, e): print("Starting to Play") sdbPlayer.Play() self.ToggleReset() def SetNowPlaying(self, artist, title): self.nowPlaying.SetValue(NOW_PLAYING + artist + " - " + title) # Player Control Handlers def OnPressPlay(self, e): if sdbPlayer.isPlaying: sdbPlayer.Pause() else: sdbPlayer.Play() def OnPressStop(self, e): sdbPlayer.Stop() def OnPressNext(self, e): sdbPlayer.Next() def OnPressPrev(self, e): sdbPlayer.Previous()