' Hardwire ' ' Copyright 2005 Ian Cowburn ' ' $Id$ ' Strict Import "types.bmx" Import "particle.bmx" Import "sounds.bmx" Type Pit Const WIDTH=10 Const HEIGHT=13 Function X:Int(p:Int) Return 230+p*32 End Function Function Y:Int(p:Int) Return 120+p*32 End Function End Type Type TWire Const CROSS:Int=0 Const LEFT_RIGHT:Int=1 Const TOP_BOTTOM:Int=2 Const TOP_LEFT:Int=3 Const TOP_RIGHT:Int=4 Const BOTTOM_LEFT:Int=5 Const BOTTOM_RIGHT:Int=6 Const SPECIAL_BOMB:Int=7 Const SPECIAL_TWISTER:Int=8 Const DIR_NONE:Int=0 Const DIR_UP:Int=1 Const DIR_RIGHT:Int=2 Const DIR_DOWN:Int=3 Const DIR_LEFT:Int=4 Global rotright:Int[] Global rotleft:Int[] Global img:TImage[] Global dir:Int[][] Global dx:Int[] Global dy:Int[] Global dirname:String[] Global typename:String[] Field t:Int Function Init() rotright=[0,2,1,4,6,3,5,7,8] rotleft=[0,2,1,5,3,6,4,7,8] img=[GameGFX.cross,GameGFX.left_right,GameGFX.top_bottom,GameGFX.top_left,GameGFX.top_right,GameGFX.bottom_left,GameGFX.bottom_right,GameGFX.special_bomb,GameGFX.special_twister] ' CROSS LEFT_RIGHT TOP_BOTTOM TOP_LEFT TOP_RIGHT BOTTOM_LEFT BOTTOM_RIGHT SPECIAL_BOMB SPECIAL_TWISTER dir=[[DIR_UP,DIR_RIGHT,DIR_DOWN,DIR_LEFT], [DIR_NONE,DIR_RIGHT,DIR_NONE,DIR_LEFT], [DIR_UP,DIR_NONE,DIR_DOWN,DIR_NONE], [DIR_NONE,DIR_UP,DIR_LEFT,DIR_NONE], [DIR_NONE,DIR_NONE,DIR_RIGHT,DIR_UP], [DIR_LEFT,DIR_DOWN,DIR_NONE,DIR_NONE], [DIR_RIGHT,DIR_NONE,DIR_NONE,DIR_DOWN], [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE]] dx=[0,0,1,0,-1] dy=[0,-1,0,1,0] dirname=["NONE","UP","RIGHT","DOWN","LEFT"] typename=["CROSS","LEFT_RIGHT","TOP_BOTTOM","TOP_LEFT","TOP_RIGHT","BOTTOM_LEFT","BOTTOM_RIGHT","SPECIAL BOMB","SPECIAL TWISTER"] End Function Method New() t=Rand(0,6) End Method Function Create:TWire(t:Int[]) Local o:TWire=New TWire o.t=t[Rand(0,t.length-1)] Return o End Function Method Image:TImage() Return img[t] End Method Method RotateLeft() t=rotleft[t] End Method Method RotateRight() t=rotright[t] End Method Method Traverse:Int(d:Int) If d=DIR_NONE Return DIR_NONE EndIf Return dir[t][d-1] End Method Function DirX:Int(d:Int) Return dx[d] End Function Function DirY:Int(d:Int) Return dy[d] End Function End Type Type TPiece Abstract Field x:Int Field y:Int Field ox:Int Field oy:Int Field map:TWire[4,4] Field rot:Int Field offx:Int[4] Field offy:Int[4] Field special:Int Field special_pulse:Int Field col:Int Field coli:Int Field frame:Int Field framed:Int Function Create:TPiece(special:Int) Local o:TPiece If special Select Rand(0,5) Case 0 o=TPiece(New TPiece_SpecialBomb) Case 1 o=TPiece(New TPiece_SpecialTwister) End Select Else Select Rand(0,5) Case 0 o=TPiece(New TPiece_S_Left) Case 1 o=TPiece(New TPiece_S_Right) Case 2 o=TPiece(New TPiece_L_Left) Case 3 o=TPiece(New TPiece_L_Right) Case 4 o=TPiece(New TPiece_Square) Case 5 o=TPiece(New TPiece_Bar) End Select EndIf o.BaseInit(special) Return o End Function Method Init() Abstract Method BaseInit(special:Int) special_pulse=False Init() rot=0 ox=offx[rot] oy=offy[rot] self.special=special col=255 coli=-1 frame=0 framed=0 End Method Method Draw() If special col:+coli If col=255 Or col=128 coli=-coli EndIf framed:+1 If framed=5 framed=0 frame=(frame+1) Mod 4 EndIf For Local px:Int=0 Until 4 For Local py:Int=0 Until 4 If map[px,py] Local gx:Int=Pit.X(x-ox+px) Local gy:Int=Pit.Y(y-oy+py) SetColor(255,255,255) DrawImage(GameGFX.tile,gx,gy) If special_pulse SetColor(col,col/2,255-col) EndIf DrawImage(map[px,py].Image(),gx,gy,frame) EndIf Next Next Else For Local px:Int=0 Until 4 For Local py:Int=0 Until 4 If map[px,py] Local gx:Int=Pit.X(x-ox+px) Local gy:Int=Pit.Y(y-oy+py) SetColor(255,255,255) DrawImage(GameGFX.tile,gx,gy) SetColor(128,128,128) DrawImage(map[px,py].Image(),gx,gy) EndIf Next Next EndIf End Method Method RotateLeft() If special Then Return If rot=0 rot=3 Else rot:-1 EndIf ox=offx[rot] oy=offy[rot] Local m:TWire[4,4] For Local px:Int=0 Until 4 For Local py:Int=0 Until 4 If map[px,py] map[px,py].RotateLeft() EndIf m[py,3-px]=map[px,py] Next Next map=m End Method Method RotateRight() If special Then Return rot=(rot+1) Mod 4 ox=offx[rot] oy=offy[rot] Local m:TWire[4,4] For Local px:Int=0 Until 4 For Local py:Int=0 Until 4 If map[px,py] map[px,py].RotateRight() EndIf m[3-py,px]=map[px,py] Next Next map=m End Method Method Collides:Int(gm:TGameMap) For Local px:Int=0 Until 4 For Local py:Int=0 Until 4 If map[px,py] Local gx:Int=x-ox+px Local gy:Int=y-oy+py If gx<0 Or gx>=Pit.WIDTH Or gy>=Pit.HEIGHT Return True EndIf If gy>=0 And gm.map[gx,gy] Return True EndIf EndIf Next Next Return False End Method Method AddToMap(gm:TGameMap) If special gm.SetSpecial(TSpecial(Self)) Else For Local px:Int=0 Until 4 For Local py:Int=0 Until 4 If map[px,py] Local gx:Int=x-ox+px Local gy:Int=y-oy+py If gy<0 gm.overflow=True Else gm.map[gx,gy]=map[px,py] If gy=Pit.HEIGHT-1 Or gm.map[gx,gy+1] Particles.AddDust(Pit.X(gx)+16,Pit.Y(gy)+32) EndIf EndIf EndIf Next Next Sound.Click() If Not gm.overflow If Not gm.CheckWires() gm.Flatten() gm.CheckWires() EndIf EndIf EndIf End Method End Type Type TSpecial Extends TPiece Abstract Method DoSpecial:Int(gm:TGameMap) Abstract End Type Type TPiece_S_Right Extends TPiece Method Init() map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_RIGHT]) map[2,0]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.BOTTOM_LEFT,TWire.LEFT_RIGHT]) map[0,1]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT,TWire.BOTTOM_RIGHT,TWire.LEFT_RIGHT]) map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT]) offx=[1,2,2,0] offy=[1,1,2,2] End Method End Type Type TPiece_S_Left Extends TPiece Method Init() map[0,0]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT,TWire.BOTTOM_RIGHT,TWire.LEFT_RIGHT]) map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_LEFT]) map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT]) map[2,1]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.BOTTOM_LEFT,TWire.LEFT_RIGHT]) offx=[1,2,2,0] offy=[1,1,2,2] End Method End Type Type TPiece_L_Right Extends TPiece Method Init() map[0,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_RIGHT]) map[1,0]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.BOTTOM_LEFT,TWire.LEFT_RIGHT]) map[0,1]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) map[0,2]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.TOP_RIGHT,TWire.TOP_BOTTOM]) offx=[0,2,3,1] offy=[1,0,2,3] End Method End Type Type TPiece_L_Left Extends TPiece Method Init() map[0,0]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT,TWire.BOTTOM_RIGHT,TWire.LEFT_RIGHT]) map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_LEFT]) map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) map[1,2]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.TOP_RIGHT,TWire.TOP_BOTTOM]) offx=[1,2,2,1] offy=[1,1,2,2] End Method End Type Type TPiece_Square Extends TPiece Method Init() map[0,0]=TWire.Create([TWire.CROSS]) map[1,0]=TWire.Create([TWire.CROSS]) map[0,1]=TWire.Create([TWire.CROSS]) map[1,1]=TWire.Create([TWire.CROSS]) offx=[0,2,2,0] offy=[1,1,3,3] End Method End Type Type TPiece_Bar Extends TPiece Method Init() map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_LEFT,TWire.BOTTOM_RIGHT,TWire.TOP_BOTTOM]) map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) map[1,2]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) map[1,3]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.TOP_RIGHT,TWire.TOP_BOTTOM]) offx=[1,1,2,1] offy=[1,1,1,2] End Method End Type Type TPiece_SpecialBomb Extends TSpecial Method Init() map[0,0]=TWire.Create([TWire.SPECIAL_BOMB]) offx=[0,0,0,0] offy=[0,0,0,0] End Method Method DoSpecial:Int(gm:TGameMap) Local l:TWireList=New TWireList If y0) Or (trode_col=200 And trode_coli<0) trode_coli=-trode_coli EndIf Return score End Method End Type