"""Game news page handler, part of SOLARWOLF.""" import math, os, threading, re import urllib, tempfile, shutil import pygame, pygame.font from pygame.locals import * import game import gfx, snd, txt import input import gameplay import webbrowser import objbox images = [] fonts = [] downimgs = [] news_downloaded = 0 ship = None Options = [ "Main Menu", "Download News", "Visit Website", ] def load_game_resources(): global images, fonts, downimgs, ship img = gfx.load('menu_news_on.png') r = img.get_rect().move(10, 10) images.append((img, r)) img = gfx.load('download.png') downimgs = gfx.animstrip(img, img.get_width()/2) for i in ('downerror', 'newversion', 'downok'): img = gfx.load(i+'.gif') downimgs.append(img) fonts.append((txt.Font(None, 36, italic=1), (150, 150, 200))) fonts.append((txt.Font(None, 22), (120, 120, 250))) fonts.append((txt.Font(None, 28), (120, 120, 250))) ship = pygame.transform.rotate(gfx.load('ship-up.png'), -90) snd.preload('select_choose', 'startlife', 'levelskip') def downloadfunc(gamenews): global news_downloaded try: news = urllib.urlopen(game.news_url).readlines() except: gamenews.downcur = 3 return gamenews.downcur = 0 try: tag = re.compile('<.*>\n*') newsfilename = game.make_dataname('news') f = open(newsfilename, 'w') for line in news: l = re.sub(tag, '', line) if l: f.write(l.rstrip() + os.linesep) f.close() gamenews.success = 1 news_downloaded = 1 except (IOError, OSError): gamenews.downcur = 3 class GameNews: def __init__(self, prevhandler): global news_downloaded news_downloaded = 0 self.prevhandler = prevhandler self.images = images self.imgs = [] self.boxes = [] self.thread = None self.newsversion = "0.0" self.loadnews() self.success = 0 self.downimgs = downimgs self.downloadpos = 660, 10 self.clocks = 0 self.downcur = 0 self.lastdownrect = None self.shipimage = [ship, ship.get_rect()] self.done = 0 self.aborted = 0 self.linesize = 60 self.current = 0 self.gamelist = [] self.buildlist() self.shipmovex = 20 self.shipmovey = 14 self.moveto(self.gamelist[0][1]) self.tempwindowed = 0 self.launchthebrowser = 0 def starting(self): pass #self.download_start() def quit(self): if self.tempwindowed: game.display = 1 gfx.switchfullscreen() game.handler = self.prevhandler self.done = 1 def makebadnews(self, title, message): t = fonts[1][0].text(fonts[1][1], title, (100, 200), 'topleft') self.imgs.append(t) t = fonts[0][0].text(fonts[1][1], message, (140, 235), 'topleft') self.imgs.append(t) def rendertext(self, font, text): return fonts[font][0].text(fonts[font][1], text) def loadnews(self): self.cleartext() self.imgs = [] self.boxes = [] newsfilename = game.make_dataname('news') if not os.path.isfile(newsfilename): newsfilename = game.get_resource('news') if os.path.isfile(newsfilename): news = open(newsfilename).readlines()[2:] if not news: self.makebadnews(' ', 'Invalid News File') return self.newsversion = news[0].split()[-1] newsitems = [] title = date = None body = [] for line in news[2:]: line = line.rstrip() if not line: if title: newsitems.append((title, date, body)) title = date = None body = [] elif not title: title = line elif not date: date = line else: body.append(line) top = 150 for t, d, body in newsitems: self.boxes.append(objbox.Box((28, top+3), 1)) self.boxes[-1].rotspeed = 2.0 self.boxes[-1].rotate = 0.0 text, r = self.rendertext(0, t) trect = r.move(60, top) self.imgs.append((text, trect)) text, r = self.rendertext(1, d) r = r.move(trect.right + 25, top+10) self.imgs.append((text, r)) top = trect.bottom for b in body: text, r = self.rendertext(2, b) r = r.move((100, top)) top = r.bottom self.imgs.append((text, r)) top += 24 else: self.makebadnews(' ', 'Cannot Download News') def download_start(self): if not self.thread: self.success = 0 thread = threading.Thread(None, downloadfunc, 'FETCHNEWS', [self]) self.downcur = 1 thread.start() self.thread = thread snd.play('startlife') def download_finished(self): self.thread = None snd.play('levelskip') self.loadnews() def moveto(self, pos): self.shippos = pos[0], pos[1] def input(self, i): if self.done: return if i.release: return if i.translated == input.ABORT: self.aborted = 1 self.done = 1 snd.play('select_choose') self.quit() if i.translated == input.PRESS: return self.pressed() if i.translated in (input.DOWN, input.UP): if i.translated == input.DOWN: self.current = (self.current+1) % len(self.gamelist) else: self.current = (self.current-1) % len(self.gamelist) snd.play('select_move') x = self.gamelist[self.current][1].left y = self.gamelist[self.current][1].top self.moveto((x, y)) self.buildlist() def event(self, e): pass def cleartext(self): for i in self.imgs: r = i[1] self.background(r) gfx.dirty(r) def run(self): self.clocks += 1 self.cleartext() if self.thread and (not self.thread.isAlive() and self.success): self.download_finished() clearme = None if self.lastdownrect: gfx.dirty(self.background(self.lastdownrect)) clearme = self.lastdownrect self.lastdownrect = None r = self.background(self.shipimage[1]) gfx.dirty(r) gfx.updatestars(self.background, gfx) if not self.done: for img, r in self.images: gfx.dirty(gfx.surface.blit(img, r)) downimg, downrect = self.downimg() if downimg: self.lastdownrect = gfx.surface.blit(downimg, downrect) gfx.dirty2(self.lastdownrect, clearme) for text, pos in self.imgs: gfx.surface.blit(text, pos) else: for img, r in self.images: gfx.dirty(self.background(r)) gfx.dirty(clearme) if not self.done: self.drawlist() self.moveship() r = gfx.surface.blit(self.shipimage[0], self.shipimage[1]) gfx.dirty(r) for b in self.boxes: b.erase(self.background) b.tick(1.0) b.draw(gfx) else: #game.handler = self.prevhandler for b in self.boxes: b.erase(self.background) self.clearlist() if self.launchthebrowser: #we do it like this so the window can get #unfullscreened and not minimized on windows self.launchthebrowser -= 1 if not self.launchthebrowser: webbrowser.open(game.site_url, 1, 1) def downimg(self): if not self.downcur: if self.newsversion > game.version: img = self.downimgs[3] r = img.get_rect() r.midtop = self.downloadpos return img, r elif news_downloaded: img = self.downimgs[4] r = img.get_rect().move(self.downloadpos) return img, r else: return None, None if self.downcur == 3: img = self.downimgs[2] else: self.downcur = (self.clocks / 8) % 2 + 1 img = self.downimgs[self.downcur-1] return img, img.get_rect().move(self.downloadpos) def background(self, area): return gfx.surface.fill((0, 0, 0), area) def buildlist(self): clr = 220, 230, 240 clr2 = 140, 150, 160 offsetx, offsety = 240, 30 self.clearlist() font = fonts[0][0] self.gamelist = [] cur = 0 for opt in Options: if self.current == cur: c = clr else: c = clr2 imgpos = font.text(c, opt, (offsetx, offsety), "midleft") self.gamelist.append(imgpos) offsety += 33 cur += 1 def clearlist(self): for o in self.gamelist: gfx.dirty(self.background(o[1])) for b in self.boxes: b.dead = 1 b.erase(self.background) def drawlist(self): for o in self.gamelist: gfx.dirty(gfx.surface.blit(*o)) def moveship(self): pos = list(self.shipimage[1].topright) if pos[0] + self.shipmovex < self.shippos[0]: pos[0] += self.shipmovex elif pos[0] < self.shippos[0]: pos[0] = self.shippos[0] if pos[0] - self.shipmovex > self.shippos[0]: pos[0] -= self.shipmovex elif pos[0] > self.shippos[0]: pos[0] = self.shippos[0] if pos[1] + self.shipmovey < self.shippos[1]: pos[1] += self.shipmovey elif pos[1] < self.shippos[1]: pos[1] = self.shippos[1] if pos[1] - self.shipmovey > self.shippos[1]: pos[1] -= self.shipmovey elif pos[1] > self.shippos[1]: pos[1] = self.shippos[1] self.shipimage[1].topright = pos def pressed(self): pref = Options[self.current] snd.play('select_choose') val = Options[self.current].split()[0].lower() getattr(self, "do_"+val)() def do_main(self): #Main Menu self.quit() def do_download(self): #Download News self.download_start() def do_visit(self): #Visit Website if game.display: #fullscreen self.tempwindowed = 1 game.display = 0 gfx.switchfullscreen() self.launchthebrowser = 2 #funny windows workaround