110 lines
4.3 KiB
Markdown
110 lines
4.3 KiB
Markdown
|
---
|
||
|
title: Node Timer und ABMs
|
||
|
layout: default
|
||
|
root: ../..
|
||
|
idx: 3.2
|
||
|
description: Lernen Sie, wie man ABMs zum Ändern von Mapblöcken erstellt.
|
||
|
redirect_from:
|
||
|
- /de/chapters/abms.html
|
||
|
- /de/map/abms.html
|
||
|
---
|
||
|
|
||
|
## Einleitung <!-- omit in toc -->
|
||
|
|
||
|
Die periodische Ausführung einer Funktion auf bestimmten Knoten ist eine häufige Aufgabe.
|
||
|
Minetest bietet dafür zwei Methoden: Aktive Mapblock Modifikatoren (ABMs) und Block-Timer(node timers).
|
||
|
|
||
|
ABMs scannen alle geladenen Map-Blöcke auf der Suche nach Blöcken, die einem Kriterium entsprechen.
|
||
|
Sie eignen sich am besten für Blöcken, die in der Welt häufig vorkommen,
|
||
|
wie zum Beispiel Gras.
|
||
|
Sie haben einen hohen CPU-Overhead, aber einen geringen Speicher- und Storage-Overhead.
|
||
|
|
||
|
Für Blöcke, die ungewöhnlich sind oder bereits Metadaten verwenden, wie Öfen
|
||
|
und Maschinen, sollten stattdessen Blocktimer verwendet werden.
|
||
|
Blocktimer funktionieren, indem sie die ausstehenden Timer in jedem MapBlock verfolgen und dann ausführen
|
||
|
wenn sie ablaufen.
|
||
|
Dies bedeutet, dass die Zeitgeber nicht alle geladenen Blöcke durchsuchen müssen, um Übereinstimmungen zu finden,
|
||
|
sondern stattdessen etwas mehr Speicherplatz für die Verfolgung
|
||
|
der ausstehenden Timer benötigen.
|
||
|
|
||
|
- [Blocktimer](#blocktimer)
|
||
|
- [Aktive Mapblock Modifikatoren](#aktive-mapblock-modifikatoren)
|
||
|
- [Sie sind dran](#sie-sind-dran)
|
||
|
|
||
|
## Blocktimer
|
||
|
|
||
|
Blocktimer sind direkt an einen einzelnen Knoten gebunden.
|
||
|
Sie können Blocktimer verwalten, indem Sie ein NodeTimerRef-Objekt erhalten.
|
||
|
|
||
|
```lua
|
||
|
local timer = minetest.get_node_timer(pos)
|
||
|
timer:start(10.5) -- in Sekunden
|
||
|
```
|
||
|
|
||
|
Wenn der Zeitgeber eines Blockes abgelaufen ist, wird die Methode `on_timer` in der Definitionstabelle des Blockes
|
||
|
aufgerufen. Die Methode benötigt nur einen einzigen Parameter, die Position des Blockes:
|
||
|
|
||
|
```lua
|
||
|
minetest.register_node("autotuer:offene_tuer", {
|
||
|
on_timer = function(pos)
|
||
|
minetest.set_node(pos, { name = "autotuer:offene_tuer" })
|
||
|
return false
|
||
|
end
|
||
|
})
|
||
|
```
|
||
|
|
||
|
Die Rückgabe von true in `on_timer` bewirkt, dass der Timer wieder für das gleiche Intervall läuft.
|
||
|
Es ist auch möglich, `get_node_timer(pos)` innerhalb von `on_timer` zu verwenden, stellen Sie nur sicher
|
||
|
dass Sie false zurückgeben, um Konflikte zu vermeiden.
|
||
|
|
||
|
Sie haben vielleicht eine Einschränkung bei den Zeitgebern bemerkt: Aus Optimierungsgründen ist
|
||
|
nur eine Art von Timern pro Blocktyp und nur ein Timer pro Block möglich.
|
||
|
|
||
|
|
||
|
## Aktive Mapblock Modifikatoren
|
||
|
|
||
|
Für die Zwecke dieses Kapitels ist Aliengras eine Grasart, die
|
||
|
in der Nähe von Wasser vorkommen kann.
|
||
|
|
||
|
```lua
|
||
|
minetest.register_node("aliens:gras", {
|
||
|
description = "Aliengras",
|
||
|
light_source = 3, -- Der Block strahlt Licht aus. Min 0, max 14
|
||
|
tiles = {"aliens_grass.png"},
|
||
|
groups = {choppy=1},
|
||
|
on_use = minetest.item_eat(20)
|
||
|
})
|
||
|
|
||
|
minetest.register_abm({
|
||
|
nodenames = {"default:dirt_with_grass"},
|
||
|
neighbors = {"default:water_source", "default:water_flowing"},
|
||
|
interval = 10.0, -- Wird alle 10 Sekunden ausgeführt
|
||
|
chance = 50, -- Jeder Block hat eine Chance von 1 zu 50 ausgewählt zu werden
|
||
|
action = function(pos, node, active_object_count,
|
||
|
active_object_count_wider)
|
||
|
local pos = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||
|
minetest.set_node(pos, {name = "aliens:gras"})
|
||
|
end
|
||
|
})
|
||
|
```
|
||
|
|
||
|
Dieser ABM läuft alle zehn Sekunden, und für jeden passenden Block besteht eine
|
||
|
Chance von 1 zu 50, dass es ausgeführt wird.
|
||
|
Wenn die ABM auf einem Block ausgeführt wird, wird ein fremder Grasblock über ihm platziert.
|
||
|
Bitte seien Sie gewarnt, dies löscht alle Blöcke, die sich zuvor an dieser Position befanden.
|
||
|
Um dies zu verhindern, sollten Sie eine Überprüfung mit minetest.get_node einbauen, um sicherzustellen, dass Platz für das Gras vorhanden ist.
|
||
|
|
||
|
Die Angabe eines Nachbarn(neighbor) ist optional.
|
||
|
Wenn Sie mehrere Nachbarn angeben, muss nur einer von ihnen vorhanden sein
|
||
|
vorhanden sein, um die Anforderungen zu erfüllen.
|
||
|
|
||
|
Die Angabe der Chance ist ebenfalls optional.
|
||
|
Wenn Sie die Chance nicht angeben, wird der ABM immer ausgeführt, wenn die anderen Bedingungen erfüllt sind.
|
||
|
|
||
|
## Sie sind dran
|
||
|
|
||
|
* Midas Berührung: Verwandelt Wasser alle 5 Sekunden mit einer Wahrscheinlichkeit von 1 zu 100 in Goldblöcke.
|
||
|
* Fäulnis: Verwandelt Holz in Dreck um, wenn Wasser der Nachbar ist.
|
||
|
* Brennen: Bringt jeden Luftknoten in Brand. (Tipp: "air" und "fire:basic_flame").
|
||
|
Warnung: Rechnen Sie damit, dass das Spiel abstürzt.
|