Partagez
Aller en bas
vincentmhd
vincentmhd
Membre

Nombre de messages : 9
Age : 32
Localisation : Amiens
Distinction : aucune
Date d'inscription : 06/03/2009
http://vincentmhdmaker.canalblog.com/

Passabilité de Contours Empty Passabilité de Contours

le Dim 18 Oct 2009 - 19:43
Passabilité de Contours



-Introduction

Ce script a été réalisé par moi-même, vincentmhd, en me basant sur le script d'Ashka permettant de gérer les reliefs et les ponts.
(lien temporairement... j'espère)


-Description


Ce script permet de générer des exceptions de passabilités. Ces exceptions ont une passabilité répartie en 4 variables, correspondantes aux 4 directions (bas, gauche, droite et haut). Ainsi des éléments pourront être passables de diverses façons, seulement verticalement, horizontalement, seulement par la gauche, tout sauf la droite...toutes les combinaisons possibles.
Cette passabilité particulière s'applique aux tiles, mais aussi aux events.
Ainsi une porte, une grille, pourra faire moins d'une tile d'épaisseur ce qui est souvent plus logique...


-Installation

Ce script n'échappe pas à la régle du "copiez en dessous de material".
Il n'a pas de nécéssité particulière.
Il n'est pas compatible avec le script d'Ashka précédement cité (nous surchargeons les mêmes fonctions sans alias).


-Utilisation

-Les Tiles

Les tiles peuvent être modifier par l'appel de la méthode dans une insersion de script en event:
change_passage(fichier, x, y, down, left, right,up)

Cette méthode est similaire à celle d'Ashka, à l'exception de down, left, right, up qui prenne séparément, la valeur true si vous voulez rendre le côté concerné passable, soit false s'il doit être impassable.
Cependant, si vous n'avez pas assez de place pour tout inscrire (ce que arrivera sûrement), vous pouvez mettre 1 pour false et 0 pour true, le script fera la transcripstion si nécéssaire.
fichier correspond au nom du tileSet sur lequel se trouve la tuile à modifier (Attention: mettre des guillements).
x et y correspondent aux coordonnées de la tuile sur le tileSet. (Attention: les coordonnées commencent à zéro)

Nota: pour les auto-tiles, la passabilité de contours ne s'appliquent qu'aux contours de la zone dessinée avec l'auto-tile. L'interieur et les "bordures ouvertes" restent passables.
Nota: je n'ai analysé qu'un seul auto-tile, et je me suis basé sur le même modèle pour tous. (il se peut qu'il y ait des distinctions entre auto-tiles)

-Les Events

En ce qui concerne les events, je me suis inspiré du script d'effets lumineux. Il suffit d'inserer un commentaire sur la page active de l'event à modifier. La syntaxe est le suivante:

PASSABILITY XXXX

PASSABILITY permet au script de reconnaitre la demande.
Les X sont à remplacer par T ou F (respectivement True ou False). Ils sont quatres pour les 4 directions: bas, gauche, droite, haut.
Nota: il faut que le commentaire soit sur la page active de l'event en arrivant sur la map. Si la page active en arrivant sur la map est la page 2, par exemple, et que le commentaire est en page 1, le script ne détectera pas la commande.




-Démo


Une toute petite démo vous aidera à mieux y voir: lien vers la Démo



-Le script

Spoiler:

Code:
#
#                              Passabilité de contours V1.2
#
#Sur une idée originale d'Ashka.
#rpg-maker-vx.bactif.com
#
#Vincentmhd.
#http://vincentmhdmaker.canalblog.com/
#
#31/08/2009
#
#================NOTE=====
#Ce script permet de réaliser des passibilités de contours. Ainsi chaque côté
#d'un tile peut avoir une passabilité propre. Ce peut être utile pour des
#bordures, des barrières.
#
#Contrairement au script d'Ashka, il s'agit de modifications sur le long
#terme, même s'il est tout à fait possible de modifier les passabilités en event.
#
#Concernant les auto-tiles, leurs passabilités changent a leur bordures
#respectives, mais l'intérieur devient passable.
#Pour modifier un tile ou auto-tile, c'est comme dans le script d'Ashka,
#à la difference qu'il y a 4 bool à rentrer, pour les 4 directions.
#Les bools peuvent être substitué par de 0 pour true et 1 pour false si
#vous n'avez pas la place sur une ligne. (Ce qui sera sûrement le cas  ^^)
#Voilà la commande:
#
#change_passage(fichier, x, y, down, left, right,up)
#
#Il est aussi possible de modifier la passabilité des events.
#Pour se faire il suffit de le signaler en commentaire, par exemple:
#
#PASSABILITY FTTT
#
#PASSABILITY est obligatoire cela permet au script de reconnaitre une modification
#de passabilité.
#N'oubliez pas l'espace!!
#F correspond à false et T à true, ils informent si le personnage
#peut passer selon les quatre directions: bas, gauche, droite et haut.
#c'est relativement simple à utiliser.
#
#Bon making Vincentmhd...
#
#------------------------------

class Game_Character
  #ajout de passabilité particulière 
  attr_accessor :p
 
  alias mhd_initialize initialize
  def initialize
    mhd_initialize
    @p = []
  end 

  #    Fonction originelle de collision
  alias mhd_collide_with_characters? collide_with_characters?
  def collide_n (x,y)
  mhd_collide_with_characters?(x, y)
  end
 

  #    Fonction customisée
  #On renvoit s'il y a collision (l'inverse de la passabilité)
  def collide_c(x,y, direction)
    for event in $game_map.events_xy(x, y)          # Matches event position
      unless event.through                          # Passage OFF?
        if event.p.size > 2                        # s'il est customisé
          return !event.p[direction]               
        end
        return true if event.priority_type == 1    # Target is normal char
      end
    end
    if @priority_type == 1                          # Self is normal char
      if $game_player.pos_nt?(x, y)                # Matches player position
        if event.p.size > 2                        # s'il est customisé
          return !event.p[direction]               
        else
          return true
        end
      end
      if $game_map.boat.pos_nt?(x, y)              # Matches player position
        if event.p.size > 2                        # s'il est customisé
          return !event.p[direction]               
        else
          return true
        end
      end
      if $game_map.ship.pos_nt?(x, y)              # Matches player position
        if event.p.size > 2                        # s'il est customisé
          return !event.p[direction]               
        else
          return true
        end
      end
    end
    return false
  end
 

  #  Mix des deux versions
  def collide_with_characters?(xb, yb, xa, ya)
    bcustom = false
    acustom = false
    #determination si besoin de customiser
    for event in $game_map.events_xy(xb, yb)
      if event.p.size > 3
        bcustom = true
      end
    end
    for event in $game_map.events_xy(xa, ya)
      if event.p.size > 3
        acustom = true
      end
    end
    #Si customisation besoin du sens de circulation
    if (acustom || bcustom)
      dx = xa -xb
      dy = ya - yb
      if(dy == -1)
        a = 0
        b = 3
      end
      if (dx == 1)
        a = 1
        b = 2
      end
      if (dx == -1)
        a = 2
        b = 1
      end
      if (dy == 1)
        a = 3
        b = 0
      end
    end   
    if (bcustom == false)
      bpass = collide_n (xb, yb)
    else
      bpass = collide_c (xb, yb, b)
    end
    if (acustom == false)
      apass = collide_n (xa, ya)
    else
      apass = collide_c (xa, ya, a)
    end
   
    if(acustom == true) && (bcustom == false) && (apass == true)
      return apass
    else
      return (apass && bpass)
    end
  end
 
  #  Determine if Passable
  def passable?(xb, yb, xa = @x, ya = @y)
    x = $game_map.round_x(xb)                        # Horizontal loop adj.
    y = $game_map.round_y(yb)                        # Vertical loop adj.
    return false unless $game_map.valid?(xb, yb)      # Outside map?
    return true if @through or debug_through?      # Through ON?
    return false unless $game_map.passable?(xb,yb, xa, ya)        # Map Impassable?
    return false if collide_with_characters?(xb, yb, xa, ya)  # Collide with character?
    return true                                    # Passable
  end

end
#========Game_Map==========
#On va du tile A vers le tile B. Le principe est le même que pour le script
#originel. Un ash contient les exceptions de passabilité que vous voulez.
#----------------------------------------

class Game_Map
  #Tableau d'exception de passabilité
  attr_accessor :tab_passage 
  #Lecture des données de la map
  attr_reader :map
 
  alias mhd_initialize initialize
  def initialize
    mhd_initialize
    @tab_passage = {663=>[false,true,true,true]}
  end
 
  def boat_passable?(x, y)
    return passable?(x, y, x, y, 0x02)
  end

  # * Determine if Ship is Passable
  def ship_passable?(x, y)
    return passable?(x, y, x, y, 0x04)
  end

  # * Determine if Airship can Land
  def airship_land_ok?(x, y)
    return passable?(x, y, x, y, 0x08)
  end
 
  # On a toujours besoin de l'ancienne passabilité 
  alias mhd_passable?  passable?
  def normal_p (x, y, flag = 0x01)
    mhd_passable?( x, y, flag)
  end
 
  # création de notre passabilité
  def custom_p (x, y, direction, flag = 0x01)
    for event in events_xy(x, y)            # events with matching coordinates
      next if event.tile_id == 0            # graphics are not tiled
      next if event.through                # pass-through state
      if event.p.size > 2                  # s'il est customisé prime sur tout
        return event.p[direction]               
      end                                 
      next if event.priority_type > 0      # not [Below characters]
      pass = @passages[event.tile_id]      # get passable attribute
      next if pass & 0x10 == 0x10          # *: Does not affect passage
      return true if pass & flag == 0x00    # o: Passable
      return false if pass & flag == flag  # x: Impassable
    end
    for i in [2, 1, 0]                      # in order from on top of layer
      tile_id = @map.data[x, y, i]          # get tile ID
      return false if tile_id == nil        # failed to get tile: Impassable
      pass = @passages[tile_id]            # get passable attribute
     
      if (@tab_passage.key?(tile_id))      #
        return @tab_passage[tile_id][direction]
      end
      next if pass & 0x10 == 0x10          # *: Does not affect passage
      return true if pass & flag == 0x00    # o: Passable
      return false if pass & flag == flag  # x: Impassable
    end
  end
 
  # mix des deux! 
  def passable?( xb, yb, xa ,  ya, flag = 0x01)
    bcustom = false
    acustom = false
    #détermination si besoin de customiser
    for event in events_xy(xb, yb)
      if event.p.size > 3
        bcustom = true
      end
    end 
    for event in events_xy(xa, ya)
      if event.p.size > 3
        acustom = true
      end
    end   
    for i in [2, 1, 0]                     
      tileB_id = @map.data[xb, yb, i] 
      if (@tab_passage.key?(tileB_id))
        bcustom = true
      end
    end
    for i in [2, 1, 0]                     
      tileA_id = @map.data[xa, ya, i] 
      if (@tab_passage.key?(tileA_id))
        acustom = true
      end
    end
    #Si customisation besoin du sens de circulation
    if (acustom || bcustom)
      dx = xa -xb
      dy = ya - yb
      if(dy == -1)
        a = 0
        b = 3
      end
      if (dx == 1)
        a = 1
        b = 2
      end
      if (dx == -1)
        a = 2
        b = 1
      end
      if (dy == 1)
        a = 3
        b = 0
      end
    end
    if (bcustom == false)
      bpass = normal_p (xb, yb, flag)
    else
      bpass = custom_p (xb, yb, b, flag)
    end 
    if (acustom == false)
      apass = normal_p (xa, ya, flag)
    else
      apass = custom_p (xa, ya, a, flag)
    end
    return (apass && bpass)
  end
 
  # met à jour les passabilités   
  alias mhd_setup_events setup_events
  def setup_events
    mhd_setup_events
    setup_pass
  end
 
    def setup_pass
    for event in $game_map.events.values
      next if event.list == nil
      for i in 0...event.list.size       
        if event.list[i].code == 108
          a = ""
          a = event.list[i].parameters.to_s
          if a[0,11] == "PASSABILITY"
            ligne = ""
            ligne = event.list[i].parameters.to_s
            for i in 0...4
              info = ""
              info = ligne[(12 + i), 1]
              if info == "T"
                event.p[i]=true
              else
                event.p[i]=false
              end
            end
          end
        end
      end
    end
  end
end


  # Reprise de Ashka presque telle qu'elle 
  # Cependant pour faire les contours d'autotile, il y a un petit rajout
  # Je n'ai analysé qu'un seul autotile, alors j'espère qu'ils ont
  # tous la même forme sinon ce serait balaud...
class Game_Interpreter
  def autotile (min, down, left, right, up)
      $game_map.tab_passage[min + 16] = [true,left,true,true]
      $game_map.tab_passage[min + 17] = [true,left,true,true]
      $game_map.tab_passage[min + 18] = [true,left,true,true]
      $game_map.tab_passage[min + 19] = [true,left,true,true]
      $game_map.tab_passage[min + 20] = [true,true,true,up]
      $game_map.tab_passage[min + 21] = [true,true,true,up]
      $game_map.tab_passage[min + 22] = [true,true,true,up]
      $game_map.tab_passage[min + 23] = [true,true,true,up]
      $game_map.tab_passage[min + 24] = [true,true,right,true]
      $game_map.tab_passage[min + 25] = [true,true,right,true]
      $game_map.tab_passage[min + 26] = [true,true,right,true]
      $game_map.tab_passage[min + 27] = [true,true,right,true]
      $game_map.tab_passage[min + 28] = [down,true,true,true]
      $game_map.tab_passage[min + 29] = [down,true,true,true]
      $game_map.tab_passage[min + 30] = [down,true,true,true]
      $game_map.tab_passage[min + 31] = [down,true,true,true]
      $game_map.tab_passage[min + 32] = [true,left,right,true]
      $game_map.tab_passage[min + 33] = [down,true,true,up]
      $game_map.tab_passage[min + 34] = [true,left,true,up]
      $game_map.tab_passage[min + 35] = [true,left,true,up]
      $game_map.tab_passage[min + 36] = [true,true,right,up]
      $game_map.tab_passage[min + 37] = [true,true,right,up]
      $game_map.tab_passage[min + 38] = [down,true,right,true]
      $game_map.tab_passage[min + 39] = [down,true,right,true]
      $game_map.tab_passage[min + 40] = [down,left,true,true]
      $game_map.tab_passage[min + 41] = [down,left,true,true]
      $game_map.tab_passage[min + 42] = [true,left,right,up]
      $game_map.tab_passage[min + 43] = [down,left,true,up]
      $game_map.tab_passage[min + 44] = [down,left,right,true]
      $game_map.tab_passage[min + 45] = [down,true,right,up]
      $game_map.tab_passage[min + 46] = [down,left,right,up]
  end
 
  def change_passage(fichier, x, y, down, left, right,up)
    if down == 1
      down = false
    else
      down = true
    end
    if left == 1
      left = false
    else
      left = true
    end
    if right == 1
      right = false
    else
      right = true
    end
    if up == 1
      up = false
    else
      up = true
    end
    case fichier
    when "A1"
      min = 2048 + (((y * 8) + x) * 48)
      max = min + 47
      autotile (min, down, left, right, up)     
    when "A2"
      min = 2816 + (((y * 8) + x) * 48)
      max = min + 47
      autotile (min, down, left, right, up)
    when "A3"
      min = 4352 + (((y * 8) + x) * 48)
      max = min + 47
      autotile (min, down, left, right, up)
    when "A4"
      min = 5888 + (((y * 8) + x) * 48)
      max = min + 47
      autotile (min, down, left, right, up)
    when "A5"
      min = 1536 + ((y * 8) + x)
      max = min + 1
      for tile_id in min...max
        $game_map.tab_passage[tile_id] = [down,left,right,up]
      end
    when "B"
      min = 0 + ((y * 8) + x)
      max = min + 1
      for tile_id in min...max
        $game_map.tab_passage[tile_id] = [down,left,right,up]
      end
    when "C"
      min = 256 + ((y * 8) + x)
      max = min + 1
      for tile_id in min...max
        $game_map.tab_passage[tile_id] = [down,left,right,up]
      end
    when "D"
      min = 512 + ((y * 8) + x)
      max = min + 1
      for tile_id in min...max
        $game_map.tab_passage[tile_id] = [down,left,right,up]
      end
    when "E"
      min = 768 + ((y * 8) + x)
      max = min + 1
      for tile_id in min...max
        $game_map.tab_passage[tile_id] = [down,left,right,up]
      end
    end
  end
end

#  Modifie la notion de si touche est appuyée...
class Game_Player
  def check_event_trigger_here(triggers)
    return false if $game_map.interpreter.running?
    result = false
    for event in $game_map.events_xy(@x, @y)
      if triggers.include?(event.trigger) #changement ici on include aussi si la priorité est 1
        event.start
        result = true if event.starting
      end
    end
    return result
  end
end



-Crédit:
Ashka, Vincentmhd
Revenir en haut
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum