Files
infinitefusion-e18/Data/Scripts/050_AddOns/OverworldShadows.rb
2023-08-03 18:00:15 -04:00

303 lines
10 KiB
Ruby

#==============================================================================#
# Overworld Shadows #
# by Marin #
#==============================================================================#
# Info #
# #
# You'll have likely heard of KleinStudios' Overworld Shadows script; many #
# fangames use it, after all. It was not compatible with Essentials v17+ #
# though, so after getting the suggestion I thought it would be cool if I #
# could make something of my own that would work with v16, as well as v17. #
#==============================================================================#
# Features: #
# - Blacklisting events from receiving shadows #
# - Whitelisting events to always receive shadows #
# - A scaling animation when an event jumps #
#==============================================================================#
# Usage #
# #
# Shadow_Path is the path to the shadow graphic. You can change this #
# sprite, though you may need to fiddle with positioning of the sprite in #
# relation to the event after, though. That's done in "def position_shadow". #
# #
# As the name literally says, if an event's name includes any of the strings #
# in "No_Shadow_If_Event_Name_Has", it won't get a shadow, UNLESS the event's #
# name also includes any of the strings in #
# "Always_Give_Shadow_If_Event_Name_Has". This is essentially "overriding". #
# #
# Case_Sensitive is either true or false. It's used when determing if an #
# event's name includes a string in the "No_Shadow" and "Always_Give" arrays. #
# If true, it must match all strings with capitals exactly as well. #
# If false, capitals don't need to match up. #
#==============================================================================#
# Please give credit when using this. #
#==============================================================================#
SHADOW_IMG_FOLDER = "Graphics/Characters/"
SHADOW_IMG_NAME = "shadow"
# Whether or not the event names below need to match in capitals as well.
Case_Sensitive = false
No_Shadow_If_Event_Name_Has = [
# I like to use "extensions" like these. Up to you though.
".shadowless",
".noshadow",
".sl",
"Door",
"Stairs"
]
# Events that have this in their event name will always receive a shadow.
# Does take "Case_Sensitive" into account.
Always_Give_Shadow_If_Event_Name_Has = [
"Trainer", "npc"
]
# Determines whether or not an event should be given a shadow.
def pbShouldGetShadow?(event)
return true if event.is_a?(Game_Player) # The player will always have a shadow
page = pbGetActiveEventPage(event)
return false unless page
comments = page.list.select { |e| e.code == 108 || e.code == 408 }.map do |e|
e.parameters.join
end
Always_Give_Shadow_If_Event_Name_Has.each do |e|
name = event.name.clone
unless Case_Sensitive
e.downcase!
name.downcase!
end
return true if name.include?(e) || comments.any? { |c| c.include?(e) }
end
No_Shadow_If_Event_Name_Has.each do |e|
name = event.name.clone
unless Case_Sensitive
e.downcase!
name.downcase!
end
return false if name.include?(e) || comments.any? { |c| c.include?(e) }
end
return true
end
# Extending so we can access some private instance variables.
class Game_Character
attr_reader :jump_count
end
unless Spriteset_Map.respond_to?(:viewport)
class Spriteset_Map
def viewport
return @viewport1
end
def self.viewport
return $scene.spriteset.viewport rescue nil
end
end
end
# Following Pokémon compatibility
def pbToggleFollowingPokemon
return if $Trainer.party[0].hp <= 0 || $Trainer.party[0].isEgg?
if $game_switches[Following_Activated_Switch]
if $game_switches[Toggle_Following_Switch]
$game_switches[Toggle_Following_Switch] = false
$PokemonTemp.dependentEvents.remove_sprite(true)
$scene.spriteset.usersprites.select do |e|
e.is_a?(DependentEventSprites)
end.each do |des|
des.sprites.each do |e|
if e && e.shadow
e.shadow.dispose
e.shadow = nil
end
end
end
pbWait(1)
else
$game_switches[Toggle_Following_Switch] = true
$PokemonTemp.dependentEvents.refresh_sprite
$scene.spriteset.usersprites.select do |e|
e.is_a?(DependentEventSprites)
end.each do |des|
des.sprites.each do |e|
e.make_shadow if e.respond_to?(:make_shadow)
end
end
pbWait(1)
end
end
end
class DependentEventSprites
def refresh
for sprite in @sprites
sprite.dispose
end
@sprites.clear
$PokemonTemp.dependentEvents.eachEvent do |event, data|
if data[2] == @map.map_id # Check current map
spr = Sprite_Character.new(@viewport,event,true)
@sprites.push(spr)
end
end
end
end
unless defined?(pbGetActiveEventPage)
def pbGetActiveEventPage(event, mapid = nil)
mapid ||= event.map.map_id if event.respond_to?(:map)
pages = (event.is_a?(RPG::Event) ? event.pages : event.instance_eval { @event.pages })
for i in 0...pages.size
c = pages[pages.size - 1 - i].condition
ss = !(c.self_switch_valid && !$game_self_switches[[mapid,
event.id,c.self_switch_ch]])
sw1 = !(c.switch1_valid && !$game_switches[c.switch1_id])
sw2 = !(c.switch2_valid && !$game_switches[c.switch2_id])
var = true
if c.variable_valid
if !c.variable_value || !$game_variables[c.variable_id].is_a?(Numeric) ||
$game_variables[c.variable_id] < c.variable_value
var = false
end
end
if ss && sw1 && sw2 && var # All conditions are met
return pages[pages.size - 1 - i]
end
end
return nil
end
end
class Spriteset_Map
attr_accessor :usersprites
end
class Sprite_Character
attr_accessor :shadow
alias ow_shadow_init initialize
def initialize(viewport, character = nil, is_follower = false)
@viewport = viewport
@is_follower = is_follower
ow_shadow_init(@viewport, character)
return unless pbShouldGetShadow?(character)
return if @is_follower && defined?(Toggle_Following_Switch) &&
!$game_switches[Toggle_Following_Switch]
return if @is_follower && defined?(Following_Activated_Switch) &&
!$game_switches[Following_Activated_Switch]
@character = character
if @character.is_a?(Game_Event)
page = pbGetActiveEventPage(@character)
return if !page || !page.graphic || page.graphic.character_name == ""
end
make_shadow
end
def make_shadow
@shadow.dispose if @shadow
@shadow = nil
@shadow = Sprite.new(@viewport)
@shadow.bitmap = RPG::Cache.load_bitmap(SHADOW_IMG_FOLDER,SHADOW_IMG_NAME)
# Center the shadow by halving the origin points
@shadow.ox = @shadow.bitmap.width / 2.0
@shadow.oy = @shadow.bitmap.height / 2.0
# Positioning the shadow
position_shadow
end
def position_shadow
return unless @shadow
# x = @character.screen_x
# y = @character.screen_y
# if @character.jumping?
# @totaljump = @character.jump_count if !@totaljump
# case @character.jump_count
# when 1..(@totaljump / 3)
# @shadow.zoom_x += 0.1
# @shadow.zoom_y += 0.1
# when (@totaljump / 3 + 1)..(@totaljump / 3 + 2)
# @shadow.zoom_x += 0.05
# @shadow.zoom_y += 0.05
# when (@totaljump / 3 * 2 - 1)..(@totaljump / 3 * 2)
# @shadow.zoom_x -= 0.05
# @shadow.zoom_y -= 0.05
# when (@totaljump / 3 * 2 + 1)..(@totaljump)
# @shadow.zoom_x -= 0.1
# @shadow.zoom_y -= 0.1
# end
# if @character.jump_count == 1
# @shadow.zoom_x = 1.0
# @shadow.zoom_y = 1.0
# @totaljump = nil
# end
# end
@shadow.x = x
@shadow.y = y - 6
@shadow.z = self.z - 1
if @shadow
if @charbitmap.disposed? || @character.instance_eval { @erased }
@shadow.dispose
@shadow = nil
end
end
end
alias ow_shadow_visible visible=
def visible=(value)
ow_shadow_visible(value)
@shadow.visible = value if @shadow
end
alias ow_shadow_dispose dispose
def dispose
ow_shadow_dispose
@shadow.dispose if @shadow
@shadow = nil
end
alias ow_shadow_update update
def update
ow_shadow_update
position_shadow
if @character.is_a?(Game_Event)
page = pbGetActiveEventPage(@character)
if @old_page != page
@shadow.dispose if @shadow
@shadow = nil
if page && page.graphic && page.graphic.character_name != "" &&
pbShouldGetShadow?(@character)
unless @is_follower && defined?(Toggle_Following_Switch) &&
!$game_switches[Toggle_Following_Switch]
unless @is_follower && defined?(Following_Activated_Switch) &&
!$game_switches[Following_Activated_Switch]
make_shadow
end
end
end
end
end
@old_page = (@character.is_a?(Game_Event) ? pbGetActiveEventPage(@character) : nil)
bushdepth = @character.bush_depth
if @shadow
@shadow.opacity = self.opacity
@shadow.visible = (bushdepth == 0)
if !self.visible || (@is_follower || @character == $game_player) &&
($PokemonGlobal.surfing || $PokemonGlobal.diving)
@shadow.visible = false
end
end
end
end