• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Overworld Shadows for v17

971
Posts
7
Years
  • Age 21
  • Seen Nov 28, 2022
This resource can be installed via the Universal Plugin Installer.

You've probably heard of KleinStudio's overworld shadow script before; a lot of fangames use it, after all. It's apparently incompatible with Essentials v17, so I thought I'd give my own take on it.

It is semi-compatible with Essentials v16. It will not crash, but due to the way viewports are handled, shadows will appear on top of events rather than underneath. That makes it pretty worthless, and thus I wouldn't say it's compatible. If you want overworld shadows for v16, use KleinStudio's.


AvbZDoj.gif



Installation
If you choose not to use the Universal Plugin Installer, you may also paste this script in a new section above Main (Make sure to place this script UNDERNEATH your Following Pok?mon script, if you have that!?):
Overworld Shadows

You will also need this sprite:
Graphics/Characters/shadow.png


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.
 
Last edited:

Soccersam

Hilbert is Badass
179
Posts
7
Years
  • Age 25
  • Seen Feb 26, 2024
Well,
I just found a bug(or whatever you might call it). It probably isn't that big, but it bugs me a lot (LOL), so...
When you set up a move route for a character who was still earlier, (like in autorun events) the character starts moving, but the shadow remains in place.
Thoughts?
 
30
Posts
6
Years
The script is still a bit bugy. My shadows only work when I call out a following pokemon and left the room , meaning before I get a pokemon and let it follow, I have no shadow.
The script is underneath following script.
 
Last edited:
1,680
Posts
8
Years
  • Age 24
  • Online now
The script is still a bit bugy. My shadows only work when I call out a following pokemon and left the room , meaning before I get a pokemon and let it follow, I have no shadow.
The script is underneath following script.

The issue is because of this line.
Code:
return if defined?(Following_Activated_Switch) &&
              !$game_switches[Following_Activated_Switch]
If you have followers installed, it will turn off shadows for all characters until the follower is given.
changing it to
Code:
return if @is_follower && defined?(Following_Activated_Switch) &&
              !$game_switches[Following_Activated_Switch]
fixes that. But look at the Wolf's post to see the fix for the followers.
 

WolfPP

Spriter/ Pixel Artist
1,309
Posts
5
Years
I checked one more bug: If we have a event with Self-Switch, after switch event (A to B, etc) the shadow disappears. I am required to activate the following pokemon, because if in case I do not, all events with self-switch will have their shadows canceled after the event ends.
What could be?

I think its here:
Spoiler:


Or here:
Spoiler:
 
Last edited:

WolfPP

Spriter/ Pixel Artist
1,309
Posts
5
Years
Your fix for the pokemon follower works fine, but the shadows when i'm surfing or diving, still appears when the pokemon aren't follow you.

Did you check that part than i posted?
Spoiler:
 
Last edited:
220
Posts
9
Years
Did you check that part than i posted?
Spoiler:
 
Last edited:

WolfPP

Spriter/ Pixel Artist
1,309
Posts
5
Years
I added that line to the shadow overworld script by marin, that's why i reported the issue. Here:

I'm using v17.2 and works fine to me:
Spoiler:

Check if you are missed some code.
 
Last edited:
220
Posts
9
Years
I'm using v17.2 and works fine to me:
Spoiler:

Check if you are missed some code.

Well, i onl'y tested it in the sea tiles and not still water. If the only code that is needed is only that red line, then it should work,no?

Here is my shadows script:

Code:
#===============================================================================
# ■ Overworld Shadows by KleinStudio
# http://pokemonfangames.com
#
# * Making a overworld shadowless
# ** Method 1
#   - Add /noShadow/ to the event name
# ** Method 2
#   - Add the event name to Shadowless_EventNames
#     this is useful for doors for example.
# ** Method 3
#   - Create a new comment in the event and type "NoShadow"
#     If the event is a dependent event you have to put the comment
#     in the common event.
#==============================================================================#
#                          Overworld Shadows for v17                           #
#                                  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_Path = "Graphics/Pictures/OverworldShadows/shadow"

# Whether or not the event names below need to match in capitals as well.
Case_Sensitive = true

No_Shadow_If_Event_Name_Has = [
    # I like to use "extensions" like these. Up to you though.
  "NoShadow",
  "BerryPlant",
  "OutdoorLight",
  "Light",
  "HeadbuttTree",
  "HiddenItem",
  "Healing balls left",
  "Healing balls right",
  "Ballons",
  "Intro",
  "Event",
  "Door",
  "Gate",
  "Machine",
  "Truck",
  "PC",
  "Nurse",
  "Nurse Joy",
  "Nurse Chansey",
  "Mart Person",
  "TV Broadcast"
]

# 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"
]

# 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 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 = BitmapCache.load_bitmap(Shadow_Path)
    # 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.real_x - @character.map.display_x + 3) / 4 + (Game_Map::TILEWIDTH / 2)
    y = (@character.real_y - @character.map.display_y + 3) / 4 + (Game_Map::TILEHEIGHT)
    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 || @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 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)
      @shadow.visible = false unless self.visible
      [COLOR="Red"]@shadow.visible = false if (@is_follower || (@character && @character==$game_player)) && ($PokemonGlobal.surfing || $PokemonGlobal.diving)[/COLOR]
    end
  end
end
 
Last edited:

WolfPP

Spriter/ Pixel Artist
1,309
Posts
5
Years
Well, i onl'y tested it in the sea tiles and not still water. If the only code that is needed is only that red line, then it should work,no?

I think i made a better code to surf/dive. I recoded to recognize Terrain Tag:
Spoiler:


Check if will work.
 
Last edited:
220
Posts
9
Years
I think i made a better code to surf/dive. I recoded to recognize Terrain Tag:
Spoiler:


Check if will work.

This method works better for me, thanks. XD The only issue that i still have, is about water reflections, where the pokemon follower don't have reflection. I followed your fixes about this matter, but no sucess in this. I checked the terrain tags script, follower script, and stillwater script to see if i madded changes, but no. So, i was thinking, can you make a fix the same way you did with this for reflections?

The ledges thing works and all of other small fixes, only this still stands. Another thing that i noted, the overworld shadows script must be under pokemon follower script, if not, some fixes will not apply.
 

WolfPP

Spriter/ Pixel Artist
1,309
Posts
5
Years
This method works better for me, thanks. XD The only issue that i still have, is about water reflections, where the pokemon follower don't have reflection. I followed your fixes about this matter, but no sucess in this. I checked the terrain tags script, follower script, and stillwater script to see if i madded changes, but no. So, i was thinking, can you make a fix the same way you did with this for reflections?

The ledges thing works and all of other small fixes, only this still stands. Another thing that i noted, the overworld shadows script must be under pokemon follower script, if not, some fixes will not apply.

That thread its about Shadow Overworld, not Water Reflection to Following Pokemon Script.
Also, i think you are using Water Pound Bubble script made by Klein. If so, i'm trying to add inside v17.2.
 
220
Posts
9
Years
That thread its about Shadow Overworld, not Water Reflection to Following Pokemon Script.
Also, i think you are using Water Pound Bubble script made by Klein. If so, i'm trying to add inside v17.2.

Yes i'm using it, but i doesn't make the reflection problem i mentioned, because, i removed the script just for testing, and the problem is there, with or without the script by klein. And, i don't have more scripts related with the reflections thing. I will check for more info and tests.
 

Pikalex04

The Project Hyper creator (Discord: Pikalex04#3285
36
Posts
5
Years
Hey, I found another bug. When there is an autorun event (that hasn't shadow) that ends, the shadow for all events will disappear, even if overrated.
 
10
Posts
4
Years
  • Age 24
  • Seen Apr 11, 2020
Hi, i have two problems with this script related to the following pokemon compatibility: 1st The following pokemon shadow disappears when moving to a new map and the only way to get it work again is to press CTRL button which removes the sprite and press CTRL another time to make it appear and 2nd When i´m using the bicycle the following pokemon shadow still shows up.
 

WolfPP

Spriter/ Pixel Artist
1,309
Posts
5
Years
Hi, i have two problems with this script related to the following pokemon compatibility: 1st The following pokemon shadow disappears when moving to a new map and the only way to get it work again is to press CTRL button which removes the sprite and press CTRL another time to make it appear and 2nd When i´m using the bicycle the following pokemon shadow still shows up.

Install this one:
https://www.pokecommunity.com/showthread.php?t=421467
 
Back
Top