Open webD97 opened 6 years ago
I've not read this in detail yet, but after skimming this, it seems to look good.
One little problem: You can't register anything in minetest.after(). This is a limitation of the Minetest engine. I suggest to run minetest.register_node() directly inside the streets.roads.register_label() function.
Ah, so this is still not possible? I always thought minetest.after(0, function) would be run before the first server step, but it seems like it's running on the first server step. I'll need to think of something different then. It's not possible to register the node directly within register_label() because this would mean that surfaces registered after this will be ignored.
As far as I can see, surfaces can only be different colors of asphalt.
Maybe we then could avoid the register_surface() by controlling the available asphalt colors ( = different surfaces) with a setting.
I know, this is not very elegant, but it would be a simple and light-weight approach.
We would still need a way to the the API which nodes are "base nodes" for markings though.
We could do this with three simple settings:
streets.roads.surface_all_markings = black,red
(all marking variations get registered for these surfaces)streets.roads.surface_limited_markings = blue
(a limited subset of marking variations will be registered for this surface)streets.roads.surface_no_markings = white
(no markings will be registered for this surface)The lines above are no final suggestions, they should only show the concept.
What I meant was: How do we tell the API which nodes to put the labels on? I really don't want to hardcode this...
I fear the only possible way would be hardcoding. As far as I can see, only customization with settings would be technically possible.
I would prefer a register_surface() function, too, but I don't think this is possible.
I'm sure there is a way. Nothing's impossible ;) I'll think about it this weekend.
I think I found a possible solution.
I'll code it today to see if it works as expected.
What do you think about this code? (untested)
streets.roads = {}
streets.roads.registered_labels = {}
streets.roads.registered_surfaces = {}
local register_combination = function(label_name, label_def, surface_name, surface_def)
-- register nodes
end
streets.roads.register_surface = function(name, def)
streets.roads.registered_surfaces[name] = def
for label_name, label_def in streets.roads.registered_labels do
register_combination(label_name, label_def, name, def)
end
end
streets.roads.register_label = function(name, def)
streets.roads.registered_labels[name] = def
for surface_name, surface_def in streets.roads.registered_surfaces do
register_combination(name, def, surface_name, surface_def)
end
end
I made a new suggestion for the roads API based on your suggestion and the signs API in 1eccfa06fa385dfca8dddbd7e27bdbed874b3259.
Quote from api.md
:
streets.roads.register_label_collection()
streets.roads.register_label_collection({
name = "sidelines",
description = "Sidelines",
})
name
is an unique technical name for the collection.
Allowed characters are: [a-zA-Z0-9-]
description
is a human-readable description of the collection.
If left blank, it will be auto-generated from the name
field.Registered collections are stored in streets.roads.registered_label_collections
.
streets.roads.registered_label_collections
is structured as follows:
streets.roads.registered_collections = {
["sidelines"] = {
name = "sidelines",
description = "Sidelines",
}
}
streets.roads.registered_label_collections
must not be accessed directly.
Use streets.roads.get_label_collection_definition(name)
instead,
which returns a copy of the definition or nil.
name
is the unique name of the collection, whose definition you want to get.
streets.roads.register_label()
streets.roads.register_label({
name = "solid",
description = "Solid Sideline",
belongs_to = "sidelines",
})
name
is an unique technical name inside the collection for the label.
Allowed characters are: [a-zA-Z0-9-]
description
is a human-readable description of the label.
If left blank, it will be auto-generated from the name
field.belongs_to
is the name of the collection this label belongs to.To avoid confusions use <collection name>:<label name>
when referring to labels.
Registered labels are stored in streets.roads.registered_labels
.
streets.roads.registered_labels
is structured as follows:
streets.roads.registered_labels = {
["sidelines:solid"] = {
name = "solid",
description = "Solid Sideline",
belongs_to = "sidelines",
}
}
streets.roads.registered_labels
must not be accessed directly.
Use streets.roads.get_label_definition(name)
instead,
which returns a copy of the definition or nil.
name
is the unique name of the label, whose definition you want to get.
It must have the format <collection name>:<label name>
.
You can get a table of label definitions with
streets.signs.get_label_definitions_by_collection(<collection name>)
.
streets.roads.register_surface()
streets.roads.register_surface({
name = "asphalt",
description = "Asphalt",
})
name
is an unique technical name for the surface.
Allowed characters are: [a-zA-Z0-9-]
description
is a human-readable description of the surface.
If left blank, it will be auto-generated from the name
field.Registered surfaces are stored in streets.roads.registered_surfaces
.
streets.roads.registered_surfaces
is structured as follows:
streets.roads.registered_surfaces = {
["asphalt"] = {
name = "asphalt",
description = "Asphalt",
}
}
streets.roads.registered_surfaces
must not be accessed directly.
Use streets.roads.get_surface_definition(name)
instead,
which returns a copy of the definition or nil.
name
is the unique name of the surface, whose definition you want to get.
I'm looking forward to your comments.
(This is still WIP, details following within the next days)
streets.roads.register_surface(name, surface_definition)
This will put the definition into a local table
streets.roads.register_label(name, label_definition)
This will put the definition into a local table
To allow for other mods (and therefore our own submods) to register their own surfaces and labels, this code only puts the definition into the private tables. They will be registered in a minetest.after(0, function) function to make sure that all other code has already been run, so that all definitions are there.
streets.roads.register_registration_hook(function)
Additionally, there should be streets.roads.register_registration_hook(function) function to allow other mods and submods to execute custom code during the registration of a road node. This could be used by #101 to register stairs.