;this loads the main window ;for level creation only ;- Map Top Global MapWidth.l Global MapHeight.l Global MapTileSet.s Global MapUnitSet.s Global MapResource.s Global WindowImage.l #WhiteLine=$070707 ;- Menu Status Stuff Global BrushType.l Global BrushSize.l Global BrushDetail.l Global BrushHeight.l Global UsePlayer.l Global IsDirty.l Global RunPath.s=GetPathPart(ProgramFilename()) ;- Help Stuff ;Global HelpFile.s="file:///"+RunPath+"RTSMaker.html" ;temp$=ReplaceString(HelpFile," ","%20") ;HelpFile=temp$ ;Global HelpFile.s=RunPath+"RTSMaker.html" Global HelpFile.s=RunPath+"RTSHelp.exe" Global HelpINI.s=RunPath+"RTSHelp.ini" ;Global HelpRunning.l ;Global OldWindow.l ;Global cap$="RTS Maker Help" Global HelpTip.s="#TOP" ;- TileData Structure TileStruct TileCount.l TileImage.l MatchTL.l MatchTR.l MatchBL.l MatchBR.l EndStructure Global Dim Tile.TileStruct(7,11) Structure XY X.l Y.l EndStructure Global Dim TileIndex.XY(8*12) Structure MapStruct TileImage.TileStruct ;Tile class for each corner TileHeight.TileStruct ;Tile Height for each corner Resource.l ;Resource Type RValue.l ;Quantity of Resource Unit.l ;Unit At Location (pointer to Unit Struct) EndStructure Global Dim MapTile.MapStruct(100,100) ;- GeneralProcs ;{ Prefrences Global INIFile.s=RunPath+"RTSMaker.ini" Global INISect.s Global INIOpen.l If OpenPreferences(INIFile) INIOpen=#True Else If CreatePreferences(INIFile) INIOpen=#True EndIf EndIf ;} XIncludeFile "myini.pbi" Procedure SmartWait(A$,B$,C$) PID.l=RunProgram(A$,B$,C$,#PB_Program_Open) If PID Repeat WaitWindowEvent(2000) If IsProgram(PID) If ProgramRunning(PID)=0 quit.l=1 EndIf Else quit=1 EndIf Until quit CloseProgram(PID) Else Debug "Unable to run "+a$ EndIf EndProcedure Procedure GetHelp(context.s) ;context should be the actual target location oldini.s=INIFile INIFile=HelpINI ;on the page INI_WriteString( "Helper", "LASTRTSHELP", context) INI_WriteString( "Helper", "LASTRTSTIME", "50") ;Debug "String"+INI_ReadString("Helper", "HANDLE", "0" ) HelpWindow=INI_ReadInteger( "Helper", "HANDLE", 0 ) ;Debug "HelpWindow"+Str(HelpWindow) INIFile=oldini If HelpWindow If IsWindow_(HelpWindow) Debug "Is Window" SetForegroundWindow_(HelpWindow) Delay(2000) ProcedureReturn Else Debug "Not a Window" EndIf EndIf helprunning=RunProgram(HelpFile,context,RunPath) If HelpRunning=0 CallDebugger HelpRunning= RunProgram(HelpFile)=0 If HelpRunning=0 MessageRequester("RTS Maker","Can't find help file"+Chr(10)+HelpFile,#MB_ICONSTOP) OldWindow=0 ProcedureReturn EndIf EndIf EndProcedure ;- Menu Manager Structure MenuStruct MenuTab.l ;0=File,4=Resources,6=Buildings,7=Units MenuUID.l ;This is the ID returned when clicked MenuPos.l ;This is the position of the menu item, Start is 8,6,6 MenuName.s ;Same as menu caption MenuData.l ;Pointer to RefUnit() EndStructure Global NewList MyMenu.MenuStruct() Declare AddMyMenu(MenuTab.l,MenuName.s,MenuUID.l,MenuData.l=0) Declare ClearCurrentMenu() Declare ClearMenu(MenuTab.l,MenuPOS.l) Declare ZapMyMenu(MenuTab.l) Declare ZapResourceMenu() Declare ZapBuildingMenu() Declare ZapUnitMenu() Declare ZapAllMenus() Declare.l CountMenu(MenuTab.l) Declare AddUnitMenu() Declare DelUnitMenu() ;- Patterns #RTSPattern="RTS Maker (*.rtm)|*.rtm|All Files (*.*)|*.*" #BMPPattern="Bitmap Files (*.bmp)|*.bmp|Image Files (*.bmp;*.jpg;*.gif;*.ico;*.png)|*.bmp;*.jpg;*.gif;*.ico;*.png|All Files (*.*)|*.*" #WAVPattern="Sound Files (*.wav)|*.wav|All Files (*.*)|*.*" #UnitPattern="RTS Units (*.rtu)|*.rtu|RTS Resourses (*.rtr)|*.rtr|RTS Weapons (*.rtw)|*.rtw|All RTS (*.rt*)|*.rt*|All Files (*.*)|*.*" #ResPattern="RTS Resourses (*.rtr)|*.rtr|All Files (*.*)|*.*" ;- Includes XIncludeFile "dialogs.pbi" XIncludeFile "procs.pbi" XIncludeFile "MainDLG.pb" XIncludeFile "MapOptDLG.pb" XIncludeFile "BlendDLG.pb" ; functions defined in "WeaponDLG.pb" but used in "BuildDLG.pb" Declare Open_Wep_Window(CWID.l) Declare Open_Window_Browse(BType.l,WID.l) ; functions define in "RTSMaker.pb" (here) and also used in "BuildDLG.pb" Declare LoadUnits(FN$) Declare saveUnits(FN$) XIncludeFile "BuildDLG.pb" XIncludeFile "WeaponDLG.pb" XIncludeFile "CBrowse.pb" XIncludeFile "StartRESDLG.pbi" ;- Externals ;use this to manage extrernal apps Structure ExtApp Caption.s ExtFile.s Handle.l ExtMenu.l EndStructure Global NewList External.ExtApp() Procedure.l ExternalCallback(AWindow.l,*Tfn) ;this function is called by windows ;in responce to the EnumWindows_() function ;this function is called once for each open window FN$=PeekS(*Tfn) Caption.s=Space(80) GetWindowText_(AWindow,@Caption,80) FP.l=FindString(Caption,FN$,0) If FP AddElement(External()) External()\Caption=Caption External()\ExtFile=FN$ External()\Handle=AWindow SetForegroundWindow_(External()\Handle) ProcedureReturn #False EndIf ;return of #True will continue searching for the window ProcedureReturn #True EndProcedure Procedure CloseAllExt() ResetList(External()) While NextElement(External()) If IsWindow_(External()\Handle) SendMessage_(External()\Handle,#WM_CLOSE,0,0) EndIf Wend ClearList(External()) EndProcedure Procedure FocusExternal(fn$) FindLinkList(External(),External()\ExtFile = fn$) Static Tfn$ If ValidIndex(External()) If IsWindow_(External()\Handle) SetForegroundWindow_(External()\Handle) EndIf Else Debug "External not found "+fn$ Tfn$=fn$ EnumWindows_(@ExternalCallBack(),@Tfn$) EndIf EndProcedure Macro SetTile(x,y,a,b,c,d) Tile(x,y)\MatchTL=a : Tile(x,y)\MatchTR=b : Tile(x,y)\MatchBL=c : Tile(x,y)\MatchBR=d EndMacro Procedure GenerateAutoTexture() ;this sets up the textures For autotexturing ;texture grid is ... ;0 | 1 ;2 | 3 ;0=water,1=grass,2=dirt, ;all remaining are listed as unique and not matchable ;unless modified by the user ;each type has 4 sides First 8 Tiles always the same For tx=0 To 7 Tile(tx,0)\MatchTL=tx : Tile(tx,0)\MatchTR=tx : Tile(tx,0)\MatchBL=tx : Tile(tx,0)\MatchBR=tx Next tx ;8 ... or 9 in original (before, 0 and 1 were copies) ; but thats because DBC first tile = 1, and 0 renders as 1 ;two tiles are first ; X Y TL TR BL BR SetTile(0, 1, 0, 1, 0, 1) SetTile(1, 1, 1, 1, 0, 0) SetTile(2, 1, 0, 0, 0, 1) SetTile(3, 1, 0, 0, 1, 0) SetTile(4, 1, 1, 1, 1, 0) SetTile(5, 1, 1, 1, 0, 1) SetTile(6, 1, 1, 0, 0, 1) SetTile(7, 1, 0, 0, 0, 0) SetTile(0, 2, 1, 0, 1, 0) SetTile(1, 2, 0, 0, 1, 1) SetTile(2, 2, 0, 1, 0, 0) SetTile(3, 2, 1, 0, 0, 0) SetTile(4, 2, 1, 0, 1, 1) SetTile(5, 2, 0, 1, 1, 1) SetTile(6, 2, 0, 1, 1, 0) SetTile(7, 2, 1, 1, 1, 1) ;grass vs rock, same As grass vs mud For X=0 To 7 For Y=1 To 2 IIF(Tile(X,Y)\MatchTL = 1,Tile(X,Y+2)\MatchTL=2, Tile(X,Y+2)\MatchTL=Tile(X,Y)\MatchTL) IIF(Tile(X,Y)\MatchTR = 1,Tile(X,Y+2)\MatchTR=2, Tile(X,Y+2)\MatchTR=Tile(X,Y)\MatchTR) IIF(Tile(X,Y)\MatchBL = 1,Tile(X,Y+2)\MatchBL=2, Tile(X,Y+2)\MatchBL=Tile(X,Y)\MatchBL) IIF(Tile(X,Y)\MatchBR = 1,Tile(X,Y+2)\MatchBR=2, Tile(X,Y+2)\MatchBR=Tile(X,Y)\MatchBR) ;and set the height map SetTile(X,Y+2,Tile(X,Y+2)\MatchTL,Tile(X,Y+2)\MatchTR,Tile(X,Y+2)\MatchBL,Tile(X,Y+2)\MatchBR) Next y Next x ;mud vs rock, same As grass vs rock For X=0 To 7 For Y=3 To 4 IIF(Tile(X,Y)\MatchTL = 0,Tile(X,Y+2)\MatchTL=1, Tile(X,Y+2)\MatchTL=Tile(X,Y)\MatchTL) IIF(Tile(X,Y)\MatchTR = 0,Tile(X,Y+2)\MatchTR=1, Tile(X,Y+2)\MatchTR=Tile(X,Y)\MatchTR) IIF(Tile(X,Y)\MatchBL = 0,Tile(X,Y+2)\MatchBL=1, Tile(X,Y+2)\MatchBL=Tile(X,Y)\MatchBL) IIF(Tile(X,Y)\MatchBR = 0,Tile(X,Y+2)\MatchBR=1, Tile(X,Y+2)\MatchBR=Tile(X,Y)\MatchBR) SetTile(X,Y+2,Tile(X,Y+2)\MatchTL,Tile(X,Y+2)\MatchTR,Tile(X,Y+2)\MatchBL,Tile(X,Y+2)\MatchBR) Next y Next x ;special hybrid tiles ; X Y TL TR BL BR SetTile(0, 7, 0, 0, 1, 2) SetTile(1, 7, 0, 0, 2, 1) SetTile(2, 7, 1, 1, 0, 2) SetTile(3, 7, 1, 1, 2, 0) SetTile(4, 7, 2, 2, 0, 1) SetTile(5, 7, 2, 2, 1, 0) SetTile(6, 7, 0, 1, 2, 0) SetTile(7, 7, 0, 2, 1, 0) SetTile(0, 8, 0, 1, 0, 2) SetTile(1, 8, 0, 2, 0, 1) SetTile(2, 8, 1, 0, 1, 2) SetTile(3, 8, 1, 2, 1, 0) SetTile(4, 8, 2, 0, 2, 1) SetTile(5, 8, 2, 1, 2, 0) SetTile(6, 8, 1, 0, 0, 2) SetTile(7, 8, 2, 0, 0, 1) SetTile(0, 9, 1, 2, 0, 0) SetTile(1, 9, 2, 1, 0, 0) SetTile(2, 9, 0, 2, 1, 1) SetTile(3, 9, 2, 0, 1, 1) SetTile(4, 9, 0, 1, 2, 2) SetTile(5, 9, 1, 0, 2, 2) SetTile(6, 9, 1, 0, 2, 1) SetTile(7, 9, 1, 2, 0, 1) SetTile(0, 10, 1, 0, 2, 0) SetTile(1, 10, 2, 0, 1, 0) SetTile(2, 10, 0, 1, 2, 1) SetTile(3, 10, 2, 1, 0, 1) SetTile(4, 10, 0, 2, 1, 2) SetTile(5, 10, 1, 2, 0, 2) SetTile(6, 10, 0, 1, 1, 2) SetTile(7, 10, 2, 1, 1, 0) SetTile(0, 11, 2, 0, 1, 2) SetTile(1, 11, 2, 1, 0, 2) SetTile(2, 11, 0, 2, 2, 1) SetTile(3, 11, 1, 2, 2, 0) ;2 extra grass tiles for details SetTile(4, 11, 1, 1, 1, 1) SetTile(5, 11, 1, 1, 1, 1) ;2 extra dirt tiles for details SetTile(6, 11, 2, 2, 2, 2) SetTile(7, 11, 2, 2, 2, 2) EndProcedure Procedure.l CheckIt(A.l,B.l) ;this checks if Tile Description A will match B If A=B ProcedureReturn #True ElseIf A<0 ProcedureReturn #True Else ProcedureReturn #False EndIf EndProcedure Procedure.l MatchTile(TL.l,TR.l,BL.l,BR.l) ;set a tile type to -1 to ignore setting ;return value is -1 if no match is found For x=0 To 7 For y=0 To 11 If CheckIt(TL,Tile(X,Y)\MatchTL) If CheckIt(TR,Tile(X,Y)\MatchTR) If CheckIt(BL,Tile(X,Y)\MatchBL) If CheckIt(BR,Tile(X,Y)\MatchBR) ProcedureReturn Tile(X,Y)\TileCount EndIf EndIf EndIf EndIf Next y Next x ProcedureReturn -1 EndProcedure Macro AutoMap(dx,dy,tl,tr,bl,br) If tx+(dx)<=MapWidth If tx+(dx)>=0 If ty+(dy)>=0 If ty+(dy)<=MapHeight MT.l=MatchTile(tl,tr,bl,br) If MT>=0 ;MTY=Int(MT/ttw) ;MTX=MT-(MTY*ttw) MTY=TileIndex(MT)\y MTX=TileIndex(MT)\x CopyStructA2B(Tile(MTX,MTY),MapTile(tx+(dx),ty+(dy))\TileImage,TileStruct) EndIf EndIf EndIf EndIf EndIf EndMacro Macro SetSpotHeight(SX,SY,Spot,HT) If HT>=0 If SX>=0 If SX<=MapWidth If SY>=0 If SY<=MapHeight MapTile(SX,SY)\TileHeight\Spot = HT EndIf EndIf EndIf EndIf EndIf EndMacro Procedure LoadTiles() ;this loads the main tile image ;and divides it into seperate images ;and store all data into the Tile.TileStruct(7,11) array Static FirstCall.l ;first, free all images If FirstCall For TX=0 To 7 For TY=0 To 11 FreeImage(Tile(TX,TY)\TileImage) Next TY Next TX Else ;prepare the autotexture data For y=0 To 11 For x=0 To 7 Tile(x,y)\TileCount=cnt.l TileIndex(cnt)\x=x TileIndex(cnt)\y=y cnt + 1 Next x Next y GenerateAutoTexture() EndIf FirstCall+1 ;load the main image If MapTileSet MapImage.l=LoadImage(#PB_Any,MapTileSet) If MapImage=0 MessageRequester("RTS Maker - Error","Unable to load tileset"+Chr(10)+MapTileSet,#MB_ICONSTOP) MapTileset="" EndIf EndIf If MapImage=0 MapImage=CatchImage(#PB_Any,?BasicGWD) If MapImage=0 MessageRequester("RTS Maker - Serious Error!!","Unable to load default tileset",#MB_ICONSTOP) End EndIf EndIf ;break up the image For y=0 To 11 For x=0 To 7 Tile(x,y)\TileImage=GrabImage(MapImage,#PB_Any,x*32,y*32,32,32) Next x Next y FreeImage(MapImage) ;update the map For X=0 To MapWidth For Y=0 To MapHeight TC.l=MapTile(X,Y)\TileImage\TileCount TX=TileIndex(TC)\X TY=TileIndex(TC)\Y MapTile(X,Y)\TileImage\TileImage=Tile(TX,TY)\TileImage Next Y Next X EndProcedure Macro HeightLine(dh,x,y,x2,y2) Select dh Case 0 ;no line Case 1 ;thin line If x2=x Line(x,y,0,(y2-y),#WhiteLine) Else Line(x,y,(x2-x),0,#WhiteLine) EndIf Case 2 ;thick line If x2=x Line(x-1,y,0,(y2-y),#WhiteLine) Line(x,y,0,(y2-y),#WhiteLine) Else Line(x,y-1,(x2-x),0,#WhiteLine) Line(x,y,(x2-x),0,#WhiteLine) EndIf Default ;thinker line If x2=x Line(x-2,y,0,(y2-y),#WhiteLine) Line(x-1,y,0,(y2-y),#WhiteLine) Line(x,y,0,(y2-y),#WhiteLine) Line(x+1,y,0,(y2-y),#WhiteLine) Else Line(x,y-2,(x2-x),0,#WhiteLine) Line(x,y-1,(x2-x),0,#WhiteLine) Line(x,y,(x2-x),0,#WhiteLine) Line(x,y+1,(x2-x),0,#WhiteLine) EndIf EndSelect EndMacro Procedure PaintWindow(WindowImage.l) ;this does all window drawing for the map ;GetUpdateRect_(WindowID(#Window_Map),@R.RECT,#False) ;R\left ;R\top ;R\right ;R\bottom TopRow=GetGadgetState(#VScrollBar) LeftRow=GetGadgetState(#HScrollBar) BotRow=TopRow+GetScrollBarPage(#VScrollBar)*2 RightRow=LeftRow+GetScrollBarPage(#HScrollBar)*2 TX1=LeftRow/32 TX2=RightRow/32 TY1=TopRow/32 TY2=BotRow/32 If TX2>MapWidth TX2=MapWidth EndIf If TY2>MapHeight TY2=MapHeight EndIf OffY=TopRow-TY1*32 OffX=LeftRow-TX1*32 If StartDrawing(ImageOutput(WindowImage)) ;do all the stuff ??? wy=-Offy For my=TY1 To TY2 wx=-OffX For mx=TX1 To TX2 DrawImage(ImageID(MapTile(mx,my)\TileImage\TileImage),wx,wy) ;and also draw the height markers DH.l=Abs(MapTile(mx,my)\TileHeight\MatchTL-MapTile(mx,my)\TileHeight\MatchTR) HeightLine(dh,16+wx,wy,16+wx,wy+16) DH.l=Abs(MapTile(mx,my)\TileHeight\MatchTL-MapTile(mx,my)\TileHeight\MatchBL) HeightLine(dh,wx,wy+16,16+wx,wy+16) DH.l=Abs(MapTile(mx,my)\TileHeight\MatchTR-MapTile(mx,my)\TileHeight\MatchBR) HeightLine(dh,wx+16,wy+16,32+wx,wy+16) DH.l=Abs(MapTile(mx,my)\TileHeight\MatchBL-MapTile(mx,my)\TileHeight\MatchBR) HeightLine(dh,wx+16,wy+16,16+wx,wy+32) wx+32 Next mx wy+32 Next my StopDrawing() EndIf ;and update the window If StartDrawing(WindowOutput(#Window_Map)) ;we just draw the windowimage DrawImage(ImageID(WindowImage),0,ToolBarHeight(#StatusBar)) If BrushType>0 If BrushType<4 ;mx=PeekW(@lParam) ;my=PeekW(@lParam+2) ;convert to tile (tx,ty) my=WindowMouseY(#Window_Map)+GetGadgetState(#VScrollBar)-ToolBarHeight(#StatusBar) mx=WindowMouseX(#Window_Map)+GetGadgetState(#HScrollBar) ty=my/32 tx=mx/32 wx=tx*32-GetGadgetState(#HScrollBar) wy=ty*32-GetGadgetState(#VScrollBar)+ToolBarHeight(#StatusBar) SX=wx-32*(BrushSize+1)+16 SY=wy-32*(BrushSize+1)+16 W=64*(BrushSize+1) H=64*(BrushSize+1) If SX<0 W=W+SX SX=0 EndIf If (SX+W)>ImageWidth(WindowImage) W=ImageWidth(WindowImage)-SX ;SX=ImageWidth(WindowImage)-W EndIf If SYImageHeight(WindowImage)+ToolBarHeight(#StatusBar) H=ImageHeight(WindowImage)+ToolBarHeight(#StatusBar)-SY ;SY=ImageHeight(WindowImage)-H EndIf EmptyBox(SX,SY,w,h,0) EndIf EndIf StopDrawing() EndIf EndProcedure ;this modifies the default list-index value ;to adjust for appending one list to another Macro ValidRead( Var , F , Mod ) Var = ReadLong(F) If Var Var + Mod EndIf EndMacro ;this converts a pointer to a unit (P2RU) ;to the index of the unit (XRU) Macro ARU2X( P2RU , XRU ) If P2RU *ARU = @RefUnit() ChangeCurrentElement(RefUnit(), P2RU ) XRU = ListIndex(RefUnit()) ChangeCurrentElement(RefUnit(),*ARU) Else XRU = -1 EndIf EndMacro ;this converts an index of a unit (XRU) ;to a pointer to a unit (P2RU) Macro X2ARU( XRU , P2RU ) If XRU<0 P2RU = 0 Else *ARU = @RefUnit() SelectElement(RefUnit(), XRU ) P2RU = @RefUnit() ChangeCurrentElement(RefUnit(),*ARU) EndIf EndMacro Macro Mem2File( Mem , File ) If Mem MS.l=MemorySize(Mem) WriteLong(File,MS) WriteData(File,Mem,MS) Else WriteLong(File,0) EndIf EndMacro Macro File2Mem( File , Mem ) MS.l=ReadLong( File ) If MS Mem = AllocateMemory( MS ) ReadData( File , Mem , MS ) Else Mem = 0 EndIf EndMacro Macro WrapFreeMem( Mem ) If Mem FreeMemory( Mem ) EndIf EndMacro Macro WrapFreeSound( snd) If IsSound(snd) FreeSound(snd) EndIf EndMacro Procedure SaveUnits(FN$) F.l=CreateFile(#PB_Any,FN$) If F ;now copy all RefUnits .... If ListIndex(RefUnit())>=0 *CE.UnitStruct=@RefUnit() Else *CE=0 EndIf ResetList(RefUnit()) While NextElement(RefUnit()) ;in game status information ;position WriteLong(F,RefUnit()\X) WriteLong(F,RefUnit()\Y) WriteLong(F,RefUnit()\Face) ;start with basic data first ;summary for Resource/Building/Unit WriteLong(F,RefUnit()\ReqLevel) *RU.UnitStruct=RefUnit()\AReqUID X.l=0 ARU2X(*RU,X) WriteLong(F,X) ;UID is a Unique ID of this structure. Based on creation time ;or via index values at time of loading ;UID.l WriteStringN(F,RefUnit()\Name) WriteLong(F,RefUnit()\Panel) WriteLong(F,RefUnit()\Sort) WriteLong(F,RefUnit()\Type) WriteLong(F,RefUnit()\Building) WriteLong(F,RefUnit()\IsActive) *RU=RefUnit()\UpgradeToUID ARU2X(*RU,X) WriteLong(F,X) ;AU2UID is address to UpGradeToUID ;AU2UID.l WriteLong(F,RefUnit()\NextLevel) WriteLong(F,RefUnit()\UpgradeT1) WriteLong(F,RefUnit()\UpgradeT2) WriteLong(F,RefUnit()\UpgradeALL) ;stats for Resources/Buildings/Units ;For weapons, these are mods to basic settings .... of target WriteLong(F,RefUnit()\Armor) WriteLong(F,RefUnit()\PArmor) WriteLong(F,RefUnit()\Health) WriteLong(F,RefUnit()\PHealth) WriteLong(F,RefUnit()\Speed) WriteLong(F,RefUnit()\TileFlag) ;WedID is address of weapon struct (or UID ref during load/save) ;Ammo is ammount of ammo, type is stored with weapon .... *RU=RefUnit()\WepID[0] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\WepID[1] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\WepID[2] ARU2X(*RU,X) WriteLong(F,X) WriteLong(F,RefUnit()\Ammo[0]) WriteLong(F,RefUnit()\Ammo[1]) WriteLong(F,RefUnit()\Ammo[2]) WriteLong(F,RefUnit()\TotalCargo) WriteLong(F,RefUnit()\Fuel) ;Wep Mods WriteLong(F,RefUnit()\MinRange) WriteLong(F,RefUnit()\MaxRange) WriteLong(F,RefUnit()\Area) WriteLong(F,RefUnit()\Homing) WriteLong(F,RefUnit()\Aim) WriteLong(F,RefUnit()\Rate) WriteLong(F,RefUnit()\Dammage) ;AI WriteLong(F,RefUnit()\ASave) WriteLong(F,RefUnit()\Bravery) WriteLong(F,RefUnit()\Scary) WriteLong(F,RefUnit()\Quiet) WriteLong(F,RefUnit()\SeeFar) ;cargo ;TotalCargo ;CarryType is address of structure *RU=RefUnit()\CarryType[0] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CarryType[1] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CarryType[2] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CarryType[3] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CarryType[4] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CarryType[5] ARU2X(*RU,X) WriteLong(F,X) WriteLong(F,RefUnit()\CarryQTY[0]) WriteLong(F,RefUnit()\CarryQTY[1]) WriteLong(F,RefUnit()\CarryQTY[2]) WriteLong(F,RefUnit()\CarryQTY[3]) WriteLong(F,RefUnit()\CarryQTY[4]) WriteLong(F,RefUnit()\CarryQTY[5]) WriteLong(F,RefUnit()\UsrSize) ;other last minute thingies (see weaponsDLG) WriteLong(F,RefUnit()\Visible) WriteLong(F,RefUnit()\FFire) WriteLong(F,RefUnit()\TSelf) WriteLong(F,RefUnit()\DLine) WriteLong(F,RefUnit()\CLine) ;TColor.l WriteLong(F,RefUnit()\UTColor) WriteLong(F,RefUnit()\Duration) WriteLong(F,RefUnit()\Redo) WriteLong(F,RefUnit()\ETemp) WriteLong(F,RefUnit()\CTeam) WriteLong(F,RefUnit()\CType) WriteLong(F,RefUnit()\Teleport) WriteLong(F,RefUnit()\Neutral) WriteLong(F,RefUnit()\Stuned) WriteLong(F,RefUnit()\Scared) WriteLong(F,RefUnit()\IsBrave) WriteLong(F,RefUnit()\VChange) WriteLong(F,RefUnit()\CSpeed) WriteLong(F,RefUnit()\CHeight) WriteLong(F,RefUnit()\LClear) WriteLong(F,RefUnit()\DelMove) WriteLong(F,RefUnit()\AddMove) *RU=RefUnit()\CostRID[0] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CostRID[1] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CostRID[2] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CostRID[3] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CostRID[4] ARU2X(*RU,X) WriteLong(F,X) WriteLong(F,RefUnit()\CostQTY[0]) WriteLong(F,RefUnit()\CostQTY[1]) WriteLong(F,RefUnit()\CostQTY[2]) WriteLong(F,RefUnit()\CostQTY[3]) WriteLong(F,RefUnit()\CostQTY[4]) WriteLong(F,RefUnit()\CostTime) ;maint RID is address to resource struct *RU=RefUnit()\MaintRID[0] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\MaintRID[1] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\MaintRID[2] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\MaintRID[3] ARU2X(*RU,X) WriteLong(F,X) WriteLong(F,RefUnit()\MaintQTY[0]) WriteLong(F,RefUnit()\MaintQTY[1]) WriteLong(F,RefUnit()\MaintQTY[2]) WriteLong(F,RefUnit()\MaintQTY[3]) WriteLong(F,RefUnit()\MaintTime) WriteLong(F,RefUnit()\MaintWorkers) *RU=RefUnit()\MakeRID ARU2X(*RU,X) WriteLong(F,X) WriteLong(F,RefUnit()\MakeQTY) If RefUnit()\IsActive=0 ;only save image information for inactive units ;Active units use refunits data to save space ;Image information WriteLong(F,RefUnit()\PlayerColor) WriteLong(F,RefUnit()\TColor) WriteLong(F,RefUnit()\Width) WriteLong(F,RefUnit()\Height) WriteLong(F,RefUnit()\FrameTime) WriteLong(F,RefUnit()\TotalFrames) ;4 sides for buildings, 5 build states ;5 damage states ;10 frames of animations(max) when finished ;4x20=80 ;Picture.l[80] For P=0 To 79 If IsImage(RefUnit()\Picture[P]) w.l=ImageWidth(RefUnit()\Picture[P])-1 h.l=ImageHeight(RefUnit()\Picture[P])-1 WriteLong(F,w) WriteLong(F,h) StartDrawing(ImageOutput(RefUnit()\Picture[P])) For x.l=0 To w For y.l=0 To h C.l=Point(x,y) WriteLong(F,C) Next y Next x StopDrawing() Else WriteLong(F,0) WriteLong(F,0) EndIf Next P ;10x10=100 ;Tiles.l[100] ;for Units and Weapons ;8 directions of 10 animations (so, use Tiles) for Unit images ;5 frames of animations for "normal" and 5 for "damaged" ;cost RID is address to resource struct (except for storage, then its an UID) For P=0 To 99 If IsImage(RefUnit()\Tiles[P]) w.l=ImageWidth(RefUnit()\Tiles[P])-1 h.l=ImageHeight(RefUnit()\Tiles[P])-1 WriteLong(F,w) WriteLong(F,h) StartDrawing(ImageOutput(RefUnit()\Tiles[P])) For x.l=0 To w For y.l=0 To h C.l=Point(x,y) WriteLong(F,C) Next y Next x StopDrawing() Else WriteLong(F,0) WriteLong(F,0) EndIf Next P ;sound (Weapons use only Com/Des/Att) Mem2File(RefUnit()\SelSound,F) Mem2File(RefUnit()\DefSound,F) Mem2File(RefUnit()\ComSound,F) Mem2File(RefUnit()\CapSound,F) Mem2File(RefUnit()\DesSound,F) Mem2File(RefUnit()\AMOSound,F) Mem2File(RefUnit()\OPPSound,F) Mem2File(RefUnit()\FulSound,F) Mem2File(RefUnit()\AttSound,F) EndIf Wend If *CE ChangeCurrentElement(RefUnit(),*CE) Else ResetList(RefUnit()) EndIf CloseFile(F) EndIf EndProcedure Procedure LoadUnits(FN$) ;adds all units from file to existing units LastElement(RefUnit()) LastIndex.l=CountList(RefUnit()) F=ReadFile(#PB_Any,FN$) If F While Eof(F)=0 AddElement(RefUnit()) ;in game status information ;position RefUnit()\X=ReadLong(F) RefUnit()\Y=ReadLong(F) RefUnit()\Face=ReadLong(F) ;start with basic data first ;summary for Resource/Building/Unit RefUnit()\ReqLevel=ReadLong(F) RefUnit()\AReqUID=ReadLong(F) ValidRead( RefUnit()\AReqUID , F , LastIndex) ;UID is a Unique ID of this structure. Based on creation time ;or via index values at time of loading ;UID.l RefUnit()\Name=ReadString(F) RefUnit()\Panel=ReadLong(F) RefUnit()\Sort=ReadLong(F) RefUnit()\Type=ReadLong(F) RefUnit()\Building=ReadLong(F) ValidRead( RefUnit()\Building , F , LastIndex) RefUnit()\IsActive=ReadLong(F) ValidRead( RefUnit()\UpgradeToUID , F , LastIndex ) ;AU2UID is address to UpGradeToUID ;AU2UID.l RefUnit()\NextLevel=ReadLong(F) RefUnit()\UpgradeT1=ReadLong(F) RefUnit()\UpgradeT2=ReadLong(F) RefUnit()\UpgradeALL=ReadLong(F) ;stats for Resources/Buildings/Units ;For weapons, these are mods to basic settings .... of target RefUnit()\Armor=ReadLong(F) RefUnit()\PArmor=ReadLong(F) RefUnit()\Health=ReadLong(F) RefUnit()\PHealth=ReadLong(F) RefUnit()\Speed=ReadLong(F) RefUnit()\TileFlag=ReadLong(F) ;WedID is address of weapon struct (or UID ref during load/save) ;Ammo is ammount of ammo, type is stored with weapon .... ValidRead( RefUnit()\WepID[0] , F , LastIndex ) ValidRead( RefUnit()\WepID[1] , F , LastIndex ) ValidRead( RefUnit()\WepID[2] , F , LastIndex ) RefUnit()\Ammo[0]=ReadLong(F) RefUnit()\Ammo[1]=ReadLong(F) RefUnit()\Ammo[2]=ReadLong(F) RefUnit()\TotalCargo=ReadLong(F) RefUnit()\Fuel=ReadLong(F) ;Wep Mods RefUnit()\MinRange=ReadLong(F) RefUnit()\MaxRange=ReadLong(F) RefUnit()\Area=ReadLong(F) RefUnit()\Homing=ReadLong(F) RefUnit()\Aim=ReadLong(F) RefUnit()\Rate=ReadLong(F) RefUnit()\Dammage=ReadLong(F) ;AI RefUnit()\ASave=ReadLong(F) RefUnit()\Bravery=ReadLong(F) RefUnit()\Scary=ReadLong(F) RefUnit()\Quiet=ReadLong(F) RefUnit()\SeeFar=ReadLong(F) ;cargo ;TotalCargo ;CarryType is address of structure ValidRead( RefUnit()\CarryType[0] , F , LastIndex ) ValidRead( RefUnit()\CarryType[1] , F , LastIndex ) ValidRead( RefUnit()\CarryType[2] , F , LastIndex ) ValidRead( RefUnit()\CarryType[3] , F , LastIndex ) ValidRead( RefUnit()\CarryType[4] , F , LastIndex ) ValidRead( RefUnit()\CarryType[5] , F , LastIndex ) RefUnit()\CarryQTY[0]=ReadLong(F) RefUnit()\CarryQTY[1]=ReadLong(F) RefUnit()\CarryQTY[2]=ReadLong(F) RefUnit()\CarryQTY[3]=ReadLong(F) RefUnit()\CarryQTY[4]=ReadLong(F) RefUnit()\CarryQTY[5]=ReadLong(F) RefUnit()\UsrSize=ReadLong(F) ;other last minute thingies (see weaponsDLG) RefUnit()\Visible=ReadLong(F) RefUnit()\FFire=ReadLong(F) RefUnit()\TSelf=ReadLong(F) RefUnit()\DLine=ReadLong(F) RefUnit()\CLine=ReadLong(F) ;TColor.l RefUnit()\UTColor=ReadLong(F) RefUnit()\Duration=ReadLong(F) RefUnit()\Redo=ReadLong(F) RefUnit()\ETemp=ReadLong(F) RefUnit()\CTeam=ReadLong(F) RefUnit()\CType=ReadLong(F) RefUnit()\Teleport=ReadLong(F) RefUnit()\Neutral=ReadLong(F) RefUnit()\Stuned=ReadLong(F) RefUnit()\Scared=ReadLong(F) RefUnit()\IsBrave=ReadLong(F) RefUnit()\VChange=ReadLong(F) RefUnit()\CSpeed=ReadLong(F) RefUnit()\CHeight=ReadLong(F) RefUnit()\LClear=ReadLong(F) RefUnit()\DelMove=ReadLong(F) RefUnit()\AddMove=ReadLong(F) ValidRead( RefUnit()\CostRID[0] , F , LastIndex ) ValidRead( RefUnit()\CostRID[1] , F , LastIndex ) ValidRead( RefUnit()\CostRID[2] , F , LastIndex ) ValidRead( RefUnit()\CostRID[3] , F , LastIndex ) ValidRead( RefUnit()\CostRID[4] , F , LastIndex ) RefUnit()\CostQTY[0]=ReadLong(F) RefUnit()\CostQTY[1]=ReadLong(F) RefUnit()\CostQTY[2]=ReadLong(F) RefUnit()\CostQTY[3]=ReadLong(F) RefUnit()\CostQTY[4]=ReadLong(F) RefUnit()\CostTime=ReadLong(F) ;maint RID is address to resource struct ValidRead( RefUnit()\MaintRID[0] , F , LastIndex ) ValidRead( RefUnit()\MaintRID[1] , F , LastIndex ) ValidRead( RefUnit()\MaintRID[2] , F , LastIndex ) ValidRead( RefUnit()\MaintRID[3] , F , LastIndex ) RefUnit()\MaintQTY[0]=ReadLong(F) RefUnit()\MaintQTY[1]=ReadLong(F) RefUnit()\MaintQTY[2]=ReadLong(F) RefUnit()\MaintQTY[3]=ReadLong(F) RefUnit()\MaintTime=ReadLong(F) RefUnit()\MaintWorkers=ReadLong(F) ValidRead( RefUnit()\MakeRID , F , LastIndex ) RefUnit()\MakeQTY=ReadLong(F) If RefUnit()\IsActive=0 ;and, add this unit to menu system AddUnitMenu() ;only save image information for inactive units ;Active units use refunits data to save space ;Image information RefUnit()\PlayerColor=ReadLong(F) RefUnit()\TColor=ReadLong(F) RefUnit()\Width=ReadLong(F) RefUnit()\Height=ReadLong(F) RefUnit()\FrameTime=ReadLong(F) RefUnit()\TotalFrames=ReadLong(F) For P=0 To 79 w.l=ReadLong(F) h.l=ReadLong(F) If w RefUnit()\Picture[P]=CreateImage(#PB_Any,w,h) StartDrawing(ImageOutput(RefUnit()\Picture[P])) For x.l=0 To w For y.l=0 To h C.l=ReadLong(F) Plot(x,y,C) Next y Next x StopDrawing() EndIf Next P For P=0 To 99 w.l=ReadLong(F) h.l=ReadLong(F) If w RefUnit()\Tiles[P]=CreateImage(#PB_Any,w,h) StartDrawing(ImageOutput(RefUnit()\Tiles[P])) For x.l=0 To w For y.l=0 To h C.l=ReadLong(F) Plot(x,y,C) Next y Next x StopDrawing() EndIf Next P ;sound (Weapons use only Com/Des/Att) File2Mem(f,RefUnit()\SelSound) File2Mem(f,RefUnit()\DefSound) File2Mem(f,RefUnit()\ComSound) File2Mem(f,RefUnit()\CapSound) File2Mem(f,RefUnit()\DesSound) File2Mem(f,RefUnit()\AMOSound) File2Mem(f,RefUnit()\OPPSound) File2Mem(f,RefUnit()\FulSound) File2Mem(f,RefUnit()\AttSound) EndIf Wend ;re-scan list ;and convert all index data to address data .... ResetList(RefUnit()) If LastIndex SelectElement(RefUnit(),LastIndex -1) While NextElement(RefUnit()) X.l=RefUnit()\AReqUID X2ARU(X,*RU) RefUnit()\AReqUID=*RU X=RefUnit()\UpgradeToUID X2ARU(X,*RU) RefUnit()\UpgradeToUID=*RU ;WedID is address of weapon struct (or UID ref during load/save) ;Ammo is ammount of ammo, type is stored with weapon .... X=RefUnit()\WepID[0] X2ARU(X,*RU) RefUnit()\WepID[0]=*RU X=RefUnit()\WepID[1] X2ARU(X,*RU) RefUnit()\WepID[1]=*RU X=RefUnit()\WepID[2] X2ARU(X,*RU) RefUnit()\WepID[2]=*RU ;cargo ;TotalCargo ;CarryType is address of structure X=RefUnit()\CarryType[0] X2ARU(X,*RU) RefUnit()\CarryType[0]=*RU X=RefUnit()\CarryType[1] X2ARU(X,*RU) RefUnit()\CarryType[1]=*RU X=RefUnit()\CarryType[2] X2ARU(X,*RU) RefUnit()\CarryType[2]=*RU X=RefUnit()\CarryType[3] X2ARU(X,*RU) RefUnit()\CarryType[3]=*RU X=RefUnit()\CarryType[4] X2ARU(X,*RU) RefUnit()\CarryType[4]=*RU X=RefUnit()\CarryType[5] X2ARU(X,*RU) RefUnit()\CarryType[5]=*RU X=RefUnit()\CostRID[0] X2ARU(X,*RU) RefUnit()\CostRID[0]=*RU X=RefUnit()\CostRID[1] X2ARU(X,*RU) RefUnit()\CostRID[1]=*RU X=RefUnit()\CostRID[2] X2ARU(X,*RU) RefUnit()\CostRID[2]=*RU X=RefUnit()\CostRID[3] X2ARU(X,*RU) RefUnit()\CostRID[3]=*RU X=RefUnit()\CostRID[4] X2ARU(X,*RU) RefUnit()\CostRID[4]=*RU X=RefUnit()\MaintRID[0] X2ARU(X,*RU) RefUnit()\MaintRID[0]=*RU X=RefUnit()\MaintRID[1] X2ARU(X,*RU) RefUnit()\MaintRID[1]=*RU X=RefUnit()\MaintRID[2] X2ARU(X,*RU) RefUnit()\MaintRID[2]=*RU X=RefUnit()\MaintRID[3] X2ARU(X,*RU) RefUnit()\MaintRID[3]=*RU X=RefUnit()\MakeRID X2ARU(X,*RU) RefUnit()\MakeRID=*RU Wend EndIf CloseFile(F) EndIf EndProcedure Procedure NewMapFile(Flag.l) ;use Flag to show the Dialog Box ;Set to 0 to use default map settings ;default map options: MapWidth=50 MapHeight=50 MapTileSet="" MapUnitSet="" MapResource="" If Flag ;show the dialog Open_Window_Opts(#Window_Map) EndIf LoadTiles() Dim MapTile.MapStruct(MapWidth,MapHeight) For X=0 To MapWidth For Y=0 To MapHeight CopyStructA2B(@Tile(1,0),@MapTile(X,Y)\TileImage,TileStruct) Next Y Next X ;and reset the scrollbars SetGadgetState(#HScrollBar,0) PW=GetScrollBarPage(#HScrollBar)*2 SetScrollBarMax(#HScrollBar,32*MapWidth-PW/2) SetGadgetState(#VScrollBar,0) PH=GetScrollBarPage(#VScrollBar)*2 SetScrollBarMax(#VScrollBar,32*MapHeight-PH/2) ;free up all memory used by current units ResetList(RefUnit()) While NextElement( RefUnit()) If RefUnit()\IsActive=0 For P=0 To 79 If IsImage(RefUnit()\Picture[P]) FreeImage(RefUnit()\Picture[P]) EndIf Next P For P=0 To 99 If IsImage(RefUnit()\Tiles[P]) FreeImage(RefUnit()\Tiles[P]) EndIf Next P ;sound (Weapons use only Com/Des/Att) WrapFreeMem(RefUnit()\SelSound) WrapFreeMem(RefUnit()\DefSound) WrapFreeMem(RefUnit()\ComSound) WrapFreeMem(RefUnit()\CapSound) WrapFreeMem(RefUnit()\DesSound) WrapFreeMem(RefUnit()\AMOSound) WrapFreeMem(RefUnit()\OPPSound) WrapFreeMem(RefUnit()\FulSound) WrapFreeMem(RefUnit()\AttSound) Else WrapFreeSound(RefUnit()\SelSound) WrapFreeSound(RefUnit()\DefSound) WrapFreeSound(RefUnit()\ComSound) WrapFreeSound(RefUnit()\CapSound) WrapFreeSound(RefUnit()\DesSound) WrapFreeSound(RefUnit()\AMOSound) WrapFreeSound(RefUnit()\OPPSound) WrapFreeSound(RefUnit()\FulSound) WrapFreeSound(RefUnit()\AttSound) EndIf Wend ;now load all RefUnits .... ClearList(RefUnit()) EndProcedure Procedure.l SaveMapFile(FN.s) F.l=CreateFile(#PB_Any,FN) If F ;map version data WriteLong(F,0) ;map size data WriteLong(F,MapWidth) WriteLong(F,MapHeight) MS.l=SizeOf(MapStruct) WriteLong(F,MS) ;first, save the map tile image ;this requires the tileimage to be rebuilt MapImage.l=CreateImage(#PB_Any,8*32,12*32) StartDrawing(ImageOutput(MapImage)) For y=0 To 11 For x=0 To 7 DrawImage(ImageID(Tile(x,y)\TileImage),x*32,y*32) Next x Next y ;now copy image to file For y=0 To (12*32)-1 For x=0 To (8*32)-1 C.l=Point(x,y) WriteLong(F,C) Next x Next y StopDrawing() FreeImage(MapImage) ;now copy map data For y=0 To MapHeight For x=0 To MapWidth WriteData(F,@MapTile(x,y),MS) Next x Next y ;now copy all RefUnits .... If ListIndex(RefUnit())>=0 *CE.UnitStruct=@RefUnit() Else *CE=0 EndIf ResetList(RefUnit()) While NextElement(RefUnit()) ;in game status information ;position WriteLong(F,RefUnit()\X) WriteLong(F,RefUnit()\Y) WriteLong(F,RefUnit()\Face) ;start with basic data first ;summary for Resource/Building/Unit WriteLong(F,RefUnit()\ReqLevel) *RU.UnitStruct=RefUnit()\AReqUID X.l=0 ARU2X(*RU,X) WriteLong(F,X) ;UID is a Unique ID of this structure. Based on creation time ;or via index values at time of loading ;UID.l WriteStringN(F,RefUnit()\Name) WriteLong(F,RefUnit()\Panel) WriteLong(F,RefUnit()\Sort) WriteLong(F,RefUnit()\Type) WriteLong(F,RefUnit()\Building) WriteLong(F,RefUnit()\IsActive) *RU=RefUnit()\UpgradeToUID ARU2X(*RU,X) WriteLong(F,X) ;AU2UID is address to UpGradeToUID ;AU2UID.l WriteLong(F,RefUnit()\NextLevel) WriteLong(F,RefUnit()\UpgradeT1) WriteLong(F,RefUnit()\UpgradeT2) WriteLong(F,RefUnit()\UpgradeALL) ;stats for Resources/Buildings/Units ;For weapons, these are mods to basic settings .... of target WriteLong(F,RefUnit()\Armor) WriteLong(F,RefUnit()\PArmor) WriteLong(F,RefUnit()\Health) WriteLong(F,RefUnit()\PHealth) WriteLong(F,RefUnit()\Speed) WriteLong(F,RefUnit()\TileFlag) ;WedID is address of weapon struct (or UID ref during load/save) ;Ammo is ammount of ammo, type is stored with weapon .... *RU=RefUnit()\WepID[0] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\WepID[1] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\WepID[2] ARU2X(*RU,X) WriteLong(F,X) WriteLong(F,RefUnit()\Ammo[0]) WriteLong(F,RefUnit()\Ammo[1]) WriteLong(F,RefUnit()\Ammo[2]) WriteLong(F,RefUnit()\TotalCargo) WriteLong(F,RefUnit()\Fuel) ;Wep Mods WriteLong(F,RefUnit()\MinRange) WriteLong(F,RefUnit()\MaxRange) WriteLong(F,RefUnit()\Area) WriteLong(F,RefUnit()\Homing) WriteLong(F,RefUnit()\Aim) WriteLong(F,RefUnit()\Rate) WriteLong(F,RefUnit()\Dammage) ;AI WriteLong(F,RefUnit()\ASave) WriteLong(F,RefUnit()\Bravery) WriteLong(F,RefUnit()\Scary) WriteLong(F,RefUnit()\Quiet) WriteLong(F,RefUnit()\SeeFar) ;cargo ;TotalCargo ;CarryType is address of structure *RU=RefUnit()\CarryType[0] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CarryType[1] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CarryType[2] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CarryType[3] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CarryType[4] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CarryType[5] ARU2X(*RU,X) WriteLong(F,X) WriteLong(F,RefUnit()\CarryQTY[0]) WriteLong(F,RefUnit()\CarryQTY[1]) WriteLong(F,RefUnit()\CarryQTY[2]) WriteLong(F,RefUnit()\CarryQTY[3]) WriteLong(F,RefUnit()\CarryQTY[4]) WriteLong(F,RefUnit()\CarryQTY[5]) ;other last minute thingies (see weaponsDLG) WriteLong(F,RefUnit()\Visible) WriteLong(F,RefUnit()\FFire) WriteLong(F,RefUnit()\TSelf) WriteLong(F,RefUnit()\DLine) WriteLong(F,RefUnit()\CLine) ;TColor.l WriteLong(F,RefUnit()\UTColor) WriteLong(F,RefUnit()\Duration) WriteLong(F,RefUnit()\Redo) WriteLong(F,RefUnit()\ETemp) WriteLong(F,RefUnit()\CTeam) WriteLong(F,RefUnit()\CType) WriteLong(F,RefUnit()\Teleport) WriteLong(F,RefUnit()\Neutral) WriteLong(F,RefUnit()\Stuned) WriteLong(F,RefUnit()\Scared) WriteLong(F,RefUnit()\IsBrave) WriteLong(F,RefUnit()\VChange) WriteLong(F,RefUnit()\CSpeed) WriteLong(F,RefUnit()\CHeight) WriteLong(F,RefUnit()\LClear) WriteLong(F,RefUnit()\DelMove) WriteLong(F,RefUnit()\AddMove) *RU=RefUnit()\CostRID[0] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CostRID[1] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CostRID[2] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CostRID[3] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\CostRID[4] ARU2X(*RU,X) WriteLong(F,X) WriteLong(F,RefUnit()\CostQTY[0]) WriteLong(F,RefUnit()\CostQTY[1]) WriteLong(F,RefUnit()\CostQTY[2]) WriteLong(F,RefUnit()\CostQTY[3]) WriteLong(F,RefUnit()\CostQTY[4]) WriteLong(F,RefUnit()\CostTime) ;maint RID is address to resource struct *RU=RefUnit()\MaintRID[0] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\MaintRID[1] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\MaintRID[2] ARU2X(*RU,X) WriteLong(F,X) *RU=RefUnit()\MaintRID[3] ARU2X(*RU,X) WriteLong(F,X) WriteLong(F,RefUnit()\MaintQTY[0]) WriteLong(F,RefUnit()\MaintQTY[1]) WriteLong(F,RefUnit()\MaintQTY[2]) WriteLong(F,RefUnit()\MaintQTY[3]) WriteLong(F,RefUnit()\MaintTime) WriteLong(F,RefUnit()\MaintWorkers) *RU=RefUnit()\MakeRID ARU2X(*RU,X) WriteLong(F,X) WriteLong(F,RefUnit()\MakeQTY) If RefUnit()\IsActive=0 ;only save image information for inactive units ;Active units use refunits data to save space ;Image information WriteLong(F,RefUnit()\PlayerColor) WriteLong(F,RefUnit()\TColor) WriteLong(F,RefUnit()\Width) WriteLong(F,RefUnit()\Height) WriteLong(F,RefUnit()\FrameTime) WriteLong(F,RefUnit()\TotalFrames) ;4 sides for buildings, 5 build states ;5 damage states ;10 frames of animations(max) when finished ;4x20=80 ;Picture.l[80] For P=0 To 79 If IsImage(RefUnit()\Picture[P]) w.l=ImageWidth(RefUnit()\Picture[P])-1 h.l=ImageHeight(RefUnit()\Picture[P])-1 WriteLong(F,w) WriteLong(F,h) StartDrawing(ImageOutput(RefUnit()\Picture[P])) For x.l=0 To w For y.l=0 To h C.l=Point(x,y) WriteLong(F,C) Next y Next x StopDrawing() Else WriteLong(F,0) WriteLong(F,0) EndIf Next P ;10x10=100 ;Tiles.l[100] ;for Units and Weapons ;8 directions of 10 animations (so, use Tiles) for Unit images ;5 frames of animations for "normal" and 5 for "damaged" ;cost RID is address to resource struct (except for storage, then its an UID) For P=0 To 99 If IsImage(RefUnit()\Tiles[P]) w.l=ImageWidth(RefUnit()\Tiles[P])-1 h.l=ImageHeight(RefUnit()\Tiles[P])-1 WriteLong(F,w) WriteLong(F,h) StartDrawing(ImageOutput(RefUnit()\Tiles[P])) For x.l=0 To w For y.l=0 To h C.l=Point(x,y) WriteLong(F,C) Next y Next x StopDrawing() Else WriteLong(F,0) WriteLong(F,0) EndIf Next P ;sound (Weapons use only Com/Des/Att) Mem2File(RefUnit()\SelSound,F) Mem2File(RefUnit()\DefSound,F) Mem2File(RefUnit()\ComSound,F) Mem2File(RefUnit()\CapSound,F) Mem2File(RefUnit()\DesSound,F) Mem2File(RefUnit()\AMOSound,F) Mem2File(RefUnit()\OPPSound,F) Mem2File(RefUnit()\FulSound,F) Mem2File(RefUnit()\AttSound,F) EndIf Wend If *CE ChangeCurrentElement(RefUnit(),*CE) Else ResetList(RefUnit()) EndIf CloseFile(F) ProcedureReturn #True Else ProcedureReturn 0 EndIf EndProcedure Procedure.l OpenMapFile(FN.s) F.l=OpenFile(#PB_Any,FN) If F ;map version data MapVersion.l=ReadLong(F) ;map size data MapWidth=ReadLong(F) MapHeight=ReadLong(F) ;and reset the scrollbars SetGadgetState(#HScrollBar,0) PW=GetScrollBarPage(#HScrollBar)*2 SetScrollBarMax(#HScrollBar,32*MapWidth-PW/2) SetGadgetState(#VScrollBar,0) PH=GetScrollBarPage(#VScrollBar)*2 SetScrollBarMax(#VScrollBar,32*MapHeight-PH/2) MSO.l=SizeOf(MapStruct) MS=ReadLong(F) If MS<>MSO CloseFile(F) MessageRequester("RTS Maker - Error","Invalid Structure Size Detected",#MB_ICONSTOP) ProcedureReturn 0 EndIf ;first, save the map tile image ;this requires the tileimage to be rebuilt MapImage.l=CreateImage(#PB_Any,8*32,12*32) StartDrawing(ImageOutput(MapImage)) ;now copy image from file For y=0 To (12*32)-1 For x=0 To (8*32)-1 C.l=ReadLong(F) Plot(x,y,C) Next x Next y StopDrawing() ;break up the image For y=0 To 11 For x=0 To 7 ;DrawImage(ImageID(Tile(x,y)\TileImage),x*32,y*32) If IsImage(Tile(x,y)\TileImage) FreeImage(Tile(x,y)\TileImage) EndIf Tile(x,y)\TileImage=GrabImage(MapImage,#PB_Any,x*32,y*32,32,32) Next x Next y FreeImage(MapImage) ;now copy map data Dim MapTile.MapStruct(MapWidth,MapHeight) For y=0 To MapHeight For x=0 To MapWidth ReadData(F,@MapTile(x,y),MS) TC=MapTile(X,Y)\TileImage\TileCount MapTile(X,Y)\TileImage\TileImage=Tile(TileIndex(TC)\X,TileIndex(TC)\Y)\TileImage Next x Next y ;free up all memory used by current units ResetList(RefUnit()) While NextElement( RefUnit()) If RefUnit()\IsActive=0 For P=0 To 79 If IsImage(RefUnit()\Picture[P]) FreeImage(RefUnit()\Picture[P]) EndIf Next P For P=0 To 99 If IsImage(RefUnit()\Tiles[P]) FreeImage(RefUnit()\Tiles[P]) EndIf Next P ;sound (Weapons use only Com/Des/Att) WrapFreeMem(RefUnit()\SelSound) WrapFreeMem(RefUnit()\DefSound) WrapFreeMem(RefUnit()\ComSound) WrapFreeMem(RefUnit()\CapSound) WrapFreeMem(RefUnit()\DesSound) WrapFreeMem(RefUnit()\AMOSound) WrapFreeMem(RefUnit()\OPPSound) WrapFreeMem(RefUnit()\FulSound) WrapFreeMem(RefUnit()\AttSound) Else WrapFreeSound(RefUnit()\SelSound) WrapFreeSound(RefUnit()\DefSound) WrapFreeSound(RefUnit()\ComSound) WrapFreeSound(RefUnit()\CapSound) WrapFreeSound(RefUnit()\DesSound) WrapFreeSound(RefUnit()\AMOSound) WrapFreeSound(RefUnit()\OPPSound) WrapFreeSound(RefUnit()\FulSound) WrapFreeSound(RefUnit()\AttSound) EndIf Wend ;now load all RefUnits .... ClearList(RefUnit()) While Eof(F)=0 AddElement(RefUnit()) ;in game status information ;position RefUnit()\X=ReadLong(F) RefUnit()\Y=ReadLong(F) RefUnit()\Face=ReadLong(F) ;start with basic data first ;summary for Resource/Building/Unit RefUnit()\ReqLevel=ReadLong(F) RefUnit()\AReqUID=ReadLong(F) ;UID is a Unique ID of this structure. Based on creation time ;or via index values at time of loading ;UID.l RefUnit()\Name=ReadString(F) RefUnit()\Panel=ReadLong(F) RefUnit()\Sort=ReadLong(F) RefUnit()\Type=ReadLong(F) RefUnit()\Building=ReadLong(F) RefUnit()\IsActive=ReadLong(F) RefUnit()\UpgradeToUID=ReadLong(F) ;AU2UID is address to UpGradeToUID ;AU2UID.l RefUnit()\NextLevel=ReadLong(F) RefUnit()\UpgradeT1=ReadLong(F) RefUnit()\UpgradeT2=ReadLong(F) RefUnit()\UpgradeALL=ReadLong(F) ;stats for Resources/Buildings/Units ;For weapons, these are mods to basic settings .... of target RefUnit()\Armor=ReadLong(F) RefUnit()\PArmor=ReadLong(F) RefUnit()\Health=ReadLong(F) RefUnit()\PHealth=ReadLong(F) RefUnit()\Speed=ReadLong(F) RefUnit()\TileFlag=ReadLong(F) ;WedID is address of weapon struct (or UID ref during load/save) ;Ammo is ammount of ammo, type is stored with weapon .... RefUnit()\WepID[0]=ReadLong(F) RefUnit()\WepID[1]=ReadLong(F) RefUnit()\WepID[2]=ReadLong(F) RefUnit()\Ammo[0]=ReadLong(F) RefUnit()\Ammo[1]=ReadLong(F) RefUnit()\Ammo[2]=ReadLong(F) RefUnit()\TotalCargo=ReadLong(F) RefUnit()\Fuel=ReadLong(F) ;Wep Mods RefUnit()\MinRange=ReadLong(F) RefUnit()\MaxRange=ReadLong(F) RefUnit()\Area=ReadLong(F) RefUnit()\Homing=ReadLong(F) RefUnit()\Aim=ReadLong(F) RefUnit()\Rate=ReadLong(F) RefUnit()\Dammage=ReadLong(F) ;AI RefUnit()\ASave=ReadLong(F) RefUnit()\Bravery=ReadLong(F) RefUnit()\Scary=ReadLong(F) RefUnit()\Quiet=ReadLong(F) RefUnit()\SeeFar=ReadLong(F) ;cargo ;TotalCargo ;CarryType is address of structure RefUnit()\CarryType[0]=ReadLong(F) RefUnit()\CarryType[1]=ReadLong(F) RefUnit()\CarryType[2]=ReadLong(F) RefUnit()\CarryType[3]=ReadLong(F) RefUnit()\CarryType[4]=ReadLong(F) RefUnit()\CarryType[5]=ReadLong(F) RefUnit()\CarryQTY[0]=ReadLong(F) RefUnit()\CarryQTY[1]=ReadLong(F) RefUnit()\CarryQTY[2]=ReadLong(F) RefUnit()\CarryQTY[3]=ReadLong(F) RefUnit()\CarryQTY[4]=ReadLong(F) RefUnit()\CarryQTY[5]=ReadLong(F) ;other last minute thingies (see weaponsDLG) RefUnit()\Visible=ReadLong(F) RefUnit()\FFire=ReadLong(F) RefUnit()\TSelf=ReadLong(F) RefUnit()\DLine=ReadLong(F) RefUnit()\CLine=ReadLong(F) ;TColor.l RefUnit()\UTColor=ReadLong(F) RefUnit()\Duration=ReadLong(F) RefUnit()\Redo=ReadLong(F) RefUnit()\ETemp=ReadLong(F) RefUnit()\CTeam=ReadLong(F) RefUnit()\CType=ReadLong(F) RefUnit()\Teleport=ReadLong(F) RefUnit()\Neutral=ReadLong(F) RefUnit()\Stuned=ReadLong(F) RefUnit()\Scared=ReadLong(F) RefUnit()\IsBrave=ReadLong(F) RefUnit()\VChange=ReadLong(F) RefUnit()\CSpeed=ReadLong(F) RefUnit()\CHeight=ReadLong(F) RefUnit()\LClear=ReadLong(F) RefUnit()\DelMove=ReadLong(F) RefUnit()\AddMove=ReadLong(F) RefUnit()\CostRID[0]=ReadLong(F) RefUnit()\CostRID[1]=ReadLong(F) RefUnit()\CostRID[2]=ReadLong(F) RefUnit()\CostRID[3]=ReadLong(F) RefUnit()\CostRID[4]=ReadLong(F) RefUnit()\CostQTY[0]=ReadLong(F) RefUnit()\CostQTY[1]=ReadLong(F) RefUnit()\CostQTY[2]=ReadLong(F) RefUnit()\CostQTY[3]=ReadLong(F) RefUnit()\CostQTY[4]=ReadLong(F) RefUnit()\CostTime=ReadLong(F) ;maint RID is address to resource struct RefUnit()\MaintRID[0]=ReadLong(F) RefUnit()\MaintRID[1]=ReadLong(F) RefUnit()\MaintRID[2]=ReadLong(F) RefUnit()\MaintRID[3]=ReadLong(F) RefUnit()\MaintQTY[0]=ReadLong(F) RefUnit()\MaintQTY[1]=ReadLong(F) RefUnit()\MaintQTY[2]=ReadLong(F) RefUnit()\MaintQTY[3]=ReadLong(F) RefUnit()\MaintTime=ReadLong(F) RefUnit()\MaintWorkers=ReadLong(F) RefUnit()\MakeRID=ReadLong(F) RefUnit()\MakeQTY=ReadLong(F) If RefUnit()\IsActive=0 ;only save image information for inactive units ;Active units use refunits data to save space ;Image information RefUnit()\PlayerColor=ReadLong(F) RefUnit()\TColor=ReadLong(F) RefUnit()\Width=ReadLong(F) RefUnit()\Height=ReadLong(F) RefUnit()\FrameTime=ReadLong(F) RefUnit()\TotalFrames=ReadLong(F) For P=0 To 79 w.l=ReadLong(F) h.l=ReadLong(F) If w RefUnit()\Picture[P]=CreateImage(#PB_Any,w,h) StartDrawing(ImageOutput(RefUnit()\Picture[P])) For x.l=0 To w For y.l=0 To h C.l=ReadLong(F) Plot(x,y,C) Next y Next x StopDrawing() EndIf Next P For P=0 To 99 w.l=ReadLong(F) h.l=ReadLong(F) If w RefUnit()\Tiles[P]=CreateImage(#PB_Any,w,h) StartDrawing(ImageOutput(RefUnit()\Tiles[P])) For x.l=0 To w For y.l=0 To h C.l=ReadLong(F) Plot(x,y,C) Next y Next x StopDrawing() EndIf Next P ;sound (Weapons use only Com/Des/Att) File2Mem(f,RefUnit()\SelSound) File2Mem(f,RefUnit()\DefSound) File2Mem(f,RefUnit()\ComSound) File2Mem(f,RefUnit()\CapSound) File2Mem(f,RefUnit()\DesSound) File2Mem(f,RefUnit()\AMOSound) File2Mem(f,RefUnit()\OPPSound) File2Mem(f,RefUnit()\FulSound) File2Mem(f,RefUnit()\AttSound) EndIf Wend ;re-scan list ;and convert all index data to address data .... ResetList(RefUnit()) While NextElement(RefUnit()) X.l=RefUnit()\AReqUID X2ARU(X,*RU) RefUnit()\AReqUID=*RU X=RefUnit()\UpgradeToUID X2ARU(X,*RU) RefUnit()\UpgradeToUID=*RU ;WedID is address of weapon struct (or UID ref during load/save) ;Ammo is ammount of ammo, type is stored with weapon .... X=RefUnit()\WepID[0] X2ARU(X,*RU) RefUnit()\WepID[0]=*RU X=RefUnit()\WepID[1] X2ARU(X,*RU) RefUnit()\WepID[1]=*RU X=RefUnit()\WepID[2] X2ARU(X,*RU) RefUnit()\WepID[2]=*RU ;cargo ;TotalCargo ;CarryType is address of structure X=RefUnit()\CarryType[0] X2ARU(X,*RU) RefUnit()\CarryType[0]=*RU X=RefUnit()\CarryType[1] X2ARU(X,*RU) RefUnit()\CarryType[1]=*RU X=RefUnit()\CarryType[2] X2ARU(X,*RU) RefUnit()\CarryType[2]=*RU X=RefUnit()\CarryType[3] X2ARU(X,*RU) RefUnit()\CarryType[3]=*RU X=RefUnit()\CarryType[4] X2ARU(X,*RU) RefUnit()\CarryType[4]=*RU X=RefUnit()\CarryType[5] X2ARU(X,*RU) RefUnit()\CarryType[5]=*RU X=RefUnit()\CostRID[0] X2ARU(X,*RU) RefUnit()\CostRID[0]=*RU X=RefUnit()\CostRID[1] X2ARU(X,*RU) RefUnit()\CostRID[1]=*RU X=RefUnit()\CostRID[2] X2ARU(X,*RU) RefUnit()\CostRID[2]=*RU X=RefUnit()\CostRID[3] X2ARU(X,*RU) RefUnit()\CostRID[3]=*RU X=RefUnit()\CostRID[4] X2ARU(X,*RU) RefUnit()\CostRID[4]=*RU X=RefUnit()\MaintRID[0] X2ARU(X,*RU) RefUnit()\MaintRID[0]=*RU X=RefUnit()\MaintRID[1] X2ARU(X,*RU) RefUnit()\MaintRID[1]=*RU X=RefUnit()\MaintRID[2] X2ARU(X,*RU) RefUnit()\MaintRID[2]=*RU X=RefUnit()\MaintRID[3] X2ARU(X,*RU) RefUnit()\MaintRID[3]=*RU X=RefUnit()\MakeRID X2ARU(X,*RU) RefUnit()\MakeRID=*RU Wend CloseFile(F) ProcedureReturn #True Else ProcedureReturn 0 EndIf EndProcedure Macro MapSavePrompt(AutoFlag) CompilerIf AutoFlag reply=#IDYES CompilerElse reply.l= MessageRequester("RTS Maker","Save Changes?",#MB_YESNOCANCEL | #MB_ICONQUESTION) CompilerEndIf If reply=#IDCANCEL Event=0 ElseIf reply=#IDYES If FN If CheckFilename(GetFilePart(FN))=0 FN="" OverWrite=1 EndIf EndIf If FN If FileSize(FN) If OverWrite reply= MessageRequester("RTS Maker","Overwrite File"+Chr(10)+FN,#MB_YESNOCANCEL | #MB_ICONQUESTION) If reply=#IDCANCEL Event=0 ElseIf reply=#IDYES If SaveMapFile(FN)=0 MessageRequester("RTS Maker","Unable to save"+Chr(10)+FN,#MB_ICONSTOP) Event=0 Else OverWrite=0 IsDirty=0 EndIf EndIf Else If SaveMapFile(FN)=0 MessageRequester("RTS Maker","Unable to save"+Chr(10)+FN,#MB_ICONSTOP) Event=0 Else OverWrite=0 IsDirty=0 EndIf EndIf Else If SaveMapFile(FN)=0 MessageRequester("RTS Maker","Unable to save"+Chr(10)+FN,#MB_ICONSTOP) Event=0 Else OverWrite=0 IsDirty=0 EndIf EndIf Else FN=SaveFileRequester("Save RTS Maker Project",RunPath+"Untitled.rtm",#RTSPattern,0) If FN If SaveMapFile(FN)=0 MessageRequester("RTS Maker","Unable to save"+Chr(10)+FN,#MB_ICONSTOP) Event=0 Else IsDirty=0 OverWrite=0 EndIf Else OverWrite=1 Event=0 EndIf EndIf EndIf EndMacro Procedure.l MapCallback(hWnd, uMsg, wParam, lParam) ;this capures window messages for #Window_Map ;to handle map drawing context information If uMSG=#WM_MOUSEMOVE Or uMSG=#WM_LBUTTONDOWN mx=PeekW(@lParam) my=PeekW(@lParam+2) ;convert to tile (tx,ty) my+GetGadgetState(#VScrollBar)-ToolBarHeight(#StatusBar) mx+GetGadgetState(#HScrollBar) ty=my/32 tx=mx/32 If ty>MapHeight ProcedureReturn #PB_ProcessPureBasicEvents EndIf If tx>MapHeight ProcedureReturn #PB_ProcessPureBasicEvents EndIf If wParam & #MK_LBUTTON StatusBarText(#StatusBar,#Status_X,"X "+Str(tx)) StatusBarText(#StatusBar,#Status_Y,"Y "+Str(ty)) H=MapTile(tx,ty)\TileHeight\MatchTL+MapTile(tx,ty)\TileHeight\MatchTR H=H+MapTile(tx,ty)\TileHeight\MatchBL+MapTile(tx,ty)\TileHeight\MatchBR H=H/4 StatusBarText(#StatusBar,#Status_Height,Str(H)) TT.l=0 If BrushType=0 ;just info on selected tile StatusBarText(#StatusBar,#Status_Object,"Select") StatusBarText(#StatusBar,#Status_Value,"TC "+Str(MapTile(tx,ty)\TileImage\TileCount)) ElseIf BrushType<4 TT=BrushType EndIf DS=BrushDetail BH=BrushHeight If TT=1 BH=0 EndIf If TT IsDirty=1 If TT=1 DS=0 EndIf For MTX=tx-BrushSize To tx+BrushSize For MTY=ty-BrushSize To ty+BrushSize If MTX>=0 If MTY>=0 If MTX<=MapWidth If MTY<=MapHeight If DS=1 R=Random(10) If R=9 CopyStructA2B(Tile(2*(TT-1)+2,11),MapTile(mtx,mty)\TileImage,TileStruct) ElseIf R=10 CopyStructA2B(Tile(2*(TT-1)+3,11),MapTile(mtx,mty)\TileImage,TileStruct) Else CopyStructA2B(Tile(TT-1,0),MapTile(mtx,mty)\TileImage,TileStruct) EndIf ElseIf DS=2 If Random(1)=1 CopyStructA2B(Tile(2*(TT-1)+2,11),MapTile(mtx,mty)\TileImage,TileStruct) Else CopyStructA2B(Tile(2*(TT-1)+3,11),MapTile(mtx,mty)\TileImage,TileStruct) EndIf Else CopyStructA2B(Tile(TT-1,0),MapTile(mtx,mty)\TileImage,TileStruct) EndIf If BH>=0 MapTile(mtx,mty)\TileHeight\MatchTL=BH MapTile(mtx,mty)\TileHeight\MatchTR=BH MapTile(mtx,mty)\TileHeight\MatchBL=BH MapTile(mtx,mty)\TileHeight\MatchBR=BH EndIf EndIf EndIf EndIf EndIf Next MTY Next MTX ;and match area tiles DMC=BrushSize+1 ;top-Right corner AutoMap(DMC,-DMC, MapTile(tx+DMC,ty-DMC)\TileImage\MatchTL, MapTile(tx+DMC,ty-DMC)\TileImage\MatchTR, MapTile(tx,ty)\TileImage\MatchTR, MapTile(tx+DMC,ty-DMC)\TileImage\MatchBR) SetSpotHeight(tx+DMC,ty-DMC,MatchBL,BH) ;Top-Left Corner AutoMap(-DMC,-DMC,MapTile(tx-DMC,ty-DMC)\TileImage\MatchTL, MapTile(tx-DMC,ty-DMC)\TileImage\MatchTR, MapTile(tx-DMC,ty-DMC)\TileImage\MatchBL, MapTile(tx,ty)\TileImage\MatchTL) SetSpotHeight(tx-DMC,ty-DMC,MatchBR,BH) ;Bot-Left Corner AutoMap(-DMC,DMC, MapTile(tx-DMC,ty+DMC)\TileImage\MatchTL, MapTile(tx,ty)\TileImage\MatchBL, MapTile(tx-DMC,ty+DMC)\TileImage\MatchBL, MapTile(tx-DMC,ty+DMC)\TileImage\MatchBR) SetSpotHeight(tx-DMC,ty+DMC,MatchTR,BH) ;Bot-Right Corner AutoMap(DMC,DMC, MapTile(tx,ty)\TileImage\MatchBR, MapTile(tx+DMC,ty+DMC)\TileImage\MatchTR, MapTile(tx+DMC,ty+DMC)\TileImage\MatchBL, MapTile(tx+DMC,ty+DMC)\TileImage\MatchBR) SetSpotHeight(tx+DMC,ty+DMC,MatchTL,BH) ;Top/Bot Side For DX=-BrushSize To BrushSize AutoMap(DX,-DMC, MapTile(tx+DX,ty-DMC)\TileImage\MatchTL, MapTile(tx+DX,ty-DMC)\TileImage\MatchTR, MapTile(tx,ty)\TileImage\MatchTL, MapTile(tx,ty)\TileImage\MatchTR) SetSpotHeight(TX+DX,ty-DMC,MatchBL,BH) SetSpotHeight(TX+DX,ty-DMC,MatchBR,BH) AutoMap(DX,DMC, MapTile(tx+DX,ty)\TileImage\MatchBL, MapTile(tx+DX,ty)\TileImage\MatchBR, MapTile(tx+DX,ty+DMC)\TileImage\MatchBL, MapTile(tx+DX,ty+DMC)\TileImage\MatchBR) SetSpotHeight(TX+DX,ty+DMC,MatchTL,BH) SetSpotHeight(TX+DX,ty+DMC,MatchTR,BH) Next DX ;left/right side For DY=-BrushSize To BrushSize AutoMap(DMC,DY, MapTile(tx,ty)\TileImage\MatchTR, MapTile(tx+DMC,ty+DY)\TileImage\MatchTR, MapTile(tx,ty)\TileImage\MatchBR, MapTile(tx+DMC,ty+DY)\TileImage\MatchBR) SetSpotHeight(TX+DMC,ty+DY,MatchTL,BH) SetSpotHeight(TX+DMC,ty+DY,MatchBL,BH) AutoMap(-DMC,DY, MapTile(tx-DMC,ty+DY)\TileImage\MatchTL, MapTile(tx,ty)\TileImage\MatchTL, MapTile(tx-DMC,ty+DY)\TileImage\MatchBL, MapTile(tx,ty)\TileImage\MatchBL) SetSpotHeight(TX-DMC,ty+DY,MatchTR,BH) SetSpotHeight(TX-DMC,ty+DY,MatchBR,BH) Next DY EndIf PaintWindow(WindowImage) Else ;just moving the mouse around If BrushType>0 If BrushType<4 ;convert tx,ty to window x,y wx=tx*32-GetGadgetState(#HScrollBar) wy=ty*32-GetGadgetState(#VScrollBar)+ToolBarHeight(#StatusBar) If StartDrawing(WindowOutput(#Window_Map)) ;we just draw the windowimage DrawImage(ImageID(WindowImage),0,ToolBarHeight(#StatusBar)) SX=wx-32*(BrushSize+1)+16 SY=wy-32*(BrushSize+1)+16 W=64*(BrushSize+1) H=64*(BrushSize+1) If SX<0 W=W+SX SX=0 EndIf If (SX+W)>ImageWidth(WindowImage) W=ImageWidth(WindowImage)-SX ;SX=ImageWidth(WindowImage)-W EndIf If SYImageHeight(WindowImage)+ToolBarHeight(#StatusBar) H=ImageHeight(WindowImage)+ToolBarHeight(#StatusBar)-SY ;SY=ImageHeight(WindowImage)-H EndIf EmptyBox(SX,SY,w,h,0) StopDrawing() EndIf EndIf EndIf EndIf EndIf ProcedureReturn #PB_ProcessPureBasicEvents EndProcedure Procedure AddMyMenu(MenuTab.l,MenuName.s,MenuUID.l,MenuData.l=0) ;This adds a new Menu and Updates the MenuStruct hMenu.l=MenuID(#MenuBar) hSub.l=GetSubMenu_(hMenu,MenuTab) AddFlag.l=#True MenuPOS.l=0 If MenuUID=0 ;locate an ID to reuse LastUID.l=0 ResetList(MyMenu()) While NextElement(MyMenu()) If MyMenu()\MenuUID>LastUID LastUID=MyMenu()\MenuUID EndIf If MyMenu()\MenuPOS=0 MenuUID=MyMenu()\MenuUID AddFlag=#False Break Else ;see if we can use the "Empty" menu option If MyMenu()\MenuTab=MenuTab If MyMenu()\MenuName="Empty" MenuPOS=MyMenu()\MenuPOS MenuUID=MyMenu()\MenuUID AddFlag=#False EndIf EndIf EndIf Wend Else ;verify menuUID exists ResetList(MyMenu()) While NextElement(MyMenu()) If MyMenu()\MenuUID=MenuUID MenuPOS=MyMenu()\MenuPOS AddFlag=#False Break EndIf Wend EndIf If AddFlag AddElement(MyMenu()) If MenuUID=0 MenuUID=LastUID + 1 EndIf EndIf If MenuPOS ;menu exists, we just need to rename it SetMenuItemText(#MenuBar,MenuUID,MenuName) ;MenuPos.l=MyMenu()\MenuPOS Else MenuPos=CountMenu(MenuTab)+1 AppendMenu_(hSub,#MF_STRING,MenuUID,MenuName) EndIf MyMenu()\MenuTab=MenuTab MyMenu()\MenuName=MenuName MyMenu()\MenuUID=MenuUID MyMenu()\MenuPOS=MenuPOS MyMenu()\MenuData=MenuData EndProcedure Procedure ClearCurrentMenu() If MyMenu()\MenuUID<#HELP_ABOUT ;this menu does not get deleted, ;only renamed SetMenuItemText(#MenuBar,MyMenu()\MenuUID,"Empty") MyMenu()\MenuName="Empty" MyMenu()\MenuData=0 Else ;delete the menu hMenu.l=MenuID(#MenuBar) hSub.l=GetSubMenu_(hMenu,MenuTab) DeleteMenu_(hSub2,MyMenu()\MenuPos,#MF_BYPOSITION ) ;mark this ID number as available for re-use MyMenu()\MenuData=0 MyMenu()\MenuPos=0 MyMenu()\MenuTab=0 ;shift this structure to the last position *This=@MyMenu() LastElement(MyMenu()) *Last=@MyMenu() SwapElements(MyMenu(),*This,*Last) ;re-order the position data of those that are left ResetList(MyMenu()) While NextElement(MyMenu()) If MyMenu()\MenuTab=MenuTab If MyMenu()\MenuPos>MenuPOS MyMenu()\MenuPOS -1 EndIf EndIf Wend EndIf EndProcedure Procedure ClearMenu(MenuTab.l,MenuPOS.l) ;this deletes the menu item, ;but reserves space so the menu UID can be reused later ResetList(MyMenu()) While NextElement(MyMenu()) If MyMenu()\MenuTab=MenuTab If MyMenu()\MenuPOS=MenuPOS ClearCurrentMenu() Break EndIf EndIf Wend EndProcedure Procedure ZapMyMenu(MenuTab.l) ;this deletes the entire menu and the structure that talks about the menu hMenu.l=MenuID(#MenuBar) hSub.l=GetSubMenu_(hMenu,MenuTab) LastElement(MyMenu()) While ValidIndex( MyMenu() ) If MyMenu()\MenuTab=MenuTab DeleteMenu_(hSub2,MyMenu()\MenuPos,#MF_BYPOSITION ) DeleteElement(MyMenu()) EndIf PreviousElement(MyMenu()) Wend EndProcedure Procedure ZapResourceMenu() ZapMyMenu(4) AddMyMenu(4,"Empty",#GOLD_EMPTY) EndProcedure Procedure ZapBuildingMenu() ZapMyMenu(6) AddMyMenu(6,"Empty",#HOUSE_EMPTY) EndProcedure Procedure ZapUnitMenu() ZapMyMenu(7) AddMyMenu(7,"Empty",#UNIT_EMPTY) EndProcedure Procedure ZapAllMenus() ZapResourceMenu() ZapBuildingMenu() ZapUnitMenu() EndProcedure Procedure.l CountMenu(MenuTab.l) ;this counts the menu elements in the structure ;if adding a new menu, use this value, +1 for the next position ResetList(MyMenu()) C.l=0 While NextElement(MyMenu()) If MyMenu()\MenuTab=MenuTab C+1 EndIf Wend ProcedureReturn C EndProcedure Procedure AddUnitMenu() ;this takes a new unit and adds it to the existing menu system ;this procedure does not check if RefUnit() is valid ;but does perform checking on RefUnit() to ensure ;it is added where it should be ;start by determining the TAB location Select RefUnit()\Building Case #UnitType AddMyMenu(7,RefUnit()\Name,0,@RefUnit()) Case #BuildingType AddMyMenu(6,RefUnit()\Name,0,@RefUnit()) Case #ResourceType AddMyMenu(4,RefUnit()\Name,0,@RefUnit()) EndSelect EndProcedure Procedure DelUnitMenu() ;this takes an exiting RefUNit() ;locates the menu option ;deletes it from the menu ;this does not delete the RefUnit(), ;It is assumed that is done later because of the complexity ... see ZapThisUnit() in CBrowse.pb FindLinkList(MyMenu(),MyMenu()\MenuData=@RefUnit()) If ValidIndex(MyMenu()) ClearCurrentMenu() EndIf EndProcedure Procedure PrepPlaceUnit(MenuID.l) ;this takes a menu click ;finds the RefUNit() ;And sets up the editor to place the object Debug "PrepPlaceUnit selecting menu "+GetMenuItemText(#MenuBar,MenuID) FindLinkList(MyMenu(),MyMenu()\MenuUID=MenuID) If ValidIndex(MyMenu()) If MyMenu()\MenuData ChangeCurrentElement(RefUnit(),MyMenu()\MenuData) EndIf EndIf EndProcedure Procedure ShowEditor(FN.s) Open_Window_Map() If FN If OpenMapFile(FN)=0 MessageRequester("RTS Maker","Unable to open"+Chr(10)+FN,#MB_ICONSTOP) NewMapFile(0) Overwrite.l=1 Else OverWrite=0 EndIf Else NewMapFile(0) Overwrite=1 EndIf W.l=WindowWidth(#Window_Map)-GadgetWidth(#VScrollBar) H.l=WindowHeight(#Window_Map)-MenuHeight()-StatusBarHeight(#StatusBar)-GadgetHeight(#HScrollBar)-ToolBarHeight(#StatusBar) TBH.l=ToolBarHeight(#StatusBar) ;ExamineDesktops() ;MaxW.l=DesktopWidth(0) ;MaxH.l=DesktopHeight(0) ;this not working ;OpenWindowedScreen(WindowID(#Window_Map),0,0,MaxW,MaxH,0,0,0) ;so, we need to do our drawing manually .... SetGadgetState(#HScrollBar,0) SetGadgetState(#VScrollBar,0) SetScrollBarMax(#HScrollBar,MapWidth*32-W/2) SetScrollBarPage(#HScrollBar,W/2) SetScrollBarMax(#VScrollBar,MapHeight*32-H/2) SetScrollBarPage(#VScrollBar,H/2) WindowImage.l=CreateImage(#PB_Any,W,H) PaintWindow(WindowImage) SetWindowCallback(@MapCallBack(),#Window_Map) Repeat ; Start of the event loop Event = WaitWindowEvent(1000) ; This line waits until an event is received from Windows WindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures GadgetID = EventGadget() ; Is it a gadget event? EventType = EventType() ; The event type ;You can place code here, and use the result as parameters for the procedures If WindowID=#Window_Map If Event = #PB_Event_Menu ;- File Menu Events MenuID = EventMenu() Select MenuID Case #FILE_NEW HelpTip="#file" If IsDirty MapSavePrompt(0) EndIf If Event NewMapFile(1) FN="" IsDirty=0 OverWrite=1 PaintWindow(WindowImage) EndIf Case #FILE_OPEN HelpTip="#file" If IsDirty MapSavePrompt(0) EndIf If Event NFN.s=OpenFileRequester("RTS Maker - Open Existing Map",RunPath+"*.rtm",#RTSPattern,0) If NFN If OpenMapFile(NFN) IsDirty=0 OverWrite=0 FN=NFN PaintWindow(WindowIMage) Else MessageRequester("RTS Maker","Unable to open file "+Chr(10)+NFN,#MB_ICONSTOP) EndIf EndIf EndIf Case #FILE_SAVE HelpTip="#file" MapSavePrompt(1) Case #FILE_AS HelpTip="#file" NFN=FN FN="" MapSavePrompt(1) If Event=0 FN=NFN EndIf Case #FILE_MAKE HelpTip="#file" If IsDirty MapSavePrompt(1) EndIf Case #FILE_TEST HelpTip="#file" If IsDirty MapSavePrompt(1) EndIf Case #FILE_EXIT HelpTip="#file" Event = #PB_Event_CloseWindow If IsDirty MapSavePrompt(0) EndIf ;- Tile Menu Case #TILE_DELETE HelpTip="#units" MessageRequester("RTS Maker - Main","Delete Feature Not Available ") Case #TILE_SETTINGS HelpTip="#units" MessageRequester("RTS Maker - Main","Settings Feature Not Available ") Case #TILE_SELECT HelpTip="#texture" SetMenuItemState(#MENUBAR,#TILE_SELECT,1) SetMenuItemState(#MENUBAR,#TILE_WATER,0) SetMenuItemState(#MENUBAR,#TILE_GRASS,0) SetMenuItemState(#MENUBAR,#TILE_DIRT,0) ;and the toolbar SetToolBarButtonState(#StatusBar,#TILE_SELECT,1) SetToolBarButtonState(#StatusBar,#TILE_WATER,0) SetToolBarButtonState(#StatusBar,#TILE_GRASS,0) SetToolBarButtonState(#StatusBar,#TILE_DIRT,0) BrushType=0 Case #TILE_WATER HelpTip="#texture" SetMenuItemState(#MENUBAR,#TILE_SELECT,0) SetMenuItemState(#MENUBAR,#TILE_WATER,1) SetMenuItemState(#MENUBAR,#TILE_GRASS,0) SetMenuItemState(#MENUBAR,#TILE_DIRT,0) ;and the toolbar SetToolBarButtonState(#StatusBar,#TILE_SELECT,0) SetToolBarButtonState(#StatusBar,#TILE_WATER,1) SetToolBarButtonState(#StatusBar,#TILE_GRASS,0) SetToolBarButtonState(#StatusBar,#TILE_DIRT,0) BrushType=1 Case #TILE_GRASS HelpTip="#texture" SetMenuItemState(#MENUBAR,#TILE_SELECT,0) SetMenuItemState(#MENUBAR,#TILE_WATER,0) SetMenuItemState(#MENUBAR,#TILE_GRASS,1) SetMenuItemState(#MENUBAR,#TILE_DIRT,0) ;and the toolbar SetToolBarButtonState(#StatusBar,#TILE_SELECT,0) SetToolBarButtonState(#StatusBar,#TILE_WATER,0) SetToolBarButtonState(#StatusBar,#TILE_GRASS,1) SetToolBarButtonState(#StatusBar,#TILE_DIRT,0) BrushType=2 Case #TILE_DIRT HelpTip="#texture" SetMenuItemState(#MENUBAR,#TILE_SELECT,0) SetMenuItemState(#MENUBAR,#TILE_WATER,0) SetMenuItemState(#MENUBAR,#TILE_GRASS,0) SetMenuItemState(#MENUBAR,#TILE_DIRT,1) ;and the toolbar SetToolBarButtonState(#StatusBar,#TILE_SELECT,0) SetToolBarButtonState(#StatusBar,#TILE_WATER,0) SetToolBarButtonState(#StatusBar,#TILE_GRASS,0) SetToolBarButtonState(#StatusBar,#TILE_DIRT,1) BrushType=3 Case #TILE_LOAD HelpTip="#texture" IIF(MapTileSet="",NFN.s="*.bmp",NFN=MapTileSet) NFN=OpenFileRequester("RTS Maker - Select a tileset",RunPath+NFN,#BMPPattern,0) If NFN MapTileSet=NFN LoadTiles() PaintWindow(WindowImage) EndIf Case #TILE_NEW HelpTip="#texture" Open_Window_Blend(#Window_Map) LoadTiles() PaintWindow(WindowImage) ;- Brush Menu Case #BRUSH_SMALL HelpTip="#brush" SetMenuItemState(#MENUBAR,#BRUSH_SMALL,1) SetMenuItemState(#MENUBAR,#BRUSH_MED,0) SetMenuItemState(#MENUBAR,#BRUSH_BIG,0) SetToolBarButtonState(#StatusBar,#BRUSH_SMALL,1) SetToolBarButtonState(#StatusBar,#BRUSH_MED,0) SetToolBarButtonState(#StatusBar,#BRUSH_BIG,0) BrushSize=0 Case #BRUSH_MED HelpTip="#brush" SetMenuItemState(#MENUBAR,#BRUSH_SMALL,0) SetMenuItemState(#MENUBAR,#BRUSH_MED,1) SetMenuItemState(#MENUBAR,#BRUSH_BIG,0) SetToolBarButtonState(#StatusBar,#BRUSH_SMALL,0) SetToolBarButtonState(#StatusBar,#BRUSH_MED,1) SetToolBarButtonState(#StatusBar,#BRUSH_BIG,0) BrushSize=1 Case #BRUSH_BIG HelpTip="#brush" SetMenuItemState(#MENUBAR,#BRUSH_SMALL,0) SetMenuItemState(#MENUBAR,#BRUSH_MED,0) SetMenuItemState(#MENUBAR,#BRUSH_BIG,1) SetToolBarButtonState(#StatusBar,#BRUSH_SMALL,0) SetToolBarButtonState(#StatusBar,#BRUSH_MED,0) SetToolBarButtonState(#StatusBar,#BRUSH_BIG,1) BrushSize=2 Case #BRUSH_OFF HelpTip="#brush" SetMenuItemState(#MENUBAR,#BRUSH_OFF,1) SetMenuItemState(#MENUBAR,#BRUSH_ON,0) SetMenuItemState(#MENUBAR,#BRUSH_ALL,0) SetToolBarButtonState(#StatusBar,#BRUSH_OFF,1) SetToolBarButtonState(#StatusBar,#BRUSH_ON,0) SetToolBarButtonState(#StatusBar,#BRUSH_ALL,0) BrushDetail=0 Case #BRUSH_ON HelpTip="#brush" SetMenuItemState(#MENUBAR,#BRUSH_OFF,0) SetMenuItemState(#MENUBAR,#BRUSH_ON,1) SetMenuItemState(#MENUBAR,#BRUSH_ALL,0) SetToolBarButtonState(#StatusBar,#BRUSH_OFF,0) SetToolBarButtonState(#StatusBar,#BRUSH_ON,1) SetToolBarButtonState(#StatusBar,#BRUSH_ALL,0) BrushDetail=1 Case #BRUSH_ALL HelpTip="#brush" SetMenuItemState(#MENUBAR,#BRUSH_OFF,0) SetMenuItemState(#MENUBAR,#BRUSH_ON,0) SetMenuItemState(#MENUBAR,#BRUSH_ALL,1) SetToolBarButtonState(#StatusBar,#BRUSH_OFF,0) SetToolBarButtonState(#StatusBar,#BRUSH_ON,0) SetToolBarButtonState(#StatusBar,#BRUSH_ALL,1) BrushDetail=2 Case #HILL_AUTO HelpTip="#height" BrushHeight=-1 ;Debug "Forcing BrushHeight to -1 for AutoHeight" SetMenuItemState(#MENUBAR,#HILL_AUTO,1) For N.l=#HILL_AUTO+1 To #HILL_AUTO+10 SetMenuItemState(#MENUBAR,N,0) Next N ;- Resources delete,settings covered as Tile_ Case #GOLD_START HelpTip="#resource" ShowStartingDLG(#Window_Map) ;Case #GOLD_SETTINGS Case #GOLD_GOAL HelpTip="#resource" Case #GOLD_NEW HelpTip="#resource" Open_Window_Build(-2) Case #GOLD_MAN HelpTip="#resource" Open_Window_Browse(#ResourceType,#Window_Map) Case #GOLD_EMPTY HelpTip="#resource" PrepPlaceUnit(#GOLD_EMPTY) ;Case #PLAYER_1 ;- Buildings Case #HOUSE_NEW HelpTip="#buildings" Open_Window_Build(0) ;Case #HOUSE_SETTINGS Case #HOUSE_MAN HelpTip="#buildings" Open_Window_Browse(#BuildingType,#Window_Map) Case #HOUSE_EMPTY HelpTip="#buildings" PrepPlaceUnit(#HOUSE_EMPTY) ;- Units Case #UNIT_NEW HelpTip="#units" Open_Window_Build(-1) Case #UNIT_MAN HelpTip="#units" Open_Window_Browse(#UnitType,#Window_Map) ;Case #UNIT_SETTINGS Case #UNIT_EMPTY HelpTip="#units" PrepPlaceUnit(#UNIT_EMPTY) ;- Help Case #HELP_HELP GetHelp("#TOP") Case #HELP_TIPS GetHelp(HelpTip) Case #HELP_ABOUT AboutRTSM(#Window_Map) ;TestAbout(#Window_Map) ;- Custom Menu Default ;CallDebugger If MenuID<#Gold_Start ;Debug "Setting Hill to "+Str(MenuID-#Hill_Auto-1) HelpTip="#height" For N.l=#HILL_AUTO To #HILL_AUTO+10 If MenuID=N SetMenuItemState(#MENUBAR,N,1) BrushHeight=(N-#HILL_AUTO)-1 ;Debug "Setting "+GetMenuItemText(#MENUBAR,MenuID)+" Brushheight "+Str(BrushHeight) Else SetMenuItemState(#MENUBAR,N,0) EndIf Next N Else If MenuID<#House_New ;Debug "Selecting Player "+Str((MenuID+1)-#Player_1) HelpTip="#player" For N.l=#Player_1 To #Player_1+7 If MenuID=N SetMenuItemState(#MENUBAR,N,1) UsePlayer=N-#Player_1+1 Else SetMenuItemState(#MENUBAR,N,0) EndIf Next N Else ;selecting a resource,building, or unit HelpTip="#units" Debug "Unknown Menu "+Str(MenuID)+GetMenuItemText(#MenuBar,MenuID) PrepPlaceUnit(MenuID) EndIf EndIf EndSelect ElseIf Event = #PB_Event_Gadget ;- ScrollBar If GadgetID = #HScrollBar LeftRow=GetGadgetState(#HScrollBar) RightRow=LeftRow+GetScrollBarPage(#HScrollBar)*2 TX2=RightRow/32 If TX2>MapWidth TX2=MapWidth RightRow=TX2*32 LeftRow=RightRow-GetScrollBarPage(#HScrollBar)*2+32 SetGadgetState(#HScrollBar,LeftRow) SetScrollBarMax(#HScrollBar,LeftRow*32) EndIf PaintWindow(WindowImage) ElseIf GadgetID = #VScrollBar TopRow=GetGadgetState(#VScrollBar) BotRow=TopRow+GetScrollBarPage(#VScrollBar)*2 TY2=BotRow/32 If TY2>MapHeight TY2=MapHeight BotRow=TY2*32 TopRow=BotRow-GetScrollBarPage(#VScrollBar)*2+32 SetGadgetState(#VScrollBar,TopRow) SetScrollBarMax(#VScrollBar,TopRow*32) EndIf PaintWindow(WindowImage) EndIf ;- PB_Event_Repaint ElseIf event= #PB_Event_Repaint ;PaintWindow() ;mx=PeekW(@lParam) ;my=PeekW(@lParam+2) ;convert to tile (tx,ty) ;my=WindowMouseY(#Window_Map)+GetGadgetState(#VScrollBar)-ToolBarHeight(#StatusBar) ;mx=WindowMouseX(#Window_Map)+GetGadgetState(#HScrollBar) ;ty=my/32 ;tx=mx/32 ;wx=tx*32-GetGadgetState(#HScrollBar) ;wy=ty*32-GetGadgetState(#VScrollBar)+ToolBarHeight(#StatusBar) If IsImage(WindowImage) If StartDrawing(WindowOutput(#Window_Map)) ;we just draw the windowimage DrawImage(ImageID(WindowImage),0,TBH) ;If BrushType>0 ; If BrushType<4 ; EmptyBox(wx-32*(BrushSize+1),wy-32*(BrushSize+1),64*(BrushSize+1),64*(BrushSize+1),0) ; EndIf ;EndIf Box(GadgetX(#VScrollBar),GadgetY(#HScrollBar),GadgetWidth(#VScrollBar),GadgetHeight(#HScrollBar),RGB(200,200,200)) StopDrawing() EndIf EndIf ;- #PB_Event_SizeWindow ElseIf Event=#PB_Event_SizeWindow W.l=WindowWidth(#Window_Map)-GadgetWidth(#VScrollBar) H.l=WindowHeight(#Window_Map)-MenuHeight()-StatusBarHeight(#StatusBar)-GadgetHeight(#HScrollBar)-ToolBarHeight(#StatusBar) RS.l=0 If W>MapWidth*32 W=MapWidth*32 RS=1 EndIf If H>MapHeight*32 H=MapHeight*32 RS=1 EndIf If RS RW.l=W+GadgetWidth(#VScrollBar) RH.l=H+MenuHeight()-StatusBarHeight(#StatusBar)-GadgetHeight(#HScrollBar)-ToolBarHeight(#StatusBar) ResizeWindow(#Window_Map,#PB_Ignore,#PB_Ignore,RW,RH) EndIf ResizeGadget(#HScrollBar,0,H+ToolBarHeight(#StatusBar),W,#PB_Ignore) ResizeGadget(#VScrollBar,W,ToolBarHeight(#StatusBar),#PB_Ignore,H) SetScrollBarMax(#HScrollBar,MapWidth*32-W/2) SetScrollBarPage(#HScrollBar,W/2) SetScrollBarMax(#VScrollBar,MapHeight*32-H/2) SetScrollBarPage(#VScrollBar,H/2) If w>10 If H>10 ResizeImage(WindowImage,W,H) EndIf EndIf LeftRow=GetGadgetState(#HScrollBar) RightRow=LeftRow+GetScrollBarPage(#HScrollBar)*2 TX2=RightRow/32 If TX2>MapWidth TX2=MapWidth RightRow=TX2*32 LeftRow=RightRow-GetScrollBarPage(#HScrollBar)*2 SetGadgetState(#HScrollBar,LeftRow) EndIf TopRow=GetGadgetState(#VScrollBar) BotRow=TopRow+GetScrollBarPage(#VScrollBar)*2 TY2=BotRow/32 If TY2>MapHeight TY2=MapHeight BotRow=TY2*32 TopRow=BotRow-GetScrollBarPage(#VScrollBar)*2 SetGadgetState(#VScrollBar,TopRow) EndIf FullPaint.l=1 ;- PB_Event_CloseWindow ElseIf Event = #PB_Event_CloseWindow If IsDirty MapSavePrompt(0) EndIf Else If FullPaint PaintWindow(WindowImage) FullPaint=0 EndIf EndIf Else ;- event for other window EndIf ;- Window End Until Event = #PB_Event_CloseWindow ; End of the event loop ;CloseScreen() If INIOpen ClosePreferences() INIOpen=0 EndIf CloseWindow(#Window_Map) FreeImage(WindowImage) ;and terminate help, if open INIFile=HelpINI HelpWindow=INI_ReadInteger( "Helper", "Handle", 0 ) If HelpWindow If IsWindow_(HelpWindow) If IsWindow_(HelpWindow) SendMessage_(HelpWindow,#WM_CLOSE,0,0) EndIf EndIf EndIf EndProcedure ;- Test If InitSprite() = 0 Or InitPalette() = 0 Or InitKeyboard() = 0 MessageRequester("RTS Maker Error", "Can't open DirectX 7 or later", 0) End EndIf If InitSound() = 0 MessageRequester("RTS Maker Error", "Can't open DirectX 7 Or Sound Card is not present", 0) End EndIf ShowEditor("") DataSection BlankGWD: IncludeBinary "3textures.bmp" BasicGWD: IncludeBinary "wgd.bmp" EndData: EndDataSection