' Particle Pinch ' ' Copyright 2005 Ian Cowburn ' ' $Id$ ' Strict Import noddybox.vector Import noddybox.bitmapfont Import noddybox.algorithm Import "types.bmx" Const MAGIC:String="PPINCH_0001" Const MAX_GRAV:Int=10 Const MAX_POINT:Int=1000 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 repel:Int Field friendly:Int Field x:Double Field y:Double Field mass:Double 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=repel Return m End Method Function FromStream:TGravPoint(s:TStream) Local o:TGravPoint=New TGravPoint o.repel=s.ReadInt() o.friendly=s.ReadInt() o.x=s.ReadDouble() o.y=s.ReadDouble() o.mass=s.ReadDouble() Return o End Function Method ToStream(s:TStream) s.WriteInt(repel) s.WriteInt(friendly) s.WriteDouble(x) s.WriteDouble(y) s.WriteDouble(mass) End Method End Type Type TPointLine Field x1:Double Field y1:Double Field x2:Double Field y2:Double Field gap:Int Field v:TVector Field circle:Int Field circvel:Double Method New() v=TVector.Create() gap=1 circle=False circvel=1 End Method Method CreatePoints(l:TList) If circle Local p:TAlgoPoint[]=DoCircle(x1,y1,Abs(x2-x1)) Local i:Int=0 For Local f:Int=0 To 359 If (i Mod gap)=0 Local tp:TPoint=New TPoint tp.x=p[f].x tp.y=p[f].y tp.v.x=Sin(f+90)*circvel tp.v.y=Cos(f+90)*circvel tp.v.Add(v) l.AddLast(tp) EndIf i:+1 Next Else 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 EndIf End Method Function FromStream:TPointLine(s:TStream) Local o:TPointLine=New TPointLine o.x1=s.ReadDouble() o.y1=s.ReadDouble() o.x2=s.ReadDouble() o.y2=s.ReadDouble() o.gap=s.ReadInt() o.v.x=s.ReadDouble() o.v.y=s.ReadDouble() o.circle=s.ReadInt() o.circvel=s.ReadDouble() Return o End Function Method ToStream(s:TStream) s.WriteDouble(x1) s.WriteDouble(y1) s.WriteDouble(x2) s.WriteDouble(y2) s.WriteInt(gap) s.WriteDouble(v.x) s.WriteDouble(v.y) s.WriteInt(circle) s.WriteDouble(circvel) 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 Field placemass:Double Field placefriend:Int Method New() grav=CreateList() point=CreateList() name="Unititled" maxmass=5 winpercent=50 timer=60 invmass=False placemass=25 placefriend=True 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() o.placemass=s.ReadDouble() o.placefriend=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.WriteDouble(placemass) s.WriteInt(placefriend) 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 Field stamp:String 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 s=LittleEndianStream(s) 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.stamp=s.ReadLine() 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=LittleEndianStream(s) s.WriteLine(MAGIC) s.WriteLine(CurrentDate()+CurrentTime()) s.WriteLine(name) s.WriteInt(level.Count()) For Local o:TLevel=EachIn level o.ToStream(s) Next s.Close() Return True End Method Method Get:TLevel(i:Int) Local tl:TLink=level.FirstLink() While i>0 And tl<>Null i:-1 tl=tl.NextLink() Wend Return TLevel(tl.Value()) End Method End Type