summaryrefslogtreecommitdiff
path: root/gametypes.bmx
diff options
context:
space:
mode:
Diffstat (limited to 'gametypes.bmx')
-rw-r--r--gametypes.bmx1937
1 files changed, 977 insertions, 960 deletions
diff --git a/gametypes.bmx b/gametypes.bmx
index 24d1617..5875363 100644
--- a/gametypes.bmx
+++ b/gametypes.bmx
@@ -1,960 +1,977 @@
-' 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 SPECIAL_NUKE:Int=9
- Const SPECIAL_CROSS:Int=10
-
- 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,9,10]
- rotleft=[0,2,1,5,3,6,4,7,8,9,10]
-
- 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, ..
- GameGFX.special_nuke, ..
- GameGFX.special_cross]
-
- dir=[[DIR_UP,DIR_RIGHT,DIR_DOWN,DIR_LEFT], .. ' CROSS
- [DIR_NONE,DIR_RIGHT,DIR_NONE,DIR_LEFT], .. ' LEFT_RIGHT
- [DIR_UP,DIR_NONE,DIR_DOWN,DIR_NONE], .. ' TOP_BOTTOM
- [DIR_NONE,DIR_UP,DIR_LEFT,DIR_NONE], .. ' TOP_LEFT
- [DIR_NONE,DIR_NONE,DIR_RIGHT,DIR_UP], .. ' TOP_RIGHT
- [DIR_LEFT,DIR_DOWN,DIR_NONE,DIR_NONE], .. ' BOTTOM_LEFT
- [DIR_RIGHT,DIR_NONE,DIR_NONE,DIR_DOWN], .. ' BOTTOM_RIGHT
- [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_BOMB
- [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_TWISTER
- [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_NUKE
- [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE]] ' SPECIAL_CROSS
-
- 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
- Field framespd:Int
- Field framei:Int
- Field pong:Int
-
- Function Create:TPiece(special:Int)
- Local o:TPiece
-
- If special
- Select Rand(0,3)
- Case 0
- o=TPiece(New TPiece_SpecialBomb)
- Case 1
- o=TPiece(New TPiece_SpecialTwister)
- Case 2
- o=TPiece(New TPiece_SpecialNuke)
- Case 3
- o=TPiece(New TPiece_SpecialCross)
- 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
-
- Function CreateSpecific:TPiece(t:Int)
- Local o:TPiece
- Local s:Int=False
-
- Select t
- 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)
- Case 6
- o=TPiece(New TPiece_SpecialBomb)
- s=True
- Case 7
- o=TPiece(New TPiece_SpecialTwister)
- s=True
- Case 8
- o=TPiece(New TPiece_SpecialNuke)
- s=True
- Case 9
- o=TPiece(New TPiece_SpecialCross)
- s=True
- Default
- Return Create(False)
- End Select
-
- o.BaseInit(s)
-
- Return o
- End Function
-
- Method Init() Abstract
-
- Method BaseInit(special:Int)
- special_pulse=False
- framespd=5
- pong=False
- Init()
- rot=0
- ox=offx[rot]
- oy=offy[rot]
- self.special=special
- col=255
- coli=-1
- frame=0
- framed=0
- framei=1
- End Method
-
- Method Draw()
- If special
- col:+coli
- If col=255 Or col=128
- coli=-coli
- EndIf
-
- framed:+1
- If framed=framespd
- framed=0
- If pong
- frame:+framei
- If frame=0 Or frame=3
- framei=-framei
- EndIf
- Else
- frame=(frame+1) Mod 4
- EndIf
- 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)
- Draw()
-
- Local l:TWireList=New TWireList
-
- If y<Pit.HEIGHT-1
- Local t:Int=gm.map[x,y+1].t
-
- For Local px:Int=0 Until Pit.WIDTH
- For Local py:Int=0 Until Pit.HEIGHT
- If gm.map[px,py] And gm.map[px,py].t=t
- l.Add(px,py,gm.map[px,py])
- EndIf
- Next
- Next
- EndIf
-
- If l.Count()=0
- TextParticles.Big("WHAT A WASTE!",255,0,0)
- Else
- TextParticles.Big("SMART BOMB!",255,255,0)
- gm.path.AddLast(l)
- EndIf
-
- ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
-
- Return False
- End Method
-End Type
-
-Type TPiece_SpecialTwister Extends TSpecial
- Field rot:Int
- Field rotd:Int
-
- Method Init()
- rot=0
- rotd=0
- special_pulse=True
- map[0,0]=TWire.Create([TWire.SPECIAL_TWISTER])
- offx=[0,0,0,0]
- offy=[0,0,0,0]
- End Method
-
- Method DoSpecial:Int(gm:TGameMap)
- Draw()
-
- If gm.path.Count()
- Return True
- EndIf
-
- If rotd=0
- rotd=60
- rot:+1
- If rot=5
- ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
- Return False
- EndIf
- TextParticles.Big("TWIST!")
- Else
- rotd:-1
- Return True
- EndIf
-
- For Local px:Int=0 Until Pit.WIDTH
- For Local py:Int=0 Until Pit.HEIGHT
- If gm.map[px,py]
- gm.map[px,py].RotateRight()
- Particles.AddDust(Pit.X(px)+16,Pit.Y(py)+32)
- EndIf
- Next
- Next
-
- Sound.Click()
-
- If Not gm.CheckWires()
- gm.Flatten()
- gm.CheckWires()
- EndIf
-
- Return True
- End Method
-End Type
-
-Type TPiece_SpecialNuke Extends TSpecial
- Method Init()
- special_pulse=True
- map[0,0]=TWire.Create([TWire.SPECIAL_NUKE])
- offx=[0,0,0,0]
- offy=[0,0,0,0]
- End Method
-
- Method AddToList(gm:TGameMap, l:TWireList, t:Int)
- For Local px:Int=0 Until Pit.WIDTH
- For Local py:Int=0 Until Pit.HEIGHT
- If gm.map[px,py] And gm.map[px,py].t=t
- l.Add(px,py,gm.map[px,py])
- EndIf
- Next
- Next
- End Method
-
- Method DoSpecial:Int(gm:TGameMap)
- Draw()
-
- Local l:TWireList=New TWireList
-
- If y<Pit.HEIGHT-1 And gm.map[x,y+1]
- AddToList(gm,l,gm.map[x,y+1].t)
- EndIf
-
- If x>0 And gm.map[x-1,y]
- AddToList(gm,l,gm.map[x-1,y].t)
- EndIf
-
- If x<Pit.WIDTH-1 And gm.map[x+1,y]
- AddToList(gm,l,gm.map[x+1,y].t)
- EndIf
-
- If l.Count()=0
- TextParticles.Big("WHAT A WASTE!",255,0,0)
- Else
- TextParticles.Big("SMART NUKE!",255,255,0)
- gm.path.AddLast(l)
- EndIf
-
- ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
-
- Return False
- End Method
-End Type
-
-Type TPiece_SpecialCross Extends TSpecial
-
- Method Init()
- special_pulse=True
- pong=True
- map[0,0]=TWire.Create([TWire.SPECIAL_CROSS])
- offx=[0,0,0,0]
- offy=[0,0,0,0]
- End Method
-
- Method DoSpecial:Int(gm:TGameMap)
- Draw()
-
- TextParticles.Big("SUPER CROSS!",255,255,0)
-
- For Local px:Int=x+1 Until Pit.WIDTH
- If gm.map[px,y]
- gm.map[px,y].t=TWire.CROSS
- Particles.AddDust(Pit.X(px)+16,Pit.Y(y)+32)
- EndIf
- Next
-
- For Local px:Int=0 Until x
- If gm.map[px,y]
- gm.map[px,y].t=TWire.CROSS
- Particles.AddDust(Pit.X(px)+16,Pit.Y(y)+32)
- EndIf
- Next
-
- For Local py:Int=y+1 Until Pit.HEIGHT
- If gm.map[x,py]
- gm.map[x,py].t=TWire.CROSS
- Particles.AddDust(Pit.X(x)+16,Pit.Y(py)+32)
- EndIf
- Next
-
- If Not gm.CheckWires()
- gm.Flatten()
- gm.CheckWires()
- EndIf
-
- ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
-
- Return False
- End Method
-End Type
-
-
-Type TWireListEnt
- Field w:TWire
- Field x:Int
- Field y:Int
-
- Function Create:TWireListEnt(x:Int, y:Int, w:TWire)
- Local o:TWireListEnt=New TWireListEnt
- o.x=x
- o.y=y
- o.w=w
- Return o
- End Function
-End Type
-
-
-Type TWireList
- Field list:TList
- Field col:Int
-
- Method New()
- list=CreateList()
- col=128
- End Method
-
- Method Add(x:Int, y:Int, w:TWire)
- list.AddLast(TWireListEnt.Create(x,y,w))
- End Method
-
- Method Draw:Int()
- col=Min(255,col+5)
- SetColor(col,col,col)
- For Local e:TWireListEnt=EachIn list
- DrawImage(e.w.Image(),Pit.X(e.x),Pit.Y(e.y))
- Next
-
- If col<255
- Return True
- Else
- For Local e:TWireListEnt=EachIn list
- Particles.AddImage(e.w.Image(),Pit.X(e.x),Pit.Y(e.y))
- Next
- Return False
- EndIf
- End Method
-
- Method Count:Int()
- Return list.Count()
- End Method
-End Type
-
-
-Type TGameMap
- Field map:TWire[Pit.WIDTH,Pit.HEIGHT]
- Field trode_col:Int
- Field trode_coli:Int
- Field overflow:Int
- Field cx:Int
- Field cy:Int
- Field path:TList
- Field special:TSpecial
-
- Method New()
- trode_col=0
- trode_coli=1
- overflow=False
- path=CreateList()
- special=Null
- End Method
-
- Method BlockInteract:Int()
- Return overflow Or path.Count() Or special
- End Method
-
- Method FindPath:Int(l:TWireList, x:Int, y:Int, dir:Int)
- If y<0
- Return False
- EndIf
-
- If x<0 Or x=Pit.WIDTH Or y=Pit.HEIGHT
- Return True
- EndIf
-
- Local w:TWire=map[x,y]
-
- If Not w
- Return False
- EndIf
-
- dir=w.Traverse(dir)
-
- If dir=TWire.DIR_NONE
- Return False
- EndIf
-
- l.Add(x,y,w)
-
- Return FindPath(l,x+TWire.DirX(dir),y+TWire.DirY(dir),dir)
- End Method
-
- Method FindLoop:Int(l:TWireList, ox:Int, oy:Int, x:Int, y:Int, dir:Int)
- If y<0 Or x<0 Or x=Pit.WIDTH Or y=Pit.HEIGHT
- Return False
- EndIf
-
- Local w:TWire=map[x,y]
-
- If Not w
- Return False
- EndIf
-
- dir=w.Traverse(dir)
-
- If dir=TWire.DIR_NONE
- Return False
- EndIf
-
- l.Add(x,y,w)
-
- x:+TWire.DirX(dir)
- y:+TWire.DirY(dir)
-
- If x=ox And y=oy And dir=TWire.DIR_RIGHT
- Return True
- EndIf
-
- Return FindLoop(l,ox,oy,x,y,dir)
- End Method
-
- Method CheckWires:Int()
- Local loop:Int=False
- Local wire:Int=False
-
- For Local y:Int=0 Until Pit.HEIGHT
- Local l:TWireList=New TWireList
-
- If FindPath(l,0,y,TWire.DIR_RIGHT)
- path.AddLast(l)
- EndIf
-
- l=New TWireList
-
- If FindPath(l,Pit.WIDTH-1,y,TWire.DIR_LEFT)
- path.AddLast(l)
- wire=True
- EndIf
- Next
-
- For Local x:Int=0 Until Pit.WIDTH
- Local l:TWireList=New TWireList
-
- If FindPath(l,x,Pit.HEIGHT-1,TWire.DIR_UP)
- path.AddLast(l)
- wire=True
- EndIf
- Next
-
- For Local x:Int=0 Until Pit.WIDTH
- For Local y:Int=0 Until Pit.HEIGHT
- If map[x,y]
- Local l:TWireList=New TWireList
- Select map[x,y].t
- Case TWire.CROSS, TWire.LEFT_RIGHT, TWire.TOP_LEFT, TWire.BOTTOM_LEFT
- If FindLoop(l,x,y,x,y,TWire.DIR_RIGHT)
- path.AddLast(l)
- loop=True
- EndIf
- End Select
- EndIf
- Next
- Next
-
- If loop And wire
- TextParticles.Big("LOOP AND WIRE",255,0,255)
- ElseIf loop
- TextParticles.Big("LOOP",255,0,255)
- ElseIf wire
- TextParticles.Big("WIRE",255,0,255)
- EndIf
-
- Return loop Or wire
- End Method
-
- Method SetSpecial(s:TSpecial)
- special=s
- End Method
-
- Method DropColumn(x:Int, y:Int)
- While y>0
- map[x,y]=map[x,y-1]
- y:-1
- Wend
- map[x,0]=Null
- End Method
-
- Method AnyAbove:Int(x:Int, y:Int)
- While y>=0
- If map[x,y]
- Return True
- EndIf
- y:-1
- Wend
-
- Return False
- End Method
-
- Method Flatten()
- For Local x:Int=0 Until Pit.WIDTH
- Local y:Int=Pit.HEIGHT-1
- Local drop:Int=False
-
- While y>0 And AnyAbove(x,y)
- If map[x,y]
- If drop
- Particles.AddDust(Pit.X(x)+16,Pit.Y(y)+32)
- EndIf
- drop=False
- y:-1
- Else
- DropColumn(x,y)
- EndIf
- Wend
- Next
- End Method
-
- Method Draw:Int()
- Local score:Int=0
-
- SetColor(255,255,255)
- DrawImage(GameGFX.pit_bottomleft,Pit.X(-1),Pit.Y(Pit.HEIGHT))
- DrawImage(GameGFX.pit_bottomright,Pit.X(Pit.WIDTH),Pit.Y(Pit.HEIGHT))
-
- DrawImage(GameGFX.pit_top,Pit.X(-1),Pit.Y(0))
- DrawImage(GameGFX.pit_top,Pit.X(Pit.WIDTH),Pit.Y(0))
- SetColor(trode_col,trode_col,0)
- DrawImage(GameGFX.trode_left,Pit.X(-1),Pit.Y(0))
- DrawImage(GameGFX.trode_right,Pit.X(Pit.WIDTH),Pit.Y(0))
-
- For Local f:Int=0 Until Pit.WIDTH
- SetColor(255,255,255)
- DrawImage(GameGFX.pit_bottom,Pit.X(f),Pit.Y(Pit.HEIGHT))
- SetColor(trode_col,trode_col,0)
- DrawImage(GameGFX.trode_bottom,Pit.X(f),Pit.Y(Pit.HEIGHT))
- Next
-
- For Local f:Int=1 Until Pit.HEIGHT
- SetColor(255,255,255)
- DrawImage(GameGFX.pit_side,Pit.X(-1),Pit.Y(f))
- DrawImage(GameGFX.pit_side,Pit.X(Pit.WIDTH),Pit.Y(f))
- SetColor(trode_col,trode_col,0)
- DrawImage(GameGFX.trode_left,Pit.X(-1),Pit.Y(f))
- DrawImage(GameGFX.trode_right,Pit.X(Pit.WIDTH),Pit.Y(f))
- Next
-
- For Local x:Int=0 Until Pit.WIDTH
- For Local y:Int=0 Until Pit.HEIGHT
- If map[x,y]
- SetColor(255,255,255)
- DrawImage(GameGFX.tile,Pit.X(x),Pit.Y(y))
- SetColor(trode_col,trode_col,0)
- DrawImage(map[x,y].Image(),Pit.X(x),Pit.Y(y))
- EndIf
- Next
- Next
-
- If special
- If Not special.DoSpecial(Self)
- special=Null
- EndIf
- EndIf
-
- Local l:TEasyLink=TEasyLink.Create(path)
- Local check:Int=False
-
- While l.Value()
- Local b:TWireList=TWireList(l.Value())
-
- If b.Draw()
- l.MoveNext()
- Else
- If Not overflow
- score:+b.list.Count()
- For Local e:TWireListEnt=EachIn b.list
- map[e.x,e.y]=Null
- Next
- EndIf
- l.Remove()
- check=True
- EndIf
- Wend
-
- If check
- Sound.Path()
- Flatten()
- CheckWires()
- EndIf
-
- trode_col:+trode_coli
-
- If (trode_col=255 And trode_coli>0) Or (trode_col=200 And trode_coli<0)
- trode_coli=-trode_coli
- EndIf
-
- Return score
- End Method
-End Type
+' Hardwire
+'
+' Copyright (C) 2005 Ian Cowburn (ianc@noddybox.co.uk)
+'
+' This program is free software; you can redistribute it and/or modify
+' it under the terms of the GNU General Public License as published by
+' the Free Software Foundation; either version 2 of the License, or
+' (at your option) any later version.
+'
+' This program is distributed in the hope that it will be useful,
+' but WITHOUT ANY WARRANTY; without even the implied warranty of
+' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+' GNU General Public License for more details.
+'
+' You should have received a copy of the GNU General Public License
+' along with this program; if not, write to the Free Software
+' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+'
+' -------------------------------------------------------------------------
+'
+' $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 SPECIAL_NUKE:Int=9
+ Const SPECIAL_CROSS:Int=10
+
+ 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,9,10]
+ rotleft=[0,2,1,5,3,6,4,7,8,9,10]
+
+ 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, ..
+ GameGFX.special_nuke, ..
+ GameGFX.special_cross]
+
+ dir=[[DIR_UP,DIR_RIGHT,DIR_DOWN,DIR_LEFT], .. ' CROSS
+ [DIR_NONE,DIR_RIGHT,DIR_NONE,DIR_LEFT], .. ' LEFT_RIGHT
+ [DIR_UP,DIR_NONE,DIR_DOWN,DIR_NONE], .. ' TOP_BOTTOM
+ [DIR_NONE,DIR_UP,DIR_LEFT,DIR_NONE], .. ' TOP_LEFT
+ [DIR_NONE,DIR_NONE,DIR_RIGHT,DIR_UP], .. ' TOP_RIGHT
+ [DIR_LEFT,DIR_DOWN,DIR_NONE,DIR_NONE], .. ' BOTTOM_LEFT
+ [DIR_RIGHT,DIR_NONE,DIR_NONE,DIR_DOWN], .. ' BOTTOM_RIGHT
+ [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_BOMB
+ [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_TWISTER
+ [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_NUKE
+ [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE]] ' SPECIAL_CROSS
+
+ 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
+ Field framespd:Int
+ Field framei:Int
+ Field pong:Int
+
+ Function Create:TPiece(special:Int)
+ Local o:TPiece
+
+ If special
+ Select Rand(0,3)
+ Case 0
+ o=TPiece(New TPiece_SpecialBomb)
+ Case 1
+ o=TPiece(New TPiece_SpecialTwister)
+ Case 2
+ o=TPiece(New TPiece_SpecialNuke)
+ Case 3
+ o=TPiece(New TPiece_SpecialCross)
+ 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
+
+ Function CreateSpecific:TPiece(t:Int)
+ Local o:TPiece
+ Local s:Int=False
+
+ Select t
+ 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)
+ Case 6
+ o=TPiece(New TPiece_SpecialBomb)
+ s=True
+ Case 7
+ o=TPiece(New TPiece_SpecialTwister)
+ s=True
+ Case 8
+ o=TPiece(New TPiece_SpecialNuke)
+ s=True
+ Case 9
+ o=TPiece(New TPiece_SpecialCross)
+ s=True
+ Default
+ Return Create(False)
+ End Select
+
+ o.BaseInit(s)
+
+ Return o
+ End Function
+
+ Method Init() Abstract
+
+ Method BaseInit(special:Int)
+ special_pulse=False
+ framespd=5
+ pong=False
+ Init()
+ rot=0
+ ox=offx[rot]
+ oy=offy[rot]
+ self.special=special
+ col=255
+ coli=-1
+ frame=0
+ framed=0
+ framei=1
+ End Method
+
+ Method Draw()
+ If special
+ col:+coli
+ If col=255 Or col=128
+ coli=-coli
+ EndIf
+
+ framed:+1
+ If framed=framespd
+ framed=0
+ If pong
+ frame:+framei
+ If frame=0 Or frame=3
+ framei=-framei
+ EndIf
+ Else
+ frame=(frame+1) Mod 4
+ EndIf
+ 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)
+ Draw()
+
+ Local l:TWireList=New TWireList
+
+ If y<Pit.HEIGHT-1
+ Local t:Int=gm.map[x,y+1].t
+
+ For Local px:Int=0 Until Pit.WIDTH
+ For Local py:Int=0 Until Pit.HEIGHT
+ If gm.map[px,py] And gm.map[px,py].t=t
+ l.Add(px,py,gm.map[px,py])
+ EndIf
+ Next
+ Next
+ EndIf
+
+ If l.Count()=0
+ TextParticles.Big("WHAT A WASTE!",255,0,0)
+ Else
+ TextParticles.Big("SMART BOMB!",255,255,0)
+ gm.path.AddLast(l)
+ EndIf
+
+ ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
+
+ Return False
+ End Method
+End Type
+
+Type TPiece_SpecialTwister Extends TSpecial
+ Field rot:Int
+ Field rotd:Int
+
+ Method Init()
+ rot=0
+ rotd=0
+ special_pulse=True
+ map[0,0]=TWire.Create([TWire.SPECIAL_TWISTER])
+ offx=[0,0,0,0]
+ offy=[0,0,0,0]
+ End Method
+
+ Method DoSpecial:Int(gm:TGameMap)
+ Draw()
+
+ If gm.path.Count()
+ Return True
+ EndIf
+
+ If rotd=0
+ rotd=60
+ rot:+1
+ If rot=5
+ ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
+ Return False
+ EndIf
+ TextParticles.Big("TWIST!")
+ Else
+ rotd:-1
+ Return True
+ EndIf
+
+ For Local px:Int=0 Until Pit.WIDTH
+ For Local py:Int=0 Until Pit.HEIGHT
+ If gm.map[px,py]
+ gm.map[px,py].RotateRight()
+ Particles.AddDust(Pit.X(px)+16,Pit.Y(py)+32)
+ EndIf
+ Next
+ Next
+
+ Sound.Click()
+
+ If Not gm.CheckWires()
+ gm.Flatten()
+ gm.CheckWires()
+ EndIf
+
+ Return True
+ End Method
+End Type
+
+Type TPiece_SpecialNuke Extends TSpecial
+ Method Init()
+ special_pulse=True
+ map[0,0]=TWire.Create([TWire.SPECIAL_NUKE])
+ offx=[0,0,0,0]
+ offy=[0,0,0,0]
+ End Method
+
+ Method AddToList(gm:TGameMap, l:TWireList, t:Int)
+ For Local px:Int=0 Until Pit.WIDTH
+ For Local py:Int=0 Until Pit.HEIGHT
+ If gm.map[px,py] And gm.map[px,py].t=t
+ l.Add(px,py,gm.map[px,py])
+ EndIf
+ Next
+ Next
+ End Method
+
+ Method DoSpecial:Int(gm:TGameMap)
+ Draw()
+
+ Local l:TWireList=New TWireList
+
+ If y<Pit.HEIGHT-1 And gm.map[x,y+1]
+ AddToList(gm,l,gm.map[x,y+1].t)
+ EndIf
+
+ If x>0 And gm.map[x-1,y]
+ AddToList(gm,l,gm.map[x-1,y].t)
+ EndIf
+
+ If x<Pit.WIDTH-1 And gm.map[x+1,y]
+ AddToList(gm,l,gm.map[x+1,y].t)
+ EndIf
+
+ If l.Count()=0
+ TextParticles.Big("WHAT A WASTE!",255,0,0)
+ Else
+ TextParticles.Big("SMART NUKE!",255,255,0)
+ gm.path.AddLast(l)
+ EndIf
+
+ ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
+
+ Return False
+ End Method
+End Type
+
+Type TPiece_SpecialCross Extends TSpecial
+
+ Method Init()
+ special_pulse=True
+ pong=True
+ map[0,0]=TWire.Create([TWire.SPECIAL_CROSS])
+ offx=[0,0,0,0]
+ offy=[0,0,0,0]
+ End Method
+
+ Method DoSpecial:Int(gm:TGameMap)
+ Draw()
+
+ TextParticles.Big("SUPER CROSS!",255,255,0)
+
+ For Local px:Int=x+1 Until Pit.WIDTH
+ If gm.map[px,y]
+ gm.map[px,y].t=TWire.CROSS
+ Particles.AddDust(Pit.X(px)+16,Pit.Y(y)+32)
+ EndIf
+ Next
+
+ For Local px:Int=0 Until x
+ If gm.map[px,y]
+ gm.map[px,y].t=TWire.CROSS
+ Particles.AddDust(Pit.X(px)+16,Pit.Y(y)+32)
+ EndIf
+ Next
+
+ For Local py:Int=y+1 Until Pit.HEIGHT
+ If gm.map[x,py]
+ gm.map[x,py].t=TWire.CROSS
+ Particles.AddDust(Pit.X(x)+16,Pit.Y(py)+32)
+ EndIf
+ Next
+
+ If Not gm.CheckWires()
+ gm.Flatten()
+ gm.CheckWires()
+ EndIf
+
+ ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
+
+ Return False
+ End Method
+End Type
+
+
+Type TWireListEnt
+ Field w:TWire
+ Field x:Int
+ Field y:Int
+
+ Function Create:TWireListEnt(x:Int, y:Int, w:TWire)
+ Local o:TWireListEnt=New TWireListEnt
+ o.x=x
+ o.y=y
+ o.w=w
+ Return o
+ End Function
+End Type
+
+
+Type TWireList
+ Field list:TList
+ Field col:Int
+
+ Method New()
+ list=CreateList()
+ col=128
+ End Method
+
+ Method Add(x:Int, y:Int, w:TWire)
+ list.AddLast(TWireListEnt.Create(x,y,w))
+ End Method
+
+ Method Draw:Int()
+ col=Min(255,col+5)
+ SetColor(col,col,col)
+ For Local e:TWireListEnt=EachIn list
+ DrawImage(e.w.Image(),Pit.X(e.x),Pit.Y(e.y))
+ Next
+
+ If col<255
+ Return True
+ Else
+ For Local e:TWireListEnt=EachIn list
+ Particles.AddImage(e.w.Image(),Pit.X(e.x),Pit.Y(e.y))
+ Next
+ Return False
+ EndIf
+ End Method
+
+ Method Count:Int()
+ Return list.Count()
+ End Method
+End Type
+
+
+Type TGameMap
+ Field map:TWire[Pit.WIDTH,Pit.HEIGHT]
+ Field trode_col:Int
+ Field trode_coli:Int
+ Field overflow:Int
+ Field cx:Int
+ Field cy:Int
+ Field path:TList
+ Field special:TSpecial
+
+ Method New()
+ trode_col=0
+ trode_coli=1
+ overflow=False
+ path=CreateList()
+ special=Null
+ End Method
+
+ Method BlockInteract:Int()
+ Return overflow Or path.Count() Or special
+ End Method
+
+ Method FindPath:Int(l:TWireList, x:Int, y:Int, dir:Int)
+ If y<0
+ Return False
+ EndIf
+
+ If x<0 Or x=Pit.WIDTH Or y=Pit.HEIGHT
+ Return True
+ EndIf
+
+ Local w:TWire=map[x,y]
+
+ If Not w
+ Return False
+ EndIf
+
+ dir=w.Traverse(dir)
+
+ If dir=TWire.DIR_NONE
+ Return False
+ EndIf
+
+ l.Add(x,y,w)
+
+ Return FindPath(l,x+TWire.DirX(dir),y+TWire.DirY(dir),dir)
+ End Method
+
+ Method FindLoop:Int(l:TWireList, ox:Int, oy:Int, x:Int, y:Int, dir:Int)
+ If y<0 Or x<0 Or x=Pit.WIDTH Or y=Pit.HEIGHT
+ Return False
+ EndIf
+
+ Local w:TWire=map[x,y]
+
+ If Not w
+ Return False
+ EndIf
+
+ dir=w.Traverse(dir)
+
+ If dir=TWire.DIR_NONE
+ Return False
+ EndIf
+
+ l.Add(x,y,w)
+
+ x:+TWire.DirX(dir)
+ y:+TWire.DirY(dir)
+
+ If x=ox And y=oy And dir=TWire.DIR_RIGHT
+ Return True
+ EndIf
+
+ Return FindLoop(l,ox,oy,x,y,dir)
+ End Method
+
+ Method CheckWires:Int()
+ Local loop:Int=False
+ Local wire:Int=False
+
+ For Local y:Int=0 Until Pit.HEIGHT
+ Local l:TWireList=New TWireList
+
+ If FindPath(l,0,y,TWire.DIR_RIGHT)
+ path.AddLast(l)
+ EndIf
+
+ l=New TWireList
+
+ If FindPath(l,Pit.WIDTH-1,y,TWire.DIR_LEFT)
+ path.AddLast(l)
+ wire=True
+ EndIf
+ Next
+
+ For Local x:Int=0 Until Pit.WIDTH
+ Local l:TWireList=New TWireList
+
+ If FindPath(l,x,Pit.HEIGHT-1,TWire.DIR_UP)
+ path.AddLast(l)
+ wire=True
+ EndIf
+ Next
+
+ For Local x:Int=0 Until Pit.WIDTH
+ For Local y:Int=0 Until Pit.HEIGHT
+ If map[x,y]
+ Local l:TWireList=New TWireList
+ Select map[x,y].t
+ Case TWire.CROSS, TWire.LEFT_RIGHT, TWire.TOP_LEFT, TWire.BOTTOM_LEFT
+ If FindLoop(l,x,y,x,y,TWire.DIR_RIGHT)
+ path.AddLast(l)
+ loop=True
+ EndIf
+ End Select
+ EndIf
+ Next
+ Next
+
+ If loop And wire
+ TextParticles.Big("LOOP AND WIRE",255,0,255)
+ ElseIf loop
+ TextParticles.Big("LOOP",255,0,255)
+ ElseIf wire
+ TextParticles.Big("WIRE",255,0,255)
+ EndIf
+
+ Return loop Or wire
+ End Method
+
+ Method SetSpecial(s:TSpecial)
+ special=s
+ End Method
+
+ Method DropColumn(x:Int, y:Int)
+ While y>0
+ map[x,y]=map[x,y-1]
+ y:-1
+ Wend
+ map[x,0]=Null
+ End Method
+
+ Method AnyAbove:Int(x:Int, y:Int)
+ While y>=0
+ If map[x,y]
+ Return True
+ EndIf
+ y:-1
+ Wend
+
+ Return False
+ End Method
+
+ Method Flatten()
+ For Local x:Int=0 Until Pit.WIDTH
+ Local y:Int=Pit.HEIGHT-1
+ Local drop:Int=False
+
+ While y>0 And AnyAbove(x,y)
+ If map[x,y]
+ If drop
+ Particles.AddDust(Pit.X(x)+16,Pit.Y(y)+32)
+ EndIf
+ drop=False
+ y:-1
+ Else
+ DropColumn(x,y)
+ drop=True
+ EndIf
+ Wend
+ Next
+ End Method
+
+ Method Draw:Int()
+ Local score:Int=0
+
+ SetColor(255,255,255)
+ DrawImage(GameGFX.pit_bottomleft,Pit.X(-1),Pit.Y(Pit.HEIGHT))
+ DrawImage(GameGFX.pit_bottomright,Pit.X(Pit.WIDTH),Pit.Y(Pit.HEIGHT))
+
+ DrawImage(GameGFX.pit_top,Pit.X(-1),Pit.Y(0))
+ DrawImage(GameGFX.pit_top,Pit.X(Pit.WIDTH),Pit.Y(0))
+ SetColor(trode_col,trode_col,0)
+ DrawImage(GameGFX.trode_left,Pit.X(-1),Pit.Y(0))
+ DrawImage(GameGFX.trode_right,Pit.X(Pit.WIDTH),Pit.Y(0))
+
+ For Local f:Int=0 Until Pit.WIDTH
+ SetColor(255,255,255)
+ DrawImage(GameGFX.pit_bottom,Pit.X(f),Pit.Y(Pit.HEIGHT))
+ SetColor(trode_col,trode_col,0)
+ DrawImage(GameGFX.trode_bottom,Pit.X(f),Pit.Y(Pit.HEIGHT))
+ Next
+
+ For Local f:Int=1 Until Pit.HEIGHT
+ SetColor(255,255,255)
+ DrawImage(GameGFX.pit_side,Pit.X(-1),Pit.Y(f))
+ DrawImage(GameGFX.pit_side,Pit.X(Pit.WIDTH),Pit.Y(f))
+ SetColor(trode_col,trode_col,0)
+ DrawImage(GameGFX.trode_left,Pit.X(-1),Pit.Y(f))
+ DrawImage(GameGFX.trode_right,Pit.X(Pit.WIDTH),Pit.Y(f))
+ Next
+
+ For Local x:Int=0 Until Pit.WIDTH
+ For Local y:Int=0 Until Pit.HEIGHT
+ If map[x,y]
+ SetColor(255,255,255)
+ DrawImage(GameGFX.tile,Pit.X(x),Pit.Y(y))
+ SetColor(trode_col,trode_col,0)
+ DrawImage(map[x,y].Image(),Pit.X(x),Pit.Y(y))
+ EndIf
+ Next
+ Next
+
+ If special
+ If Not special.DoSpecial(Self)
+ special=Null
+ EndIf
+ EndIf
+
+ Local l:TEasyLink=TEasyLink.Create(path)
+ Local check:Int=False
+
+ While l.Value()
+ Local b:TWireList=TWireList(l.Value())
+
+ If b.Draw()
+ l.MoveNext()
+ Else
+ If Not overflow
+ score:+b.list.Count()
+ For Local e:TWireListEnt=EachIn b.list
+ map[e.x,e.y]=Null
+ Next
+ EndIf
+ l.Remove()
+ check=True
+ EndIf
+ Wend
+
+ If check
+ Sound.Path()
+ Flatten()
+ CheckWires()
+ EndIf
+
+ trode_col:+trode_coli
+
+ If (trode_col=255 And trode_coli>0) Or (trode_col=200 And trode_coli<0)
+ trode_coli=-trode_coli
+ EndIf
+
+ Return score
+ End Method
+End Type