Group: Member
Posts: 26
Type: Writer
RM Skill: Beginner
Sel Feena's Photo System
Version 1.5
Information
This script keeps a collection of photos for your party. These photos hold both images, and information about any Events that were caught in the photo.
You can use tags to set whether an Event's details are recorded or not, and also set Event-specific functions to run AFTER a photo is saved.
Images
Saving a Photo
This is the window that will appear when you call the script:
CODE
sfp_save_photo
An example of putting this in a Common Event:
Displaying and / or Choosing Photos
This is the window that appears when you use the sfp_choose_photo script call. An example of putting this in a Common Event:
Using the [FORCEPHOTO] tag
First, make sure the image you want to force the photo to be is imported into your database:
Now you need to set up the [FORCEPHOTO] tags inside the event.
In the example above, our event is at (9, 7) on the map and doesn't move. I've set up the tag data so that if the player stands next to her, and is looking at her, the photo produced will be a copy of the image "sexypixie".
Basically, for each comment you are: 1) Defining a rectangle the player must be within (x, y, width, height) 2) Defining an array of possible directions the player should be facing. 3) Defining the image the photo will be. 4) Saying whether the x, y position you gave for the rectangle are: * Map coordinates (false) * Added to the event's x, y position (true)
In the example above, our event walks around. I've set up the tag data so that if the player stands next to her, and is looking at her, the photo produced will be a copy of the image "sexypixie".
Tada! This is the image that the photo will be if we stand next to our event, look at her, and take a photo.
The Photos Scene
This is what the Photos Scene looks like when there are no photos. You can set the image and text to whatever you like.
This is what the Photos Scene looks like with photos in your party's collection. You can set what type of information is shown about photos as you like.
Instructions
Place the Photo script in the Materials section, above Main. Place the ZLib script above that.
Make sure you have a folder in your game's 'Graphics' folder called 'Photos'.
The comments at the start of the script will tell you how to use the system.
Notes
This is the final version of the script, and includes windows for saving and choosing a photo, and finally a Scene too.
Credits
The ZLib script was not written by me, and I don't know the author, sorry.
Scripts ZLib Script
CODE
#============================================================================= # ** ZLIB #============================================================================= module Zlib class Png_File < GzipWriter def make_png(bitmap, mode = 0) @bitmap, @mode = bitmap, mode self.write(make_header) self.write(make_ihdr) self.write(make_idat) self.write(make_iend) end def make_header return [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a].pack('C*') end def make_ihdr ih_size = [13].pack('N') ih_sign = 'IHDR' ih_width = [@bitmap.width].pack('N') ih_height = [@bitmap.height].pack('N') ih_bit_depth = [8].pack('C') ih_color_type = [6].pack('C') ih_compression_method = [0].pack('C') ih_filter_method = [0].pack('C') ih_interlace_method = [0].pack('C') string = ih_sign + ih_width + ih_height + ih_bit_depth + ih_color_type + ih_compression_method + ih_filter_method + ih_interlace_method ih_crc = [Zlib.crc32(string)].pack('N') return ih_size + string + ih_crc end def make_idat header = "\x49\x44\x41\x54" data = @mode == 0 ? make_bitmap_data0 : make_bitmap_data1 data = Zlib::Deflate.deflate(data, 8) crc = [Zlib.crc32(header + data)].pack('N') size = [data.length].pack('N') return size + header + data + crc end def make_bitmap_data0 gz = Zlib::GzipWriter.open('png2.tmp') t_Fx = 0 w = @bitmap.width h = @bitmap.height data = [] for y in 0...h data.push(0) for x in 0...w t_Fx += 1 if t_Fx % 10000 == 0 Graphics.update end if t_Fx % 100000 == 0 s = data.pack('C*') gz.write(s) data.clear end color = @bitmap.get_pixel(x, y) red = color.red green = color.green blue = color.blue alpha = color.alpha data.push(red) data.push(green) data.push(blue) data.push(alpha) end end s = data.pack('C*') gz.write(s) gz.close data.clear gz = Zlib::GzipReader.open('png2.tmp') data = gz.read gz.close File.delete('png2.tmp') return data end def make_bitmap_data1 w = @bitmap.width h = @bitmap.height data = [] for y in 0...h data.push(0) for x in 0...w color = @bitmap.get_pixel(x, y) red = color.red green = color.green blue = color.blue alpha = color.alpha data.push(red) data.push(green) data.push(blue) data.push(alpha) end end return data.pack('C*') end def make_iend ie_size = [0].pack('N') ie_sign = 'IEND' ie_crc = [Zlib.crc32(ie_sign)].pack('N') return ie_size + ie_sign + ie_crc end end end
#============================================================================= # ** Bitmap #============================================================================= class Bitmap def make_png(name = 'like', path = '', mode = 0) Zlib::Png_File.open('png.tmp') { |gz| gz.make_png(self, mode) } Zlib::GzipReader.open('png.tmp') { |gz| $read = gz.read } f = File.open(path + name + '.png', 'wb') f.write($read) f.close File.delete('png.tmp') end end
Photo System
CODE
=begin
############################## ## Basic Photo System V 1.5 ## ##############################
Author : Sel Feena Date : 06.07.11
Dependencies ------------
You need to have the ZLib module for this to work; put the script above this one. Thanks to Kread-EX from RRR forums for showing it to me.
You also need to make a folder called 'Photos' in the game's Graphics folder.
Overview --------
A simple system that lets your party keep a collection of screenshots, which are stored along with descriptive data. The data stored is:
* The snapshot itself (obviously), which is a Bitmap object. * The ID of the map the photo was taken on. * The name of the map the photo was taken on. * The player's XY coords and what direction they were facing. * The top left XY coords of the photo. * Information about any events that are captured in the photo: -The event's ID -The event's name -The event's XY coords -The values for the event's Self-Switches
If you don't want an event's info to be stored in a photo (i.e. if the event's something like a Player Transfer) then put '[NP]' at the start or end of the event's name. For example:
'Warp to town [NP]' '[NP] Puzzle switch 1'
If you want to use switches to determine if an event's info is stored, then put '[x]' at the start or end of an event's name, where x is the switch number. For example: 'Clue [21]' # Event info only stored if switch 21 is ON. '[1][74] Phantom' # Event info only stored if switches 1 and 74 are ON.
Event Specific Processing -------------------------
You can set individual script calls for an event, after the photo image is saved.
BEAR IN MIND: The function will only be called if the event is going to be stored in a photo. Some example event names: 'Alexander' # Event-specific processing ALWAYS performed. '[NP] Switch' # Event-specific processing NEVER performed. 'Clue [21]' # Event-specific processing performed if switch 21 is ON. '[1][9] Sue' # Event-specific processing performed if switches 1 and 9 are ON.
In the event's Page, insert a single-line comment anywhere that reads: '[POSTPHOTO]'
IMMEDIATELY AFTER that comment, insert the function you wish to call as another single-line comment. This function MUST: * Be inside class Game_Interpreter (just add it at the bottom). * Take a Game_Event object as THE LAST PARAMETER. This represents the event itself.
When you're done, insert a single-line comment anywhere that reads: '[/POSTPHOTO]'
Example:
GOAL - Create a function that will cause an event to turn invisible.
STEP 1 - Place the function inside class Game_Interpreter:
def set_transparency(val, event) event.transparent = val end
STEP 2 - Set up the tags inside an event's Page, by entering 2 single-line comments like so:
There's no need to mention the event parameter in the function calls; the photo system does that for you.
The photo system refreshes itself for you as well, so don't worry about doing that either.
Forcing the Photo Image -----------------------
You can force the image that a photo captures by using the tag [FORCEPHOTO] This works by specifying the an area that the player must be in, and the image to be shown (which must be in the Pictures folder, and 544 * 416)
1) The top-left corner of the rectangle (X). 2) The top-left corner of the rectangle (Y). 3) The width of the rectangle. 4) The height of the rectangle. 5) An array of the directions that the player can be facing. 6) The image within the Pictures folder to use. 7) Whether the numbers given for 1 and 2 are added to the event's x and y to get their position or not. Use true for moving events.
If the photo is forced to an image by an event, then bear in mind that: 1) The only event whose details will be recorded are that event. 2) Only that event will be checked for a [POSTPHOTO] event.
################### ## Possible Bugs ## ###################
It doesn't seem possible in the editor, but using maps in your game that are smaller than 17 X 13 in size could mess things up.
######################## ## How To Use Windows ## ########################
Photos Scene ------------
There is a Scene_Photos class that displays all the photos in the party's collection, and various info about them (you can set this in the module below).
I recommend using a custom main menu manager to add this scene to your menu. Leongon's Main Menu Manager is very easy to use. :3
Select a Photo --------------
To let the player select a photo from their collection, use the script:
$game_variables[ x ] = sfp_choose_photo( s, z )
Where s is the string displayed for the 'confirm' option. Where z sets whether the player can cancel (true / false).
After this script call, $game_variables[10] may contain: * The index of the selected photo (0 and above) * The code SFPhotoModule::CANCEL_SELECTION (-1) * The code SFPhotoModule::EMPTY_COLLECTION (-2)
You can set what is displayed by the selection window by setting values in SFPhotoModule below.
Take a Photo ------------
To let the player take a photo, use the script:
sfp_save_photo
The player can then choose to save the photo, or cancel.
################################# ## How To Use Script Functions ## #################################
Create Photo ------------
To create a photo, use the following script call:
myPhoto = SelFeenaPhoto.new
Add Photo to Collection -----------------------
To add the photo to your collection, you'd then type:
$game_party.addPhoto(myPhoto)
The new photo will be added to your party's collection. HOWEVER, if your collection is full then the photo in slot 0 will be erased to make room. Set the maximum number of photos allowed in the module below.
Get Photo from Collection -------------------------
To get a photo, call:
myPhoto = $game_party.getPhoto( x )
Where x is the index of the photo in the collection. Just like arrays, this starts from 0
Remove Photo from Collection ----------------------------
To destroy a photo, call:
$game_party.delPhoto( x )
Where x is the index of the photo in the collection. Just like arrays, this starts from 0
Get Number of Photos in Collection ----------------------------------
Use this script:
collection_size = $game_party.getPhotoCount
Make good use of this function call to avoid out-of-bounds errors!
Determine if Photo was Created Through [FORCEPHOTO] tag -------------------------------------------------------
forced_image = $game_party.getPhoto( x ).isForcedImage
Where x is the index of the photo in the collection. Just like arrays, this starts from 0
Get Photo Image ---------------
myPhoto = $game_party.getPhoto( x ) picture = myPhoto.getImage
Where x is the index of the photo in the collection. Just like arrays, this starts from 0 This function returns a Bitmap object.
Get Location of Photo ---------------------
myPhoto = $game_party.getPhoto( x ) location_id = myPhoto.getLocationID
Where x is the index of the photo in the collection. Just like arrays, this starts from 0 Variable 'location_id' will then have the Map ID of where the photo was taken.
myPhoto = $game_party.getPhoto( x ) location_name = myPhoto.getLocationName
Where x is the index of the photo in the collection. Just like arrays, this starts from 0 Variable 'location_name' will then have the name of the map where the photo was taken.
Get Player's Position when Taking Photo ---------------------------------------
myPhoto = $game_party.getPhoto( x ) player_loc_data = myPhoto.getPlayerPosition
Where x is the index of the photo in the collection. Just like arrays, this starts from 0 This function returns an array of three integers: - The player's X position. - The player's Y position. - The direction the player was facing: - 2 -> Down - 4 -> Left - 6 -> Right - 8 -> Up
Get Photo's Position --------------------
myPhoto = $game_party.getPhoto( x ) photo_loc_data = myPhoto.getPhotoPosition
Where x is the index of the photo in the collection. Just like arrays, this starts from 0 This function returns an array of two integers: - The photo's top-left X position. - The photo's top-left Y position.
Get Number of Events in Photo -----------------------------
myPhoto = $game_party.getPhoto( x ) events_in_photo = myPhoto.getEventCount
Where x is the index of the photo in the collection. Just like arrays, this starts from 0
Is a Certain Event in Photo? ---------------------------
myPhoto = $game_party.getPhoto( x ) has_event = myPhoto.hasEventWithID( i )
Where x is the index of the photo in the collection, and i is the ID number you're looking for. Returns true or false.
How Many Events With Name "???" Are There? -----------------------------------------
myPhoto = $game_party.getPhoto( x ) ev_count = myPhoto.countEventsWithName( z )
Where x is the index of the photo in the collection, and z is the name you're looking for.
Get Info About Event With ID ----------------------------
myEventInfo = $game_party.getPhoto( x ).getEventWithID( z )
Where x is the index of the photo in the collection, and z is the event ID you're looking for.
This function returns a SelFeenaPhotoEvent object.
WARNING! If photo x doesn't have an event with ID z, then you will get nil
Get Info About Events With Name -------------------------------
myEventInfoArray = $game_party.getPhoto( x ).getEventsWithName( z )
Where x is the index of the photo in the collection, and z is the name you're looking for. This function returns an array of SelFeenaPhotoEvent objects.
Get All Event Data From Photo -----------------------------
myEventInfoArray = $game_party.getPhoto( x ).getEvents
Where x is the index of the photo in the collection. This function returns an array of SelFeenaPhotoEvent objects.
Handling Event Data From a Photo --------------------------------
You can use the following functions on a SelFeenaPhotoEvent object:
* getID : Returns the ID number of this event.
* getName : Returns the event name, MINUS any tags.
* getPosition : Returns an array in the format [event.x, event.y]
* getSwitch( x ) : Returns the recorded status of self-switch x, where: 0 returns self_switch A 1 returns self_switch B 2 returns self_switch C 3 returns self_switch D
* getSwitches : Returns self-switch data in the format [A, B, C, D]
=end
#============================================================================== # ** SFPhotoModule #------------------------------------------------------------------------------ # Settings for the system and error/GUI codes stored here. #==============================================================================
# Image to display on top of a new photo when saving. Maybe something # saying 'NEW!' or what have you. # Must be in the Pictures folder.
NEW_PICTURE = ""
# Position of this image in the New Photo window, in format [ X, Y ]
NEW_POS = [0, 0]
# Name of the image to display if the party's photo collection is empty. # This image must be in the Pictures folder, and should be 544 * 416
EMPTY_PICTURE = ""
# Message to display at the bottom of the Photos Scene when the photo # collection is empty.
EMPTY_MSG = ""
# The type of info you want to display about a photo that is a snapshot # of the screen (i.e. not a forced image). The format is: # 1) Start string # 2) Photo function to call. Must return a string. # 3) End string.
SNAP_INFO = [ #String, Photo function, String ["Photo taken at ", "getLocationName", ""] ]
# The type of info you want to display about a photo that is a forced image. # The format is: # 1) Start string # 2) Photo function to call # 3) End string.
FORCED_INFO = [ #String, Photo function, String ["Photo taken at ", "getLocationName", ""], ["Photo of ", "getEvents[0].getName", ""] ]
# ******************** # *** SYSTEM STUFF *** # ********************
# DON'T change the values here!
EMPTY_COLLECTION = -2 CANCEL_SELECTION = -1
end
############################### ############################### ## ## ## DON'T GO PAST HERE! ## ## ## ############################### ###############################
#============================================================================== # ** Game_Map #------------------------------------------------------------------------------ # Update Game_Map to allow access to map name. #==============================================================================
class Game_Map attr_reader :name alias mapname_setup setup def setup(map_id) mapname_setup(map_id) data = load_data("Data/MapInfos.rvdata") @name = data[map_id].name end end
#============================================================================== # ** Game_Event #------------------------------------------------------------------------------ # Update Game_Event to allow access to name and test it against tags. #==============================================================================
class Game_Event < Game_Character attr_accessor :event
# Return the full name of the Event.
def getName return @event.name end
# Removes any occurence of photo tags from name and returns it.
# Do the tags in this Event's name allow it to be stored in a photo?
def allowPhoto # [NP] tag means NEVER record event's info... if(@event.name.scan(/\[NP\]/).size > 0) return false end
# Go through switch tags and check if the switches referenced are ON. result = true switch_arr = [] @event.name.scan(/\[[0-9]*\]/){|s| switch_arr.push(s[1, s.length - 2].to_i)} for switch_id in switch_arr if($game_switches[switch_id] == false) result = false end end return result end end
#============================================================================== # ** Game_Party #------------------------------------------------------------------------------ # Update Game_Party to include access to photo data. #==============================================================================
class Game_Party < Game_Unit alias selfeenaphoto_init initialize def initialize @photos = []
if(SFPhotoModule::PHOTO_COUNT_VAR >= 0) $game_variables[SFPhotoModule::PHOTO_COUNT_VAR] = 0 end if(SFPhotoModule::HAS_PHOTO_SWITCH >= 0) $game_switches[SFPhotoModule::HAS_PHOTO_SWITCH] = false end
selfeenaphoto_init end
# Number of photos currently in collection.
def getPhotoCount return @photos.length end
# Is the photo collection full?
def photoAlbumFull return (@photos.length == SFPhotoModule::MAX_PHOTOS) end
# Return photo at index i # Use getPhotoCount to avoid out-of-bounds errors!
def getPhoto(i) return @photos[i] end
# Destroy photo at index i # Use getPhotoCount to avoid out-of-bounds errors!
def delPhoto(i) @photos.delete_at(i)
if(SFPhotoModule::PHOTO_COUNT_VAR >= 0) $game_variables[SFPhotoModule::PHOTO_COUNT_VAR] = @photos.length end if(SFPhotoModule::HAS_PHOTO_SWITCH >= 0) $game_switches[SFPhotoModule::HAS_PHOTO_SWITCH] = (@photos.length > 0) end end
# Add a new photo to the collection. If the collection is full, # the photo at index 0 is destroyed to make room.
def addPhoto(p) if(@photos.length == SFPhotoModule::MAX_PHOTOS) @photos.delete_at(0) end @photos.push(p)
if(SFPhotoModule::PHOTO_COUNT_VAR >= 0) $game_variables[SFPhotoModule::PHOTO_COUNT_VAR] = @photos.length end if(SFPhotoModule::HAS_PHOTO_SWITCH >= 0) $game_switches[SFPhotoModule::HAS_PHOTO_SWITCH] = (@photos.length > 0) end end end
arr = [] for x in @photo_pos_x..(@photo_pos_x + 16) if(x >= $game_map.width) # Horizontal loop fix x -= $game_map.width end for y in @photo_pos_y..(@photo_pos_y + 12) if(y >= $game_map.height) # Vertical loop fix y -= $game_map.height end arr = arr + $game_map.events_xy(x, y) end end
# Whittle down events to those that are valid...
ev_arr = [] for e in arr if(e.allowPhoto == true) ev_arr.push(e) end end
# Check for image forcing. processEvents("[FORCEPHOTO]", "self.forceImage ", "[/FORCEPHOTO]", ev_arr)
# Store event data. If a forced image has been triggered, # only store information about that event. @event_data = [] for i in ev_arr if (@forcedeventid == 0) or (@forcedeventid == i.id)
# Store image. Either a screenshot or the forced image. if(@forcedeventid == 0) @image_data = Graphics.snap_to_bitmap else @image_data = Cache.picture(@forcedpicture).clone end
# Postprocessing. Process either ALL events or just the event # that has forced the photo image. if(@forcedeventid == 0) processEvents("[POSTPHOTO]", "$game_map.interpreter.", "[/POSTPHOTO]", ev_arr) else fev = $game_map.events[@forcedeventid] processEvent(fev, "[POSTPHOTO]", "$game_map.interpreter.", "[/POSTPHOTO]") end end
# Remove Bitmap. Go on, shoo! :3
def dispose @image_data.dispose end
# Is this photo a forced image ([FORCEPHOTO] tag)?
def isForcedImage return (@forcedeventid != 0) end
# Loop through Events and perform processing if tag is present in Page. # When done, update to reflect changes.
def processEvents(tag, eval_str, endtag, ev_a) for ev in ev_a processEvent(ev, tag, eval_str, endtag) end $game_map.refresh end
# Perform processing for a specific Event based on the tag given.
def processEvent(my_event, my_tag, my_str, my_endtag) for i in 0...my_event.list.size if (my_event.list[i].code == 108) if (my_event.list[i].parameters == [my_tag])
linecount = i + 1 command = my_event.list[linecount].parameters until (command == [my_endtag]) eval(my_str + command[0] + ", my_event") linecount += 1 command = my_event.list[linecount].parameters end return
end end end end
# Determine if image should be a specified bitmap.
def forceImage(x, y, width, height, dir_arr, pic_name, centred, ev)
# Is the rectangle's position based on the event's? if(centred == true) x = ev.x + x y = ev.y + y end
# Go through rectangle, with corrections for looping maps. for ix in x..(x + width - 1) if(ix >= $game_map.width) and ($game_map.loop_horizontal?) ix -= $game_map.width end for iy in y..(y + height - 1) if(iy >= $game_map.height) and ($game_map.loop_vertical?) iy -= $game_map.height end
# We have a match inside our rectangle. Now, what about direction? if(@player_x == ix) and (@player_y == iy) if(dir_arr.include?(@player_dir)) @forcedeventid = ev.id @forcedpicture = pic_name end return end end end end
# Return image bitmap.
def getImage return @image_data end
# Set image bitmap.
def setImage(pic) @image_data = pic end
# Destroy image bitmap.
def delImage @image_data.dispose @image_data = nil end
# Return ID of map where photo was taken.
def getLocationID return @map_id end
# Return name of map where photo was taken.
def getLocationName return @map_name end
# Return player position when photo was taken. # Format = [ Map X position, Map Y position, Direction player was facing ]
def getPlayerPosition return [@player_x, @player_y, @player_dir] end
# Return position of photo's top-left corner on map. # Format = [ Photo X position, Photo Y position ]
def getPhotoPosition return [@photo_pos_x, @photo_pos_y] end
# Number of SelFeenaPhotoEvents caught on camera.
def getEventCount return @event_data.length end
# Does photo have info about a SelFeenaPhotoEvent with a specific ID?
def hasEventWithID(target_id) result = false
for i in @event_data if i.getID == target_id result = true end end
return result end
# How many SelFeenaPhotoEvents with a specific name are in the photo?
def countEventsWithName(target_name) result = 0
for i in @event_data if i.getName == target_name result += 1 end end
return result end
# Return an array of SelFeenaPhotoEvents with a specific name. May be empty.
def getEventsWithName(target_name) result = []
for i in @event_data if i.getName == target_name result.push(i) end end
return result end
# Return SelFeenaPhotoEvent with a specific ID. # If there is no SelFeenaPhotoEvent with that ID, returns nil.
def getEventWithID(target_id) result = nil
for i in @event_data if i.getID == target_id result = i end end
return result end
# Return all SelFeenaPhotoEvents in photo as an array.
def getEvents return @event_data end end
#============================================================================== # ** SelFeenaPhotoEvent #------------------------------------------------------------------------------ # Class encapsulating info about an event captured in a photo. #==============================================================================
class SelFeenaPhotoEvent def initialize(e_id, e_name, e_pos, e_switches) @id = e_id @name = e_name @position = e_pos @switches = e_switches end
# Event ID.
def getID return @id end
# Event name.
def getName return @name end
# Return MAP position of Event. # Format = [ Event X position, Event Y position ]
def getPosition return @position end
# Return Self-Switch information recorded for Event: # 0 : Self-Switch A # 1 : Self-Switch B # 2 : Self-Switch C # 3 : Self-Switch D
def getSwitch(s) return @switches[s] end
# Return recorded Self-Switch information for Event. # Format = [ A, B, C, D ]
def getSwitches return @switches end end
#============================================================================== # ** Window_PhotoSelect #------------------------------------------------------------------------------ # This window displays photos from the party's collection. #==============================================================================
class Window_PhotoSelect < Window_Base def initialize(x, y, w, h, sa = true) super(x, y, w, h) @showarrows = sa
# If the party's collection is empty, then set index to error code. if($game_party.getPhotoCount == 0) @index = SFPhotoModule::EMPTY_COLLECTION else @index = 0 end refresh end
# Return index of the currently displayed photo.
def getIndex return @index end
# Select the previous photo in collection (wraps around).
def prevPhoto # Only if there are photos in collection. if(@index != SFPhotoModule::EMPTY_COLLECTION) oldindex = @index @index -= 1 # Wraparound. if (@index < 0) @index = $game_party.getPhotoCount - 1 end # Sound if new photo selected. if(@index != oldindex) Sound.play_cursor end end end
# Select the next photo in collection (wraps around).
def nextPhoto # Only if there are photos in collection. if(@index != SFPhotoModule::EMPTY_COLLECTION) oldindex = @index @index += 1 # Wraparound. if (@index == $game_party.getPhotoCount) @index = 0 end # Sound if new photo selected. if(@index != oldindex) Sound.play_cursor end end end
# Display a photo from party's collection.
def refresh self.contents.clear
# Check if we're dealing with an empty collection. if(@index == SFPhotoModule::EMPTY_COLLECTION)
# Display arrows if collection larger than 1 if($game_party.getPhotoCount > 1) and (@showarrows == true) l_rect = Rect.new(80, 25, 8, 14) r_rect = Rect.new(104, 25, 8, 14) self.contents.blt(0, (height / 2) - 23, windowskin, l_rect) self.contents.blt(width - 40, (height / 2) - 23, windowskin, r_rect) end end end end
#============================================================================== # ** Window_PhotoPreview #------------------------------------------------------------------------------ # This window displays a photo passed to it on instantiation. #==============================================================================
class Window_PhotoPreview < Window_Base def initialize(x, y, w, h, p, newp) @preview = p @newphoto = newp super(x, y, w, h) refresh end
# Display 'new image' tag. if(SFPhotoModule::NEW_PICTURE.length > 0) and (newp == true) pic_x = SFPhotoModule::NEW_POS[0] pic_y = SFPhotoModule::NEW_POS[1] pic = Cache.picture(SFPhotoModule::NEW_PICTURE) pic_rect = Rect.new(0, 0, pic.width, pic.height) self.contents.blt(pic_x, pic_y, pic, pic_rect) end end end
#============================================================================== # ** Window_PhotoStrip #------------------------------------------------------------------------------ # This displays a list of all photos in a strip. #==============================================================================
class Window_PhotoStrip < Window_Base def initialize super(0, 0, 104, 344)
# If the party's collection is empty, then set index to error code. if($game_party.getPhotoCount == 0) @index = SFPhotoModule::EMPTY_COLLECTION else @index = 0 end @startindex = 0 refresh end
# Update cursor position.
def prevPhoto # Only if there are photos in collection. if(@index != SFPhotoModule::EMPTY_COLLECTION) # Update cursor. @index -= 1 flip = false if(@index < 0) @index = $game_party.getPhotoCount - 1 flip = true end
# Update strip display. if(flip == true) if($game_party.getPhotoCount - 5 < 0) @startindex = 0 else @startindex = $game_party.getPhotoCount - 5 end else if(@index < @startindex) @startindex -= 1 end end refresh end end
# Update cursor position.
def nextPhoto # Only if there are photos in collection. if(@index != SFPhotoModule::EMPTY_COLLECTION) # Update cursor. @index += 1 flip = false if(@index == $game_party.getPhotoCount) @index = 0 flip = true end
# Update strip display. if(flip == true) @startindex = 0 else if(@index > @startindex + 4) @startindex += 1 end end refresh end end
# Calculate how far to draw from current @startindex value.
def getDrawLimit if(@startindex + 4 <= $game_party.getPhotoCount - 1) return @startindex + 4 else return $game_party.getPhotoCount - 1 end end
# Display photo strip.
def refresh self.contents.clear # Only if there are photos in collection. if(@index != SFPhotoModule::EMPTY_COLLECTION) # Draw cursor. cursor_rect = Rect.new(0, 10 + (@index - @startindex) * 60, 72, 52) self.contents.font.color = normal_color self.contents.fill_rect(cursor_rect, self.contents.font.color)
# Draw strip. for i in @startindex..getDrawLimit pic = $game_party.getPhoto(i).getImage scaled_rect = Rect.new(2, 10 + (i - @startindex) * 60, 68, 52) pic_rect = Rect.new(0, 0, 544, 416) self.contents.stretch_blt(scaled_rect, pic, pic_rect) end
# Draw up / down arrows if necessary. if($game_party.getPhotoCount > 5) u_rect = Rect.new(89, 17, 14, 8) d_rect = Rect.new(89, 40, 14, 8) self.contents.blt((width / 2) - 23, 0, windowskin, u_rect) self.contents.blt((width / 2) - 23, height - 40, windowskin, d_rect) end end end end
#============================================================================== # ** Window_PhotoText #------------------------------------------------------------------------------ # This window displays info about a photo. #==============================================================================
class Window_PhotoText < Window_Base def initialize super(0, 344, 544, 72) @info = 0 # If the party's collection is empty, then set index to error code. if($game_party.getPhotoCount == 0) @index = SFPhotoModule::EMPTY_COLLECTION else @index = 0 end refresh end
# Set the window to display info about the previous photo.
def prevPhoto # Only if there are photos in collection. if(@index != SFPhotoModule::EMPTY_COLLECTION) oldindex = @index @index -= 1 # Wraparound. if (@index < 0) @index = $game_party.getPhotoCount - 1 end # Reset info index if new photo selected. if(@index != oldindex) @info = 0 end refresh end end
# Set the window to display info about the previous photo.
def nextPhoto # Only if there are photos in collection. if(@index != SFPhotoModule::EMPTY_COLLECTION) oldindex = @index @index += 1 # Wraparound. if (@index == $game_party.getPhotoCount) @index = 0 end # Reset info index if new photo selected. if(@index != oldindex) @info = 0 end refresh end end
# Get limit of info index for the current photo
def getInfoSize if(@index != SFPhotoModule::EMPTY_COLLECTION) if($game_party.getPhoto(@index).isForcedImage) return SFPhotoModule::FORCED_INFO.length else return SFPhotoModule::SNAP_INFO.length end else return 0 end end
# Display previous piece of info about the photo
def prevInfo # Only if there is info to display. if(getInfoSize != 0) oldinfo = @info @info -= 1 # Wraparound. if (@info < 0) @info = getInfoSize - 1 end # Play sound if new info selected. if(@info != oldinfo) Sound.play_cursor end refresh end end
# Display next piece of info about the photo
def nextInfo # Only if there is info to display. if(getInfoSize != 0) oldinfo = @info @info += 1 # Wraparound. if (@info == getInfoSize) @info = 0 end # Play sound if new info selected. if(@info != oldinfo) Sound.play_cursor end refresh end end
def refresh self.contents.clear # Only if there are photos in collection. if(@index != SFPhotoModule::EMPTY_COLLECTION) # Only if there is info to display. if(getInfoSize != 0) info_arr = [] if($game_party.getPhoto(@index).isForcedImage) info_arr = SFPhotoModule::FORCED_INFO[@info] else info_arr = SFPhotoModule::SNAP_INFO[@info] end info_str = info_arr[0] info_str = info_str + eval("$game_party.getPhoto(@index)." + info_arr[1]) info_str = info_str + info_arr[2] self.contents.font.color = normal_color self.contents.draw_text(16, 8, width, WLH, info_str, 0)
# Display arrows if info array larger than 1. if(getInfoSize > 1) l_rect = Rect.new(80, 25, 8, 14) r_rect = Rect.new(104, 25, 8, 14) self.contents.blt(0, (height / 2) - 23, windowskin, l_rect) self.contents.blt(width - 40, (height / 2) - 23, windowskin, r_rect) end end else self.contents.font.color = normal_color self.contents.draw_text(16, 8, width, WLH, SFPhotoModule::EMPTY_MSG, 0) end end end
#============================================================================== # ** Scene_Photos #------------------------------------------------------------------------------ # Display photographs taken by the player. #==============================================================================
class Scene_Photos < Scene_Base #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize end #-------------------------------------------------------------------------- # * Start processing #-------------------------------------------------------------------------- def start super create_menu_background @photo_window = Window_PhotoSelect.new(104, 0, 440, 344, false) @photo_strip = Window_PhotoStrip.new @text_window = Window_PhotoText.new end #-------------------------------------------------------------------------- # * Termination Processing #-------------------------------------------------------------------------- def terminate super dispose_menu_background @photo_window.dispose @photo_strip.dispose @text_window.dispose end #-------------------------------------------------------------------------- # * Return to Original Screen #-------------------------------------------------------------------------- def return_scene $scene = Scene_Menu.new end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def update update_menu_background @photo_window.update @text_window.update
if Input.trigger?(Input::UP) @photo_window.prevPhoto @photo_window.refresh @photo_strip.prevPhoto @text_window.prevPhoto end if Input.trigger?(Input::DOWN) @photo_window.nextPhoto @photo_window.refresh @photo_strip.nextPhoto @text_window.nextPhoto end if Input.trigger?(Input::LEFT) @text_window.prevInfo end if Input.trigger?(Input::RIGHT) @text_window.nextInfo end if Input.trigger?(Input::B) Sound.play_cancel return_scene end super end end
class Game_Interpreter # Select a photo from the party's collection. Returns the index. # Selecting from empty collection returns SFPhotoModule::EMPTY_COLLECTION # Cancelling will return SFPhotoModule::CANCEL_SELECTION
# Process input... while true Graphics.update Input.update confirm_window.update photo_window.update if Input.trigger?(Input::LEFT) photo_window.prevPhoto photo_window.refresh end if Input.trigger?(Input::RIGHT) photo_window.nextPhoto photo_window.refresh end break if Input.trigger?(Input::C) end Input.update
# Save photo, or dispose of it... if(choice == 0) Sound.play_decision # Overwrite photo or just add to collection? if($game_party.photoAlbumFull == true) overwrite_index = sfp_choose_photo("Overwrite", true) # Photo selected, or cancel? if(overwrite_index >= 0) $game_party.delPhoto(overwrite_index) $game_party.addPhoto(newphoto) else newphoto.dispose end else $game_party.addPhoto(newphoto) end else Sound.play_cancel newphoto.dispose end end end
#============================================================================== # ** Scene_File #------------------------------------------------------------------------------ # It's necessary to overwrite these two functions as VX doesn't like # writing Bitmap objects to file. Somewhat annoying, but whatever. # # Instead the photo images are saved as png files, and loaded up when # the player loads a game. Example file format, in case you wanted to know... # # S0P7.png <= Photo number 7, Save slot 0. # # This means a bit of a pause when saving/loading, but not much. #==============================================================================
class Scene_File < Scene_Base #-------------------------------------------------------------------------- # * Write Save Data # file : write file object (opened) #-------------------------------------------------------------------------- alias selfeenaphoto_save write_save_data alias selfeenaphoto_read read_save_data def write_save_data(file) # Save photos to file, and temporarily destroy Bitmaps. i = 0 tempphoto_arr = [] while (i < $game_party.getPhotoCount) pic = $game_party.getPhoto(i).getImage.clone tempphoto_arr.push(pic) pic.make_png("S" + @index.to_s + "P" + i.to_s, "Graphics/Photos/") $game_party.getPhoto(i).delImage i += 1 end # Normal save stuff. selfeenaphoto_save(file) # Put image data back in photos. i = 0 for p in tempphoto_arr $game_party.getPhoto(i).setImage(p) i += 1 end end #-------------------------------------------------------------------------- # * Read Save Data # file : file object for reading (opened) #-------------------------------------------------------------------------- def read_save_data(file) # Normal load stuff. selfeenaphoto_read(file) # Load images from files into photos. i = 0 while(i < $game_party.getPhotoCount) pic = Bitmap.new("Graphics/Photos/S" + @index.to_s + "P" + i.to_s) $game_party.getPhoto(i).setImage(pic) i += 1 end end end
This post has been edited by Sel Feena: Jul 8 2011, 06:26 AM