diff options
author | Ian C <ianc@noddybox.co.uk> | 2006-05-27 23:24:02 +0000 |
---|---|---|
committer | Ian C <ianc@noddybox.co.uk> | 2006-05-27 23:24:02 +0000 |
commit | 26c98ba56e72beaf8a99eafbedd2b0c64ac13954 (patch) | |
tree | 6460c30f185bfdf0647055a9a32af111b8f87894 /gametypes.bmx | |
parent | 0129dc56ba73e43f148b779d9ff549f286e66f1d (diff) |
Diffstat (limited to 'gametypes.bmx')
-rw-r--r-- | gametypes.bmx | 1937 |
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 |