#=============================================================================== # Miniature game map drawing #=============================================================================== class MapSprite def initialize(map,viewport=nil) @sprite=Sprite.new(viewport) @sprite.bitmap=createMinimap(map) @sprite.x=(Graphics.width/2)-(@sprite.bitmap.width/2) @sprite.y=(Graphics.height/2)-(@sprite.bitmap.height/2) end def dispose @sprite.bitmap.dispose @sprite.dispose end def z=(value) @sprite.z=value end def getXY return nil if !Input.trigger?(Input::MOUSELEFT) mouse = Mouse::getMousePos(true) return nil if !mouse if mouse[0]<@sprite.x || mouse[0]>=@sprite.x+@sprite.bitmap.width return nil end if mouse[1]<@sprite.y || mouse[1]>=@sprite.y+@sprite.bitmap.height return nil end x = mouse[0]-@sprite.x y = mouse[1]-@sprite.y return [x/4,y/4] end end #=============================================================================== # #=============================================================================== class SelectionSprite < Sprite def initialize(viewport=nil) @sprite=Sprite.new(viewport) @sprite.bitmap=nil @sprite.z=2 @othersprite=nil end def disposed? return @sprite.disposed? end def dispose @sprite.bitmap.dispose if @sprite.bitmap @othersprite=nil @sprite.dispose end def othersprite=(value) @othersprite=value if @othersprite && !@othersprite.disposed? && @othersprite.bitmap && !@othersprite.bitmap.disposed? @sprite.bitmap=pbDoEnsureBitmap( @sprite.bitmap,@othersprite.bitmap.width,@othersprite.bitmap.height) red=Color.new(255,0,0) @sprite.bitmap.clear @sprite.bitmap.fill_rect(0,0,@othersprite.bitmap.width,2,red) @sprite.bitmap.fill_rect(0,@othersprite.bitmap.height-2, @othersprite.bitmap.width,2,red) @sprite.bitmap.fill_rect(0,0,2,@othersprite.bitmap.height,red) @sprite.bitmap.fill_rect(@othersprite.bitmap.width-2,0,2, @othersprite.bitmap.height,red) end end def update if @othersprite && !@othersprite.disposed? @sprite.visible=@othersprite.visible @sprite.x=@othersprite.x @sprite.y=@othersprite.y else @sprite.visible=false end end end #=============================================================================== # #=============================================================================== class RegionMapSprite def initialize(map,viewport=nil) @sprite=Sprite.new(viewport) @sprite.bitmap=createRegionMap(map) @sprite.x=(Graphics.width/2)-(@sprite.bitmap.width/2) @sprite.y=(Graphics.height/2)-(@sprite.bitmap.height/2) end def dispose @sprite.bitmap.dispose @sprite.dispose end def z=(value) @sprite.z=value end def createRegionMap(map) @mapdata = pbLoadTownMapData @map=@mapdata[map] bitmap=AnimatedBitmap.new("Graphics/Pictures/#{@map[1]}").deanimate retbitmap=BitmapWrapper.new(bitmap.width/2,bitmap.height/2) retbitmap.stretch_blt( Rect.new(0,0,bitmap.width/2,bitmap.height/2), bitmap, Rect.new(0,0,bitmap.width,bitmap.height) ) bitmap.dispose return retbitmap end def getXY return nil if !Input.trigger?(Input::MOUSELEFT) mouse=Mouse::getMousePos(true) return nil if !mouse if mouse[0]<@sprite.x||mouse[0]>=@sprite.x+@sprite.bitmap.width return nil end if mouse[1]<@sprite.y||mouse[1]>=@sprite.y+@sprite.bitmap.height return nil end x=mouse[0]-@sprite.x y=mouse[1]-@sprite.y return [x/8,y/8] end end #=============================================================================== # Visual Editor (map connections) #=============================================================================== class MapScreenScene def getMapSprite(id) if !@mapsprites[id] @mapsprites[id]=Sprite.new(@viewport) @mapsprites[id].z=0 @mapsprites[id].bitmap=nil end if !@mapsprites[id].bitmap || @mapsprites[id].bitmap.disposed? @mapsprites[id].bitmap=createMinimap(id) end return @mapsprites[id] end def close pbDisposeSpriteHash(@sprites) pbDisposeSpriteHash(@mapsprites) @viewport.dispose end def setMapSpritePos(id,x,y) sprite=getMapSprite(id) sprite.x=x sprite.y=y sprite.visible=true end def putNeighbors(id,sprites) conns=@mapconns mapsprite=getMapSprite(id) dispx=mapsprite.x dispy=mapsprite.y for conn in conns if conn[0]==id b=sprites.any? { |i| i==conn[3] } if !b x=(conn[1]-conn[4])*4+dispx y=(conn[2]-conn[5])*4+dispy setMapSpritePos(conn[3],x,y) sprites.push(conn[3]) putNeighbors(conn[3],sprites) end elsif conn[3]==id b=sprites.any? { |i| i==conn[0] } if !b x=(conn[4]-conn[1])*4+dispx y=(conn[5]-conn[2])*4+dispy setMapSpritePos(conn[0],x,y) sprites.push(conn[3]) putNeighbors(conn[0],sprites) end end end end def hasConnections?(conns,id) for conn in conns return true if conn[0]==id || conn[3]==id end return false end def connectionsSymmetric?(conn1,conn2) if conn1[0]==conn2[0] # Equality return false if conn1[1]!=conn2[1] return false if conn1[2]!=conn2[2] return false if conn1[3]!=conn2[3] return false if conn1[4]!=conn2[4] return false if conn1[5]!=conn2[5] return true elsif conn1[0]==conn2[3] # Symmetry return false if conn1[1]!=-conn2[1] return false if conn1[2]!=-conn2[2] return false if conn1[3]!=conn2[0] return false if conn1[4]!=-conn2[4] return false if conn1[5]!=-conn2[5] return true end return false end def removeOldConnections(ret,mapid) for i in 0...ret.length ret[i]=nil if ret[i][0]==mapid || ret[i][3]==mapid end ret.compact! end # Returns the maps within _keys_ that are directly connected to this map, _map_. def getDirectConnections(keys,map) thissprite=getMapSprite(map) thisdims=MapFactoryHelper.getMapDims(map) ret=[] for i in keys next if i==map othersprite=getMapSprite(i) otherdims=MapFactoryHelper.getMapDims(i) x1=(thissprite.x-othersprite.x)/4 y1=(thissprite.y-othersprite.y)/4 if (x1==otherdims[0] || x1==-thisdims[0] || y1==otherdims[1] || y1==-thisdims[1]) ret.push(i) end end # If no direct connections, add an indirect connection if ret.length==0 key=(map==keys[0]) ? keys[1] : keys[0] ret.push(key) end return ret end def generateConnectionData ret=[] # Create a clone of current map connection for conn in @mapconns ret.push(conn.clone) end keys=@mapsprites.keys return ret if keys.length<2 # Remove all connections containing any sprites on the canvas from the array for i in keys removeOldConnections(ret,i) end # Rebuild connections for i in keys refs=getDirectConnections(keys,i) for refmap in refs othersprite=getMapSprite(i) refsprite=getMapSprite(refmap) c1=(refsprite.x-othersprite.x)/4 c2=(refsprite.y-othersprite.y)/4 conn=[refmap,0,0,i,c1,c2] j=0 while j 0 end def onClick(mapid,x,y) if @lastclick>0 && Graphics.frame_count - @lastclick < Graphics.frame_rate * 0.5 onDoubleClick(mapid) @lastclick=-1 else @lastclick=Graphics.frame_count if mapid>=0 @dragging=true @dragmapid=mapid sprite=getMapSprite(mapid) @sprites["selsprite"].othersprite=sprite @selmapid=mapid @dragOffsetX=sprite.x-x @dragOffsetY=sprite.y-y setTopSprite(mapid) else @sprites["selsprite"].othersprite=nil @dragging=true @dragmapid=mapid @selmapid=-1 @dragOffsetX=x @dragOffsetY=y saveMapSpritePos end end end def onRightClick(mapid,x,y) # echo("rightclick (#{mapid})\r\n") end def onMouseUp(mapid) # echo("mouseup (#{mapid})\r\n") @dragging=false if @dragging end def onRightMouseUp(mapid) # echo("rightmouseup (#{mapid})\r\n") end def onMouseOver(mapid,x,y) # echo("mouseover (#{mapid},#{x},#{y})\r\n") end def onMouseMove(mapid,x,y) # echo("mousemove (#{mapid},#{x},#{y})\r\n") if @dragging if @dragmapid>=0 sprite=getMapSprite(@dragmapid) x=x+@dragOffsetX y=y+@dragOffsetY sprite.x=x&~3 sprite.y=y&~3 @sprites["title"].text=_ISPRINTF("D: Help [{1:03d}: {2:s}]",mapid,@mapinfos[@dragmapid].name) else xpos=x-@dragOffsetX ypos=y-@dragOffsetY for i in @mapspritepos.keys sprite=getMapSprite(i) sprite.x=(@mapspritepos[i][0]+xpos)&~3 sprite.y=(@mapspritepos[i][1]+ypos)&~3 end @sprites["title"].text=_INTL("D: Help") end else if mapid>=0 @sprites["title"].text=_ISPRINTF("D: Help [{1:03d}: {2:s}]",mapid,@mapinfos[mapid].name) else @sprites["title"].text=_INTL("D: Help") end end end def hittest(x,y) for i in @mapsprites.keys sx=@mapsprites[i].x sy=@mapsprites[i].y sr=sx+@mapsprites[i].bitmap.width sb=sy+@mapsprites[i].bitmap.height return i if x>=sx && x=sy && y0 addSprite(id) setTopSprite(id) @mapconns=generateConnectionData end elsif Input.triggerex?(:S) id=chooseMapScreen(_INTL("Go to Map"),@currentmap) if id>0 @mapconns=generateConnectionData pbDisposeSpriteHash(@mapsprites) @mapsprites.clear @sprites["selsprite"].othersprite=nil @selmapid=-1 putSprite(id) @currentmap=id end elsif Input.triggerex?(:DELETE) if @mapsprites.keys.length>1 && @selmapid>=0 @mapsprites[@selmapid].bitmap.dispose @mapsprites[@selmapid].dispose @mapsprites.delete(@selmapid) @sprites["selsprite"].othersprite=nil @selmapid=-1 end elsif Input.triggerex?(:D) helpWindow end pbUpdateSpriteHash(@sprites) end def pbMapScreenLoop loop do Graphics.update Input.update update if Input.trigger?(Input::B) if pbConfirmMessage(_INTL("Save changes?")) serializeConnectionData MapFactoryHelper.clear else GameData::Encounter.load end break if pbConfirmMessage(_INTL("Exit from the editor?")) end end end end #=============================================================================== # #=============================================================================== def pbConnectionsEditor pbCriticalCode { Graphics.resize_screen(Settings::SCREEN_WIDTH + 288, Settings::SCREEN_HEIGHT + 288) pbSetResizeFactor(1) mapscreen = MapScreenScene.new mapscreen.mapScreen mapscreen.pbMapScreenLoop mapscreen.close Graphics.resize_screen(Settings::SCREEN_WIDTH, Settings::SCREEN_HEIGHT) pbSetResizeFactor($PokemonSystem.screensize) } end