<<[Ivy]Top>MazeWar.df=>MazeWarPlayerImpl3.Mesa>> <> DIRECTORY Commander, Graphics, GraphicsOps, MazeWarFinder, MazeWarPlayer, MazeWarPlayerInsides, ViewerBlast, ViewerClasses, ViewerOps; MazeWarPlayerImpl3: CEDAR MONITOR IMPORTS Graphics, GraphicsOps, MazeWarPlayerInsides, ViewerBlast, ViewerOps EXPORTS MazeWarPlayerInsides = <> <> BEGIN OPEN MazeWarPlayerInsides; wb: Number = w+2; PaintMaze: PUBLIC ENTRY ViewerClasses.PaintProc--PROC [self: Viewer, context: Graphics.Context, whatChanged: REF ANY, clear: BOOL]-- = BEGIN ENABLE UNWIND => {}; --not strictly right, but it helps debugging Decisions: PROC = BEGIN crow, ccol, d, me, di: INTEGER; mes: Square; row _ p.row; col _ p.col; angle _ p.angle; peek _ p.peek; [prow, pcol, pdrow, pdcol, pangle] _ Peek[peek, row, col, angle]; IF fromScratch _ whatChanged = NIL THEN NULL ELSE IF notMe _ whatChanged # p THEN BEGIN q _ NARROW[whatChanged]; shot _ q.shot; wasShown _ q.sdistance > 0; q.shot _ FALSE; row _ q.row; col _ q.col; angle _ q.angle; [prow, pcol, pdrow, pdcol, pangle] _ Peek[p.speek, p.srow, p.scol, p.sangle]; oDistance _ q.sdistance; oAngle _ (q.sangle + 4 - pangle) MOD 4; IF nowShown _ (q.sdistance _ Visible[p.mv, prow, pcol, pdrow, pdcol, row, col]) > 0 THEN BEGIN q.srow _ row; q.scol _ col; q.sangle _ angle; nowShown _ TRUE; END; IF wasShown = nowShown THEN NULL ELSE IF wasShown THEN shownPlayers _ Filter[shownPlayers, q] ELSE shownPlayers _ CONS[q, shownPlayers]; RETURN; END ELSE BEGIN oRow _ p.srow; oCol _ p.scol; oAngle _ p.sangle; END; IF shot _ p.shot THEN p.shot _ FALSE; FOR sp: PlayerList _ shownPlayers, sp.rest WHILE sp # NIL DO sp.first.sdistance _ -1; ENDLOOP; shownPlayers _ NIL; crow _ prow; ccol _ pcol; mes _ p.mv.squares[me _ Index[p.mv, prow, pcol]]; d _ 0; di _ Direction[p.mv, pdrow, pdcol]; WHILE mes.open DO nu: INTEGER _ me + di; IF d>0 AND mes.occupants # NIL THEN BEGIN FOR pl: PlayerList _ mes.occupants, pl.rest WHILE pl # NIL DO pa: Angle _ pl.first.angle; pl.first.srow _ crow; pl.first.scol _ ccol; pl.first.sangle _ pa; pl.first.sdistance _ d; shownPlayers _ CONS[pl.first, shownPlayers]; ENDLOOP; END; d _ d + 1; mes _ p.mv.squares[me _ nu]; crow _ crow + pdrow; ccol _ ccol + pdcol; ENDLOOP; p.srow _ row; p.scol _ col; p.sangle _ angle; p.speek _ peek; END; p: Player _ NARROW[self.data]; q: Player _ NIL; fromScratch, notMe, wasShown, nowShown, shot: BOOLEAN; oRow, oCol, oDistance, oAngle: INTEGER; row, col, peek, prow, pcol, pdrow, pdcol: INTEGER; angle, pangle: Angle; CallUnderMonitor1[Decisions]; Graphics.Translate[context, p.mv.topX, p.mv.topY]; IF fromScratch THEN BEGIN DrawTopview[context, p.mv]; DrawPlayerTop[context, row, col, angle]; END ELSE IF notMe THEN BEGIN Graphics.Translate[context, p.mv.inX, p.mv.inY]; [] _ Graphics.SetPaintMode[context, invert]; Graphics.SetCP[context, 0, 0]; IF wasShown THEN DrawHallPlayer[context, q, oDistance, oAngle, shot, FALSE]; IF nowShown THEN DrawHallPlayer[context, q, q.sdistance, (angle + 4 - pangle) MOD 4, shot, TRUE]; RETURN; END ELSE BEGIN IF clear THEN ERROR; [] _ Graphics.SetPaintMode[context, invert]; DrawPlayerTop[context, oRow, oCol, oAngle]; DrawPlayerTop[context, p.srow, p.scol, p.sangle]; END; Graphics.Translate[context, p.mv.inX, p.mv.inY]; IF shot THEN BEGIN left, top, topCompl: INTEGER; [left, top] _ ViewerOps.UserToScreenCoords[ self, p.mv.inX + p.mv.topX - wb, p.mv.inY + p.mv.topY + wb]; topCompl _ screenBitmap.height-top; Graphics.SetCP[blastContext, 0, 0]; [] _ Graphics.SetPaintMode[blastContext, opaque]; IF left < 0 OR topCompl < 0 THEN BEGIN --ViewerBlast.DrawBitmap should do this, but doesn't Graphics.SetColor[blastContext, Graphics.white]; Graphics.DrawBox[blastContext, [-wb, -wb, wb, wb]]; Graphics.SetColor[blastContext, Graphics.black]; END; ViewerBlast.DrawBitmap[self: blastContext, bitmap: screenBitmap, w: 2*wb, h: 2*wb, x: left, y: topCompl, xorigin: left+wb, yorigin: screenBitmap.height-top+wb]; ViewerBlast.Blast[bm: blastBitmap, bmw: [0, 0, blastBitmap.width, blastBitmap.height], lowerLeft: [left, top-2*wb], speedChooser: ViewerBlast.RandomSpeed, initial: TRUE, backwards: FALSE]; DrawHall[blastContext, p.mv, prow, pcol, pdrow, pdcol, pangle]; ViewerBlast.Blast[bm: blastBitmap, bmw: [0, 0, blastBitmap.width, blastBitmap.height], lowerLeft: [left, top-2*wb], speedChooser: ViewerBlast.RandomSpeed, initial: TRUE, backwards: TRUE]; END ELSE BEGIN DrawHall[context, p.mv, prow, pcol, pdrow, pdcol, pangle]; END; END; screenBitmap: Bitmap _ GraphicsOps.ScreenBitmap[]; blastBitmap: Bitmap _ GraphicsOps.NewBitmap[2*wb, 2*wb]; blastContext: Context _ GraphicsOps.NewContextFromBitmap[blastBitmap]; DrawHallPlayer: PROC [context: Context, q: Player, d: INTEGER, angle: Angle, shot, backwards: BOOLEAN] = BEGIN b: Bitmap _ q.pics.pics[d][angle]; IF shot THEN BEGIN lowerLeft: ViewerBlast.IntPt; [lowerLeft.x, lowerLeft.y] _ ViewerOps.UserToScreenCoords[ q.mv.maze, q.mv.inX + q.mv.topX - b.width/2, q.mv.inY + q.mv.topY + b.height/2 - b.height]; ViewerBlast.Blast[bm: b, bmw: [0, 0, b.width, b.height], lowerLeft: lowerLeft, speedChooser: ViewerBlast.RandomSpeed, backwards: backwards]; END ELSE GraphicsOps.DrawBitmap[self: context, bitmap: b, w: b.width, h: b.height, x: 0, y: 0, xorigin: b.width/2, yorigin: b.height/2]; END; DrawTopview: PROC [context: Context, mv: MazeView] = BEGIN FOR row: INTEGER IN [0 .. mv.rows) DO FOR col: INTEGER IN [0 .. mv.cols) DO x: INTEGER _ col*tvd; y: INTEGER _ -row*tvd; index: INTEGER _ Index[mv, row, col]; IF NOT mv.squares[index].open THEN Graphics.DrawBox[context, [x, y-tvd, x+tvd, y]]; ENDLOOP; ENDLOOP; END; DrawPlayerTop: PROC [context: Context, row, col: INTEGER, angle: Angle] = BEGIN Graphics.SetCP[context, col*tvd, -(row+1)*tvd]; GraphicsOps.DrawBitmap[self: context, bitmap: topviews[angle], w: tvd, h: tvd, x: 0, y: 0, xorigin: 0, yorigin: tvd]; END; <> Setup: PROC = BEGIN <<[] _ CommandTool.Run[bcdName: releaseDirectory.Cat["MazeWar>MazeWarCommon.BCD"]];>> <<[] _ CommandTool.Run[bcdName: "[Ivy]Top>PutFPatchImpl.BCD"];>> Graphics.Translate[blastContext, wb, wb]; END; Setup[]; END.