summaryrefslogtreecommitdiff
path: root/bubbob/ext5/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'bubbob/ext5/__init__.py')
-rw-r--r--bubbob/ext5/__init__.py289
1 files changed, 289 insertions, 0 deletions
diff --git a/bubbob/ext5/__init__.py b/bubbob/ext5/__init__.py
new file mode 100644
index 0000000..ef73f14
--- /dev/null
+++ b/bubbob/ext5/__init__.py
@@ -0,0 +1,289 @@
+from __future__ import generators
+import os, random
+import images, gamesrv
+from images import ActiveSprite
+import boards
+from boards import CELL, HALFCELL, bget
+from monsters import Monster
+from player import Dragon, BubPlayer
+from bubbles import Bubble
+import bonuses
+
+LocalDir = os.path.basename(os.path.dirname(__file__))
+
+localmap = {
+ ('lem-walk', 1,0) : ('image1.ppm', ( 0, 0, 32, 32)),
+ ('lem-walk', 1,1) : ('image1.ppm', ( 32, 0, 32, 32)),
+ ('lem-walk', 1,2) : ('image1.ppm', ( 64, 0, 32, 32)),
+ ('lem-walk', 1,3) : ('image1.ppm', ( 96, 0, 32, 32)),
+ ('lem-walk', 1,4) : ('image1.ppm', (128, 0, 32, 32)),
+ ('lem-walk', 1,5) : ('image1.ppm', (160, 0, 32, 32)),
+ ('lem-walk', 1,6) : ('image1.ppm', (192, 0, 32, 32)),
+ ('lem-walk', 1,7) : ('image1.ppm', (224, 0, 32, 32)),
+ ('lem-fall', 1,0) : ('image1.ppm', (256, 0, 32, 32)),
+ ('lem-fall', 1,1) : ('image1.ppm', (288, 0, 32, 32)),
+ ('lem-fall', 1,2) : ('image1.ppm', (320, 0, 32, 32)),
+ ('lem-fall', 1,3) : ('image1.ppm', (352, 0, 32, 32)),
+
+ ('lem-fall',-1,3) : ('image2.ppm', ( 0, 0, 32, 32)),
+ ('lem-fall',-1,2) : ('image2.ppm', ( 32, 0, 32, 32)),
+ ('lem-fall',-1,1) : ('image2.ppm', ( 64, 0, 32, 32)),
+ ('lem-fall',-1,0) : ('image2.ppm', ( 96, 0, 32, 32)),
+ ('lem-walk',-1,7) : ('image2.ppm', (128, 0, 32, 32)),
+ ('lem-walk',-1,6) : ('image2.ppm', (160, 0, 32, 32)),
+ ('lem-walk',-1,5) : ('image2.ppm', (192, 0, 32, 32)),
+ ('lem-walk',-1,4) : ('image2.ppm', (224, 0, 32, 32)),
+ ('lem-walk',-1,3) : ('image2.ppm', (256, 0, 32, 32)),
+ ('lem-walk',-1,2) : ('image2.ppm', (288, 0, 32, 32)),
+ ('lem-walk',-1,1) : ('image2.ppm', (320, 0, 32, 32)),
+ ('lem-walk',-1,0) : ('image2.ppm', (352, 0, 32, 32)),
+
+ ('lem-jail', 0) : ('image4.ppm', ( 0, 0, 32, 32)),
+ ('lem-jail', 1) : ('image4.ppm', ( 0, 32, 32, 32)),
+ ('lem-jail', 2) : ('image4.ppm', ( 0, 64, 32, 32)),
+ }
+for n in range(16):
+ localmap[('lem-crash', n)] = ('image3.ppm', (32*n, 0, 32, 32))
+
+music = gamesrv.getmusic(os.path.join(LocalDir, 'music.wav'))
+snd_ouch = gamesrv.getsample(os.path.join(LocalDir, 'ouch.wav'))
+
+
+class Lemmy:
+ right = [('lem-walk', 1,n) for n in range(8)]
+ left = [('lem-walk',-1,n) for n in range(8)]
+ jailed = [('lem-jail', n) for n in range(3)]
+
+
+class Lemming(Monster):
+
+ def __init__(self, lemmings, x, y, dir):
+ Monster.__init__(self, Lemmy, x, y, dir, in_list=lemmings.lemlist)
+ self.lemmings = lemmings
+
+ def argh(self, *args, **kwds):
+ self.untouchable()
+ self.gen = [self.jumpout()]
+
+ def resetimages(self):
+ pass
+
+ def touched(self, dragon):
+ if 20 >= abs(self.x - dragon.x) >= 14:
+ if self.x < dragon.x:
+ self.dir = -1
+ else:
+ self.dir = 1
+
+ def in_bubble(self, bubble):
+ self.move(bubble.x, bubble.y)
+ Monster.in_bubble(self, bubble)
+ return -1
+
+ def bubbling(self, bubble):
+ dx = random.randrange(-3, 4)
+ dy = random.randrange(-4, 2)
+ counter = 0
+ while not hasattr(bubble, 'poplist'):
+ if self.y < -CELL and bubble.y > CELL: # bubble wrapped
+ self.leaveboard(bubble)
+ return
+ self.move(bubble.x+dx, bubble.y+dy)
+ yield None
+ if bubble.poplist is None and bubble.y <= -2*CELL+1:
+ self.leaveboard(bubble)
+ return
+ self.setimages(None)
+ self.gen = [self.jumpout()]
+
+ def jumpout(self):
+ # jumping out of the bubble
+ self.seticon(images.sprget(self.mdef.jailed[1]))
+ dxy = [(random.random()-0.5) * 9.0,
+ (random.random()+0.5) * (-5.0)]
+ for n in self.parabolic(dxy):
+ yield n
+ if dxy[1] >= 2.0:
+ break
+ if dxy[0] < 0:
+ self.dir = -1
+ else:
+ self.dir = 1
+ self.touchable = 1
+ self.gen.append(self.falling())
+
+ def falling(self):
+ self.setimages(None)
+ n = 0
+ lemmap = self.lemmings.lemmap
+ while not self.onground():
+ yield None
+ self.move(self.x, (self.y + 4) & ~3,
+ lemmap['lem-fall', self.dir, n&3])
+ n += 1
+ if self.y >= boards.bheight:
+ self.kill()
+ return
+ yield None
+ if n <= 33:
+ self.gen.append(self.walking())
+ else:
+ self.play(snd_ouch)
+ self.untouchable()
+ self.to_front()
+ self.gen = [self.die([('lem-crash', n) for n in range(16)], 2)]
+
+ def walking(self):
+ self.setimages(None)
+ n = 0
+ lemmap = self.lemmings.lemmap
+ y0 = self.y // 16
+ while self.y == y0*16:
+ yield None
+ nx = self.x + self.dir*2
+ x0 = (nx+15) // 16
+ if bget(x0, y0+1) == ' ':
+ if bget(x0, y0+2) == ' ':
+ y0 += 1 # fall
+ elif bget(x0, y0) != ' ':
+ self.dir = -self.dir
+ self.resetimages()
+ continue
+ else: # climb
+ y0 -= 1
+ n2 = 0
+ while self.y > y0*16:
+ self.step(0, -2)
+ if n2:
+ n2 -= 1
+ else:
+ self.seticon(lemmap['lem-walk', self.dir, n&7])
+ n += 1
+ n2 = 2
+ yield None
+ self.move(nx, self.y, lemmap['lem-walk', self.dir, n&7])
+ n += 1
+ yield None
+ yield None
+ self.gen.append(self.falling())
+
+ def onground(self):
+ if self.y & 15:
+ return 0
+ x0 = (self.x+15) // 16
+ y0 = self.y // 16 + 2
+ return bget(x0, y0) != ' ' == bget(x0, y0-1)
+
+ def leaveboard(self, bubble):
+ if hasattr(bubble, 'd'):
+ bubble.play(images.Snd.Extra)
+ score = self.lemmings.score
+ bubber = bubble.d.bubber
+ score[bubber] = score.get(bubber, 0) + 1
+ bonuses.points(bubble.x, bubble.y, bubble.d, 500)
+ self.kill()
+
+ default_mode = walking
+
+
+class Lemmings:
+
+ def bgen(self, limittime = 60.1): # 0:60
+ self.score = {}
+ for t in boards.initsubgame(music, self.displaypoints):
+ yield t
+ self.lemmap = {}
+ for key in localmap:
+ self.lemmap[key] = images.sprget(key)
+
+ tc = boards.TimeCounter(limittime)
+ self.lemlist = []
+ self.lemtotal = 0
+ for t in self.frame():
+ t = boards.normal_frame()
+ yield t
+ tc.update(t)
+ if tc.time == 0.0:
+ break
+
+ tc.restore()
+ for s in self.lemlist[:]:
+ if s.alive:
+ s.kill()
+ for s in images.ActiveSprites[:]:
+ if isinstance(s, Bubble):
+ s.pop()
+ for t in boards.result_ranking(self.score.copy(), self.lemtotal):
+ yield t
+
+ def displaypoints(self, bubber):
+ return self.score.get(bubber, 0)
+
+ def frame(self):
+ windline = '>>' + '^'*(curboard.width-4) + '<<'
+ curboard.winds = [windline] * curboard.height
+
+ countholes = 0
+ ymax = curboard.height-1
+ for x in range(2, curboard.width-2):
+ if bget(x, ymax) == ' ':
+ countholes += 1
+
+ xrange = []
+ try:
+ for delta in range(2, curboard.width):
+ for x in [delta, curboard.width-delta-1]:
+ if x in xrange: raise StopIteration
+ xrange.append(x)
+ except StopIteration:
+ pass
+
+ for x in xrange:
+ if countholes > curboard.width//6 and bget(x, ymax) == ' ':
+ curboard.putwall(x, ymax)
+ curboard.reorder_walls()
+ countholes -= 1
+ for y in range(0, ymax):
+ if bget(x, y) == ' ':
+ break
+ curboard.killwall(x, y)
+ yield None
+
+ testing = {}
+ def addlemming():
+ for x, y in testing.items():
+ if bget(x, y) != ' ' == bget(x, y-1):
+ if x <= curboard.width//2:
+ dir = 1
+ else:
+ dir = -1
+ s = Lemming(self, x*CELL-HALFCELL, (y-2)*CELL, dir)
+ self.lemtotal += 1
+ if y < ymax:
+ testing[x] = y+1
+ else:
+ del testing[x]
+ for x in xrange:
+ testing[x] = 1
+ addlemming()
+ yield None
+ while testing:
+ addlemming()
+ yield None
+
+ while self.lemlist:
+ yield None
+
+# This game is suitable for at least min_players players
+min_players = 1
+
+def run():
+ global curboard
+ from boards import curboard
+ boards.replace_boardgen(Lemmings().bgen())
+
+def setup():
+ for key, (filename, rect) in localmap.items():
+ filename = os.path.join(LocalDir, filename)
+ images.sprmap[key] = (filename, rect)
+setup()