FL
Pokémon Island Creator
- 2,544
- Posts
- 14
- Years
- Seen yesterday
PokéCommunity is breaking codes. For copying scripts at PokéCommunity: Click Thread Tools, and then Show Printable Version, and copy that instead.
Code:
#===============================================================================
# * Scene Positioner - by FL with some Poccil scripts
#===============================================================================
#
# This script is for RPG Maker XP. This is a scripter tool for helping
# scripters making scenes.
#
# It allows reading sprites coordinates in a windows or at txt log and even
# changing sprites positions/visibility. It is compatible with Pokémon
# Essentials and Crazyninjaguy Mouse Script, you can even easily adapt
# other mouse scripts.
#
#===============================================================================
#
# To this script works, put it above main and below other scripts.
#
# At every scene that you wish it working, put the line
# '@scenePositioner = ScenePositioner.new(@sprites)' before update loop
# where '@sprites' is a hash with all sprites/windows that you wish that
# this script affect. Put the line '@scenePositioner.update' when you
# update the graphics and the input at the scene. After you dispose the
# sprites, put the line '@scenePositioner.destroy'. If you wish to
# display ox/oy/rotation when displaying coordinates, just use
# '@scenePositioner = ScenePositioner.new(@sprites,true)' instead of
# '@scenePositioner = ScenePositioner.new(@sprites)'.
#
# For obtaining the selected sprite coordinates, a list of all sprites that
# you moved, a control list and even printing these data in a txt file (except
# the control list), just press Q.
#
# For allowing pause button to pause the game, wrap every update lines,
# except 'Graphics.update', 'Input.update' and '@scenePositioner.update' at
# 'if [email protected]'.
#
# For making Crazyninjaguy script working at game that doesn't uses
# Pokémon Essentials, just put the line '$ResizeFactor=1' before line
# 'module Resolution'.
#
#===============================================================================
class ScenePositioner
attr_writer :paused # You can pause by your scripts too.
ONLYINDEBUG = true # If true, this script only works when $DEBUG == true
SPEED = 2 # Speed when moving sprites
class Border < Sprite
def initialize
super
@spriteBelow = nil
end
def update
super
if @spriteBelow && [email protected]?
[email protected] if [email protected]
[email protected] if [email protected]
createBitmap if !self.bitmap
end
finishBitmap if self.bitmap && (!@spriteBelow || !(
@spriteBelow.is_a?(Window) || @spriteBelow.bitmap))
end
BORDERSIZE = 2
def createBitmap # Draw the border bitmap
return if !(@spriteBelow.is_a?(Window) || @spriteBelow.bitmap)
if @spriteBelow.is_a?(Window)
spriteWidth = @spriteBelow.width
spriteHeight = @spriteBelow.height
else
spriteWidth = @spriteBelow.bitmap.width
spriteHeight = @spriteBelow.bitmap.height
end
self.bitmap=Bitmap.new(spriteWidth,spriteHeight)
borderColor = Color.new(240,0,0)
widthBelowSize = spriteWidth<BORDERSIZE
heightBelowSize = spriteHeight<BORDERSIZE
borderWidth = widthBelowSize ? spriteWidth : BORDERSIZE
borderHeight = heightBelowSize ? spriteHeight : BORDERSIZE
self.bitmap.fill_rect(Rect.new(0,0,spriteWidth,borderHeight), borderColor)
self.bitmap.fill_rect(Rect.new(0,spriteHeight-borderHeight,
spriteWidth,borderHeight), borderColor)
self.bitmap.fill_rect(Rect.new(0,0,borderWidth,spriteHeight), borderColor)
self.bitmap.fill_rect(Rect.new(spriteWidth-borderWidth,0,
borderWidth,spriteHeight), borderColor)
end
def finishBitmap
self.bitmap=nil
end
def setSpriteBelow(sprite)
@spriteBelow = sprite
self.z=9999998
createBitmap
end
end
def initialize(sprites, showOXOY=false)
if isActive?
@lastTone=nil # Used for storing the tone before select a sprite
@highlight = true
@paused=false
@spritesLog = {}
@spriteSelectedName=nil
@sprites=sprites
@mouseClickedStack = []
@showOXOY=showOXOY
@border=Border.new
end
end
def destroy
return if !isActive?
@border.dispose
@border = nil
end
def isActive?
return !ONLYINDEBUG || $DEBUG
end
def paused
@paused && isActive?
end
def update
return if !isActive?
@border.update
mouseClicked = mouseClicked?
move = false
axisX = 0
axisY = 0
if mouseClicked
lastMouseCoordinates = mouseCoordinates
# Pick the biggest Z at point, if already
# clicked, picks the second one and so on
mouseClickStack=[]
for spriteName in @sprites.keys
sprite=@sprites[spriteName]
if sprite && !sprite.is_a?(Plane) && spriteIsOnCoordinate(sprite,
lastMouseCoordinates[0],lastMouseCoordinates[1])
mouseClickStack.push(spriteName)
end
end
if !mouseClickStack.empty?
# Do a stack with Z value
mouseClickStack.sort!{|a,b|@sprites[b].z <=> @sprites[a].z}
found=false
for i in 0...mouseClickStack.size
# if something is different, just copy the entire stack before and
# add the different at last.
if (mouseClickStack[i]!=@mouseClickedStack[i] ||
[email protected])
@mouseClickedStack=mouseClickStack[0,i+1]
found=true
break
end
end
# If the stacks are equals, just start @mouseClickedStack again.
@mouseClickedStack=[mouseClickStack[0]] if !found
selectSprite(@mouseClickedStack[-1])
end
end
spinSelection = 0
if Input.triggerex?(0x46) # F # Go to the previous sprite
spinSelection = -1
end
if Input.triggerex?(0x47) # G # Go to the next sprite
spinSelection = 1
end
if spinSelection != 0
spriteNames = @sprites.keys
newIndex = spriteNames.index(@spriteSelectedName)
overflowCount = 0
overflow = false
if newIndex
loop do # Search a valid next
newIndex+=spinSelection
newIndex=0 if spinSelection==spriteNames.size
name = spriteNames[newIndex]
break if name && @sprites[name] && !@sprites[name].is_a?(Plane)
# Solving infinite loops
overflowCount+=1
if overflowCount>9000
overflow=true
break
end
end
else
newIndex = spinSelection==1 ? 0 : -1
end
selectSprite(spriteNames[newIndex]) if !overflow
end
if Input.repeatex?(0x57) # W
axisY=-1
move=true
end
if Input.repeatex?(0x53) # S
axisY=1
move=true
end
if Input.repeatex?(0x41) # A
axisX=-1
move=true
end
if Input.repeatex?(0x44) # D
axisX=1
move=true
end
@paused= !@paused if Input.triggerex?(0x45) # E # Pause
if Input.triggerex?(0x52) # R # Toggle highlight
selectedSprite = @sprites[@spriteSelectedName]
@highlight=!@highlight
highlightSelectedSprite(@highlight)
end
# T # Toggle sprite visibility
@sprites[@spriteSelectedName].visible = !@sprites[@spriteSelectedName
].visible if Input.triggerex?(0x54) && @sprites[@spriteSelectedName]
if move
selectedSprite = @sprites[@spriteSelectedName]
if selectedSprite && (axisX != 0 || axisY!=0)
selectedSprite.x+= axisX*SPEED
selectedSprite.y+= axisY*SPEED
@spritesLog[@spriteSelectedName]=spriteData(@spriteSelectedName)
end
end
if Input.triggerex?(0x51) # Q
selectedText=spriteData(@spriteSelectedName)
helpText=%{WSAD - Move Sprite
FG - Switch between sprites
Q - Info
E - Pause
R - Toggle highlight
T - Toggle visible}
logText = ""
for log in @spritesLog.values
logText+=log+"\r\n"
end
print selectedText+"\r\n"+helpText+"\r\n"+logText
filename="ScenePositionerLog.txt"
formatedDate = (Time.new+98765432).strftime("%Y-%m-%d %I:%M:%S %p")
header = "##### #{formatedDate} #####"
File.open(filename,"ab"){|f|
f.write(header+"\r\n"+selectedText+"\r\n-\r\n"+logText)
}
end
end
def spriteIsOnCoordinate(sprite, x, y)
return false if !(sprite.is_a?(Window) || sprite.bitmap)
spriteWidth = 0
spriteHeight = 0
if sprite.is_a?(Window)
spriteWidth = sprite.width
spriteHeight = sprite.height
else
spriteWidth = sprite.bitmap.width
spriteHeight = sprite.bitmap.height
end
spriteX = sprite.x - sprite.ox
spriteY = sprite.y - sprite.oy
inXAxis = spriteX <= x && x < spriteX+spriteWidth
inYAxis = spriteY <= y && y < spriteY+spriteHeight
return inXAxis && inYAxis
end
def selectSprite(spriteName)
highlightSelectedSprite(false)
@spriteSelectedName = spriteName
@border.setSpriteBelow(@sprites[spriteName])
highlightSelectedSprite(true) if @highlight
end
def highlightSelectedSprite(activate)
if activate
spriteSelected = @sprites[@spriteSelectedName]
return if !spriteSelected
@lastTone = spriteSelected.tone.clone
spriteSelected.tone = Tone.new(
@lastTone.red+32,@lastTone.green,@lastTone.blue,@lastTone.gray)
elsif @lastTone
@sprites[@spriteSelectedName].tone = @lastTone
@lastTone = nil
end
@border.visible = activate
end
def spriteData(spriteName)
sprite = @sprites[spriteName]
ret=""
ret="#{spriteName} x=#{sprite.x} y=#{sprite.y} z=#{sprite.z}" if sprite
if @showOXOY && sprite
ret+=" ox=#{sprite.ox} oy=#{sprite.oy}"
ret+=" angle=#{sprite.angle}" if !sprite.is_a?(Window)
end
return ret
end
# Returns if this sprite have a bitmap or is a Windows.
# Used for know if the sprite have valid width and height
def hasSize(sprite)
return sprite.is_a?(Window) || sprite.bitmap
end
USEOTHERMOUSESCRIPT = false
if USEOTHERMOUSESCRIPT
# If you use another moude script, just change the USEOTHERMOUSESCRIPT to
# true and overload the two method below
def mouseClicked?
# must return true if mouse click. Otherside returns false
end
def mouseCoordinates
# must return two length aray with mouse X and Y coordinates on screen
end
elsif defined?(USE_MOUSE) && USE_MOUSE # Have Crazyninjaguy Mouse Script
def mouseClicked?
return Mouse.click?(Mouse::Left_Click)
end
def mouseCoordinates
return [Mouse.pos_x,Mouse.pos_y]
end
else
def mouseClicked?
return false
end
end
end
# If doesn't have triggerex? implement methods for reading keyboard inputs
if !defined?(Input.triggerex?)
module Input
class << self
alias poccilUpdate update
end
# Original methods for reading other keyboard keys by
# Poccil slightly adjusted
def self.pbSameThread(wnd)
return false if wnd==0
processid=[0].pack('l')
getCurrentThreadId=Win32API.new('kernel32','GetCurrentThreadId', '%w()','l')
getWindowThreadProcessId=Win32API.new('user32','GetWindowThreadProcessId', '%w(l p)','l')
threadid=getCurrentThreadId.call
wndthreadid=getWindowThreadProcessId.call(wnd,processid)
return (wndthreadid==threadid)
end
# GetAsyncKeyState or GetKeyState will work here
@GetKeyState=Win32API.new("user32", "GetAsyncKeyState", "i", "i")
@GetForegroundWindow=Win32API.new("user32", "GetForegroundWindow", "", "i")
# Returns whether a key is being pressed
def self.getstate(key)
return (@GetKeyState.call(key)&0x8000)>0
end
def self.updateKeyState(i)
gfw=pbSameThread(@GetForegroundWindow.call())
if !@stateUpdated[i]
newstate=self.getstate(i) && gfw
@triggerstate[i]=(newstate&&@keystate[i]==0)
@releasestate[i]=(!newstate&&@keystate[i]>0)
@keystate[i]=newstate ? @keystate[i]+1 : 0
@stateUpdated[i]=true
end
end
def self.update
poccilUpdate
if @keystate
for i in 0...256
# just noting that the state should be updated
# instead of thunking to Win32 256 times
@stateUpdated[i]=false
if @keystate[i] > 0
# If there is a repeat count, update anyway
# (will normally apply only to a very few keys)
updateKeyState(i)
end
end
else
@stateUpdated=[]
@keystate=[]
@triggerstate=[]
@releasestate=[]
for i in 0...256
@stateUpdated[i]=true
@keystate[i]=self.getstate(i) ? 1 : 0
@triggerstate[i]=false
@releasestate[i]=false
end
end
end
def self.repeatex?(key)
return false if !@keystate
updateKeyState(key)
return @keystate[key]==1 || (@keystate[key]>20 && (@keystate[key]&1)==0)
end
def self.releaseex?(key)
return false if !@releasestate
updateKeyState(key)
return @releasestate[key]
end
def self.triggerex?(key)
return false if !@triggerstate
updateKeyState(key)
return @triggerstate[key]
end
def self.repeatcount(key)
return 0 if !@keystate
updateKeyState(key)
return @keystate[key]
end
def self.pressex?(key)
return self.repeatcount(key)>0
end
end
end
Attachments
Last edited: