1

Mittwoch, 7. Februar 2018, 23:23

Tiles kopieren [RMXP] [RMVX Ace]

Letztens wurde im Forum gefragt, wie man Häuser auf einer Map erscheinen lassen könnte: Erscheinende und verschwindene Gebäude
Ich habe dazu eine Scriptlösung vorgeschlagen, die ich dann heute auch nochmal für den RMXP umgesetzt habe. (Der originale Thread bezog sich auf den Ace.)

Die Idee ist man hat zwei Maps: Eine Map auf der der Spieler rumläuft ohne die Häuser und eine Map mit den Häusern. Bei Bedarf werden bestimmte Ausschnitte der anderen Map auf die aktive Map kopiert wodurch plötzlich Häuser erscheinen können.
Das Prinzip erinnert mich auch sehr an das "Häuser einrichten" aus den Elder Scrolls Titeln. Wer sich in Oblivion mal das Haus in der Kaiserstadt gekauft und mit allen Möbeln vollgestopft hat, kann es sich vielleicht vorstellen. Im Anhang ist ein RMXP-Projekt als Demo, das eben das hier vorgestellte Script benutzt um ein an ES angelehnte Einrichtungssystem umzusetzen.

:hammer: Nutzungsbedingung für das RMXP-Script

Einfache Nutzung in nicht-kommerziellen _RMXP_ Projekten ist gestattet.
Keine kommerzielle Nutzung gestattet. Für Lizenzen an den Autor wenden.
Keine Weiterverbreitung in originaler oder abgeänderter Form gestattet.


Wer eine kommerzielle Lizenz benötigt schreibt mir einfach eine PN. :-)
Die Bedingungen für das Ace-Script sind analog.

  • :ruby: Quellcode

    Ich habe das Script für verschiedene Maker umgesetzt. Wenn ihr es auch als MV-Plugin braucht oder für den RPG Maker VX schreibt es in den Thread. Dann reiche ich das auch noch nach. :-)

    Für den RPG Maker XP und VX Ace gilt: Einfach das Script als neues Script über Main einfügen.
    Aufruf erfolgt per Event Call Script mit

    Ruby Quellcode

    1
    
    $game_map.copy_from( map_id, dx, dy, sx, sy, width, height)

    Wobei map_id die Id der Map ist, auf der das Haus steht. dx|dy ist die Position, wo er das Haus einfügen soll und [sx, sy, width, height] ist der Ausschnitt, den er von der anderen Map nehmen soll.
  • :rmxp: Script für den RPG Maker XP

    Ruby Quellcode

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
    #==============================================================================
    # ** Tiles einer anderen Map auf die aktuelle Map kopieren
    #    von Playm
    #------------------------------------------------------------------------------
    #  Angenommen wir haben zwei Maps M und N mit dem gleichen Tileset.
    #  Sei Map M die aktuelle Map auf der sich der Spieler befindet und
    #  wir nehmen an Map N hat die Id 57.
    #  Die Funktion $game_map.copy_from( 57, dx, dy, sx, sy, width, height)
    #  kopiert von Map N nun einen Ausschnitt der Breite +width+ und der Höhe
    #  +height+ und fühgt diesen Ausschnitt an der Position (dx|dy) auf die 
    #  aktuelle Map M ein.
    #  Es werden alle Tiles in dem Rechteck (dx,dy,width,height) mit den Tiles
    #  von der anderen Map im Rechteck (sx,sy,width,height) überschrieben.
    #  
    #  Die Änderung wird nicht gespeichert. Ein Neuladen der Map setzt diese
    #  Änderung also zurück. Möchte man die Änderung dauerhaft haben, sollte
    #  ein ParallelProcess-Event auf Map M laufen, dass bei Mapbetreten die 
    #  neuen Tiles einfügt und sich dann mit "Event entfernen" selbst rausnimmt.
    #==============================================================================
    # ** Game_Map
    #==============================================================================
    class Game_Map
      #--------------------------------------------------------------------------
      # * Copy part of another map to the current map
      #--------------------------------------------------------------------------
      def copy_from(map_id, dx, dy, sx, sy, width, height)
        other_map = load_data(sprintf("Data/Map%03d.rxdata", map_id))
        if $data_tilesets[other_map.tileset_id].tileset_name != @tileset_name
          print "Unpassendes Tileset in Map##{map_id}"
          return
        end
        for ix in 0...width
          for iy in 0...height
            for z in 0..2
              @map.data[dx+ix,dy+iy,z] = other_map.data[sx+ix,sy+iy,z]
            end
          end
        end
      end
    end
  • :ace: Script für den RPG Maker VX Ace

    Ruby Quellcode

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
    #==============================================================================
    # ** Tiles einer anderen Map auf die aktuelle Map kopieren
    #    von Playm
    #------------------------------------------------------------------------------
    #  Angenommen wir haben zwei Maps M und N mit dem gleichen Tileset.
    #  Sei Map M die aktuelle Map auf der sich der Spieler befindet und
    #  wir nehmen an Map N hat die Id 57.
    #  Die Funktion $game_map.copy_from( 57, dx, dy, sx, sy, width, height)
    #  kopiert von Map N nun einen Ausschnitt der Breite +width+ und der Höhe
    #  +height+ und fühgt diesen Ausschnitt an der Position (dx|dy) auf die 
    #  aktuelle Map M ein.
    #  Es werden alle Tiles in dem Rechteck (dx,dy,width,height) mit den Tiles
    #  von der anderen Map im Rechteck (sx,sy,width,height) überschrieben.
    #  
    #  Die Änderung wird nicht gespeichert. Ein Neuladen der Map setzt diese
    #  Änderung also zurück. Möchte man die Änderung dauerhaft haben, sollte
    #  ein ParallelProcess-Event auf Map M laufen, dass bei Mapbetreten die 
    #  neuen Tiles einfügt und sich dann mit "Event entfernen" selbst rausnimmt.
    #==============================================================================
    # ** Game_Map
    #==============================================================================
    class Game_Map
      #--------------------------------------------------------------------------
      # * Copy part of another map to the current map
      #--------------------------------------------------------------------------
      def copy_from(map_id, dx, dy, sx, sy, width, height)
        other_map = load_data(sprintf("Data/Map%03d.rvdata2", map_id))
        if other_map.tileset_id != @tileset_id
          print "Unpassendes Tileset in Map##{map_id}"
          return
        end
        for ix in 0...width
          for iy in 0...height
            for z in 0..3
              @map.data[dx+ix,dy+iy,z] = other_map.data[sx+ix,sy+iy,z]
            end
          end
        end
      end
    end
»Playm« hat folgende Datei angehängt:

2

Montag, 26. Februar 2018, 20:43

Hey Playm,

danke für die kleine Skript Arbeit.
Ich möchte betonen, dass die zu kopierenden Tiles auf der Destination Map nicht unbedingt an gleicher Stelle platziert werden müssen.
Es könnte vielleicht für den einen oder anderen durch die Demo der Eindruck enstehen :).

Ich hätte zwei (kleine) Zusatzfeatures als Anregung, welche das Ding noch interessanter machen würden.

1. Änderungen werden gespeichert
2. Änderungen direkt sichtbar machen ohne die Map neu betreten zu müssen

greetz

3

Montag, 26. Februar 2018, 21:01

Hallo schM0ggi,
versteht sich, dass dieses Script deine Aufmerksamkeit erregt. :-D

Zitat

Ich hätte zwei (kleine) Zusatzfeatures als Anregung, welche das Ding noch interessanter machen würden.

1. Änderungen werden gespeichert
In der Demo wird ja demonstriert, wie man mithilfe eines Switches die Änderung speichern kann. Ist das nicht ausreichend?

Zitat

2. Änderungen direkt sichtbar machen ohne die Map neu betreten zu müssen
Ich glaube da hast Du einen Bug gefunden. Eigentlich sollten die Änderungen direkt sichtbar sein. Zumindest bei meinen Tests war das so. Kannst Du eine Demo basteln, wo der Fehler auftritt?

4

Montag, 26. Februar 2018, 21:15

Hallo schM0ggi,
versteht sich, dass dieses Script deine Aufmerksamkeit erregt. :-D


Naja ... tehehe :pardon:


In der Demo wird ja demonstriert, wie man mithilfe eines Switches die Änderung speichern kann. Ist das nicht ausreichend?

Für fest vorgegebene Geschichten sicherlich. Für Bereiche, die dynamisch die Position wechseln können und/oder die Position dem Spieler überlassen wird eher weniger :).
In so einem Fall lassen sich schlecht alle möglichen Varianten per Event abfangen.


Ich glaube da hast Du einen Bug gefunden. Eigentlich sollten die Änderungen direkt sichtbar sein. Zumindest bei meinen Tests war das so. Kannst Du eine Demo basteln, wo der Fehler auftritt?

Kommando zurück. schM0ggi war etwas zu übereifrig. Alles gut!

greetz

5

Dienstag, 27. Februar 2018, 22:03

Zitat von »schM0ggi«

Zitat von »Playm«

In der Demo wird ja demonstriert, wie man mithilfe eines Switches die Änderung speichern kann. Ist das nicht ausreichend?

Für fest vorgegebene Geschichten sicherlich. Für Bereiche, die dynamisch die Position wechseln können und/oder die Position dem Spieler überlassen wird eher weniger :).
In so einem Fall lassen sich schlecht alle möglichen Varianten per Event abfangen.
Naja, sollange die Anzahl der platzierbaren Objekte endlich ist, kann ich jedem Objekt zwei eindeutige Variablen zuweisen, in denen ich X und Y Position speichere. Diese GameVariables setze ich dann so ein

Ruby Quellcode

1
$game_map.copy_from( map_id, $game_variables[14], $game_variables[15], sx, sy, width, height)
und wenn ich möchte speichere ich noch in einer weiteren GameVariable die betroffene Map ID für das Objekt und kann dann per ConditionalBranch den Scriptaufruf darauf beschränken, dass er nur ausgeführt wird wenn das Objekt auch wirklich auf dieser und nicht einer anderen Map platziert wurde.

Ich lehne mich mal nicht zu weit aus dem Fenster und behaupte, nur mit diesem Script da oben in Benutzung, kann ich ein minimalistisches Age of Empires eventen, inklusive Zeitalterwechsel und Gebäude bauen (wenn ich dafür wie auf der Playstation 2 die maximale Anzahl an baubaren Gebäuden beschränken darf), Ressourcen sammeln bekomme ich wohl auch noch hin.
(Oster-Challenge? 1 vs 1, AoE-Klon bauen?)


Hm, aber natürlich könnte man solche Änderungen auch per Script speichern. Dann würde ich natürlich auch das Patchen der Map von einem automatischen Script und keinem Event erledigen lassen. Wenn ich dann aber schon Anfange Spieldaten abzuspeichern und das Setup der Map zu verändern würde ich direkt mehr Features einbauen wollen, um zu rechtfertigen so tiefgreifend das Spielsystem zu ändern. Auf der anderen Seite, weiß ich nicht, wie sinnvoll solche Änderungen sind, wenn der Kern sich halt auch event lässt und nicht erfordert ältere SaveFile inkompatibel zu machen (was immer passiert, wenn man großartig Spieldaten zusätzlich abspeichern möchte).

6

Donnerstag, 1. März 2018, 10:33

Hey,

du hast Recht. Es lässt sich mit Events etwas basteln. Das ist mir klar und das war nicht mein Punkt.
Ich muss ja dennoch mir Gedanken machen, Variablen bereit halten und pro Map entsprechende Abfragen konstruieren und
damit einhergehende Möglichkeiten, welche ich dem Spieler gebe, abzufangen. Das mag bei paar Maps vllt. gut gehen.
Möchte man dem Spieler an vielen Orten diese Möglichkeiten bieten, könnte das ausarten. Sind nur Gedankenspiele von mir.
Und ja, wenn Status quo schon abgespeichert wird, macht es Sinn die Idee und das Skript auszubauen.

Keine Ahnung, ob dafür überhaupt Bedarf besteht. Gut vorstellen könnte ich mir so etwas in einem Spiel mit Survival Elementen.
Wo der Spieler eben die Möglichkeit hat Dinge zu bauen und platzieren. Vielleicht packt dich ja irgendwann die Motivation, haha.

greetz