' Particle Pinch ' ' Copyright 2005 Ian Cowburn ' ' $Id$ ' Strict Import noddybox.vector Import noddybox.bitmapfont Import noddybox.algorithm Import "types.bmx" Const MAGIC:String="PPINCH0.0" Const MAX_GRAV:Int=10 Const MAX_POINT:Int=1000 Const GRAV_ATTRACT:Int=0 Const GRAV_REPEL:Int=0 Type TLevelException Field message:String Function Error(msg:String) Local o:TLevelException=New TLevelException o.message=msg Throw o End Function End Type Type TGravPoint Field mode:Int Field friendly:Int Field x:Float Field y:Float Field mass:Float Method CreateMass:TMass() Local m:TMass=New TMass m.mass=mass If friendly m.img=GameGFX.collector m.friend=True Else m.img=GameGFX.star m.friend=False EndIf m.x=x m.y=y m.inverse=(mode=GRAV_REPEL) End Method Function FromStream:TGravPoint(s:TStream) Local o:TGravPoint=New TGravPoint o.mode=s.ReadInt() o.friendly=s.ReadInt() o.x=s.ReadFloat() o.y=s.ReadFloat() o.mass=s.ReadFloat() Return o End Function Method ToStream(s:TStream) s.WriteInt(mode) s.WriteInt(friendly) s.WriteFloat(x) s.WriteFloat(y) s.WriteFloat(mass) End Method End Type Type TPointLine Field x1:Float Field y1:Float Field x2:Float Field y2:Float Field gap:Int Field v:TVector Method New() v=TVector.Create() End Method Method CreatePoints(l:TList) Local line:TList=DoLine(x1,y1,x2,y2) Local n:Int=line.Count() Local i:Int=0 For Local p:TAlgoPoint=EachIn line If (i Mod gap)=0 Local tp:TPoint=New TPoint tp.x=p.x tp.y=p.y tp.v.x=v.x tp.v.y=v.y l.AddLast(tp) EndIf i:+1 Next End Method Function FromStream:TPointLine(s:TStream) Local o:TPointLine=New TPointLine o.x1=s.ReadFloat() o.y1=s.ReadFloat() o.x2=s.ReadFloat() o.y2=s.ReadFloat() o.gap=s.ReadInt() o.v.x=s.ReadInt() o.v.y=s.ReadInt() Return o End Function Method ToStream(s:TStream) s.WriteFloat(x1) s.WriteFloat(y1) s.WriteFloat(x2) s.WriteFloat(y2) s.WriteInt(gap) s.WriteInt(v.x) s.WriteInt(v.y) End Method End Type Type TLevel Field name:String Field maxmass:Int Field grav:TList Field point:TList Field winpercent:Int Field timer:Int Field invmass:Int Method New() grav=CreateList() point=CreateList() name="Unititled" maxmass=5 winpercent=50 timer=60 invmass=False End Method Method CreatePlayfield(masslist:TList, pointlist:TList) For Local gp:TGravPoint=EachIn grav masslist.AddLast(gp.CreateMass()) Next For Local lp:TPointLine=EachIn point lp.CreatePoints(pointlist) Next End Method Function FromStream:TLevel(s:TStream) Local o:TLevel=New TLevel Local c:Int o.name=s.ReadLine() o.maxmass=s.ReadInt() o.winpercent=s.ReadInt() o.timer=s.ReadInt() o.invmass=s.ReadInt() c=s.ReadInt() For Local f:Int=1 To c o.grav.AddLast(TGravPoint.FromStream(s)) Next c=s.ReadInt() For Local f:Int=1 To c o.point.AddLast(TPointLine.FromStream(s)) Next Return o End Function Method ToStream(s:TStream) s.WriteLine(name) s.WriteInt(maxmass) s.WriteInt(winpercent) s.WriteInt(timer) s.WriteInt(invmass) s.WriteInt(grav.Count()) For Local o:TGravPoint=EachIn grav o.ToStream(s) Next s.WriteInt(point.Count()) For Local o:TPointLine=EachIn point o.ToStream(s) Next End Method End Type Type TLevelSet Field name:String Field level:TList Method New() level=CreateList() name="Untitled" End Method Function Load:TLevelSet(file:String) Local s:TStream=ReadStream(file) If s=Null TLevelException.Error(file + " couldn't be opened") EndIf Local o:TLevelSet=New TLevelSet Local c:Int Local m:String=s.ReadLine() If m<>MAGIC s.Close() TLevelException.Error(file + " doesn't appear to be a valid file for this version") EndIf o.name=s.ReadLine() c=s.ReadInt() For Local f:Int=1 To c o.level.AddLast(TLevel.FromStream(s)) Next s.Close() Return o End Function Method Save:Int(file:String) Local s:TStream=WriteStream(file) If s=Null Return False EndIf s.WriteLine(MAGIC) s.WriteLine(name) s.WriteInt(level.Count()) For Local o:TLevel=EachIn level o.ToStream(s) Next s.Close() Return True End Method End Type