Latest Posts

Topic: Mauern Skript

hessenfarmer
Avatar
Joined: 2014-12-11, 22:16
Posts: 2708
Ranking
One Elder of Players
Location: Bavaria
Posted at: 2024-09-13, 08:43

MIt der oben beschriebenen Skriptvariante würde n die Probleme 3 und 4 entfallen.
für Problem 5 braucht man ja kein Immovable sondern lediglich einen Marker wie für die Priorisierung der Abholzung oder eine pinned note.
Problem 2 sollte eigentlich derzeit bereits möglich sein.


Top Quote
kaputtnik
Avatar
Joined: 2013-02-18, 19:48
Posts: 2489
OS: Archlinux
Version: current master
Ranking
One Elder of Players
Location: Germany
Posted at: 2024-09-13, 08:51

Evtll verstehe ich das Problem nicht ganz, aber:

Wenn zwei Mauer Objekte sich nicht auf der gleichen Höhe befinden , ist ein graphischer Versatz bei Ihrer Verbindung zu sehen .
- Es ist noch nicht möglich abzufragen auf welcher Höhe sich Objekte befinden .

Jedes Feld, besser gesagt Knoten oder Schnittpunkt, hat eine Höhe, siehe: https://www.widelands.org/documentation/autogen_wl_map/#wl.map.Field.height


Fight simulator for Widelands:
https://wide-fighter.netlify.app/

Top Quote
Teayo
Avatar
Topic Opener
Joined: 2015-03-09, 21:11
Posts: 182
OS: Windows 11 Home 64-bit
Version: 1.2 from Juni (06) 2023
Ranking
Widelands-Forum-Junkie
Location: Deutschland
Posted at: 2024-09-15, 17:53

@hessenfarmer
In Bezug zu deinen letzten Skript Vorschlag hier von mir nochmal ausführlicher , auch damit ich es besser verstehe :

  1. Der Arbeiter:Maurer nutzt findobject um einen Objekt:Marker zu finden , und geht dort hin , mittels walk=object .
  2. Wenn der Arbeiter:Maurer den Objekt:Marker erreicht hat , wird das Skript von hessenfarmer mittels include=skript.lua aufgerufen .
  3. Das Skript startet an der Position des Arbeiters ( worker.field ) und sucht zunächst den Marker , um dessen Position zu ermitteln .
    get_value_from_selected_object Objekt:Marker oder Arbeiter:Maurer , Variable : position[x.y] .
    get_value_from_world for position[x.y] , Variable : position[z] (Höhe) .
    Die Position des Arbeiter:Maurer = Position des Objekt:Marker , da der Arbeiter:Maurer sich beim Objekt:Marker befindet .
  4. Von der Position des Objekt:Marker wird Reihum , in der Reihenfolge : [ east , north-east , north-west , south-east , south-west , west ]
    in jeder Richtung das Nachbarfeld geprüft , ob sich dort ein Objekt:Mauer befindet .
  5. Sollte dort bereits ein Mauerteil sein ( has_attribute = wall ) oder findobject=attribute:empire_plus_immovable_wall wird per String-Pattern ( String-Muster ) suche
    das Bit-Muster ( Bit-Pattern ) aus dem Namen ( immovable.name ) extrahiert und das richtige Bit hinzugefügt ,
    wenn nicht bereits existent ( zum Beispiel weil es ursprünglich schon mal eine Verbindung zwischen den beiden Mauer-Positionen gab , welche zerstört wurde .
  6. Dann wird das vorhandene Objekt:Mauer ( Mauerteil ) mit dem neuen Objekt:Mauer ( Mauerteil ) inklusive der neuen Anschlussrichtung ausgetauscht und
    das korrespondierende Bit in das Bit-Muster ( Bit-Pattern ) für das Mauerteil an der Objekt:Marker Position eingefügt .
    Korrespondierende Bits sind :
    100001 east-west
    010010 north-east-south-west
    001100 north-west-south-east
  7. Zum Schluß wird der Objekt:Marker durch ein Objekt:Mauer ( Mauerteil ) ausgetauscht , mit dem ermittelten Bit-Muster ( Bit-Pattern ) .

Möchtest du mit deinen Skript das Mauer Objekt direkt manipulieren ?
data edit object=selected_object attribute=object.name set value "Konstante + Bit-Muster" [Value-Type:String]
Weil es gibt schon einen Unterschied ob ein Objekt direkt manipuliert wird und zwischen der Aktion transform die zusätzlich bewirkt ,
dass das main Programm für das transformierte Objekt gesetzt wird .
Also meinerseits kann ich versichern das es mit meinen Vorschlag bei der Aktionserweiterung möglich sein wird , das richtige Mauer Objekt für beide Mauer Objekte zu ermitteln .
Für Detais siehe dazu meine vorherigen Posts .

Außerdem noch ein wichtiger Punkt meinerseits , ein Skript ist sehr stark auf seinen Bereich , in diesen Fall , auf die Mauer-Funktion beschränkt .
Die Aktionserweiterung für call , on_failure und teilweise auch für findobject lassen sich dafür auch bei zukünftigen Ideen und anderen Bereichen nutzen .

Also ich präferiere weiterhin die Lösung durch die Aktionserweiterung , statt dem Skript , unter anderen auch deswegen ,
weil ich nicht einschätzen kann , was man alles mit so einen Skript machen kann .
Allerdings brauche ich auch von euch nun eine klare Entscheidung , den ich möchte mir unnötigen Aufwand ersparen
und die Programme für die Mauern und den Maurer , nur möglichst wenig ändern ,
da mich das letzlich auch Zeit kostet . Bisher ist alles teilweise schon für meinen Lösungsweg ausgerichet ,
auch wenn ich am Zug bin und die Programme aller Mauer Objekte nochmal anpassen muss .
Bisher sind die Mauer Objekt Programme noch für die alte Lösung mit den Objekt Impulsen ausgerichtet ,
beziehungsweise , noch gar nicht vorhanden ( Programme ) , da es damals für mich noch unklar war , wie die Lösung aussehen wird .

Noch eine wichtige Frage , soll das aktuelle Bit-Muster was auch in der Mauer Objekt Namensgebung verwendet wird , so beibehalten werden ?
Das Bit kann "0" sein oder "e0" oder "east.0" sein , relevant ist hier die Anordnung der Richtungen in der Reihenfolge .

Aktuelles
Oben / Unten
Aktuelles
Rechts / Links
Aktuelles
Korrespondierende Bits
Geändertes
Oben / Unten
Geändertes
Rechts / Links
Geändertes
Korrespondiere Bits
east 100001 east 100001
north east 010010 west 100001
north west 001100 north east 010010
south east 001100 north west 001100
south west 010010 south east 001100
west 100001 south west 010010


@kaputtnik , in Bezug zu deinen Post ,
Als ich in der Vergangenheit mal Nordfriese in einer Privat-Nachricht danach fragte , antwortete er mir , das es aktuell in Widelands nicht möglich sei für ein Objekt ,
Variablen zu speichern und zu verarbeiten und das es auch nicht möglich ist die Höhe auf der sich ein Objekt befindet zu ermitteln .

Wie man dieses Höhen-Problem löst , schwierig , der Lösungsweg über weitere Mauer Objekt Varianten wird naja brutal , ( 84 * 2 * 3 ) * 6 = 3.024 Objekte . Das ist krank und wahnsinnig .
Da macht eine Lösung über die Render-Engine vielleicht mehr Sinn , "Bild verzerren" . Verzerrungsstärke = Delta-Höhen Unterschied zwischen Mauer Objekt 1 und Mauer Objekt 2 .
Aber dieses Problem interessiert mich momentan und auch auf absehbare Zeit nicht , erstmal möchte ich es überhaupt grundlegend Funktionsfähig bekommen .
Das Höhen-Problem ist nur ein graphisches Problem .

Edited: 2024-09-15, 17:55

Das Imperium schlägt zurück ! TY

Top Quote
hessenfarmer
Avatar
Joined: 2014-12-11, 22:16
Posts: 2708
Ranking
One Elder of Players
Location: Bavaria
Posted at: 2024-09-15, 20:25

Die Möglichkeit für Mapobjekte "normale" lua Skripte auszuführen, wurde explizit mit der Begründung implementiert, dass es Ideen für Addons gibt, die die Möglichkeiten der jetzigen Engines der Mapobjektprogramme sprengen. Deine Idee isr definitv eine davon.
Daher präferiere ich den Weg der Nutzung eines Skripts, da eine Implementierung ohne jede Änderung im Hauptspiel per Addon zumindest möglich ist.
Wenn wir ansonsten anfangen, für jede noch ausgefeiltere Idee eines Addons immer unseren "normalen" Code anzupassen, fürchte ich wir öffnen die Büchse der Pandora.
Wenn du wissen willst, wie sowas mit einem einfachen Skript funktioniert, kannst du dir das Addon im Anhang anschauen.

Das Bit Muster kann entweder in binärer Notation oder auch asl dezimale Repräsentation am NAmen hängen. Wichtig ist aber, dass es eine reine zusammenhängende Zahl ist, da dann die Stringmanipulation in lua deutlich einfacher ist.

Das Höhen Problem wird wohl eher nicht zu lösen sein.


Attachment:
forestfire.wad.zip (2.5 KB)

Top Quote
hessenfarmer
Avatar
Joined: 2014-12-11, 22:16
Posts: 2708
Ranking
One Elder of Players
Location: Bavaria
Posted at: 2024-09-15, 21:41

Zum besseren Verständnis anbei der erste (ungetestete) Entwurf des Skriptes.

function buildwall(worker)
    local map = wl.Game().map
   local wall_field = nil
    for i,field in ipairs(worker.field:region(2, 0)) do
        if field.bob and field.bob.name == "pinned_note" then
            wall_field = field
        end
    end
   local wall_bit_pattern = 0
   -- east
   if wall_field.rn.immovable and wall_field.rn.immovable:has_attribute("empire_wall") then
      wall_bit_pattern = wall_bit_pattern | 1
      local new_neighbour_pattern = string.match(wall_field.rn.immovable.name, '%S+$') | 8
      wall_field.rn.immovable.remove()
      map:place_immovable("empire_wall" .. new_neighbour_pattern, wall_field.rn)
   end
   -- northeast
   if wall_field.trn.immovable and wall_field.trn.immovable:has_attribute("empire_wall") then
      wall_bit_pattern = wall_bit_pattern | 2
      local new_neighbour_pattern = string.match(wall_field.trn.immovable.name, '%S+$') | 16
      wall_field.trn.immovable.remove()
      map:place_immovable("empire_wall" .. new_neighbour_pattern, wall_field.trn)
   end
   -- northwest
   if wall_field.tln.immovable and wall_field.tln.immovable:has_attribute("empire_wall") then
      wall_bit_pattern = wall_bit_pattern | 4
      local new_neighbour_pattern = string.match(wall_field.tln.immovable.name, '%S+$') | 32
      wall_field.tln.immovable.remove()
      map:place_immovable("empire_wall" .. new_neighbour_pattern, wall_field.tln)
   end
   -- west
   if wall_field.ln.immovable and wall_field.ln.immovable:has_attribute("empire_wall") then
      wall_bit_pattern = wall_bit_pattern | 8
      local new_neighbour_pattern = string.match(wall_field.ln.immovable.name, '%S+$') | 1
      wall_field.ln.immovable.remove()
      map:place_immovable("empire_wall" .. new_neighbour_pattern, wall_field.ln)
   end
   -- southwest
   if wall_field.bln.immovable and wall_field.bln.immovable:has_attribute("empire_wall") then
      wall_bit_pattern = wall_bit_pattern | 16
      local new_neighbour_pattern = string.match(wall_field.bln.immovable.name, '%S+$') | 2
      wall_field.bln.immovable.remove()
      map:place_immovable("empire_wall" .. new_neighbour_pattern, wall_field.bln)
   end
   -- southeast
   if wall_field.brn.immovable and wall_field.brn.immovable:has_attribute("empire_wall") then
      wall_bit_pattern = wall_bit_pattern | 32
      local new_neighbour_pattern = string.match(wall_field.brn.immovable.name, '%S+$') | 4
      wall_field.brn.immovable.remove()
      map:place_immovable("empire_wall" .. new_neighbour_pattern, wall_field.brn)
   end
   wall_field.bob.remove()
   map:place_immovable("empire_wall" .. wall_bit_pattern, wall_field)
end

Da lua keine echte Binärnotation hat sollten die Bittpattern dezimal aufgebaut sein mit den werten Ost = 1, Nordost = 2, Nordwest = 4, ....., Südost = 32,

das zugehörige Arbeiterprogramm für eine funktionierende Implementierung auf Basis der Nutzung von pinned notes als Mauermarker könnte lauten.
(Funktion zum Finden von Mapobjekten per Name wurde heute in master aufgenommen)

findobject=type:special name:pinned_note radius:15
walk=object
script=buildwall
return

Top Quote
Teayo
Avatar
Topic Opener
Joined: 2015-03-09, 21:11
Posts: 182
OS: Windows 11 Home 64-bit
Version: 1.2 from Juni (06) 2023
Ranking
Widelands-Forum-Junkie
Location: Deutschland
Posted at: 2024-09-15, 22:38

Oke ich habe mir das forestfire.wad Addon angeschaut und den Code schreibe ich hier jetzt nicht , da er strukturell gleich dem Code ist , von deinem letzten Post .

findobject=type:special name:pinned_note radius:15
walk=object
script=buildwall
return

Ich finde die Lösung per Haftnotiz nicht so gut , da sich ein UI-Fenster öffnet , indem man den Namen als auch die Farbe der Haftnotiz definieren kann .
Diese UI-Fenster interaktion macht das erstellen eines Mauer Verlaufes klick intensiv und daher aufwändig .
Solange das nur eine temporäre Lösung ist , für Testzwecke , dann habe ich damit kein Problem .
Aber in der finalen Version möchte ich dann schon ein eigenes Marker Objekt haben , was eher dem Marker ähnelt , den es schon gibt um den Abbau von Bäumen und Felsen zu priorisieren .
Und das es genau wie bei den Holzfällerhütten und Steinbrüchen der Fall ist , das der Marker nur platziert werden kann , innerhalb des Arbeitsradius des Mauerbauer Gebäudes .

function buildwall(worker)
    local map = wl.Game().map
...
end

Ich bin vollkommen überfordert , ich verstehe das im Gegensatz zu den Programm Aktionen gar nicht , aber oke .

Benötigt für hessenfarmers Skript

Oke also du brauchst für dein Skript einen standardisierten technischen Namen für die Mauer Objekte :
[stamm][objekt-typ][objekt-gruppe][lokaler-objekt-index][objekt-verbindungen]
empire_plus_immovable_wall_01.84_connections.0_type.1_rotation.1_east.0_north-east.0_north-west.0_south-east.0_south-west.0_west.0
wird zu
empire_plus_immovable_wall_01.84_000000
Zeichen 1 bis Zeichen 33 Teil 1 vom Namen , Zeichen 34 bis Zeichen 39 Teil 2 vom Namen . Teil 2 vom Namen ist das Bitpattern .
Der lokale Objekt Index 01.84 muss unbedingt im Namen enthalten sein und dieser verändert sich ( 01 ) auch , genauso wie das Bitpattern bei jeden Mauer Objekt .

Enthält dein Skript auch die Verriegelung gegen überlagerte Mauer Bearbeitungen und bedenke das der Aufbau 60 Sekunden dauert und der Abbau 240 Sekunden dauert ,
wobei die 60 Sekunden beziehungsweise 240 Sekunden veränderlich sind , wegen der späteren finalen Version , Balancing .

Wenn dein Skript keine Verriegelung gegen überlagerte Mauer Bearbeitungen beinhaltet , dann stelle ich diese bereit :

Bereitgestellte Mauer-Objekte-Sets

Mauer-Objekte-Set-1 : 84 Objekte ( size : medium , nicht-passierbar , nicht-bebaubar )
empire_plus_immovable_wall_01.84_000000
Mauer-Objekte-Set-2 : 84 Objekte ( size : medium , nicht-passierbar , nicht-bebaubar )
empire_plus_immovable_wall_on_change_01.84_000000
In diesen Fall wird dein Skript auf das Set 2 , also obriges zurückgreifen , dann ist ein Schutz für überlagerter Bearbeitung gegeben .

callobject=change_wall (empire_plus_immovable_wall_01.84_000000)
transform=empire_plus_immovable_wall_on_change_01.84_000000
script=buildwall / destroy_wall
callobject=change_wall (empire_plus_immovable_wall_on_change_01.84_000000)
transform=empire_plus_immovable_change_01.84_000000

Mauer-Objekte-Set-3 : 84 Objekte ( size : small , passierbar , nicht-bebaubar )
empire_plus_immovable_wall_damaged_01.84_000000
Mauer-Objekte-Set-4 : 84 Objekte ( size : small , passierbar , nicht-bebaubar )
empire_plus_immovable_wall_damaged_on_change_01.84_000000
Mauer-Objekte-Set-5 : 84 Objekte ( size : none , passierbar , bebaubar )
empire_plus_immovable_wall_ruin_01.84_000000
Mauer-Objekte-Set-6 : 84 Objekte ( size : none , passierbar , bebaubar )
empire_plus_immovable_wall_ruin_on_change_01.84_000000

Gesamt : 6 Mauer-Objekte-Sets , 84 * 6 = 504 Mauer-Objekte
Mauer-Marker ( Temporär Haftnotiz ) + build ---> Set 1 (wall)
Set 3 (damaged) + build ---> Set 1
Set 5 (ruin) + build ---> Set 1
Set 1 (wall) + destroy ---> Set 3
Set 3 (damaged) + destroy ---> Set 5

Set Größe von 84 = V0.1 + V1.1 + V2.1 + V2.2 + V2.3 + V3.1 + V3.2 + V3.3 + V3.4 + V4.1 + V4.2 + V4.3 + V5.1 + V6.1
84 = 6 + 6 + 6 + 6 + 6 + 6 + 6 + 6+ 6 + 6 + 6 + 6 + 6 + 6
genau genommen 64 = 1 + 6 + 3 + 6 + 6 + 6 + 6 + 2 + 6 + 6 + 6 + 3 + 6 + 1

Aufgrund deines letzten Posts gehe ich davon aus das die aktuelle Bit-Pattern Notation ( Siehe Tabelle von meinen letzten Post ) so bleibt und als Basis genommen wird .

Welche Programme benötigen die Mauer Objekte für dein Skript ?
Derzeit besitzen alle empire_plus_immovable_wall_... Mauer Objekte aus Set 1 folgende Programme :

change_wall : bewirkt eine transformation in die on_change Variante des Mauer Objektes ( Set 2 )

Derzeit besitzen alle empire_plus_immovable_wall_on_change... Mauer Objekte aus Set 2 folgende Programme :

construction_complete : bewirkt eine transformation in die normale Variante des Mauer Objektes ( Set 1 )
constrution : Animiert den kompletten Aufbau , danach Set 0 ( Mauer Marker )
destruction_complete : bewirkt eine transformation in die beschädigte Variante des Mauer Objektes ( Set 3 )
destruction : Animiert den kompletten Abbau , danach Set 1
change_east : bewirkt eine transformaton in die normale Variante des Mauer Objektes und ändert die Verbindung , aus 0 wird 1 und aus 1 wird 0 ( Set 1 )
change_north-east : ...
...
add_east : Animiert den Aufbau der Verbindung nach Osten . Das Kernstück und alle anderen Verbindungen ( mit 1 ) existieren bereits . Danach Set 0
...
remove_east : Animiert den Abbau der Verbindung nach Osten . Das Kernstück und alle anderen Verbindungen ( mit 1 ) existieren bereits . Danach Set 1
...

Gesamt : 2 + 2 + 6 + 6 + 6 = 22 Programme .


Das Imperium schlägt zurück ! TY

Top Quote
hessenfarmer
Avatar
Joined: 2014-12-11, 22:16
Posts: 2708
Ranking
One Elder of Players
Location: Bavaria
Posted at: 2024-09-16, 10:02
  1. ja die Nutzung einer Haftnotiz ist ein Workaround, um ggf. ein funktionierendes Addon als Proof of Concept zu erreichen.
  2. Die Nutzung eines Skriptes ermöglicht die Nutzung unserer gesamten lua Funktionen (https://www.widelands.org/documentation/reference/), anstelle der Beschränkung auf die definierten Mapobject Programme. Diese Funktionen werden z.B. in Szenarios oder in der Definition von Start oder Siegbedingungen verwendet.
  3. Damit das mit der Stringmanipulation funktioniert, muss der Name für alle Objekte wie folgt sein IDENTISCHER_NAME_FÜR_ALLE_MAUERN_bitpattern_in_dezimal also z.B. empire_wall_0 bis empire_wall_63
  4. Die Mauern brauchen zunächst überhaupt kein eigenes Programm, um zu funktionieren. Ggf. kann man aus grafischen Gründen welche für den Abbau nutzen.
  5. zum Thema Verriegelung: der Marker wird über findobject verriegelt. Die umliegenden Mauern werden im Bruchteil einer Millisekunde verändert, somit braucht es aus meiner Sicht für den Aufbau keiner Verriegelung. Einzig die Veränderung eines umliegenden Mauerteils, an dem ein Steinmetz versucht es abzubauen, könnte ein Problem sein. Das würde ich dann lösen, wenn ich es getestet habe und weiß wie sich das Problem manifestiert.

Aus meiner Sicht ist die Nutzung eines Skriptes, mit dem derzeitigen Code möglich und weniger Kompliziert als die Nutzung der Mapobjectprogramme.
Daher schätze ich die Chancen für eine Implemetierung aller notwendigen Mapobjectprogrammänderungen, um deinen Ansatz zu ermöglichen eher als gering ein.

Edited: 2024-09-16, 10:03

Top Quote
Teayo
Avatar
Topic Opener
Joined: 2015-03-09, 21:11
Posts: 182
OS: Windows 11 Home 64-bit
Version: 1.2 from Juni (06) 2023
Ranking
Widelands-Forum-Junkie
Location: Deutschland
Posted at: 2024-09-16, 14:51

Oke . Dann werde ich erstmal nur 2 Sets bereitstellen und das mit den beschädigten Mauern und den Mauer Ruinen kommt viel später .
Die Mauern werden dann erstmal nur 6 Programme , wie bisher haben , "change_east" , "change_..." , damit die Verknüpfung der Objekte als Backup gesichert bleibt ,
sollte es bei Tests im Namen und beim Bitpattern Probleme geben , das man zur not in der init die gültigen transforms sehen kann .

von empire_plus_immovable_wall_on_change_01.84_00
bis empire_plus_immovable_wall_on_change_84.84_63
und
von empire_plus_immovable_wall_01.84_00
bis empire_plus_immovable_wall_84.84_63

Und zur Richtungs Notation :

000000
00000X - east | 1
0000X0 - west | 2
000X00 - north-east | 4
00X000 - north-west | 8
0X0000 - south-east | 16
X00000 - south-west | 32

32+16+8+4+2+1=63 | check
Jetzt bin ich erst einmal eine Weile beschäftigt dies so anzupassen .


Das Imperium schlägt zurück ! TY

Top Quote
hessenfarmer
Avatar
Joined: 2014-12-11, 22:16
Posts: 2708
Ranking
One Elder of Players
Location: Bavaria
Posted at: 2024-09-16, 19:03

die "on_change" Elemente werden für meinen Ansatz momentan nicht benöttigt.
Der Name der Mauerteile also das was in der init.lua unter name = "----" steht und das auch in der register.lua verwendet wird, sollte wirklich für alle Teile gleich sein, und sich nur durch das Pattern unterscheiden.


Top Quote