Charakterbewegungen hinzugefügt, Deko hinzugefügt, Kochrezepte angepasst
This commit is contained in:
parent
95945c0306
commit
a0c893ca0b
1124 changed files with 64294 additions and 763 deletions
657
mods/moreblocks/stairsplus/.luacheckrc
Normal file
657
mods/moreblocks/stairsplus/.luacheckrc
Normal file
|
@ -0,0 +1,657 @@
|
|||
std = "lua51+luajit+minetest+stairsplus"
|
||||
unused_args = false
|
||||
max_line_length = 120
|
||||
|
||||
stds.minetest = {
|
||||
read_globals = {
|
||||
"DIR_DELIM",
|
||||
"dump",
|
||||
"dump2",
|
||||
|
||||
math = {
|
||||
fields = {
|
||||
abs = {},
|
||||
acos = {},
|
||||
asin = {},
|
||||
atan = {},
|
||||
atan2 = {},
|
||||
ceil = {},
|
||||
cos = {},
|
||||
cosh = {},
|
||||
deg = {},
|
||||
exp = {},
|
||||
factorial = {},
|
||||
floor = {},
|
||||
fmod = {},
|
||||
frexp = {},
|
||||
huge = {},
|
||||
hypot = {},
|
||||
ldexp = {},
|
||||
log = {},
|
||||
log10 = {},
|
||||
max = {},
|
||||
min = {},
|
||||
modf = {},
|
||||
pi = {},
|
||||
pow = {},
|
||||
rad = {},
|
||||
random = {},
|
||||
randomseed = {},
|
||||
round = {},
|
||||
sign = {},
|
||||
sin = {},
|
||||
sinh = {},
|
||||
sqrt = {},
|
||||
tan = {},
|
||||
tanh = {},
|
||||
},
|
||||
},
|
||||
table = {
|
||||
fields = {
|
||||
copy = {},
|
||||
concat = {},
|
||||
foreach = {},
|
||||
foreachi = {},
|
||||
getn = {},
|
||||
indexof = {},
|
||||
insert = {},
|
||||
insert_all = {},
|
||||
key_value_swap = {},
|
||||
maxn = {},
|
||||
move = {},
|
||||
remove = {},
|
||||
shuffle = {},
|
||||
sort = {},
|
||||
},
|
||||
},
|
||||
string = {
|
||||
fields = {
|
||||
byte = {},
|
||||
char = {},
|
||||
dump = {},
|
||||
find = {},
|
||||
format = {},
|
||||
gmatch = {},
|
||||
len = {},
|
||||
lower = {},
|
||||
match = {},
|
||||
rep = {},
|
||||
reverse = {},
|
||||
split = {},
|
||||
sub = {},
|
||||
trim = {},
|
||||
upper = {},
|
||||
},
|
||||
},
|
||||
vector = {
|
||||
fields = {
|
||||
add = {},
|
||||
angle = {},
|
||||
apply = {},
|
||||
check = {},
|
||||
combine = {},
|
||||
copy = {},
|
||||
cross = {},
|
||||
dir_to_rotation = {},
|
||||
direction = {},
|
||||
distance = {},
|
||||
divide = {},
|
||||
dot = {},
|
||||
equals = {},
|
||||
floor = {},
|
||||
from_string = {},
|
||||
length = {},
|
||||
metatable = {},
|
||||
multiply = {},
|
||||
new = {},
|
||||
normalize = {},
|
||||
offset = {},
|
||||
rotate = {},
|
||||
rotate_around_axis = {},
|
||||
round = {},
|
||||
sort = {},
|
||||
subtract = {},
|
||||
to_string = {},
|
||||
zero = {},
|
||||
},
|
||||
},
|
||||
|
||||
ItemStack = {
|
||||
fields = {
|
||||
add_item = {},
|
||||
add_wear = {},
|
||||
add_wear_by_uses = {},
|
||||
clear = {},
|
||||
get_count = {},
|
||||
get_definition = {},
|
||||
get_description = {},
|
||||
get_free_space = {},
|
||||
get_meta = {},
|
||||
get_metadata = {},
|
||||
get_name = {},
|
||||
get_short_description = {},
|
||||
get_stack_max = {},
|
||||
get_tool_capabilities = {},
|
||||
get_wear = {},
|
||||
is_empty = {},
|
||||
is_known = {},
|
||||
item_fits = {},
|
||||
peek_item = {},
|
||||
replace = {},
|
||||
set_count = {},
|
||||
set_metadata = {},
|
||||
set_name = {},
|
||||
set_wear = {},
|
||||
take_item = {},
|
||||
to_string = {},
|
||||
to_table = {},
|
||||
},
|
||||
},
|
||||
PerlinNoise = {
|
||||
fields = {
|
||||
get_2d = {},
|
||||
get_3d = {},
|
||||
},
|
||||
},
|
||||
PerlinNoiseMap = {
|
||||
fields = {
|
||||
calc_2d_map = {},
|
||||
calc_3d_map = {},
|
||||
get_2d_map = {},
|
||||
get_2d_map_flat = {},
|
||||
get_3d_map = {},
|
||||
get_3d_map_flat = {},
|
||||
get_map_slice = {},
|
||||
},
|
||||
},
|
||||
PseudoRandom = {
|
||||
fields = {
|
||||
next = {},
|
||||
},
|
||||
},
|
||||
PcgRandom = {
|
||||
fields = {
|
||||
next = {},
|
||||
rand_normal_dist = {},
|
||||
},
|
||||
},
|
||||
SecureRandom = {
|
||||
fields = {
|
||||
next_bytes = {},
|
||||
},
|
||||
},
|
||||
Settings = {
|
||||
fields = {
|
||||
get = {},
|
||||
get_bool = {},
|
||||
get_flags = {},
|
||||
get_names = {},
|
||||
get_np_group = {},
|
||||
remove = {},
|
||||
set = {},
|
||||
set_bool = {},
|
||||
set_np_group = {},
|
||||
to_table = {},
|
||||
write = {},
|
||||
},
|
||||
},
|
||||
VoxelArea = {
|
||||
fields = {
|
||||
MaxEdge = {},
|
||||
MinEdge = {},
|
||||
contains = {},
|
||||
containsi = {},
|
||||
containsp = {},
|
||||
getExtent = {},
|
||||
getVolume = {},
|
||||
index = {},
|
||||
indexp = {},
|
||||
iter = {},
|
||||
iterp = {},
|
||||
new = {},
|
||||
position = {},
|
||||
ystride = {},
|
||||
zstride = {},
|
||||
},
|
||||
},
|
||||
VoxelManip = {
|
||||
fields = {
|
||||
calc_lighting = {},
|
||||
get_data = {},
|
||||
get_emerged_area = {},
|
||||
get_light_data = {},
|
||||
get_node_at = {},
|
||||
get_param2_data = {},
|
||||
read_from_map = {},
|
||||
set_data = {},
|
||||
set_light_data = {},
|
||||
set_lighting = {},
|
||||
set_node_at = {},
|
||||
set_param2_data = {},
|
||||
update_liquids = {},
|
||||
update_map = {},
|
||||
was_modified = {},
|
||||
write_to_map = {},
|
||||
},
|
||||
},
|
||||
|
||||
minetest = {
|
||||
fields = {
|
||||
CONTENT_AIR = {},
|
||||
CONTENT_IGNORE = {},
|
||||
CONTENT_UNKNOWN = {},
|
||||
EMERGE_CANCELLED = {},
|
||||
EMERGE_ERRORED = {},
|
||||
EMERGE_FROM_DISK = {},
|
||||
EMERGE_FROM_MEMORY = {},
|
||||
EMERGE_GENERATED = {},
|
||||
LIGHT_MAX = {},
|
||||
MAP_BLOCKSIZE = {},
|
||||
PLAYER_MAX_BREATH_DEFAULT = {},
|
||||
PLAYER_MAX_HP_DEFAULT = {},
|
||||
add_entity = {},
|
||||
add_item = {},
|
||||
add_node = {},
|
||||
add_node_level = {},
|
||||
add_particle = {},
|
||||
add_particlespawner = {},
|
||||
after = {},
|
||||
async_event_handler = {},
|
||||
async_jobs = {},
|
||||
auth_reload = {},
|
||||
ban_player = {},
|
||||
builtin_auth_handler = {},
|
||||
bulk_set_node = {},
|
||||
calculate_knockback = {},
|
||||
callback_origins = {},
|
||||
cancel_shutdown_requests = {},
|
||||
chat_send_all = {},
|
||||
chat_send_player = {},
|
||||
chatcommands = {},
|
||||
check_for_falling = {},
|
||||
check_password_entry = {},
|
||||
check_player_privs = {},
|
||||
check_single_for_falling = {},
|
||||
clear_craft = {},
|
||||
clear_objects = {},
|
||||
clear_registered_biomes = {},
|
||||
clear_registered_decorations = {},
|
||||
clear_registered_ores = {},
|
||||
clear_registered_schematics = {},
|
||||
close_formspec = {},
|
||||
colorize = {},
|
||||
colorspec_to_bytes = {},
|
||||
colorspec_to_colorstring = {},
|
||||
compare_block_status = {},
|
||||
compress = {},
|
||||
cpdir = {},
|
||||
craft_predict = {},
|
||||
craftitemdef_default = {},
|
||||
create_detached_inventory = {},
|
||||
create_detached_inventory_raw = {},
|
||||
create_schematic = {},
|
||||
debug = {},
|
||||
decode_base64 = {},
|
||||
decompress = {},
|
||||
delete_area = {},
|
||||
delete_particlespawner = {},
|
||||
deserialize = {},
|
||||
detached_inventories = {},
|
||||
dig_node = {},
|
||||
dir_to_facedir = {},
|
||||
dir_to_wallmounted = {},
|
||||
dir_to_yaw = {},
|
||||
disconnect_player = {},
|
||||
do_async_callback = {},
|
||||
do_item_eat = {},
|
||||
dynamic_add_media = {},
|
||||
dynamic_media_callbacks = {},
|
||||
emerge_area = {},
|
||||
encode_base64 = {},
|
||||
encode_png = {},
|
||||
env = {},
|
||||
explode_scrollbar_event = {},
|
||||
explode_table_event = {},
|
||||
explode_textlist_event = {},
|
||||
facedir_to_dir = {},
|
||||
features = {},
|
||||
find_node_near = {},
|
||||
find_nodes_in_area = {},
|
||||
find_nodes_in_area_under_air = {},
|
||||
find_nodes_with_meta = {},
|
||||
find_path = {},
|
||||
fix_light = {},
|
||||
forceload_block = {},
|
||||
forceload_free_block = {},
|
||||
format_chat_message = {},
|
||||
formspec_escape = {},
|
||||
generate_decorations = {},
|
||||
generate_ores = {},
|
||||
get_all_craft_recipes = {},
|
||||
get_artificial_light = {},
|
||||
get_auth_handler = {},
|
||||
get_background_escape_sequence = {},
|
||||
get_ban_description = {},
|
||||
get_ban_list = {},
|
||||
get_biome_data = {},
|
||||
get_biome_id = {},
|
||||
get_biome_name = {},
|
||||
get_builtin_path = {},
|
||||
get_color_escape_sequence = {},
|
||||
get_connected_players = {},
|
||||
get_content_id = {},
|
||||
get_craft_recipe = {},
|
||||
get_craft_result = {},
|
||||
get_current_modname = {},
|
||||
get_day_count = {},
|
||||
get_decoration_id = {},
|
||||
get_dig_params = {},
|
||||
get_dir_list = {},
|
||||
get_gametime = {},
|
||||
get_gen_notify = {},
|
||||
get_heat = {},
|
||||
get_hit_params = {},
|
||||
get_humidity = {},
|
||||
get_inventory = {},
|
||||
get_item_group = {},
|
||||
get_last_run_mod = {},
|
||||
get_mapgen_object = {},
|
||||
get_mapgen_params = {},
|
||||
get_mapgen_setting = {},
|
||||
get_mapgen_setting_noiseparams = {},
|
||||
get_meta = {},
|
||||
get_mod_storage = {},
|
||||
get_modnames = {},
|
||||
get_modpath = {},
|
||||
get_name_from_content_id = {},
|
||||
get_natural_light = {},
|
||||
get_node = {},
|
||||
get_node_drops = {},
|
||||
get_node_group = {},
|
||||
get_node_level = {},
|
||||
get_node_light = {},
|
||||
get_node_max_level = {},
|
||||
get_node_or_nil = {},
|
||||
get_node_timer = {},
|
||||
get_noiseparams = {},
|
||||
get_objects_in_area = {},
|
||||
get_objects_inside_radius = {},
|
||||
get_password_hash = {},
|
||||
get_perlin = {},
|
||||
get_perlin_map = {},
|
||||
get_player_by_name = {},
|
||||
get_player_information = {},
|
||||
get_player_ip = {},
|
||||
get_player_privs = {},
|
||||
get_player_radius_area = {},
|
||||
get_pointed_thing_position = {},
|
||||
get_position_from_hash = {},
|
||||
get_server_max_lag = {},
|
||||
get_server_status = {},
|
||||
get_server_uptime = {},
|
||||
get_spawn_level = {},
|
||||
get_timeofday = {},
|
||||
get_tool_wear_after_use = {},
|
||||
get_translated_string = {},
|
||||
get_translator = {},
|
||||
get_us_time = {},
|
||||
get_user_path = {},
|
||||
get_version = {},
|
||||
get_voxel_manip = {},
|
||||
get_worldpath = {},
|
||||
global_exists = {},
|
||||
handle_async = {},
|
||||
handle_node_drops = {},
|
||||
has_feature = {},
|
||||
hash_node_position = {},
|
||||
hud_replace_builtin = {},
|
||||
inventorycube = {},
|
||||
is_area_protected = {},
|
||||
is_colored_paramtype = {},
|
||||
is_creative_enabled = {},
|
||||
is_nan = {},
|
||||
is_player = {},
|
||||
is_protected = {},
|
||||
is_singleplayer = {},
|
||||
is_yes = {},
|
||||
item_drop = {},
|
||||
item_eat = {},
|
||||
item_place = {},
|
||||
item_place_node = {},
|
||||
item_place_object = {},
|
||||
item_secondary_use = {},
|
||||
itemstring_with_color = {},
|
||||
itemstring_with_palette = {},
|
||||
kick_player = {},
|
||||
line_of_sight = {},
|
||||
load_area = {},
|
||||
log = {},
|
||||
luaentities = {},
|
||||
mkdir = {},
|
||||
mod_channel_join = {},
|
||||
mvdir = {},
|
||||
node_dig = {},
|
||||
node_punch = {},
|
||||
nodedef_default = {},
|
||||
noneitemdef_default = {},
|
||||
notify_authentication_modified = {},
|
||||
object_refs = {},
|
||||
on_craft = {},
|
||||
override_chatcommand = {},
|
||||
override_item = {},
|
||||
parse_coordinates = {},
|
||||
parse_json = {},
|
||||
parse_relative_number = {},
|
||||
place_node = {},
|
||||
place_schematic = {},
|
||||
place_schematic_on_vmanip = {},
|
||||
player_exists = {},
|
||||
pointed_thing_to_face_pos = {},
|
||||
pos_to_string = {},
|
||||
print = {},
|
||||
privs_to_string = {},
|
||||
punch_node = {},
|
||||
raillike_group = {},
|
||||
raycast = {},
|
||||
read_schematic = {},
|
||||
record_protection_violation = {},
|
||||
register_abm = {},
|
||||
register_alias = {},
|
||||
register_alias_force = {},
|
||||
register_allow_player_inventory_action = {},
|
||||
register_async_dofile = {},
|
||||
register_authentication_handler = {},
|
||||
register_biome = {},
|
||||
register_can_bypass_userlimit = {},
|
||||
register_chatcommand = {},
|
||||
register_craft = {},
|
||||
register_craft_predict = {},
|
||||
register_craftitem = {},
|
||||
register_decoration = {},
|
||||
register_entity = {},
|
||||
register_globalstep = {},
|
||||
register_item = {},
|
||||
register_lbm = {},
|
||||
register_node = {},
|
||||
register_on_auth_fail = {},
|
||||
register_on_authplayer = {},
|
||||
register_on_chat_message = {},
|
||||
register_on_chatcommand = {},
|
||||
register_on_cheat = {},
|
||||
register_on_craft = {},
|
||||
register_on_dieplayer = {},
|
||||
register_on_dignode = {},
|
||||
register_on_generated = {},
|
||||
register_on_item_eat = {},
|
||||
register_on_joinplayer = {},
|
||||
register_on_leaveplayer = {},
|
||||
register_on_liquid_transformed = {},
|
||||
register_on_mapgen_init = {},
|
||||
register_on_modchannel_message = {},
|
||||
register_on_mods_loaded = {},
|
||||
register_on_newplayer = {},
|
||||
register_on_placenode = {},
|
||||
register_on_player_hpchange = {},
|
||||
register_on_player_inventory_action = {},
|
||||
register_on_player_receive_fields = {},
|
||||
register_on_prejoinplayer = {},
|
||||
register_on_priv_grant = {},
|
||||
register_on_priv_revoke = {},
|
||||
register_on_protection_violation = {},
|
||||
register_on_punchnode = {},
|
||||
register_on_punchplayer = {},
|
||||
register_on_respawnplayer = {},
|
||||
register_on_rightclickplayer = {},
|
||||
register_on_shutdown = {},
|
||||
register_ore = {},
|
||||
register_playerevent = {},
|
||||
register_privilege = {},
|
||||
register_schematic = {},
|
||||
register_tool = {},
|
||||
registered_abms = {other_fields = true},
|
||||
registered_aliases = {other_fields = true},
|
||||
registered_allow_player_inventory_actions = {other_fields = true},
|
||||
registered_biomes = {other_fields = true},
|
||||
registered_can_bypass_userlimit = {other_fields = true},
|
||||
registered_chatcommands = {other_fields = true},
|
||||
registered_craft_predicts = {other_fields = true},
|
||||
registered_craftitems = {other_fields = true},
|
||||
registered_decorations = {other_fields = true},
|
||||
registered_entities = {other_fields = true},
|
||||
registered_globalsteps = {other_fields = true},
|
||||
registered_items = {other_fields = true},
|
||||
registered_lbms = {other_fields = true},
|
||||
registered_nodes = {other_fields = true},
|
||||
registered_on_authplayers = {other_fields = true},
|
||||
registered_on_chat_messages = {other_fields = true},
|
||||
registered_on_chatcommands = {other_fields = true},
|
||||
registered_on_cheats = {other_fields = true},
|
||||
registered_on_crafts = {other_fields = true},
|
||||
registered_on_dieplayers = {other_fields = true},
|
||||
registered_on_dignodes = {other_fields = true},
|
||||
registered_on_generateds = {other_fields = true},
|
||||
registered_on_item_eats = {other_fields = true},
|
||||
registered_on_joinplayers = {other_fields = true},
|
||||
registered_on_leaveplayers = {other_fields = true},
|
||||
registered_on_liquid_transformed = {other_fields = true},
|
||||
registered_on_modchannel_message = {other_fields = true},
|
||||
registered_on_mods_loaded = {other_fields = true},
|
||||
registered_on_newplayers = {other_fields = true},
|
||||
registered_on_placenodes = {other_fields = true},
|
||||
registered_on_player_hpchange = {other_fields = true},
|
||||
registered_on_player_hpchanges = {other_fields = true},
|
||||
registered_on_player_inventory_actions = {other_fields = true},
|
||||
registered_on_player_receive_fields = {other_fields = true},
|
||||
registered_on_prejoinplayers = {other_fields = true},
|
||||
registered_on_priv_grant = {other_fields = true},
|
||||
registered_on_priv_revoke = {other_fields = true},
|
||||
registered_on_protection_violation = {other_fields = true},
|
||||
registered_on_punchnodes = {other_fields = true},
|
||||
registered_on_punchplayers = {other_fields = true},
|
||||
registered_on_respawnplayers = {other_fields = true},
|
||||
registered_on_rightclickplayers = {other_fields = true},
|
||||
registered_on_shutdown = {other_fields = true},
|
||||
registered_ores = {other_fields = true},
|
||||
registered_playerevents = {other_fields = true},
|
||||
registered_privileges = {other_fields = true},
|
||||
registered_tools = {other_fields = true},
|
||||
remove_detached_inventory = {},
|
||||
remove_detached_inventory_raw = {},
|
||||
remove_node = {},
|
||||
remove_player = {},
|
||||
remove_player_auth = {},
|
||||
request_http_api = {},
|
||||
request_insecure_environment = {},
|
||||
request_shutdown = {},
|
||||
rgba = {},
|
||||
rmdir = {},
|
||||
rollback_get_last_node_actor = {},
|
||||
rollback_get_node_actions = {},
|
||||
rollback_punch_callbacks = {},
|
||||
rollback_revert_actions_by = {},
|
||||
rotate_and_place = {},
|
||||
rotate_node = {},
|
||||
run_callbacks = {},
|
||||
run_priv_callbacks = {},
|
||||
safe_file_write = {},
|
||||
send_join_message = {},
|
||||
send_leave_message = {},
|
||||
serialize = {},
|
||||
serialize_roundtrip = {},
|
||||
serialize_schematic = {},
|
||||
set_gen_notify = {},
|
||||
set_last_run_mod = {},
|
||||
set_mapgen_params = {},
|
||||
set_mapgen_setting = {},
|
||||
set_mapgen_setting_noiseparams = {},
|
||||
set_node = {},
|
||||
set_node_level = {},
|
||||
set_noiseparams = {},
|
||||
set_player_password = {},
|
||||
set_player_privs = {},
|
||||
set_timeofday = {},
|
||||
setting_get = {},
|
||||
setting_get_pos = {},
|
||||
setting_getbool = {},
|
||||
setting_save = {},
|
||||
setting_set = {},
|
||||
setting_setbool = {},
|
||||
settings = {
|
||||
fields = {
|
||||
get = {},
|
||||
get_bool = {},
|
||||
get_np_group = {},
|
||||
get_flags = {},
|
||||
set = {},
|
||||
set_bool = {},
|
||||
set_np_group = {},
|
||||
remove = {},
|
||||
get_names = {},
|
||||
write = {},
|
||||
to_table = {},
|
||||
},
|
||||
},
|
||||
sha1 = {},
|
||||
show_formspec = {},
|
||||
show_general_help_formspec = {},
|
||||
show_privs_help_formspec = {},
|
||||
sound_fade = {},
|
||||
sound_play = {},
|
||||
sound_stop = {},
|
||||
spawn_falling_node = {},
|
||||
spawn_item = {},
|
||||
spawn_tree = {},
|
||||
string_to_area = {},
|
||||
string_to_pos = {},
|
||||
string_to_privs = {},
|
||||
strip_background_colors = {},
|
||||
strip_colors = {},
|
||||
strip_foreground_colors = {},
|
||||
strip_param2_color = {},
|
||||
swap_node = {},
|
||||
tooldef_default = {},
|
||||
transforming_liquid_add = {},
|
||||
translate = {},
|
||||
unban_player_or_ip = {},
|
||||
unregister_biome = {},
|
||||
unregister_chatcommand = {},
|
||||
unregister_item = {},
|
||||
wallmounted_to_dir = {},
|
||||
wrap_text = {},
|
||||
write_json = {},
|
||||
yaw_to_dir = {},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
stds.stairsplus = {
|
||||
globals = {
|
||||
"stairsplus",
|
||||
},
|
||||
read_globals = {
|
||||
"default",
|
||||
"fmod",
|
||||
"futil",
|
||||
},
|
||||
}
|
335
mods/moreblocks/stairsplus/API.md
Normal file
335
mods/moreblocks/stairsplus/API.md
Normal file
|
@ -0,0 +1,335 @@
|
|||
# API documentation for Stairs+
|
||||
|
||||
In general, function arguments specified in square brackets ("[ ]") are optional.
|
||||
|
||||
## Shape API
|
||||
|
||||
For registering new shapes.
|
||||
|
||||
* `stairsplus.api.register_shape(name, def)`
|
||||
An example of a node_box shape:
|
||||
```lua
|
||||
stairsplus.api.register_shape("slab_8", {
|
||||
name_format = "slab_%s_8",
|
||||
aliases = {"slab_%s"},
|
||||
description = "@1 1/2 Slab",
|
||||
shape_groups = {slab = 1, legacy = 1},
|
||||
eighths = 4,
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
|
||||
},
|
||||
})
|
||||
```
|
||||
An example of a mesh shape:
|
||||
```lua
|
||||
local box_slope = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5, -0.5, -0.5, 0.5, -0.25, 0.5},
|
||||
{-0.5, -0.25, -0.25, 0.5, 0, 0.5},
|
||||
{-0.5, 0, 0, 0.5, 0.25, 0.5},
|
||||
{-0.5, 0.25, 0.25, 0.5, 0.5, 0.5}
|
||||
}
|
||||
}
|
||||
|
||||
stairsplus.api.register_shape("slope", {
|
||||
name_format = "slope_%s",
|
||||
description = "@1 Slope",
|
||||
shape_groups = {slope = 1, legacy = 1},
|
||||
eighths = 4,
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope.obj",
|
||||
collision_box = box_slope,
|
||||
selection_box = box_slope,
|
||||
})
|
||||
```
|
||||
Hopefully most of the paramaters should be self explanatory. `eighths` is the number of 1/8th node
|
||||
microblocks that the shape is "worth", i.e. how much material is used in crafting it. when assigning a value to
|
||||
`eighths`, generally 1 is the minimum, and 8 is the maximum. often, you should round to the nearest eighth
|
||||
(`eights = round(volume * 8)`). however, sometimes shapes will form a natural complement w/ another shape to form
|
||||
a simple volume, and you should instead choose values so that the eighths in the complements match the combined form.
|
||||
|
||||
* `stairsplus.api.register_shape_group(shape_group, shapes)`
|
||||
Register a new shape group.
|
||||
|
||||
The following tables are exposed for convenience, but shouldn't be directly modified:
|
||||
|
||||
* `stairsplus.api.registered_shapes`
|
||||
A hash of shape definitions by name.
|
||||
|
||||
* `stairsplus.api.shapes_by_group`
|
||||
A hash of lists of shapes in a group, by the shape group name.
|
||||
|
||||
|
||||
## Node API
|
||||
|
||||
These are for registering shapes of a node
|
||||
|
||||
* `stairsplus.api.register_on_register_single(function(node, shaped_name))`
|
||||
Register a callback for when a shaped node is registered. Mostly useful for integration with
|
||||
inventory managers.
|
||||
|
||||
* `stairsplus.api.register_single(node, shape, [overrides], [meta])`
|
||||
Register a single shape of a node.
|
||||
If no "micro_8" shape is defined, it will be defined before registering another shape. Attempting to
|
||||
register an already-registered shape will not override anything.
|
||||
Many of the node's properties will be inherited from the
|
||||
node and shape definition, but can be manually changed via `overrides`. `meta` is used to specify
|
||||
whether special logic should be used while defining the shaped node. The following values are supported:
|
||||
* `ignore_type = true`
|
||||
Whether to ignore the base node's `type` - usually, it is an error to try to register a shape for a
|
||||
non-node.
|
||||
* `ignore_drawtype = true`
|
||||
Whether to ignore the base node's `drawtye`. Usually, it is an error to try to register a shape for a
|
||||
non-node-like drawtype.
|
||||
* `ignore_paramtype2 = true`
|
||||
Whether to ignore the base node's `paramtype2`. Usually, it is an error to register a shape for node
|
||||
which is not compatible with a `facedir` drawtype.
|
||||
* `align_style = "node" | "user" | "world"`
|
||||
Whether to override the align_style for the textures used to draw the shaped node. The default behavior
|
||||
is to use the value defined by the `stairsplus.default_align_style` setting, which defaults to `"user"`.
|
||||
* `allow_override_groups = true`
|
||||
Whether to allow groups to be specified in the overrides (otherwise, they are ignored).
|
||||
* `allow_override_drawtype = true`
|
||||
Whether to allow a drawtype to be specified in the overrides (otherwise, it is ignored).
|
||||
* `allow_override_paramtype2 = true`
|
||||
Whether to allow a paramtype2 to be specified in the overrides (otherwise, it is ignored).
|
||||
|
||||
* `stairsplus.api.register_all(node, [overrides], [meta])`
|
||||
Register all registered shapes for a node. we do not recommend using this, due to the 32767 node limit.
|
||||
we recommend using
|
||||
|
||||
* `stairsplus.api.register_shapes(node, shapes, [overrides], [meta])`
|
||||
Register variants for a custom list of shapes.
|
||||
* `stairsplus.api.register_group(node, shape_group, [overrides], [meta])`
|
||||
Register variants for a defined shape group.
|
||||
* `stairsplus.api.register_groups(node, shape_groups, [overrides], [meta])`
|
||||
Register variants for a list of shape groups.
|
||||
|
||||
* `stairsplus.api.format_name(node, shape)`
|
||||
Get the itemstring for a shaped variant. It is not guaranteed that the resulting itemstring actually
|
||||
exists.
|
||||
|
||||
* `stairsplus.api.get_shapes(node)`
|
||||
Get the defined shapes for a node. Returns `nil` if no shapes are registered for the node.
|
||||
|
||||
* `stairsplus.api.get_shapes_hash(node)`
|
||||
Get a hash where the keys are the shapes supported by the node. Mutating the return value is not
|
||||
recommended. Will return `nil` if no shapes are registered for the node.
|
||||
|
||||
* `stairsplus.api.get_schema_recipe_item(node, shape_or_item)`
|
||||
If `shape_or_item` is an empty string, return an empty string. If it is an itemstring (contains a ":"),
|
||||
that itemstring is returned. If it is a shape, and the shape is defined for the given node, returns
|
||||
the name of the shaped node. If it is a shape, but the shape is not defined for the given node, returns
|
||||
`nil`. If it is the special string `"node"`, then it returns the node argument. `shape_or_item` may
|
||||
optionally specify a count value, which will modify the returned value accordingly.
|
||||
```lua
|
||||
assert(stairsplus.api.get_schema_recipe_item("default:stone", "node 3") == "default:stone 3")
|
||||
assert(stairsplus.api.get_schema_recipe_item("default:stone", "slope 3") == "default:slope_stone 3")
|
||||
```
|
||||
|
||||
* `stairsplus.api.get_micronode(node)`
|
||||
Convenience method for `stairsplus.api.get_schema_recipe_item(node, "micro_8")`.
|
||||
|
||||
* `stairsplus.api.get_node_of_shaped_node(shaped_node)`
|
||||
Given a shaped node, get the "base" node it was made from.
|
||||
|
||||
* `stairsplus.api.get_shape_of_shaped_node(shaped_node)`
|
||||
Given a shaped node, get its shape.
|
||||
|
||||
|
||||
## Alias API
|
||||
|
||||
* `stairsplus.api.register_alias_single(old_node, new_node, shape)`
|
||||
Hopefully this is self-explanatory.
|
||||
* `stairsplus.api.register_alias_all(old_node, new_node)`
|
||||
* `stairsplus.api.register_alias_shapes(old_node, new_node, shapes)`
|
||||
* `stairsplus.api.register_alias_group(old_node, new_node, group)`
|
||||
* `stairsplus.api.register_alias_groups(old_node, new_node, groups)`
|
||||
|
||||
* `stairsplus.api.register_alias_force_single(old_node, new_node, shape)`
|
||||
`alias_force` implies that the shapes for the "old_node" already exist, so after aliasing them,
|
||||
we remove them from internal data structures.
|
||||
* `stairsplus.api.register_alias_force_all(old_node, new_node)`
|
||||
* `stairsplus.api.register_alias_force_shapes(old_node, new_node, shape)`
|
||||
* `stairsplus.api.register_alias_force_group(old_node, new_node, group)`
|
||||
* `stairsplus.api.register_alias_force_groups(old_node, new_node, groups)`
|
||||
|
||||
## Group API
|
||||
|
||||
Specify how to handle a node's groups when creating a shaped variant. By default, a node's
|
||||
groups have their name transformed in the same way that the node's name is, e.g. `"wood"` will become e.g.
|
||||
`"micro_wood_8"`, so that the shaped nodes can't be used in crafting recipes that call for `"group:wood"`.
|
||||
|
||||
* `stairsplus.api.register_passthrough_group(group)`
|
||||
Mark a group as "passthrough", i.e. it will not be transformed when assigned to a shaped node.
|
||||
This is necessary to e.g. allow nodes to dig-able (e.g. groups like `"cracky"`, `"oddly_breakable_by_hand"`).
|
||||
|
||||
* `stairsplus.api.register_passthrough_groups(groups)`
|
||||
Marks a list of groups as passthrough.
|
||||
|
||||
* `stairsplus.api.register_scaling_group(group)`
|
||||
Like "passthrough", but this scales the group's *value* depending on the # of "eighths" that the shape
|
||||
is worth. This is useful for groups like `"fall_damage_add_percent"` and `"slippery"`.
|
||||
|
||||
* `stairsplus.api.register_scaling_groups(groups)`
|
||||
Marks a list of groups as scaling.
|
||||
|
||||
* `stairsplus.api.register_ignore_group(group)`
|
||||
Marks a group as something we should just ignore entirely when creating a shaped node. Useful
|
||||
for things like `"connect_to_raillike"` or `"attached_node"`, which don't makde sense for a shaped
|
||||
node.
|
||||
|
||||
* `stairsplus.api.register_ignore_groups(groups)`
|
||||
Marks a list of groups to ignore.
|
||||
|
||||
* `stairsplus.api.build_groups(node, shape)`
|
||||
Given a node and a shape, return the groups to assign to a shaped node.
|
||||
|
||||
## Legacy API
|
||||
|
||||
These are methods that support legacy behavior which can optionally be disabled.
|
||||
|
||||
* `stairsplus.api.on_place(itemstack, placer, pointed_thing)`
|
||||
Handle placing a node. The legacy behavior is to try to rotate the node based on a number of
|
||||
obscure factors. It can be useful sometimes, but confusing other times.
|
||||
|
||||
* `stairsplus.api.scale_light(light_source, shape_def)`
|
||||
How much light should a shaped glowing node emit? The legacy behavior was to drop the value by `1`.
|
||||
The non-legacy behavior scales it down more, based on the number of eighths used in the shape.
|
||||
|
||||
## Crafting API
|
||||
|
||||
A powerful new API for registering crafting recipes involving shaped nodes.
|
||||
|
||||
* `stairsplus.api.register_on_register_craft_schema(func)`
|
||||
A callback for when a schema is registered. Useful for integrating inventory managers.
|
||||
|
||||
* `stairsplus.api.register_craft_schema(schema)`
|
||||
Register a crafting schema, which is like a normal crafting recipe, but it may have bare "shapes" in the
|
||||
recipe/output. For every node w/ the variants in the recipe, a variant involving those shaped nodes
|
||||
will be created (when all mods are loaded, so you don't have to worry about the order in which things
|
||||
are defined).
|
||||
```lua
|
||||
stairsplus.api.register_craft_schema({
|
||||
output = "panel_8 6",
|
||||
recipe = {{"node", "node", "node"}},
|
||||
})
|
||||
|
||||
stairsplus.api.register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "micro_8 7",
|
||||
recipe = {"stair_inner"},
|
||||
})
|
||||
```
|
||||
|
||||
* `stairsplus.api.register_schema_crafts_for_node(node)`
|
||||
Creates real recipes for all schemas using available variants of the given node. Called automatically after all
|
||||
mods are loaded for every node which has shaped nodes. Currently only supports "shaped" and "shapeless" recipe
|
||||
types (these don't make much sense for cooking/fuel). Given the schemas above, if called for `"default:stone"`,
|
||||
this would result in the following:
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
output = "default:panel_stone_8 6",
|
||||
recipe = {{"default:stone", "default:stone", "default:stone"}},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "default:micro_stone_8 7",
|
||||
recipe = {"default:stair_stone_inner"},
|
||||
})
|
||||
```
|
||||
|
||||
* `stairsplus.api.register_crafts_for_shapes(recipe)`
|
||||
For "cooking" and "fuel" recipe types, register scaled variants for all *currently defined*
|
||||
shaped variants. It is an error to try to register a cooking recipe for nodes with mis-matched shapes.
|
||||
```lua
|
||||
stairsplus.api.register_crafts_for_shapes({
|
||||
type = "cooking",
|
||||
output = "default:stone",
|
||||
recipe = "default:cobblestone",
|
||||
cooktime = 3,
|
||||
})
|
||||
|
||||
stairsplus.api.register_crafts_for_shapes({
|
||||
type = "fuel",
|
||||
recipe = "default:coalblock",
|
||||
burntime = 370,
|
||||
})
|
||||
```
|
||||
which would result in concrete recipes like
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "default:panel_stone_8",
|
||||
recipe = "default:panel_cobblestone_8",
|
||||
cooktime = 0.75,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:panel_coalblock_8",
|
||||
burntime = 92.5,
|
||||
})
|
||||
```
|
||||
|
||||
## Station API
|
||||
|
||||
For the creation of crafting stations which can be used to transform nodes into shaped variants, and back.
|
||||
|
||||
* `stairsplus.api.register_station(name, def)`
|
||||
* `name`: an itemstring
|
||||
* `def`: a regular node definition, with the following parameters:
|
||||
* `shape_groups`: a list of shape groups that can be created with the station (required).
|
||||
* `build_formspec = function(meta, inv)`
|
||||
A function which will build the formspec for the node (not required, but you probably want to use it).
|
||||
* `update_metadata = function(meta, inv)`
|
||||
A function which updates the node's metadata (optional)
|
||||
|
||||
## Compat API
|
||||
|
||||
For compatability w/ other mods
|
||||
|
||||
* `function stairsplus.compat.override_stairs(name, node, overrides, meta)`
|
||||
Override stairs registered w/ the `stairs` mod, and replace them w/ stairsplus-compatible nodes.
|
||||
|
||||
# Legacy API
|
||||
|
||||
Methods from the previous "moreblocks" version of stairsplus which are still provided so as not to break
|
||||
compatability with older mods.
|
||||
|
||||
* `stairsplus:register_all(modname, subname, recipeitem, fields)`
|
||||
Example:
|
||||
```lua
|
||||
stairsplus:register_all("moreblocks", "wood", "default:wood", {
|
||||
description = "Wooden",
|
||||
tiles = {"default_wood.png"},
|
||||
groups = {oddly_breakabe_by_hand=1},
|
||||
sounds = moreblocks.node_sound_wood_defaults(),
|
||||
})
|
||||
```
|
||||
* `stairsplus:register_micro(modname, subname, recipeitem, fields)`
|
||||
* `stairsplus:register_panel(modname, subname, recipeitem, fields)`
|
||||
* `stairsplus:register_slab(modname, subname, recipeitem, fields)`
|
||||
* `stairsplus:register_slope(modname, subname, recipeitem, fields)`
|
||||
* `stairsplus:register_stair(modname, subname, recipeitem, fields)`
|
||||
* `stairsplus:register_custom_subset(subset, modname, subname, recipeitem, fields)`
|
||||
|
||||
* `stairsplus:register_alias_all(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_alias_micro(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_alias_panel(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_alias_slab(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_alias_slope(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_alias_stair(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_custom_subset_alias(subset, modname_old, subname_old, modname_new, subname_new)`
|
||||
|
||||
* `stairsplus:register_alias_force_all(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_alias_force_micro(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_alias_force_panel(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_alias_force_slab(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_alias_force_slope(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_alias_force_stair(modname_old, subname_old, modname_new, subname_new)`
|
||||
* `stairsplus:register_custom_subset_alias(subset, modname_old, subname_old, modname_new, subname_new)`
|
2
mods/moreblocks/stairsplus/aliases.lua
Normal file
2
mods/moreblocks/stairsplus/aliases.lua
Normal file
|
@ -0,0 +1,2 @@
|
|||
minetest.register_alias("circular_saw", "stairsplus:circular_saw")
|
||||
minetest.register_alias("moreblocks:circular_saw", "stairsplus:circular_saw")
|
104
mods/moreblocks/stairsplus/api/alias.lua
Normal file
104
mods/moreblocks/stairsplus/api/alias.lua
Normal file
|
@ -0,0 +1,104 @@
|
|||
local api = stairsplus.api
|
||||
|
||||
local table_is_empty = futil.table.is_empty
|
||||
|
||||
function api.register_alias_shape(old_node, new_node, shape)
|
||||
local old_shaped_node = api.format_name(old_node, shape)
|
||||
local new_shaped_node = api.format_name(new_node, shape)
|
||||
|
||||
minetest.register_alias(old_shaped_node, new_shaped_node)
|
||||
|
||||
local shape_def = api.registered_shapes[shape]
|
||||
if shape_def.aliases then
|
||||
local old_mod, old_name = old_node:match("^([^:]+):(.*)$")
|
||||
for _, alias in ipairs(shape_def.aliases) do
|
||||
old_shaped_node = ("%s:%s"):format(old_mod, alias:format(old_name))
|
||||
minetest.register_alias(old_shaped_node, new_shaped_node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_alias_all(old_node, new_node)
|
||||
for shape in pairs(api.registered_shapes) do
|
||||
api.register_alias_shape(old_node, new_node, shape)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_alias_shapes(old_node, new_node, shapes)
|
||||
for _, shape in ipairs(shapes) do
|
||||
api.register_alias_shape(old_node, new_node, shape)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_alias_group(old_node, new_node, group)
|
||||
for _, shape in ipairs(api.shapes_by_group[group] or {}) do
|
||||
api.register_alias_shape(old_node, new_node, shape)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_alias_groups(old_node, new_node, groups)
|
||||
for _, group in ipairs(groups) do
|
||||
api.register_alias_group(old_node, new_node, group)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_alias_force_shape(old_node, new_node, shape)
|
||||
local old_shaped_node = api.format_name(old_node, shape)
|
||||
local new_shaped_node = api.format_name(new_node, shape)
|
||||
|
||||
minetest.register_alias_force(old_shaped_node, new_shaped_node)
|
||||
|
||||
local shape_def = api.registered_shapes[shape]
|
||||
if shape_def.aliases then
|
||||
local old_mod, old_name = old_node:match("^([^:]+):(.*)$")
|
||||
for _, alias in ipairs(shape_def.aliases) do
|
||||
old_shaped_node = ("%s:%s"):format(old_mod, alias:format(old_name))
|
||||
minetest.register_alias_force(old_shaped_node, new_shaped_node)
|
||||
end
|
||||
end
|
||||
|
||||
local nodes = api.nodes_by_shape[shape] or {}
|
||||
if nodes[old_node] then
|
||||
nodes[old_node] = nil
|
||||
nodes[new_node] = true
|
||||
api.nodes_by_shape[shape] = nodes
|
||||
end
|
||||
|
||||
local old_shapes = api.shapes_by_node[old_node] or {}
|
||||
if old_shapes[shape] then
|
||||
old_shapes[shape] = nil
|
||||
if table_is_empty(old_shapes) then
|
||||
api.shapes_by_node[old_node] = nil
|
||||
else
|
||||
api.shapes_by_node[old_node] = old_shapes
|
||||
end
|
||||
|
||||
local new_shapes = api.shapes_by_node[new_node] or {}
|
||||
new_shapes[new_node] = true
|
||||
api.shapes_by_node[new_node] = new_shapes
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_alias_force_all(old_node, new_node)
|
||||
for shape in pairs(api.registered_shapes) do
|
||||
api.register_alias_force_shape(old_node, new_node, shape)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_alias_force_shapes(old_node, new_node, shapes)
|
||||
for _, shape in ipairs(shapes) do
|
||||
api.register_alias_force_shape(old_node, new_node, shape)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_alias_force_group(old_node, new_node, group)
|
||||
for _, shape in ipairs(api.shapes_by_group[group] or {}) do
|
||||
api.register_alias_force_shape(old_node, new_node, shape)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_alias_force_groups(old_node, new_node, groups)
|
||||
for _, group in ipairs(groups) do
|
||||
api.register_alias_force_group(old_node, new_node, group)
|
||||
end
|
||||
end
|
66
mods/moreblocks/stairsplus/api/group_filters.lua
Normal file
66
mods/moreblocks/stairsplus/api/group_filters.lua
Normal file
|
@ -0,0 +1,66 @@
|
|||
local api = stairsplus.api
|
||||
|
||||
local in_creative_inventory = stairsplus.settings.in_creative_inventory
|
||||
local in_craft_guide = stairsplus.settings.in_craft_guide
|
||||
|
||||
api.passthrough_groups = {}
|
||||
api.scaling_groups = {}
|
||||
api.ignore_groups = {}
|
||||
|
||||
function api.register_passthrough_group(group)
|
||||
api.passthrough_groups[group] = true
|
||||
end
|
||||
|
||||
function api.register_passthrough_groups(groups)
|
||||
for _, group in ipairs(groups) do
|
||||
api.register_passthrough_group(group)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_scaling_group(group)
|
||||
api.scaling_groups[group] = true
|
||||
end
|
||||
|
||||
function api.register_scaling_groups(groups)
|
||||
for _, group in ipairs(groups) do
|
||||
api.register_scaling_group(group)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_ignore_group(group)
|
||||
api.ignore_groups[group] = true
|
||||
end
|
||||
|
||||
function api.register_ignore_groups(groups)
|
||||
for _, group in ipairs(groups) do
|
||||
api.register_ignore_group(group)
|
||||
end
|
||||
end
|
||||
|
||||
function api.build_groups(node, shape)
|
||||
local node_def = minetest.registered_nodes[node]
|
||||
|
||||
local groups = {
|
||||
[("shape_%s"):format(shape)] = 1,
|
||||
not_in_creative_inventory = (not in_creative_inventory) and 1 or nil,
|
||||
not_in_craft_guide = (not in_craft_guide) and 1 or nil,
|
||||
}
|
||||
|
||||
local shape_def = api.registered_shapes[shape]
|
||||
|
||||
for group, value in pairs(shape_def.groups or {}) do
|
||||
groups[group] = value
|
||||
end
|
||||
|
||||
for group, value in pairs(node_def.groups) do
|
||||
if api.passthrough_groups[group] then
|
||||
groups[group] = value
|
||||
elseif api.scaling_groups[group] then
|
||||
groups[group] = (shape_def.eighths / 8) * value
|
||||
elseif not api.ignore_groups[group] then
|
||||
groups[shape_def.name_format:format(group)] = value
|
||||
end
|
||||
end
|
||||
|
||||
return groups
|
||||
end
|
10
mods/moreblocks/stairsplus/api/init.lua
Normal file
10
mods/moreblocks/stairsplus/api/init.lua
Normal file
|
@ -0,0 +1,10 @@
|
|||
stairsplus.api = {}
|
||||
|
||||
stairsplus.dofile("api", "legacy")
|
||||
stairsplus.dofile("api", "shape")
|
||||
stairsplus.dofile("api", "group_filters")
|
||||
stairsplus.dofile("api", "node")
|
||||
stairsplus.dofile("api", "alias")
|
||||
stairsplus.dofile("api", "recipe")
|
||||
stairsplus.dofile("api", "station")
|
||||
stairsplus.dofile("api", "whitelist")
|
107
mods/moreblocks/stairsplus/api/legacy.lua
Normal file
107
mods/moreblocks/stairsplus/api/legacy.lua
Normal file
|
@ -0,0 +1,107 @@
|
|||
local api = stairsplus.api
|
||||
|
||||
local legacy_mode = stairsplus.settings.legacy_mode
|
||||
local legacy_place_mechanic = stairsplus.settings.legacy_place_mechanic
|
||||
|
||||
if legacy_place_mechanic then
|
||||
local wall_right_dirmap = { 9, 18, 7, 12 }
|
||||
local wall_left_dirmap = { 11, 16, 5, 14 }
|
||||
local ceil_dirmap = { 20, 23, 22, 21 }
|
||||
|
||||
function api.on_place(itemstack, placer, pointed_thing)
|
||||
if not futil.is_player(placer) then
|
||||
return minetest.item_place(itemstack, placer, pointed_thing)
|
||||
end
|
||||
|
||||
local controls = placer:get_player_control()
|
||||
|
||||
local sneak = controls.sneak
|
||||
local aux = controls.aux1
|
||||
|
||||
local shaped_node_name = itemstack:get_name()
|
||||
local shape = api.get_shape_of_shaped_node(shaped_node_name)
|
||||
|
||||
local under = pointed_thing.under
|
||||
local under_node = minetest.get_node(under)
|
||||
local under_shape = api.get_shape_of_shaped_node(under_node.name)
|
||||
|
||||
local same_cat = shape == under_shape
|
||||
|
||||
-- standard (floor) facedir, also used for sneak placement against the lower half of the wall
|
||||
local p2 = placer and minetest.dir_to_facedir(placer:get_look_dir()) or 0
|
||||
|
||||
-- check which face and which quadrant we are interested in
|
||||
-- this is used both to check if we're handling parallel placement in the same-category case,
|
||||
-- and in general for sneak placement
|
||||
local face_pos = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
|
||||
local face_off = vector.subtract(face_pos, under)
|
||||
|
||||
-- we cannot trust face_off to tell us the correct directionif the
|
||||
-- under node has a non-standard shape, so use the distance between under and above
|
||||
local wallmounted = minetest.dir_to_wallmounted(vector.subtract(pointed_thing.above, under))
|
||||
|
||||
if same_cat and not aux then
|
||||
p2 = under_node.param2
|
||||
-- flip if placing above or below an upright or upside-down node
|
||||
-- TODO should we also flip when placing next to a side-mounted node?
|
||||
if wallmounted < 2 then
|
||||
if p2 < 4 then
|
||||
p2 = (p2 + 2) % 4
|
||||
p2 = ceil_dirmap[p2 + 1]
|
||||
elseif p2 > 19 then
|
||||
p2 = ceil_dirmap[p2 - 19] - 20
|
||||
p2 = (p2 + 2) % 4
|
||||
end
|
||||
end
|
||||
else
|
||||
-- for same-cat placement, aux is used to disable param2 copying
|
||||
if same_cat then
|
||||
aux = not aux
|
||||
end
|
||||
|
||||
local remap
|
||||
|
||||
-- standard placement against the wall
|
||||
local use_wallmap = (wallmounted > 1 and not sneak) or (wallmounted < 2 and sneak)
|
||||
|
||||
-- standard placement against the ceiling, or sneak placement against the upper half of the wall
|
||||
local use_ceilmap = wallmounted == 1 and not sneak
|
||||
use_ceilmap = use_ceilmap or (wallmounted > 1 and sneak and face_off.y > 0)
|
||||
|
||||
if use_wallmap then
|
||||
local left = (p2 == 0 and face_off.x < 0)
|
||||
or (p2 == 1 and face_off.z > 0)
|
||||
or (p2 == 2 and face_off.x > 0)
|
||||
or (p2 == 3 and face_off.z < 0)
|
||||
if aux then
|
||||
left = not left
|
||||
end
|
||||
remap = left and wall_left_dirmap or wall_right_dirmap
|
||||
elseif use_ceilmap then
|
||||
remap = ceil_dirmap
|
||||
end
|
||||
|
||||
if aux then
|
||||
p2 = (p2 + 2) % 4
|
||||
end
|
||||
|
||||
if remap then
|
||||
p2 = remap[p2 + 1]
|
||||
end
|
||||
end
|
||||
|
||||
return minetest.item_place(itemstack, placer, pointed_thing, p2)
|
||||
end
|
||||
else
|
||||
api.on_place = minetest.item_place
|
||||
end
|
||||
|
||||
function api.scale_light(light_source, shape_def)
|
||||
if not light_source or light_source == 0 then
|
||||
return 0
|
||||
elseif legacy_mode then
|
||||
return light_source - 1
|
||||
end
|
||||
|
||||
return math.max(1, math.min(math.round(light_source * shape_def.eighths / 4), light_source))
|
||||
end
|
341
mods/moreblocks/stairsplus/api/node.lua
Normal file
341
mods/moreblocks/stairsplus/api/node.lua
Normal file
|
@ -0,0 +1,341 @@
|
|||
-- for registering variants of a specific node
|
||||
local api = stairsplus.api
|
||||
|
||||
local table_set_all = futil.table.set_all
|
||||
local table_sort_keys = futil.table.sort_keys
|
||||
|
||||
local S = stairsplus.S
|
||||
|
||||
local default_align_style = stairsplus.settings.default_align_style
|
||||
local silence_group_overrides = stairsplus.settings.silence_group_overrides
|
||||
|
||||
api.nodes_by_shape = {}
|
||||
api.shapes_by_node = {}
|
||||
|
||||
api.node_by_shaped_node = {}
|
||||
api.shape_by_shaped_node = {}
|
||||
|
||||
api.registered_singles = {}
|
||||
api.registered_on_register_singles = {}
|
||||
|
||||
function api.register_on_register_single(func)
|
||||
table.insert(api.registered_on_register_singles, func)
|
||||
end
|
||||
|
||||
local function check_node_validity(node_def, meta)
|
||||
local type_ = node_def.type
|
||||
if not meta.ignore_type and type_ ~= "node" then
|
||||
error(("cannot register non-node %q w/ stairsplus"):format(node_def.name))
|
||||
end
|
||||
|
||||
local drawtype = node_def.drawtype
|
||||
if
|
||||
not meta.ignore_drawtype
|
||||
and (
|
||||
drawtype == "airlike"
|
||||
or drawtype == "liquid"
|
||||
or drawtype == "flowingliquid"
|
||||
or drawtype == "torchlike"
|
||||
or drawtype == "signlike"
|
||||
or drawtype == "plantlike"
|
||||
or drawtype == "firelike"
|
||||
or drawtype == "fencelike"
|
||||
or drawtype == "raillike"
|
||||
or drawtype == "nodebox"
|
||||
or drawtype == "mesh"
|
||||
or drawtype == "plantlike_rooted"
|
||||
)
|
||||
then
|
||||
error(("cannot register %q w/ drawtype %q w/ stairsplus"):format(node_def.name, drawtype))
|
||||
end
|
||||
|
||||
local paramtype2 = node_def.paramtype2
|
||||
if
|
||||
not meta.ignore_paramtype2
|
||||
and (
|
||||
paramtype2 == "flowingliquid"
|
||||
or paramtype2 == "wallmounted"
|
||||
or paramtype2 == "leveled"
|
||||
or paramtype2 == "degrotate"
|
||||
or paramtype2 == "meshoptions"
|
||||
or paramtype2 == "color"
|
||||
or paramtype2 == "colorwallmounted"
|
||||
or paramtype2 == "glasslikeliquidlevel"
|
||||
or paramtype2 == "colordegrotate"
|
||||
)
|
||||
then
|
||||
error(("cannot register %q w/ paramtype2 %q w/ stairsplus"):format(node_def.name, paramtype2))
|
||||
end
|
||||
end
|
||||
|
||||
function api.format_name(node, shape)
|
||||
local mod, name = node:match("^([^:]+):(.*)$")
|
||||
local shape_def = api.registered_shapes[shape]
|
||||
return ("%s:%s"):format(mod, shape_def.name_format:format(name))
|
||||
end
|
||||
|
||||
function api.register_single(node, shape, overrides, meta)
|
||||
if not minetest.registered_nodes[node] then
|
||||
error(("node %q is not defined"):format(node))
|
||||
end
|
||||
|
||||
if shape ~= "micro_8" and not (api.nodes_by_shape.micro_8 or {})[node] then
|
||||
-- always make sure a microblock exists
|
||||
api.register_single(node, "micro_8", overrides, meta)
|
||||
end
|
||||
|
||||
local shaped_name = api.format_name(node, shape)
|
||||
|
||||
if shape ~= "micro_8" and not api.is_whitelisted(shaped_name) then
|
||||
return false
|
||||
end
|
||||
|
||||
stairsplus.log("info", "registering %s", shaped_name)
|
||||
|
||||
meta = meta or {}
|
||||
overrides = table.copy(overrides or {})
|
||||
|
||||
local node_def = table.copy(minetest.registered_nodes[node])
|
||||
|
||||
check_node_validity(node_def, meta)
|
||||
|
||||
if (api.nodes_by_shape[shape] or {})[node] then
|
||||
return -- already registered
|
||||
end
|
||||
|
||||
local shape_def = api.registered_shapes[shape]
|
||||
|
||||
local paramtype2
|
||||
if node_def.paramtype2 == "colorfacedir" then
|
||||
paramtype2 = "colorfacedir"
|
||||
else
|
||||
paramtype2 = shape_def.paramtype2 or "facedir"
|
||||
end
|
||||
|
||||
-- shaped_node definition
|
||||
local def = {
|
||||
description = S(shape_def.description, node_def.description or node),
|
||||
|
||||
drawtype = shape_def.drawtype,
|
||||
mesh = shape_def.mesh,
|
||||
node_box = shape_def.node_box,
|
||||
collision_box = shape_def.collision_box,
|
||||
selection_box = shape_def.selection_box,
|
||||
paramtype = shape_def.paramtype or "light",
|
||||
paramtype2 = paramtype2,
|
||||
|
||||
light_source = api.scale_light(node_def.light_source, shape_def),
|
||||
groups = api.build_groups(node, shape),
|
||||
|
||||
tiles = node_def.tiles,
|
||||
overlay_tiles = node_def.overlay_tiles,
|
||||
use_texture_alpha = node_def.use_texture_alpha,
|
||||
color = node_def.color,
|
||||
palette = node_def.palette, -- for coloredfacedir
|
||||
stack_max = node_def.stack_max,
|
||||
sounds = node_def.sounds,
|
||||
is_ground_content = node_def.is_ground_content,
|
||||
walkable = node_def.walkable,
|
||||
pointable = node_def.pointable,
|
||||
diggable = node_def.diggable,
|
||||
climbable = node_def.climbable,
|
||||
move_resistance = node_def.move_resistance,
|
||||
|
||||
on_place = function(...)
|
||||
return api.on_place(...)
|
||||
end,
|
||||
}
|
||||
|
||||
-- see-through nodes tend to look better if we just use the first tile
|
||||
if (node_def.drawtype or ""):match("glass") then
|
||||
if #def.tiles > 1 then
|
||||
def.tiles = { def.tiles[1] }
|
||||
end
|
||||
|
||||
if def.overlay_tiles and #def.overlay_tiles > 1 then
|
||||
def.overlay_tiles = { def.overlay_tiles[1] }
|
||||
end
|
||||
end
|
||||
|
||||
if node_def.short_description then
|
||||
def.short_description = S(shape_def.description, node_def.short_description)
|
||||
end
|
||||
|
||||
-- if there's a drop defined, and we can drop a shaped version, do so
|
||||
if meta.legacy_drop then
|
||||
if type(meta.legacy_drop) == "string" then
|
||||
local item = api.get_schema_recipe_item(meta.legacy_drop, shape)
|
||||
if item then
|
||||
def.drop = item
|
||||
end
|
||||
end
|
||||
elseif node_def.drop and type(node_def.drop) == "string" then
|
||||
local item = api.get_schema_recipe_item(node_def.drop, shape)
|
||||
if item then
|
||||
def.drop = item
|
||||
end
|
||||
end
|
||||
|
||||
if not silence_group_overrides and not meta.allow_override_groups and overrides.groups then
|
||||
stairsplus.log(
|
||||
"warning",
|
||||
"removing group overrides from %s (was %s, will be %s)",
|
||||
shaped_name,
|
||||
minetest.write_json(overrides.groups),
|
||||
minetest.write_json(def.groups)
|
||||
)
|
||||
overrides.groups = nil
|
||||
end
|
||||
|
||||
if not meta.allow_override_drawtype and overrides.drawtype then
|
||||
stairsplus.log("warning", "removing drawtype override %s from %s", overrides.drawtype, shaped_name)
|
||||
overrides.drawtype = nil
|
||||
end
|
||||
|
||||
if not meta.allow_override_paramtype2 and overrides.paramtype2 then
|
||||
stairsplus.log("warning", "removing paramtype2 override %s from %s", overrides.paramtype2, shaped_name)
|
||||
overrides.paramtype2 = nil
|
||||
end
|
||||
|
||||
table_set_all(def, overrides)
|
||||
|
||||
-- set backface_culling and align_style
|
||||
local align_style = meta.align_style or default_align_style
|
||||
for i, tile in ipairs(def.tiles) do
|
||||
if type(tile) == "string" then
|
||||
def.tiles[i] = {
|
||||
name = tile,
|
||||
backface_culling = true,
|
||||
align_style = align_style,
|
||||
}
|
||||
elseif not (tile.animation or tile.color) then
|
||||
tile.backface_culling = true
|
||||
tile.align_style = align_style
|
||||
end
|
||||
end
|
||||
|
||||
if def.overlay_tiles then
|
||||
for i, tile in ipairs(def.overlay_tiles) do
|
||||
if type(tile) == "string" then
|
||||
def.overlay_tiles[i] = {
|
||||
name = tile,
|
||||
backface_culling = true,
|
||||
align_style = align_style,
|
||||
}
|
||||
elseif not (tile.animation or tile.color) then
|
||||
tile.backface_culling = true
|
||||
tile.align_style = align_style
|
||||
end
|
||||
def.overlay_tiles[i] = tile
|
||||
end
|
||||
end
|
||||
|
||||
-- register node
|
||||
minetest.register_node(":" .. shaped_name, def)
|
||||
|
||||
-- alias old name formats
|
||||
if shape_def.aliases then
|
||||
local mod, name = node:match("^([^:]+):(.*)$")
|
||||
for _, alias in ipairs(shape_def.aliases) do
|
||||
minetest.register_alias(("%s:%s"):format(mod, alias:format(name)), shaped_name)
|
||||
end
|
||||
end
|
||||
|
||||
local nodes = api.nodes_by_shape[shape] or {}
|
||||
nodes[node] = true
|
||||
api.nodes_by_shape[shape] = nodes
|
||||
|
||||
local shapes = api.shapes_by_node[node] or {}
|
||||
shapes[shape] = true
|
||||
api.shapes_by_node[node] = shapes
|
||||
|
||||
api.node_by_shaped_node[shaped_name] = node
|
||||
api.shape_by_shaped_node[shaped_name] = shape
|
||||
|
||||
api.node_by_shaped_node[node] = node
|
||||
api.shape_by_shaped_node[node] = "node"
|
||||
|
||||
table.insert(api.registered_singles, { node, shaped_name })
|
||||
|
||||
for _, func in ipairs(api.registered_on_register_singles) do
|
||||
func(node, shaped_name)
|
||||
end
|
||||
|
||||
return shaped_name
|
||||
end
|
||||
|
||||
function api.register_all(node, overrides, meta)
|
||||
for shape in pairs(api.registered_shapes) do
|
||||
api.register_single(node, shape, overrides, meta)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_singles(node, shapes, overrides, meta)
|
||||
for _, shape in ipairs(shapes) do
|
||||
api.register_single(node, shape, overrides, meta)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_group(node, shape_group, overrides, meta)
|
||||
for _, shape in ipairs(api.shapes_by_group[shape_group] or {}) do
|
||||
api.register_single(node, shape, overrides, meta)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_groups(node, shape_groups, overrides, meta)
|
||||
for _, group in ipairs(shape_groups) do
|
||||
api.register_group(node, group, overrides, meta)
|
||||
end
|
||||
end
|
||||
|
||||
function api.get_shapes(node)
|
||||
if api.shapes_by_node[node] then
|
||||
return table_sort_keys(api.shapes_by_node[node])
|
||||
end
|
||||
end
|
||||
|
||||
-- warning: don't mutate the return value
|
||||
function api.get_shapes_hash(node)
|
||||
return api.shapes_by_node[node]
|
||||
end
|
||||
|
||||
-- turn a recipe item into a shape if possible
|
||||
function api.get_schema_recipe_item(node, shape_or_item)
|
||||
if shape_or_item == "" then
|
||||
return ""
|
||||
end
|
||||
|
||||
local name, count = shape_or_item:match("^([^ ]+) (%d+)")
|
||||
|
||||
if not name then
|
||||
name = shape_or_item
|
||||
end
|
||||
|
||||
count = tonumber(count)
|
||||
|
||||
if api.registered_shapes[name] then
|
||||
name = api.format_name(node, name)
|
||||
elseif name == "node" then
|
||||
name = node
|
||||
elseif not name:match(":") then
|
||||
return
|
||||
end
|
||||
|
||||
if count then
|
||||
return ("%s %s"):format(name, count)
|
||||
else
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
function api.get_micronode(node)
|
||||
return api.get_schema_recipe_item(node, "micro_8")
|
||||
end
|
||||
|
||||
function api.get_node_of_shaped_node(shaped_node)
|
||||
return api.node_by_shaped_node[shaped_node]
|
||||
end
|
||||
|
||||
function api.get_shape_of_shaped_node(shaped_node)
|
||||
return api.shape_by_shaped_node[shaped_node]
|
||||
end
|
257
mods/moreblocks/stairsplus/api/recipe.lua
Normal file
257
mods/moreblocks/stairsplus/api/recipe.lua
Normal file
|
@ -0,0 +1,257 @@
|
|||
-- for registering recipe schemas
|
||||
local api = stairsplus.api
|
||||
|
||||
api.registered_recipe_schemas = {}
|
||||
api.registered_on_register_craft_schemas = {}
|
||||
|
||||
local registered_schemas_by_node = {}
|
||||
|
||||
local function is_valid_output(item, shapes)
|
||||
local item_name = item:match("^([^ ]+)")
|
||||
|
||||
return item_name and (shapes[item_name] or item_name == "node" or item_name:match(":"))
|
||||
end
|
||||
|
||||
local function is_valid_item(item, shapes)
|
||||
return is_valid_output(item, shapes) or item == ""
|
||||
end
|
||||
|
||||
local function verify_schema(schema)
|
||||
local problems = {}
|
||||
|
||||
if not (schema.type == "shaped" or schema.type == "shapeless" or schema.type == nil) then
|
||||
table.insert(problems, ("unimplemented schema type %q"):format(schema.type))
|
||||
end
|
||||
|
||||
if not is_valid_output(schema.output, api.registered_shapes) then
|
||||
table.insert(problems, ("don't know how to handle output %q"):format(schema.output))
|
||||
end
|
||||
|
||||
if schema.replacements then
|
||||
for _, replacement in ipairs(schema.replacements) do
|
||||
for _, item in ipairs(replacement) do
|
||||
if not is_valid_item(item, api.registered_shapes) then
|
||||
table.insert(problems, ("don't know how to handle replacement item %q"):format(item))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if schema.type == "shapeless" then
|
||||
for _, item in ipairs(schema.recipe) do
|
||||
if not is_valid_item(item, api.registered_shapes) then
|
||||
table.insert(problems, ("don't know how to handle craft item %q"):format(item))
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, row in ipairs(schema.recipe) do
|
||||
for _, item in ipairs(row) do
|
||||
if not is_valid_item(item, api.registered_shapes) then
|
||||
table.insert(problems, ("don't know how to handle craft item %q"):format(item))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #problems > 0 then
|
||||
return table.concat(problems, ", ")
|
||||
end
|
||||
end
|
||||
|
||||
local function has_the_right_shapes(schema, shapes)
|
||||
if not is_valid_output(schema.output, shapes) then
|
||||
return false
|
||||
end
|
||||
|
||||
if schema.replacements then
|
||||
for _, replacement in ipairs(schema.replacements) do
|
||||
for _, item in ipairs(replacement) do
|
||||
if not is_valid_item(item, shapes) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if schema.type == "shapeless" then
|
||||
for _, item in ipairs(schema.recipe) do
|
||||
if not is_valid_item(item, shapes) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
elseif schema.type == "shaped" or schema.type == nil then
|
||||
for _, row in ipairs(schema.recipe) do
|
||||
for _, item in ipairs(row) do
|
||||
if not is_valid_item(item, shapes) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function register_for_schema(node, schema)
|
||||
stairsplus.log("verbose", "using schema %s w/ node %s", minetest.write_json(schema), node)
|
||||
|
||||
local recipe = table.copy(schema)
|
||||
|
||||
recipe.output = api.get_schema_recipe_item(node, recipe.output)
|
||||
|
||||
if recipe.replacements then
|
||||
for _, replacement in ipairs(recipe.replacements) do
|
||||
for i, item in ipairs(replacement) do
|
||||
replacement[i] = api.get_schema_recipe_item(node, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if recipe.type == "shapeless" then
|
||||
for i, item in ipairs(recipe.recipe) do
|
||||
recipe.recipe[i] = api.get_schema_recipe_item(node, item)
|
||||
end
|
||||
elseif recipe.type == "shaped" or recipe.type == nil then
|
||||
for _, row in ipairs(recipe.recipe) do
|
||||
for i, item in ipairs(row) do
|
||||
row[i] = api.get_schema_recipe_item(node, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
stairsplus.log("info", "registering recipe %s", minetest.write_json(recipe))
|
||||
|
||||
minetest.register_craft(recipe)
|
||||
end
|
||||
|
||||
function api.register_on_register_craft_schema(func)
|
||||
table.insert(api.registered_on_register_craft_schemas, func)
|
||||
end
|
||||
|
||||
function api.register_craft_schema(schema)
|
||||
local problems = verify_schema(schema)
|
||||
|
||||
if problems then
|
||||
error(problems)
|
||||
end
|
||||
|
||||
stairsplus.log("info", "registering craft schema %s", minetest.write_json(schema))
|
||||
|
||||
table.insert(api.registered_recipe_schemas, schema)
|
||||
|
||||
for node, shapes in pairs(api.shapes_by_node) do
|
||||
local registered_schemas = registered_schemas_by_node[node] or {}
|
||||
|
||||
if has_the_right_shapes(schema, shapes) and not registered_schemas[schema] then
|
||||
register_for_schema(node, schema)
|
||||
registered_schemas[schema] = true
|
||||
end
|
||||
|
||||
registered_schemas_by_node[node] = registered_schemas
|
||||
end
|
||||
|
||||
for _, func in ipairs(api.registered_on_register_craft_schemas) do
|
||||
func(schema)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_schema_crafts_for_node(node)
|
||||
local registered_schemas = registered_schemas_by_node[node] or {}
|
||||
|
||||
local shapes = api.get_shapes_hash(node)
|
||||
for _, schema in ipairs(api.registered_recipe_schemas) do
|
||||
if has_the_right_shapes(schema, shapes) and not registered_schemas[schema] then
|
||||
register_for_schema(node, schema)
|
||||
registered_schemas[schema] = true
|
||||
end
|
||||
end
|
||||
|
||||
registered_schemas_by_node[node] = registered_schemas
|
||||
end
|
||||
|
||||
api.register_on_register_single(api.register_schema_crafts_for_node)
|
||||
|
||||
local function get_shape_intersection(a, b)
|
||||
local a_shapes = api.get_shapes(a)
|
||||
local b_shapes = api.get_shapes(b)
|
||||
local filter = {}
|
||||
for i = 1, #b_shapes do
|
||||
filter[b_shapes[i]] = true
|
||||
end
|
||||
local intersection = {}
|
||||
for i = 1, #a_shapes do
|
||||
local shape = a_shapes[i]
|
||||
if filter[shape] then
|
||||
intersection[#intersection + 1] = shape
|
||||
end
|
||||
end
|
||||
return intersection
|
||||
end
|
||||
|
||||
local function register_cooking_for_shapes(recipe)
|
||||
local mod, name = recipe.recipe:match("^([^:]+):(.*)$")
|
||||
|
||||
local shapes
|
||||
if mod == "group" then
|
||||
shapes = api.get_shapes(recipe.output)
|
||||
else
|
||||
shapes = get_shape_intersection(recipe.output, recipe.recipe)
|
||||
end
|
||||
|
||||
for _, shape in ipairs(shapes) do
|
||||
local shape_def = api.registered_shapes[shape]
|
||||
local input
|
||||
if mod == "group" then
|
||||
input = "group:" .. shape_def.name_format:format(name)
|
||||
else
|
||||
input = api.get_schema_recipe_item(recipe.recipe, shape)
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = api.get_schema_recipe_item(recipe.output, shape),
|
||||
recipe = input,
|
||||
cooktime = math.max(1.0, (recipe.cooktime or 3) * (shape_def.eighths / 8)),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local function register_fuel_for_shapes(recipe)
|
||||
local mod, name = recipe.recipe:match("^([^:]+):(.*)$")
|
||||
local shapes
|
||||
if mod == "group" then
|
||||
shapes = api.registered_shapes
|
||||
else
|
||||
shapes = api.get_shapes_hash(recipe.recipe)
|
||||
end
|
||||
|
||||
if not shapes then
|
||||
error(("don't know how to handle fuel %s"):format(recipe.recipe))
|
||||
end
|
||||
|
||||
for shape in pairs(shapes) do
|
||||
local shape_def = api.registered_shapes[shape]
|
||||
local input
|
||||
if mod == "group" then
|
||||
input = "group:" .. shape_def.name_format:format(name)
|
||||
else
|
||||
input = api.get_schema_recipe_item(recipe.recipe, shape)
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = input,
|
||||
burntime = math.max(1.0, (recipe.burntime or 1) * (shape_def.eighths / 8)),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_crafts_for_shapes(recipe)
|
||||
if recipe.type == "cooking" then
|
||||
register_cooking_for_shapes(recipe)
|
||||
elseif recipe.type == "fuel" then
|
||||
register_fuel_for_shapes(recipe)
|
||||
else
|
||||
error(("unsupported recipe type %s"):format(recipe.type))
|
||||
end
|
||||
end
|
48
mods/moreblocks/stairsplus/api/shape.lua
Normal file
48
mods/moreblocks/stairsplus/api/shape.lua
Normal file
|
@ -0,0 +1,48 @@
|
|||
local f = string.format
|
||||
|
||||
local api = stairsplus.api
|
||||
|
||||
api.registered_on_register_shapes = {}
|
||||
api.registered_shapes = {}
|
||||
api.shapes_by_group = {}
|
||||
|
||||
function api.register_on_register_shape(func)
|
||||
table.insert(api.registered_on_register_shapes, func)
|
||||
end
|
||||
|
||||
function api.register_shape(name, def)
|
||||
stairsplus.log("info", "registering shape %q", name)
|
||||
def.shape_groups = def.shape_groups or {}
|
||||
api.registered_shapes[name] = def
|
||||
|
||||
for group in pairs(def.shape_groups) do
|
||||
local shapes = api.shapes_by_group[group] or {}
|
||||
table.insert(shapes, name)
|
||||
api.shapes_by_group[group] = shapes
|
||||
end
|
||||
|
||||
for _, func in ipairs(api.registered_on_register_shapes) do
|
||||
func(name, def)
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_shape_group(shape_group, shapes)
|
||||
for _, shape in ipairs(shapes) do
|
||||
api.registered_shapes[shape].shape_groups[shape_group] = 1
|
||||
end
|
||||
api.shapes_by_group[shape_group] = shapes
|
||||
end
|
||||
|
||||
function api.guess_shape(node_name)
|
||||
local mod, namepart = node_name:match("^([^:]+):([^:]+)$")
|
||||
if not (mod and namepart) then
|
||||
return
|
||||
end
|
||||
for name, def in pairs(api.registered_shapes) do
|
||||
local pattern = def.name_format:gsub("%%s", "(.*)")
|
||||
local matched = namepart:match(pattern)
|
||||
if matched and minetest.registered_nodes[f("%s:%s", mod, matched)] then
|
||||
return name
|
||||
end
|
||||
end
|
||||
end
|
357
mods/moreblocks/stairsplus/api/station.lua
Normal file
357
mods/moreblocks/stairsplus/api/station.lua
Normal file
|
@ -0,0 +1,357 @@
|
|||
-- for creating the circular saw and similar nodes
|
||||
|
||||
local api = stairsplus.api
|
||||
|
||||
local item_has_metadata = stairsplus.util.item_has_metadata
|
||||
local resolve_itemstack = futil.resolve_itemstack
|
||||
|
||||
local default_stack_max = tonumber(minetest.settings:get("default_stack_max")) or 99
|
||||
|
||||
local station = {}
|
||||
|
||||
function station.get_cost(shaped_node)
|
||||
if shaped_node == "" then
|
||||
return 0
|
||||
end
|
||||
|
||||
local shape = api.get_shape_of_shaped_node(shaped_node)
|
||||
if shape == "node" then
|
||||
return 8
|
||||
end
|
||||
|
||||
local shape_def = api.registered_shapes[shape]
|
||||
return shape_def and shape_def.eighths
|
||||
end
|
||||
|
||||
function station.get_current_node(inv)
|
||||
local input_stack = inv:get_stack("stairsplus:input", 1)
|
||||
if not input_stack:is_empty() then
|
||||
return api.get_node_of_shaped_node(input_stack:get_name())
|
||||
end
|
||||
|
||||
local micro_stack = inv:get_stack("stairsplus:micro", 1)
|
||||
if not micro_stack:is_empty() then
|
||||
return api.get_node_of_shaped_node(micro_stack:get_name())
|
||||
end
|
||||
|
||||
local recycle_stack = inv:get_stack("stairsplus:recycle", 1)
|
||||
if not recycle_stack:is_empty() then
|
||||
return api.get_node_of_shaped_node(recycle_stack:get_name())
|
||||
end
|
||||
end
|
||||
|
||||
function station.can_dig(meta, inv)
|
||||
return inv:is_empty("stairsplus:input") and inv:is_empty("stairsplus:micro")
|
||||
end
|
||||
|
||||
function station.on_receive_fields(meta, inv, formname, fields, sender, build_formspec, update_metadata)
|
||||
local max = tonumber(fields.max_offered)
|
||||
if max and max > 0 then
|
||||
meta:set_int("stairsplus:max_offered", max)
|
||||
-- Update to show the correct number of items:
|
||||
station.update_inventory(meta, inv)
|
||||
if update_metadata then
|
||||
update_metadata(meta, inv)
|
||||
end
|
||||
|
||||
if build_formspec then
|
||||
meta:set_string("formspec", build_formspec(meta, inv))
|
||||
end
|
||||
end
|
||||
|
||||
return not not fields.max_offered
|
||||
end
|
||||
|
||||
local function fix_aliases(inv)
|
||||
local input = inv:get_stack("stairsplus:input", 1)
|
||||
input:set_name(resolve_itemstack(input):get_name())
|
||||
inv:set_stack("stairsplus:input", 1, input)
|
||||
|
||||
local micro = inv:get_stack("stairsplus:micro", 1)
|
||||
micro:set_name(resolve_itemstack(micro):get_name())
|
||||
inv:set_stack("stairsplus:micro", 1, micro)
|
||||
|
||||
local recycle = inv:get_stack("stairsplus:recycle", 1)
|
||||
recycle:set_name(resolve_itemstack(recycle):get_name())
|
||||
inv:set_stack("stairsplus:recycle", 1, recycle)
|
||||
|
||||
for i = 1, inv:get_size("stairsplus:output") do
|
||||
local output = inv:get_stack("stairsplus:output", i)
|
||||
output:set_name(resolve_itemstack(output):get_name())
|
||||
inv:set_stack("stairsplus:output", i, output)
|
||||
end
|
||||
end
|
||||
|
||||
function station.update_inventory(meta, inv, taken_stack)
|
||||
fix_aliases(inv)
|
||||
|
||||
local node = station.get_current_node(inv)
|
||||
local valid_shapes = api.shapes_by_node[node]
|
||||
|
||||
if not (node and valid_shapes) then
|
||||
inv:set_stack("stairsplus:input", 1, ItemStack())
|
||||
inv:set_stack("stairsplus:micro", 1, ItemStack())
|
||||
inv:set_stack("stairsplus:recycle", 1, ItemStack())
|
||||
for i = 1, inv:get_size("stairsplus:output") do
|
||||
inv:set_stack("stairsplus:output", i, ItemStack())
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local input_stack = inv:get_stack("stairsplus:input", 1)
|
||||
local micro_stack = inv:get_stack("stairsplus:micro", 1)
|
||||
local recycle_stack = inv:get_stack("stairsplus:recycle", 1)
|
||||
|
||||
local input_cost = station.get_cost(input_stack:get_name())
|
||||
local micro_cost = station.get_cost(micro_stack:get_name())
|
||||
local recycle_cost = station.get_cost(recycle_stack:get_name())
|
||||
|
||||
local total_value = (
|
||||
(input_stack:get_count() * input_cost)
|
||||
+ (micro_stack:get_count() * micro_cost)
|
||||
+ (recycle_stack:get_count() * recycle_cost)
|
||||
)
|
||||
|
||||
if taken_stack then
|
||||
total_value = total_value - station.get_cost(taken_stack:get_name()) * taken_stack:get_count()
|
||||
end
|
||||
|
||||
local new_micros = total_value % 8
|
||||
local new_blocks = math.floor(total_value / 8)
|
||||
|
||||
local micronode = api.get_micronode(node)
|
||||
|
||||
inv:set_stack("stairsplus:input", 1, ItemStack({ name = node, count = new_blocks }))
|
||||
inv:set_stack("stairsplus:micro", 1, ItemStack({ name = micronode, count = new_micros }))
|
||||
inv:set_stack("stairsplus:recycle", 1, ItemStack())
|
||||
|
||||
if total_value == 0 then
|
||||
for i = 1, inv:get_size("stairsplus:output") do
|
||||
inv:set_stack("stairsplus:output", i, "")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local max_offered = meta:get_int("stairsplus:max_offered")
|
||||
local shape_groups = minetest.parse_json(meta:get_string("stairsplus:shape_groups"))
|
||||
|
||||
local i = 1
|
||||
for _, group in ipairs(shape_groups) do
|
||||
for _, shape in ipairs(api.shapes_by_group[group]) do
|
||||
if valid_shapes[shape] then
|
||||
local shape_def = api.registered_shapes[shape]
|
||||
local shaped_node = api.format_name(node, shape)
|
||||
local stack_max = math.min(max_offered, ItemStack(shaped_node):get_stack_max())
|
||||
local count = math.min(stack_max, math.floor(total_value / shape_def.eighths))
|
||||
local stack
|
||||
if count > 0 then
|
||||
stack = ItemStack({ name = shaped_node, count = count })
|
||||
else
|
||||
stack = ""
|
||||
end
|
||||
inv:set_stack("stairsplus:output", i, stack)
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for j = i, inv:get_size("stairsplus:output") do
|
||||
inv:set_stack("stairsplus:output", j, "")
|
||||
end
|
||||
end
|
||||
|
||||
-- Moving the inventory of the station around is not allowed because it
|
||||
-- is a fictional inventory. Moving inventory around would be rather
|
||||
-- impractical and make things more difficult to calculate:
|
||||
function station.allow_inventory_move(meta, inv, from_list, from_index, to_list, to_index, count, player)
|
||||
return 0
|
||||
end
|
||||
|
||||
function station.allow_inventory_put(meta, inv, listname, index, stack, player)
|
||||
if listname == "stairsplus:output" then
|
||||
return 0
|
||||
end
|
||||
|
||||
if item_has_metadata(stack) then
|
||||
return 0
|
||||
end
|
||||
|
||||
local to_put_name = resolve_itemstack(stack):get_name()
|
||||
local node = api.get_node_of_shaped_node(to_put_name)
|
||||
local shape = api.get_shape_of_shaped_node(to_put_name)
|
||||
|
||||
if not (node and shape) then
|
||||
return 0
|
||||
end
|
||||
|
||||
local current_node = station.get_current_node(inv)
|
||||
|
||||
local input_stack = inv:get_stack("stairsplus:input", 1)
|
||||
local micro_stack = inv:get_stack("stairsplus:micro", 1)
|
||||
|
||||
if current_node and node ~= current_node then
|
||||
if
|
||||
(input_stack:is_empty() and listname == "stairsplus:micro")
|
||||
or (micro_stack:is_empty() and listname == "stairsplus:input")
|
||||
then
|
||||
return stack:get_count()
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
local count = stack:get_count()
|
||||
local cost = station.get_cost(to_put_name)
|
||||
|
||||
local current_value = 8 * input_stack:get_count() + micro_stack:get_count()
|
||||
local max_value = 8 * ItemStack(node):get_stack_max() + 7
|
||||
|
||||
local available_value = max_value - current_value
|
||||
local available_count = math.floor(available_value / cost)
|
||||
|
||||
return math.min(count, available_count)
|
||||
end
|
||||
|
||||
function station.on_inventory_put(meta, inv, listname, index, stack, player, update_metadata)
|
||||
station.update_inventory(meta, inv)
|
||||
if update_metadata then
|
||||
update_metadata(meta, inv)
|
||||
end
|
||||
end
|
||||
|
||||
function station.on_inventory_take(meta, inv, listname, index, stack, player, update_metadata)
|
||||
if listname == "stairsplus:output" then
|
||||
station.update_inventory(meta, inv, stack)
|
||||
else
|
||||
station.update_inventory(meta, inv)
|
||||
end
|
||||
|
||||
if update_metadata then
|
||||
update_metadata(meta, inv)
|
||||
end
|
||||
end
|
||||
|
||||
function station.initialize_metadata(meta, inv, shape_groups, build_formspec, update_metadata)
|
||||
meta:set_string("stairsplus:shape_groups", minetest.write_json(shape_groups))
|
||||
|
||||
if meta:get_int("max_offered") ~= 0 then
|
||||
meta:set_int("stairsplus:max_offered", meta:get_int("max_offered"))
|
||||
elseif meta:get_int("stairsplus:max_offered") == 0 then
|
||||
meta:set_int("stairsplus:max_offered", default_stack_max)
|
||||
end
|
||||
|
||||
if build_formspec then
|
||||
meta:set_string("formspec", build_formspec(meta, inv))
|
||||
end
|
||||
|
||||
if update_metadata then
|
||||
update_metadata(meta, inv)
|
||||
end
|
||||
end
|
||||
|
||||
function station.initialize_inventory(inv, shape_groups)
|
||||
local output_size = 0
|
||||
for _, group in ipairs(shape_groups) do
|
||||
output_size = output_size + #api.shapes_by_group[group]
|
||||
end
|
||||
|
||||
inv:set_size("stairsplus:input", 1)
|
||||
inv:set_size("stairsplus:micro", 1)
|
||||
inv:set_size("stairsplus:recycle", 1)
|
||||
inv:set_size("stairsplus:output", output_size)
|
||||
|
||||
-- get rid of old lists
|
||||
for _, listname in ipairs({ "input", "micro", "recycle", "output" }) do
|
||||
if inv:get_size(listname) > 0 then
|
||||
inv:set_list(("stairsplus:%s"):format(listname), inv:get_list(listname))
|
||||
inv:set_size(listname, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function station.on_construct(pos, shape_groups, build_formspec, update_metadata)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
|
||||
station.initialize_inventory(inv, shape_groups)
|
||||
station.initialize_metadata(meta, inv, shape_groups, build_formspec, update_metadata)
|
||||
station.update_inventory(meta, inv)
|
||||
end
|
||||
|
||||
function station.after_place_node(pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if futil.is_player(placer) then
|
||||
meta:set_string("owner", placer:get_player_name())
|
||||
end
|
||||
end
|
||||
|
||||
function api.register_station(name, def)
|
||||
local shape_groups = def.shape_groups
|
||||
local build_formspec = def.build_formspec
|
||||
local update_metadata = def.update_metadata
|
||||
|
||||
if not shape_groups then
|
||||
error("station requires shape_groups defined")
|
||||
end
|
||||
|
||||
def.shape_groups = nil
|
||||
def.build_formspec = nil
|
||||
def.update_metadata = nil
|
||||
|
||||
def.after_place_node = def.after_place_node or station.after_place_node
|
||||
def.on_construct = def.on_construct
|
||||
or function(pos)
|
||||
return station.on_construct(pos, shape_groups, build_formspec, update_metadata)
|
||||
end
|
||||
|
||||
def.can_dig = def.can_dig
|
||||
or function(pos, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return station.can_dig(meta, inv, player)
|
||||
end
|
||||
|
||||
def.on_receive_fields = def.on_receive_fields
|
||||
or function(pos, formname, fields, sender)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return station.on_receive_fields(meta, inv, formname, fields, sender, build_formspec, update_metadata)
|
||||
end
|
||||
|
||||
def.allow_metadata_inventory_move = def.allow_metadata_inventory_move
|
||||
or function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return station.allow_inventory_move(meta, inv, from_list, from_index, to_list, to_index, count, player)
|
||||
end
|
||||
|
||||
def.allow_metadata_inventory_put = def.allow_metadata_inventory_put
|
||||
or function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return station.allow_inventory_put(meta, inv, listname, index, stack, player)
|
||||
end
|
||||
|
||||
def.on_metadata_inventory_put = def.on_metadata_inventory_put
|
||||
or function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return station.on_inventory_put(meta, inv, listname, index, stack, player, update_metadata)
|
||||
end
|
||||
|
||||
def.on_metadata_inventory_take = def.on_metadata_inventory_take
|
||||
or function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return station.on_inventory_take(meta, inv, listname, index, stack, player, update_metadata)
|
||||
end
|
||||
|
||||
def._stairsplus_shape_groups = shape_groups
|
||||
|
||||
def.groups = table.copy(def.groups or {})
|
||||
def.groups.stairsplus_station = 1
|
||||
|
||||
minetest.register_node(name, def)
|
||||
end
|
||||
|
||||
api.station = station
|
25
mods/moreblocks/stairsplus/api/whitelist.lua
Normal file
25
mods/moreblocks/stairsplus/api/whitelist.lua
Normal file
|
@ -0,0 +1,25 @@
|
|||
local f = string.format
|
||||
|
||||
local s = stairsplus.settings
|
||||
local api = stairsplus.api
|
||||
|
||||
if s.whitelist_mode then
|
||||
api.whitelisted = {}
|
||||
local filename = futil.path_concat(minetest.get_worldpath(), "stairsplus.whitelist")
|
||||
local contents = futil.load_file(filename)
|
||||
if not contents then
|
||||
error(f("error initializing stairsplus whitelist: %s does not exist", filename))
|
||||
end
|
||||
local items = contents:split("\n")
|
||||
for i = 1, #items do
|
||||
api.whitelisted[items[i]] = true
|
||||
end
|
||||
stairsplus.log("action", f("%s nodes whitelisted", #api.whitelisted))
|
||||
end
|
||||
|
||||
function api.is_whitelisted(name)
|
||||
if not s.whitelist_mode then
|
||||
return true
|
||||
end
|
||||
return api.whitelisted[name]
|
||||
end
|
132
mods/moreblocks/stairsplus/circular_saw.lua
Normal file
132
mods/moreblocks/stairsplus/circular_saw.lua
Normal file
|
@ -0,0 +1,132 @@
|
|||
stairsplus.api.circular_saw = {}
|
||||
local circular_saw = stairsplus.api.circular_saw
|
||||
local api = stairsplus.api
|
||||
local station = api.station
|
||||
|
||||
local get_location_string = futil.get_location_string
|
||||
|
||||
local S = stairsplus.S
|
||||
local F = minetest.formspec_escape
|
||||
|
||||
local formspec_style = stairsplus.resources.formspec_style
|
||||
|
||||
function circular_saw.build_formspec(meta, inv)
|
||||
local inv_location = get_location_string(inv)
|
||||
return ([[
|
||||
size[10,11]
|
||||
%s
|
||||
label[0,0;]
|
||||
label[0,0;%s]
|
||||
list[%s;stairsplus:input;1.7,0;1,1;]
|
||||
label[0,1;%s]
|
||||
list[%s;stairsplus:micro;1.7,1;1,1;]
|
||||
label[0,2;%s]
|
||||
list[%s;stairsplus:recycle;1.7,2;1,1;]
|
||||
field[0.3,3.5;1,1;max_offered;%s:;%i]
|
||||
button[1,3.2;1.7,1;Set;%s]
|
||||
|
||||
list[%s;stairsplus:output;2.8,0;7,7;]
|
||||
list[current_player;main;1.5,7.25;8,4;]
|
||||
|
||||
listring[%s;stairsplus:output]
|
||||
listring[current_player;main]
|
||||
listring[%s;stairsplus:recycle]
|
||||
|
||||
listring[%s;stairsplus:micro]
|
||||
listring[current_player;main]
|
||||
|
||||
listring[%s;stairsplus:input]
|
||||
listring[current_player;main]
|
||||
]]):format(
|
||||
formspec_style,
|
||||
F(S("Nodes")),
|
||||
inv_location,
|
||||
F(S("Microblocks")),
|
||||
inv_location,
|
||||
F(S("Input")),
|
||||
inv_location,
|
||||
F(S("Max")),
|
||||
meta:get_int("stairsplus:max_offered"),
|
||||
F(S("Set")),
|
||||
inv_location,
|
||||
inv_location,
|
||||
inv_location,
|
||||
inv_location,
|
||||
inv_location
|
||||
)
|
||||
end
|
||||
|
||||
function circular_saw.update_metadata(meta, inv)
|
||||
local parts = { S("Circular Saw") }
|
||||
|
||||
local owner = meta:get_string("owner")
|
||||
if owner ~= "" then
|
||||
table.insert(parts, S("(owned by @1)", owner))
|
||||
end
|
||||
|
||||
local working_on = station.get_current_node(inv)
|
||||
if working_on then
|
||||
local stack = ItemStack(working_on)
|
||||
table.insert(parts, S("Working on @1", stack:get_short_description() or stack:get_description()))
|
||||
else
|
||||
table.insert(parts, S("Empty"))
|
||||
end
|
||||
|
||||
meta:set_string("infotext", table.concat(parts, " "))
|
||||
end
|
||||
|
||||
api.register_station("stairsplus:circular_saw", {
|
||||
description = S("Circular Saw"),
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.4, -0.5, -0.4, -0.25, 0.25, -0.25 }, -- Leg
|
||||
{ 0.25, -0.5, 0.25, 0.4, 0.25, 0.4 }, -- Leg
|
||||
{ -0.4, -0.5, 0.25, -0.25, 0.25, 0.4 }, -- Leg
|
||||
{ 0.25, -0.5, -0.4, 0.4, 0.25, -0.25 }, -- Leg
|
||||
{ -0.5, 0.25, -0.5, 0.5, 0.375, 0.5 }, -- Tabletop
|
||||
{ -0.01, 0.4375, -0.125, 0.01, 0.5, 0.125 }, -- Saw blade (top)
|
||||
{ -0.01, 0.375, -0.1875, 0.01, 0.4375, 0.1875 }, -- Saw blade (bottom)
|
||||
{ -0.25, -0.0625, -0.25, 0.25, 0.25, 0.25 }, -- Motor case
|
||||
},
|
||||
},
|
||||
tiles = {
|
||||
"stairsplus_circular_saw_top.png",
|
||||
"stairsplus_circular_saw_bottom.png",
|
||||
"stairsplus_circular_saw_side.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = { choppy = 2, oddly_breakable_by_hand = 2 },
|
||||
sounds = stairsplus.resources.sounds.wood,
|
||||
|
||||
shape_groups = { "legacy" },
|
||||
build_formspec = circular_saw.build_formspec,
|
||||
update_metadata = circular_saw.update_metadata,
|
||||
})
|
||||
|
||||
local cm = stairsplus.resources.craft_materials
|
||||
|
||||
if stairsplus.settings.circular_saw_crafting and cm.steel_ingot then
|
||||
minetest.register_craft({
|
||||
output = "stairsplus:circular_saw",
|
||||
recipe = {
|
||||
{ "", cm.steel_ingot, "" },
|
||||
{ "group:wood", "group:wood", "group:wood" },
|
||||
{ "group:wood", "", "group:wood" },
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_lbm({
|
||||
label = "Upgrade legacy saws",
|
||||
name = "stairsplus:replace_legacy_saws",
|
||||
nodenames = { "stairsplus:circular_saw" },
|
||||
run_at_every_load = false,
|
||||
action = function(pos, node)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
def.on_construct(pos, { "legacy" }, circular_saw.build_formspec, circular_saw.update_metadata)
|
||||
end,
|
||||
})
|
43
mods/moreblocks/stairsplus/compat/i3.lua
Normal file
43
mods/moreblocks/stairsplus/compat/i3.lua
Normal file
|
@ -0,0 +1,43 @@
|
|||
-- luacheck: globals i3
|
||||
|
||||
if not stairsplus.has.i3 then
|
||||
return
|
||||
end
|
||||
|
||||
-- https://github.com/fluxionary/minetest-moreblocks/issues/13
|
||||
-- remove i3's assumption that it controls our compression groups
|
||||
for node in pairs(i3.compress_groups) do
|
||||
if node:match("^moreblocks:slope_") or node:match("^wool:slope_") then
|
||||
i3.compress_groups[node] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local api = stairsplus.api
|
||||
|
||||
i3.register_craft_type("stairsplus:circular_saw", {
|
||||
description = "Stairs+ circular saw",
|
||||
icon = "stairsplus_saw_button.png",
|
||||
})
|
||||
|
||||
local function on_register_single(node, shaped_name)
|
||||
i3.register_craft({
|
||||
type = "stairsplus:circular_saw",
|
||||
result = shaped_name,
|
||||
items = { node },
|
||||
})
|
||||
|
||||
local micronode = api.get_micronode(node)
|
||||
if shaped_name ~= micronode then
|
||||
local compress_groups = i3.compress_groups[micronode] or {}
|
||||
table.insert(compress_groups, shaped_name)
|
||||
i3.compress_groups[micronode] = compress_groups
|
||||
i3.compressed[shaped_name] = true
|
||||
end
|
||||
end
|
||||
|
||||
for _, single in ipairs(api.registered_singles) do
|
||||
local node, shaped_name = unpack(single)
|
||||
on_register_single(node, shaped_name)
|
||||
end
|
||||
|
||||
api.register_on_register_single(on_register_single)
|
19
mods/moreblocks/stairsplus/compat/init.lua
Normal file
19
mods/moreblocks/stairsplus/compat/init.lua
Normal file
|
@ -0,0 +1,19 @@
|
|||
stairsplus.compat = {
|
||||
is_legacy_drawtype = function(node)
|
||||
local def = minetest.registered_nodes[node]
|
||||
return (def.drawtype == "mesh" or def.drawtype == "plantlike" or def.drawtype == "nodebox")
|
||||
end,
|
||||
is_legacy_paramtype2 = function(node)
|
||||
local def = minetest.registered_nodes[node]
|
||||
return (
|
||||
def.paramtype2 == "color"
|
||||
or def.paramtype2 == "colorwallmounted"
|
||||
or def.paramtype2 == "glasslikeliquidlevel"
|
||||
)
|
||||
end,
|
||||
}
|
||||
|
||||
stairsplus.dofile("compat", "i3")
|
||||
stairsplus.dofile("compat", "unified_inventory")
|
||||
|
||||
stairsplus.dofile("compat", "old_moreblocks")
|
251
mods/moreblocks/stairsplus/compat/old_moreblocks.lua
Normal file
251
mods/moreblocks/stairsplus/compat/old_moreblocks.lua
Normal file
|
@ -0,0 +1,251 @@
|
|||
-- legacy: export old API for mods which depend on it
|
||||
-- provide a configuration option to *disable* legacy. it must be enabled by default, to prevent breaking
|
||||
-- existing servers
|
||||
local api = stairsplus.api
|
||||
|
||||
local is_legacy_drawtype = stairsplus.compat.is_legacy_drawtype
|
||||
local is_legacy_paramtype2 = stairsplus.compat.is_legacy_paramtype2
|
||||
|
||||
local legacy_mode = stairsplus.settings.legacy_mode
|
||||
|
||||
local function clean_legacy_fields(fields)
|
||||
fields = table.copy(fields) or {}
|
||||
|
||||
fields.drawtype = nil
|
||||
fields.light_source = nil
|
||||
fields.inventory_image = nil
|
||||
fields.inventory_overlay = nil
|
||||
fields.wield_image = nil
|
||||
fields.wield_overlay = nil
|
||||
fields.wield_scale = nil
|
||||
fields.tool_capabilities = nil
|
||||
fields.node_placement_prediction = nil
|
||||
fields.node_dig_prediction = nil
|
||||
fields.on_place = nil
|
||||
fields.on_secondary_use = nil
|
||||
fields.on_drop = nil
|
||||
fields.on_use = nil
|
||||
fields.after_use = nil
|
||||
fields.paramtype2 = nil
|
||||
fields.node_box = nil
|
||||
fields.mesh = nil
|
||||
fields.connects_to = nil
|
||||
fields.connect_sides = nil
|
||||
fields.selection_box = nil
|
||||
fields.collision_box = nil
|
||||
fields.legacy_facedir_simple = nil
|
||||
fields.legacy_wallmounted = nil
|
||||
fields.drop = nil
|
||||
fields.on_construct = nil
|
||||
fields.on_destruct = nil
|
||||
fields.after_destruct = nil
|
||||
fields.after_place_node = nil
|
||||
fields.after_dig_node = nil
|
||||
fields.can_dig = nil
|
||||
fields.on_punch = nil
|
||||
fields.on_rightclick = nil
|
||||
fields.on_dig = nil
|
||||
fields.on_timer = nil
|
||||
fields.on_receive_fields = nil
|
||||
|
||||
return fields
|
||||
end
|
||||
|
||||
local function handle_legacy_drop(modname, drop)
|
||||
if not drop then
|
||||
return
|
||||
end
|
||||
|
||||
if type(drop) == "table" then
|
||||
return drop
|
||||
else
|
||||
return ("%s:%s"):format(modname, drop)
|
||||
end
|
||||
end
|
||||
|
||||
local function register_group(modname, subname, recipeitem, fields, group)
|
||||
if not minetest.registered_nodes[recipeitem] then
|
||||
error(("cannot register stairs for %s before the node is defined"):format(recipeitem))
|
||||
end
|
||||
|
||||
local meta = {}
|
||||
|
||||
meta.legacy_drop = handle_legacy_drop(modname, fields.drop)
|
||||
|
||||
if is_legacy_drawtype(recipeitem) then
|
||||
meta.ignore_drawtype = true
|
||||
end
|
||||
|
||||
if is_legacy_paramtype2(recipeitem) then
|
||||
meta.ignore_paramtype2 = true
|
||||
end
|
||||
|
||||
fields = clean_legacy_fields(fields)
|
||||
|
||||
api.register_group(recipeitem, group, fields, meta)
|
||||
|
||||
local old_name = ("%s:%s"):format(modname, subname)
|
||||
if old_name ~= recipeitem then
|
||||
api.register_alias_group(old_name, recipeitem, group)
|
||||
end
|
||||
end
|
||||
|
||||
function stairsplus:register_all(modname, subname, recipeitem, fields)
|
||||
if legacy_mode then
|
||||
register_group(modname, subname, recipeitem, fields, "legacy")
|
||||
else
|
||||
register_group(modname, subname, recipeitem, fields, "common")
|
||||
end
|
||||
end
|
||||
|
||||
function stairsplus:register_micro(modname, subname, recipeitem, fields)
|
||||
register_group(modname, subname, recipeitem, fields, "micro")
|
||||
end
|
||||
|
||||
function stairsplus:register_panel(modname, subname, recipeitem, fields)
|
||||
register_group(modname, subname, recipeitem, fields, "panel")
|
||||
end
|
||||
|
||||
function stairsplus:register_slab(modname, subname, recipeitem, fields)
|
||||
register_group(modname, subname, recipeitem, fields, "slab")
|
||||
end
|
||||
|
||||
function stairsplus:register_slope(modname, subname, recipeitem, fields)
|
||||
register_group(modname, subname, recipeitem, fields, "slope")
|
||||
end
|
||||
|
||||
function stairsplus:register_stair(modname, subname, recipeitem, fields)
|
||||
register_group(modname, subname, recipeitem, fields, "stair")
|
||||
end
|
||||
|
||||
local fix_shape_table = {
|
||||
micro = "micro_8",
|
||||
panel = "panel_8",
|
||||
slab = "slab_8",
|
||||
slab_quarter = "slab_4",
|
||||
slab_three_quarter = "slab_12",
|
||||
stair_alt = "stair_alt_8",
|
||||
}
|
||||
|
||||
local function interpret_subset(subset)
|
||||
local shapes = {}
|
||||
for _, v in ipairs(subset) do
|
||||
local shape = table.concat(v, "")
|
||||
shape = fix_shape_table[shape] or shape
|
||||
table.insert(shapes, shape)
|
||||
end
|
||||
return shapes
|
||||
end
|
||||
|
||||
function stairsplus:register_custom_subset(subset, modname, subname, recipeitem, fields)
|
||||
local shapes = interpret_subset(subset)
|
||||
|
||||
fields = clean_legacy_fields(fields)
|
||||
local meta = {}
|
||||
if is_legacy_drawtype(recipeitem) then
|
||||
meta.ignore_drawtype = true
|
||||
end
|
||||
|
||||
api.register_singles(recipeitem, shapes, fields, meta)
|
||||
|
||||
local old_name = ("%s:%s"):format(modname, subname)
|
||||
if old_name ~= recipeitem then
|
||||
api.register_alias_shapes(old_name, recipeitem, shapes)
|
||||
end
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_all(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
|
||||
if legacy_mode then
|
||||
api.register_alias_group(old_node, new_node, "legacy")
|
||||
else
|
||||
api.register_alias_group(old_node, new_node, "common")
|
||||
end
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_micro(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_group(old_node, new_node, "micro")
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_panel(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_group(old_node, new_node, "panel")
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_slab(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_group(old_node, new_node, "slab")
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_slope(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_group(old_node, new_node, "slope")
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_stair(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_group(old_node, new_node, "stair")
|
||||
end
|
||||
|
||||
function stairsplus:register_custom_subset_alias(subset, modname_old, subname_old, modname_new, subname_new)
|
||||
local shapes = interpret_subset(subset)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_shapes(old_node, new_node, shapes)
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_force_all(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
|
||||
if legacy_mode then
|
||||
api.register_alias_force_group(old_node, new_node, "legacy")
|
||||
else
|
||||
api.register_alias_force_group(old_node, new_node, "common")
|
||||
end
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_force_micro(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_force_group(old_node, new_node, "micro")
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_force_panel(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_force_group(old_node, new_node, "panel")
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_force_slab(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_force_group(old_node, new_node, "slab")
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_force_slope(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_force_group(old_node, new_node, "slope")
|
||||
end
|
||||
|
||||
function stairsplus:register_alias_force_stair(modname_old, subname_old, modname_new, subname_new)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_force_group(old_node, new_node, "stair")
|
||||
end
|
||||
|
||||
function stairsplus:register_custom_subset_alias(subset, modname_old, subname_old, modname_new, subname_new)
|
||||
local shapes = interpret_subset(subset)
|
||||
local old_node = ("%s:%s"):format(modname_old, subname_old)
|
||||
local new_node = ("%s:%s"):format(modname_new, subname_new)
|
||||
api.register_alias_force_shapes(old_node, new_node, shapes)
|
||||
end
|
54
mods/moreblocks/stairsplus/compat/unified_inventory.lua
Normal file
54
mods/moreblocks/stairsplus/compat/unified_inventory.lua
Normal file
|
@ -0,0 +1,54 @@
|
|||
-- luacheck: read globals unified_inventory
|
||||
|
||||
if not stairsplus.has.unified_inventory then
|
||||
return
|
||||
end
|
||||
|
||||
local in_creative_inventory = stairsplus.settings.in_creative_inventory
|
||||
|
||||
local api = stairsplus.api
|
||||
|
||||
unified_inventory.register_craft_type("stairsplus:circular_saw", {
|
||||
description = "Stairs+ circular saw",
|
||||
icon = "stairsplus_saw_button.png",
|
||||
width = 1,
|
||||
height = 1,
|
||||
uses_crafting_grid = false,
|
||||
})
|
||||
|
||||
unified_inventory.register_category("stairsplus:cuttable", {
|
||||
symbol = "stairsplus:circular_saw",
|
||||
label = "Cuttable in the circular saw",
|
||||
index = 0,
|
||||
items = {},
|
||||
})
|
||||
|
||||
if in_creative_inventory then
|
||||
unified_inventory.register_category("stairsplus:cut_node", {
|
||||
symbol = "stairsplus:circular_saw",
|
||||
label = "Nodes cut in the circular saw",
|
||||
index = 0,
|
||||
items = {},
|
||||
})
|
||||
end
|
||||
|
||||
local function on_register_single(node, shaped_name)
|
||||
unified_inventory.register_craft({
|
||||
output = shaped_name,
|
||||
type = "stairsplus:circular_saw",
|
||||
items = { node },
|
||||
width = 1,
|
||||
})
|
||||
|
||||
unified_inventory.add_category_item("stairsplus:cuttable", node)
|
||||
if in_creative_inventory then
|
||||
unified_inventory.add_category_item("stairsplus:cut_node", shaped_name)
|
||||
end
|
||||
end
|
||||
|
||||
for _, single in ipairs(api.registered_singles) do
|
||||
local node, shaped_name = unpack(single)
|
||||
on_register_single(node, shaped_name)
|
||||
end
|
||||
|
||||
api.register_on_register_single(on_register_single)
|
5
mods/moreblocks/stairsplus/craft_schemas/init.lua
Normal file
5
mods/moreblocks/stairsplus/craft_schemas/init.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
stairsplus.dofile("craft_schemas", "micro_8_all")
|
||||
stairsplus.dofile("craft_schemas", "other")
|
||||
stairsplus.dofile("craft_schemas", "slopes")
|
||||
stairsplus.dofile("craft_schemas", "stairs")
|
||||
stairsplus.dofile("craft_schemas", "standard_composition")
|
12
mods/moreblocks/stairsplus/craft_schemas/micro_8_all.lua
Normal file
12
mods/moreblocks/stairsplus/craft_schemas/micro_8_all.lua
Normal file
|
@ -0,0 +1,12 @@
|
|||
local api = stairsplus.api
|
||||
local register_craft_schema = api.register_craft_schema
|
||||
|
||||
for shape, shape_def in pairs(api.registered_shapes) do
|
||||
if shape ~= "micro_8" and math.floor(shape_def.eighths) > 0 then
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = ("micro_8 %i"):format(shape_def.eighths),
|
||||
recipe = { shape },
|
||||
})
|
||||
end
|
||||
end
|
84
mods/moreblocks/stairsplus/craft_schemas/other.lua
Normal file
84
mods/moreblocks/stairsplus/craft_schemas/other.lua
Normal file
|
@ -0,0 +1,84 @@
|
|||
local api = stairsplus.api
|
||||
local register_craft_schema = api.register_craft_schema
|
||||
|
||||
---- panel_8
|
||||
|
||||
register_craft_schema({
|
||||
output = "panel_8 12",
|
||||
recipe = {
|
||||
{ "node", "" },
|
||||
{ "node", "node" },
|
||||
},
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
output = "panel_8 12",
|
||||
recipe = {
|
||||
{ "", "node" },
|
||||
{ "node", "node" },
|
||||
},
|
||||
})
|
||||
|
||||
-- slabs
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slab_8",
|
||||
recipe = { "micro_8", "micro_8", "micro_8", "micro_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slab_8",
|
||||
recipe = { "slab_2", "slab_2", "slab_2", "slab_2" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slab_8 2",
|
||||
recipe = { "slab_1", "slab_1", "slab_1", "slab_1", "slab_1", "slab_1", "slab_1", "slab_1" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slab_4 2",
|
||||
recipe = { "slab_1", "slab_1", "slab_1", "slab_1" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slab_12",
|
||||
recipe = { "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slab_14",
|
||||
recipe = { "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2" },
|
||||
})
|
||||
|
||||
-- node
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "panel_8", "panel_8", "panel_8", "panel_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "slab_4", "slab_4", "slab_4", "slab_4" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2" },
|
||||
})
|
106
mods/moreblocks/stairsplus/craft_schemas/slopes.lua
Normal file
106
mods/moreblocks/stairsplus/craft_schemas/slopes.lua
Normal file
|
@ -0,0 +1,106 @@
|
|||
local api = stairsplus.api
|
||||
local register_craft_schema = api.register_craft_schema
|
||||
|
||||
-- slopes
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slab_8",
|
||||
recipe = { "slope_half", "slope_half" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slab_8",
|
||||
recipe = { "slope_outer_half", "slope_inner_half" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slab_8",
|
||||
recipe = { "slope_outer_cut_half", "slope_inner_cut_half" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slope_half_raised",
|
||||
recipe = { "slope_half", "slope_half", "slope_half" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slope_half_raised",
|
||||
recipe = { "slab_8", "slope_half" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slope_inner_half_raised",
|
||||
recipe = { "slab_8", "slope_inner_half" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slope_outer_half_raised",
|
||||
recipe = { "slab_8", "slope_outer_half" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slope_inner_cut_half_raised",
|
||||
recipe = { "slab_8", "slope_inner_cut_half" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "slope", "slope" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "slope_half", "slope_half_raised" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "slope_half", "slope_half", "slope_half", "slope_half" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "slope_outer", "slope_inner" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "slope_outer_half", "slope_inner_half_raised" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "slope_outer_half_raised", "slope_inner_half" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "slope_outer_cut", "slope_inner_cut" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "slope_outer_cut_half", "slope_inner_cut_half_raised" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node",
|
||||
recipe = { "slope_cut", "slope_cut" },
|
||||
})
|
150
mods/moreblocks/stairsplus/craft_schemas/stairs.lua
Normal file
150
mods/moreblocks/stairsplus/craft_schemas/stairs.lua
Normal file
|
@ -0,0 +1,150 @@
|
|||
local api = stairsplus.api
|
||||
local register_craft_schema = api.register_craft_schema
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "slab_8 3",
|
||||
recipe = { "stair", "stair" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "node 3",
|
||||
recipe = { "stair", "stair", "stair", "stair" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
output = "stair 8",
|
||||
recipe = {
|
||||
{ "node", "", "" },
|
||||
{ "node", "node", "" },
|
||||
{ "node", "node", "node" },
|
||||
},
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
output = "stair 8",
|
||||
recipe = {
|
||||
{ "", "", "node" },
|
||||
{ "", "node", "node" },
|
||||
{ "node", "node", "node" },
|
||||
},
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "stair",
|
||||
recipe = { "panel_8", "slab_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "stair",
|
||||
recipe = { "panel_8", "panel_8", "panel_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "stair",
|
||||
recipe = { "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "stair",
|
||||
recipe = { "panel_8", "panel_8", "panel_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "stair_inner",
|
||||
recipe = { "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "stair_outer",
|
||||
recipe = { "micro_8", "slab_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "stair_outer",
|
||||
recipe = { "micro_8", "micro_8", "micro_8", "micro_8", "micro_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "stair_half",
|
||||
recipe = { "micro_8", "micro_8", "micro_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
type = "shapeless",
|
||||
output = "stair_half",
|
||||
recipe = { "panel_8", "micro_8" },
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
output = "stair_alt_1",
|
||||
recipe = {
|
||||
{ "panel_1", "" },
|
||||
{ "", "panel_1" },
|
||||
},
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
output = "stair_alt_1",
|
||||
recipe = {
|
||||
{ "", "panel_1" },
|
||||
{ "panel_1", "" },
|
||||
},
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
output = "stair_alt_2",
|
||||
recipe = {
|
||||
{ "panel_2", "" },
|
||||
{ "", "panel_2" },
|
||||
},
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
output = "stair_alt_2",
|
||||
recipe = {
|
||||
{ "", "panel_2" },
|
||||
{ "panel_2", "" },
|
||||
},
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
output = "stair_alt_4",
|
||||
recipe = {
|
||||
{ "panel_4", "" },
|
||||
{ "", "panel_4" },
|
||||
},
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
output = "stair_alt_4",
|
||||
recipe = {
|
||||
{ "", "panel_4" },
|
||||
{ "panel_4", "" },
|
||||
},
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
output = "stair_alt_8",
|
||||
recipe = {
|
||||
{ "panel_8", "" },
|
||||
{ "", "panel_8" },
|
||||
},
|
||||
})
|
||||
|
||||
register_craft_schema({
|
||||
output = "stair_alt_8",
|
||||
recipe = {
|
||||
{ "", "panel_8" },
|
||||
{ "panel_8", "" },
|
||||
},
|
||||
})
|
|
@ -0,0 +1,132 @@
|
|||
local api = stairsplus.api
|
||||
local register_craft_schema = api.register_craft_schema
|
||||
|
||||
local slices = { 1, 2, 4, 8, 12, 14, 15 }
|
||||
|
||||
local valid_slice = {
|
||||
[1] = true,
|
||||
[2] = true,
|
||||
[4] = true,
|
||||
[8] = true,
|
||||
[12] = true,
|
||||
[14] = true,
|
||||
[15] = true,
|
||||
}
|
||||
|
||||
local full_promotion = {
|
||||
micro = "panel_8",
|
||||
panel = "slab_8",
|
||||
slab = "node",
|
||||
}
|
||||
|
||||
local half_promotion = {
|
||||
micro = "panel",
|
||||
panel = "slab",
|
||||
}
|
||||
|
||||
local demotion = {
|
||||
node = "slab",
|
||||
slab = "panel",
|
||||
panel = "micro",
|
||||
}
|
||||
|
||||
-- stack things on top of each other
|
||||
for _, shape in ipairs({ "micro", "panel", "slab" }) do
|
||||
for _, slice1 in ipairs(slices) do
|
||||
local shape1 = ("%s_%s"):format(shape, slice1)
|
||||
local def1 = api.registered_shapes[shape1]
|
||||
|
||||
for _, slice2 in ipairs(slices) do
|
||||
local shape2 = ("%s_%s"):format(shape, slice2)
|
||||
local def2 = api.registered_shapes[shape2]
|
||||
|
||||
local slice3 = slice1 + slice2
|
||||
|
||||
if valid_slice[slice3] then
|
||||
local shape3 = ("%s_%s"):format(shape, slice3)
|
||||
local def3 = api.registered_shapes[shape3]
|
||||
local n = math.floor((def1.eighths + def2.eighths) / def3.eighths)
|
||||
|
||||
register_craft_schema({
|
||||
output = ("%s %s"):format(shape3, n),
|
||||
recipe = {
|
||||
{ shape1 },
|
||||
{ shape2 },
|
||||
},
|
||||
})
|
||||
elseif slice3 == 16 then
|
||||
register_craft_schema({
|
||||
output = ("%s"):format(full_promotion[shape]),
|
||||
recipe = {
|
||||
{ shape1 },
|
||||
{ shape2 },
|
||||
},
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- stack things next to each other
|
||||
for _, shape in ipairs({ "micro", "panel" }) do
|
||||
for _, slice in ipairs(slices) do
|
||||
local shape1 = ("%s_%s"):format(shape, slice)
|
||||
local def1 = api.registered_shapes[shape1]
|
||||
local shape2 = ("%s_%s"):format(half_promotion[shape], slice)
|
||||
local def2 = api.registered_shapes[shape2]
|
||||
local n = math.floor(2 * def1.eighths / def2.eighths)
|
||||
|
||||
register_craft_schema({
|
||||
output = ("%s %s"):format(shape2, n),
|
||||
recipe = {
|
||||
{ shape1, shape1 },
|
||||
},
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- split in half horizontally
|
||||
|
||||
register_craft_schema({
|
||||
output = "slab_8 6",
|
||||
recipe = { { "node", "node", "node" } },
|
||||
})
|
||||
|
||||
for _, shape in ipairs({ "micro", "panel", "slab" }) do
|
||||
for _, slice1 in ipairs({ 2, 4, 8 }) do
|
||||
local slice2 = slice1 / 2
|
||||
local shape1 = ("%s_%s"):format(shape, slice1)
|
||||
local shape2 = ("%s_%s"):format(shape, slice2)
|
||||
local def1 = api.registered_shapes[shape1]
|
||||
local def2 = api.registered_shapes[shape2]
|
||||
local n = math.floor(3 * def1.eighths / def2.eighths)
|
||||
|
||||
register_craft_schema({
|
||||
output = ("%s %s"):format(shape2, n),
|
||||
recipe = {
|
||||
{ shape1, shape1, shape1 },
|
||||
},
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- split in half vertically
|
||||
|
||||
for _, shape in ipairs({ "panel", "slab" }) do
|
||||
for _, slice in ipairs(slices) do
|
||||
local shape1 = ("%s_%s"):format(shape, slice)
|
||||
local shape2 = ("%s_%s"):format(demotion[shape], slice)
|
||||
local def1 = api.registered_shapes[shape1]
|
||||
local def2 = api.registered_shapes[shape2]
|
||||
local n = math.floor(3 * def1.eighths / def2.eighths)
|
||||
|
||||
register_craft_schema({
|
||||
output = ("%s %s"):format(shape2, n),
|
||||
recipe = {
|
||||
{ shape1 },
|
||||
{ shape1 },
|
||||
{ shape1 },
|
||||
},
|
||||
})
|
||||
end
|
||||
end
|
21
mods/moreblocks/stairsplus/groups/builtin.lua
Normal file
21
mods/moreblocks/stairsplus/groups/builtin.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
stairsplus.api.register_passthrough_groups({
|
||||
"not_in_creative_inventory",
|
||||
"dig_immediate",
|
||||
"float",
|
||||
"level",
|
||||
"slippery",
|
||||
"falling_node",
|
||||
"disable_jump",
|
||||
})
|
||||
|
||||
stairsplus.api.register_scaling_groups({
|
||||
"bouncy",
|
||||
"fall_damage_add_percent",
|
||||
"slippery",
|
||||
})
|
||||
|
||||
stairsplus.api.register_ignore_groups({
|
||||
"attached_node",
|
||||
"connect_to_raillike",
|
||||
"tool",
|
||||
})
|
15
mods/moreblocks/stairsplus/groups/default.lua
Normal file
15
mods/moreblocks/stairsplus/groups/default.lua
Normal file
|
@ -0,0 +1,15 @@
|
|||
if not stairsplus.has.default then
|
||||
return
|
||||
end
|
||||
|
||||
stairsplus.api.register_passthrough_groups({
|
||||
"crumbly",
|
||||
"cracky",
|
||||
"snappy",
|
||||
"choppy",
|
||||
"fleshy",
|
||||
"flammable",
|
||||
"explody",
|
||||
"oddly_breakable_by_hand",
|
||||
"snowy", -- https://github.com/fluxionary/minetest-moreblocks/issues/20 might revisit this later
|
||||
})
|
3
mods/moreblocks/stairsplus/groups/init.lua
Normal file
3
mods/moreblocks/stairsplus/groups/init.lua
Normal file
|
@ -0,0 +1,3 @@
|
|||
stairsplus.dofile("groups", "builtin")
|
||||
stairsplus.dofile("groups", "default")
|
||||
stairsplus.dofile("groups", "other")
|
61
mods/moreblocks/stairsplus/groups/other.lua
Normal file
61
mods/moreblocks/stairsplus/groups/other.lua
Normal file
|
@ -0,0 +1,61 @@
|
|||
-- group overrides for various other mods
|
||||
|
||||
-- various things found in the wild
|
||||
stairsplus.api.register_passthrough_groups({
|
||||
"bendy",
|
||||
"dig_generic",
|
||||
"dig_sand",
|
||||
"dig_stone",
|
||||
"dig_tree",
|
||||
"fast_travel",
|
||||
"melty",
|
||||
"unbreakable",
|
||||
})
|
||||
|
||||
stairsplus.api.register_ignore_groups({
|
||||
"type_node",
|
||||
"ud_param2_colorable",
|
||||
})
|
||||
|
||||
-- mineclone
|
||||
stairsplus.api.register_passthrough_groups({
|
||||
"pickaxey",
|
||||
"axey",
|
||||
"shovely",
|
||||
"swordy",
|
||||
"swordy_cobweb",
|
||||
"shearsy",
|
||||
"shearsy_wool",
|
||||
"handy",
|
||||
"creative_breakable",
|
||||
"dig_by_water",
|
||||
"destroy_by_lava_flow",
|
||||
"dig_by_piston",
|
||||
"non_mycelium_plant",
|
||||
"enderman_takable",
|
||||
"disable_suffocation",
|
||||
"no_rename",
|
||||
})
|
||||
|
||||
stairsplus.api.register_scaling_groups({
|
||||
"falling_node_damage",
|
||||
"fire_encouragement",
|
||||
"fire_flammability",
|
||||
"comparator_signal",
|
||||
"set_on_fire",
|
||||
"compostability",
|
||||
})
|
||||
|
||||
stairsplus.api.register_ignore_groups({
|
||||
"crush_after_fall",
|
||||
"cultivatable",
|
||||
"path_creation_possible",
|
||||
"spreading_dirt_type",
|
||||
"dirtifies_below_solid",
|
||||
"dirtifier",
|
||||
"destroys_items",
|
||||
"no_eat_delay",
|
||||
"can_eat_when_full",
|
||||
"attached_node_facedir",
|
||||
"supported_node",
|
||||
})
|
25
mods/moreblocks/stairsplus/init.lua
Normal file
25
mods/moreblocks/stairsplus/init.lua
Normal file
|
@ -0,0 +1,25 @@
|
|||
fmod.check_version({ year = 2023, month = 2, day = 1 })
|
||||
futil.check_version({ year = 2023, month = 11, day = 1 }) -- is_player
|
||||
|
||||
stairsplus = fmod.create()
|
||||
|
||||
-- please don't change the order in which things are loaded, without understanding why they're ordered like this
|
||||
stairsplus.dofile("util")
|
||||
|
||||
stairsplus.dofile("api", "init")
|
||||
|
||||
stairsplus.dofile("shapes", "init")
|
||||
stairsplus.dofile("groups", "init")
|
||||
|
||||
if stairsplus.settings.crafting_schemata_enabled then
|
||||
stairsplus.dofile("craft_schemas", "init")
|
||||
end
|
||||
|
||||
stairsplus.dofile("resources", "init")
|
||||
stairsplus.dofile("circular_saw")
|
||||
|
||||
stairsplus.dofile("compat", "init")
|
||||
|
||||
stairsplus.dofile("aliases")
|
||||
|
||||
stairsplus.dofile("scripts", "init")
|
51
mods/moreblocks/stairsplus/locale/default.txt
Normal file
51
mods/moreblocks/stairsplus/locale/default.txt
Normal file
|
@ -0,0 +1,51 @@
|
|||
# textdomain: stairsplus
|
||||
|
||||
@1 Microblock=
|
||||
@1 1/16 Microblock=
|
||||
@1 1/8 Microblock=
|
||||
@1 1/4 Microblock=
|
||||
@1 3/4 Microblock=
|
||||
@1 7/8 Microblock=
|
||||
@1 15/16 Microblock=
|
||||
@1 1/16 Panel=
|
||||
@1 1/8 Panel=
|
||||
@1 1/4 Panel=
|
||||
@1 1/2 Panel=
|
||||
@1 3/4 Panel=
|
||||
@1 7/8 Panel=
|
||||
@1 15/16 Panel=
|
||||
@1 1/16 Slab=
|
||||
@1 1/8 Slab=
|
||||
@1 1/4 Slab=
|
||||
@1 1/2 Slab=
|
||||
@1 3/4 Slab=
|
||||
@1 7/8 Slab=
|
||||
@1 15/16 Slab=
|
||||
@1 1/16 Slab Two Sides=
|
||||
@1 1/16 Slab Three Sides=
|
||||
@1 1/16 Slab Three Sides U=
|
||||
@1 Slope=
|
||||
@1 1/2 Slope=
|
||||
@1 1/2 Slope Raised=
|
||||
@1 Slope Inner=
|
||||
@1 Slope Outer=
|
||||
@1 Slope Inner Cut=
|
||||
@1 Slope Outer Cut=
|
||||
@1 Slope Inner Half=
|
||||
@1 Slope Outer Half=
|
||||
@1 Slope Inner Cut Half=
|
||||
@1 Slope Outer Cut Half=
|
||||
@1 Slope Inner Half Raised=
|
||||
@1 Slope Inner Cut Half Raised=
|
||||
@1 Slope Outer Half Raised=
|
||||
@1 Slope Outer Cut Half Raised=
|
||||
@1 Slope Cut=
|
||||
@1 Half Stair=
|
||||
@1 Right Half Stair=
|
||||
@1 Stair=
|
||||
@1 Inner Stair=
|
||||
@1 Outer Stair=
|
||||
@1 1/16 Alt Stair=
|
||||
@1 1/8 Alt Stair=
|
||||
@1 1/4 Alt Stair=
|
||||
@1 1/2 Alt Stair=
|
51
mods/moreblocks/stairsplus/locale/stairsplus.ru.tr
Normal file
51
mods/moreblocks/stairsplus/locale/stairsplus.ru.tr
Normal file
|
@ -0,0 +1,51 @@
|
|||
# textdomain: stairsplus
|
||||
|
||||
@1 Microblock=@1 (микроблок)
|
||||
@1 1/16 Microblock=@1 (1/16 микроблок)
|
||||
@1 1/8 Microblock=@1 (1/8 микроблок)
|
||||
@1 1/4 Microblock=@1 (1/4 микроблок)
|
||||
@1 3/4 Microblock=@1 (3/4 микроблок)
|
||||
@1 7/8 Microblock=@1 (7/8 микроблок)
|
||||
@1 15/16 Microblock=@1 (15/16 микроблок)
|
||||
@1 1/16 Panel=@1 (1/16 панель)
|
||||
@1 1/8 Panel=@1 (1/8 панель)
|
||||
@1 1/4 Panel=@1 (1/4 панель)
|
||||
@1 1/2 Panel=@1 (1/2 панель)
|
||||
@1 3/4 Panel=@1 (3/4 панель)
|
||||
@1 7/8 Panel=@1 (7/8 панель)
|
||||
@1 15/16 Panel=@1 (15/16 панель)
|
||||
@1 1/16 Slab=@1 (1/16 плита)
|
||||
@1 1/8 Slab=@1 (1/8 плита)
|
||||
@1 1/4 Slab=@1 (1/4 плита)
|
||||
@1 1/2 Slab=@1 (1/2 плита)
|
||||
@1 3/4 Slab=@1 (3/4 плита)
|
||||
@1 7/8 Slab=@1 (7/8 плита)
|
||||
@1 15/16 Slab=@1 (15/16 плита)
|
||||
@1 1/16 Slab Two Sides=@1 (1/16 двухсторонняя плита)
|
||||
@1 1/16 Slab Three Sides=@1 (1/16 трехсторонняя плита)
|
||||
@1 1/16 Slab Three Sides U=@1 (1/16 U-трехсторонняя плита)
|
||||
@1 Slope=@1 (скос)
|
||||
@1 1/2 Slope=@1 (1/2 скос)
|
||||
@1 1/2 Slope Raised=@1 (1/2 приподнятый скос)
|
||||
@1 Slope Inner=@1 (внутренний скос)
|
||||
@1 Slope Outer=@1 (внешний скос)
|
||||
@1 Slope Inner Cut=@1 (скос, внутренний срез)
|
||||
@1 Slope Outer Cut=@1 (скос, внешний срез)
|
||||
@1 Slope Inner Half=@1 (скос, внутренняя половина)
|
||||
@1 Slope Outer Half=@1 (скос, внешняя половина)
|
||||
@1 Slope Inner Cut Half=@1 (скос, внутренний срез, половина)
|
||||
@1 Slope Outer Cut Half=@1 (скос, внешний срез, половина)
|
||||
@1 Slope Inner Half Raised=@1 (скос, внутренняя половина, приподнятый)
|
||||
@1 Slope Inner Cut Half Raised=@1 (скос, внутренний срез, половина, приподнятый)
|
||||
@1 Slope Outer Half Raised=@1 (скос, наружная половина, приподнятый)
|
||||
@1 Slope Outer Cut Half Raised=@1 (скос, наружный срез, половина, приподнятый)
|
||||
@1 Slope Cut=@1 (скос, срез)
|
||||
@1 Half Stair=@1 (полуступени)
|
||||
@1 Right Half Stair=@1 (правая половина ступеней)
|
||||
@1 Stair=@1 (ступени)
|
||||
@1 Inner Stair=@1 (внутренние ступени)
|
||||
@1 Outer Stair=@1 (внешние ступени)
|
||||
@1 1/16 Alt Stair=@1 (1/16 альт. ступени)
|
||||
@1 1/8 Alt Stair=@1 (1/8 альт. ступени)
|
||||
@1 1/4 Alt Stair=@1 (1/4 альт. ступени)
|
||||
@1 1/2 Alt Stair=@1 (1/2 альт. ступени)
|
10
mods/moreblocks/stairsplus/mod.conf
Normal file
10
mods/moreblocks/stairsplus/mod.conf
Normal file
|
@ -0,0 +1,10 @@
|
|||
name = stairsplus
|
||||
title = stairs+
|
||||
description = microblock API
|
||||
website = https://content.minetest.net/packages/rheo/moreblocks/.
|
||||
author = Hugo Locurcio, fluxionary, others (see commit log)
|
||||
license = LGPL-3.0-or-later
|
||||
media_license = CC-BY-SA-4.0
|
||||
version = 2024-12-23
|
||||
depends = fmod, futil
|
||||
optional_depends = default, i3, unified_inventory
|
56
mods/moreblocks/stairsplus/models/stairsplus_slope.obj
Normal file
56
mods/moreblocks/stairsplus/models/stairsplus_slope.obj
Normal file
|
@ -0,0 +1,56 @@
|
|||
g top
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 0.7071 -0.7071
|
||||
s off
|
||||
f 2/1/1 1/2/1 4/3/1 3/4/1
|
||||
g bottom
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s off
|
||||
f 6/5/2 5/6/2 7/7/2 8/8/2
|
||||
g right
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 9/9/3 11/10/3 10/11/3
|
||||
g left
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 12/12/4 13/13/4 14/14/4
|
||||
g back
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s off
|
||||
f 15/15/5 16/16/5 17/17/5 18/18/5
|
68
mods/moreblocks/stairsplus/models/stairsplus_slope_cut.obj
Normal file
68
mods/moreblocks/stairsplus/models/stairsplus_slope_cut.obj
Normal file
|
@ -0,0 +1,68 @@
|
|||
g top
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.5000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.5000 2.0000
|
||||
vt 0.0000 1.0000
|
||||
vn -0.4082 0.8165 -0.4082
|
||||
s 1
|
||||
f 4/1/1 2/2/1 1/3/1 3/4/1
|
||||
g bottom
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s 1
|
||||
f 6/5/2 5/6/2 8/7/2 7/8/2
|
||||
g right
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 0.5000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
s 1
|
||||
f 11/9/3 9/10/3 10/11/3
|
||||
g left
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s 1
|
||||
f 12/12/4 14/13/4 15/14/4 13/15/4
|
||||
g back
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.000000 0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.5000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
s 1
|
||||
f 16/16/5 17/17/5 18/18/5 19/19/5
|
||||
g front
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 0.5000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
s 1
|
||||
f 20/20/6 22/21/6 21/22/6
|
56
mods/moreblocks/stairsplus/models/stairsplus_slope_half.obj
Normal file
56
mods/moreblocks/stairsplus/models/stairsplus_slope_half.obj
Normal file
|
@ -0,0 +1,56 @@
|
|||
g top
|
||||
v 0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 0.8944 -0.4472
|
||||
s off
|
||||
f 2/1/1 1/2/1 4/3/1 3/4/1
|
||||
g bottom
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s off
|
||||
f 6/5/2 5/6/2 7/7/2 8/8/2
|
||||
g right
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 9/9/3 11/10/3 10/11/3
|
||||
g left
|
||||
v 0.500000 -0.000000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 12/12/4 13/13/4 14/14/4
|
||||
g back
|
||||
v 0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s off
|
||||
f 15/15/5 16/16/5 17/17/5 18/18/5
|
|
@ -0,0 +1,72 @@
|
|||
g top
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vn 0.0000 0.8944 -0.4472
|
||||
s off
|
||||
f 2/1/1 1/2/1 4/3/1 3/4/1
|
||||
g bottom
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s off
|
||||
f 6/5/2 5/6/2 7/7/2 8/8/2
|
||||
g right
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 9/9/3 10/10/3 11/11/3 12/12/3
|
||||
g left
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 13/13/4 15/14/4 16/15/4 14/16/4
|
||||
g back
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s off
|
||||
f 19/17/5 17/18/5 18/19/5 20/20/5
|
||||
g front
|
||||
v -0.500000 0.000000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
s off
|
||||
f 21/21/6 23/22/6 24/23/6 22/24/6
|
81
mods/moreblocks/stairsplus/models/stairsplus_slope_inner.obj
Normal file
81
mods/moreblocks/stairsplus/models/stairsplus_slope_inner.obj
Normal file
|
@ -0,0 +1,81 @@
|
|||
g top
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vn 0.0000 0.7071 -0.7071
|
||||
vn -0.7071 0.7071 0.0000
|
||||
s 1
|
||||
f 3/1/1 2/2/1 4/3/1
|
||||
f 2/4/2 1/5/2 5/6/2
|
||||
g bottom
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s 1
|
||||
f 9/7/3 7/8/3 6/9/3 8/10/3
|
||||
l 8 10
|
||||
g right
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
s 1
|
||||
f 11/11/4 12/12/4 13/13/4
|
||||
g left
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s 1
|
||||
f 14/14/5 15/15/5 16/16/5 17/17/5
|
||||
l 15 18
|
||||
g back
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s 1
|
||||
f 22/18/6 20/19/6 19/20/6 21/21/6
|
||||
l 22 23
|
||||
l 19 23
|
||||
g front
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
s 1
|
||||
f 24/22/7 25/23/7 27/24/7
|
|
@ -0,0 +1,72 @@
|
|||
g top
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.5000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn -0.5774 0.5774 -0.5774
|
||||
s 1
|
||||
f 3/1/1 2/2/1 1/3/1
|
||||
f 4/4/2 3/5/2 1/6/2
|
||||
g bottom
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s 1
|
||||
f 6/7/3 5/8/3 7/9/3 8/10/3
|
||||
g right
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
s 1
|
||||
f 11/11/4 9/12/4 10/13/4
|
||||
g left
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s 1
|
||||
f 12/14/5 13/15/5 14/16/5 15/17/5
|
||||
g back
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s 1
|
||||
f 18/18/6 16/19/6 17/20/6 19/21/6
|
||||
g front
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
s 1
|
||||
f 20/22/7 22/23/7 21/24/7
|
|
@ -0,0 +1,72 @@
|
|||
g top
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v 0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.5000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn -0.4082 0.8165 -0.4082
|
||||
s 1
|
||||
f 3/1/1 2/2/1 1/3/1
|
||||
f 4/4/2 3/5/2 1/6/2
|
||||
g bottom
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s 1
|
||||
f 6/7/3 5/8/3 7/9/3 8/10/3
|
||||
g right
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 0.5000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
s 1
|
||||
f 11/11/4 9/12/4 10/13/4
|
||||
g left
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v 0.500000 -0.000000 0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 0.5000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s 1
|
||||
f 12/14/5 13/15/5 14/16/5 15/17/5
|
||||
g back
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.000000 0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 0.5000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s 1
|
||||
f 18/18/6 16/19/6 17/20/6 19/21/6
|
||||
g front
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 0.5000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
s 1
|
||||
f 20/22/7 22/23/7 21/24/7
|
|
@ -0,0 +1,76 @@
|
|||
g top
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.5000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn -0.4082 0.8165 -0.4082
|
||||
s 1
|
||||
f 3/1/1 2/2/1 1/3/1
|
||||
f 4/4/2 3/5/2 1/6/2
|
||||
g bottom
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s 1
|
||||
f 6/7/3 5/8/3 7/9/3 8/10/3
|
||||
g right
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.5000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
s 1
|
||||
f 11/11/4 9/12/4 10/13/4 12/14/4
|
||||
g left
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s 1
|
||||
f 13/15/5 14/16/5 15/17/5 16/18/5
|
||||
g back
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s 1
|
||||
f 19/19/6 17/20/6 18/21/6 20/22/6
|
||||
g front
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 1.0000
|
||||
vn -0.0000 0.0000 -1.0000
|
||||
s 1
|
||||
f 21/23/7 23/24/7 24/25/7 22/26/7
|
|
@ -0,0 +1,85 @@
|
|||
g top
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v 0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vn 0.0000 0.8944 -0.4472
|
||||
vn -0.4472 0.8944 0.0000
|
||||
s off
|
||||
f 3/1/1 2/2/1 4/3/1
|
||||
f 2/4/2 1/5/2 5/6/2
|
||||
g bottom
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s off
|
||||
f 10/7/3 7/8/3 6/9/3 9/10/3
|
||||
l 9 8
|
||||
l 11 9
|
||||
g right
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 12/11/4 13/12/4 14/13/4
|
||||
l 15 14
|
||||
g left
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v 0.500000 -0.000000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 16/14/5 17/15/5 18/16/5 19/17/5
|
||||
l 20 17
|
||||
g back
|
||||
v 0.500000 -0.000000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s off
|
||||
f 24/18/6 22/19/6 21/20/6 23/21/6
|
||||
l 25 24
|
||||
l 25 21
|
||||
g front
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
s off
|
||||
f 26/22/7 27/23/7 29/24/7
|
|
@ -0,0 +1,86 @@
|
|||
g top
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 0.8944 -0.4472
|
||||
vn -0.4472 0.8944 0.0000
|
||||
s off
|
||||
f 3/1/1 2/2/1 4/3/1
|
||||
f 2/2/2 1/4/2 5/5/2
|
||||
g bottom
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s off
|
||||
f 8/6/3 9/7/3 7/8/3 6/9/3
|
||||
l 10 8
|
||||
g right
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 13/10/4 11/11/4 12/12/4 15/13/4
|
||||
g left
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 16/14/5 17/15/5 18/16/5 19/17/5
|
||||
l 20 17
|
||||
g back
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v -0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s off
|
||||
f 24/18/6 22/19/6 21/20/6 23/21/6
|
||||
l 25 21
|
||||
l 25 24
|
||||
g front
|
||||
v 0.500000 0.500000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn -0.0000 0.0000 -1.0000
|
||||
s off
|
||||
f 28/22/7 26/23/7 27/24/7 30/25/7
|
||||
l 29 26
|
48
mods/moreblocks/stairsplus/models/stairsplus_slope_outer.obj
Normal file
48
mods/moreblocks/stairsplus/models/stairsplus_slope_outer.obj
Normal file
|
@ -0,0 +1,48 @@
|
|||
g top
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn -0.7071 0.7071 0.0000
|
||||
vn 0.0000 0.7071 -0.7071
|
||||
s off
|
||||
f 4/1/1 2/2/1 1/3/1
|
||||
f 4/4/2 3/5/2 2/6/2
|
||||
g bottom
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s off
|
||||
f 5/7/3 6/8/3 7/9/3 8/10/3
|
||||
g right
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s off
|
||||
f 10/11/4 9/12/4 11/13/4
|
||||
g left
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 14/14/5 12/15/5 13/16/5
|
|
@ -0,0 +1,40 @@
|
|||
g top
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.5000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vn -0.5774 0.5774 -0.5774
|
||||
s off
|
||||
f 2/1/1 1/2/1 3/3/1
|
||||
g bottom
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s off
|
||||
f 5/4/2 4/5/2 6/6/2
|
||||
g right
|
||||
v 0.500000 0.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s off
|
||||
f 7/7/3 8/8/3 9/9/3
|
||||
g left
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 12/10/4 10/11/4 11/12/4
|
|
@ -0,0 +1,40 @@
|
|||
g top
|
||||
v 0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.5000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vn -0.4082 0.8165 -0.4082
|
||||
s off
|
||||
f 2/1/1 1/2/1 3/3/1
|
||||
g bottom
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s off
|
||||
f 5/4/2 4/5/2 6/6/2
|
||||
g right
|
||||
v 0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s off
|
||||
f 7/7/3 8/8/3 9/9/3
|
||||
g left
|
||||
v 0.500000 -0.000000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 12/10/4 10/11/4 11/12/4
|
|
@ -0,0 +1,56 @@
|
|||
g top
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vn -0.4082 0.8165 -0.4082
|
||||
s off
|
||||
f 1/1/1 2/2/1 3/3/1
|
||||
g bottom
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 1.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s off
|
||||
f 4/4/2 6/5/2 5/6/2
|
||||
g right
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vn -0.7071 0.0000 -0.7071
|
||||
s off
|
||||
f 8/7/3 7/8/3 10/9/3 9/10/3
|
||||
g left
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 0.5000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 12/11/4 11/12/4 13/13/4 14/14/4
|
||||
g back
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
s off
|
||||
f 15/15/5 16/16/5 17/17/5 18/18/5
|
|
@ -0,0 +1,48 @@
|
|||
g top
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.000000 0.500000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vn 0.0000 0.8944 -0.4472
|
||||
vn -0.4472 0.8944 0.0000
|
||||
s off
|
||||
f 2/1/1 4/2/1 3/3/1
|
||||
f 1/4/2 4/5/2 2/6/2
|
||||
g bottom
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s off
|
||||
f 5/7/3 6/8/3 7/9/3 8/10/3
|
||||
g right
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.000000 0.500000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
s off
|
||||
f 11/11/4 9/12/4 10/13/4
|
||||
g left
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.000000 0.500000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 12/14/5 14/15/5 13/16/5
|
|
@ -0,0 +1,74 @@
|
|||
g top
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
vt 1.0000 0.0000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vn 0.0000 0.8944 -0.4472
|
||||
vn -0.4472 0.8944 0.0000
|
||||
s off
|
||||
f 4/1/1 2/2/1 3/3/1
|
||||
f 4/1/2 1/4/2 2/2/2
|
||||
g bottom
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vn 0.0000 -1.0000 -0.0000
|
||||
s off
|
||||
f 7/5/3 6/6/3 5/7/3 8/8/3
|
||||
g right
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 9/9/4 11/10/4 12/11/4 10/12/4
|
||||
g left
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
vt 0.0000 1.0000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 0.5000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
s off
|
||||
f 14/13/5 13/14/5 15/15/5 16/16/5
|
||||
g back
|
||||
v -0.500000 -0.000000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 0.500000 0.500000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 1.0000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
s off
|
||||
f 17/17/6 18/18/6 19/19/6 20/20/6
|
||||
g front
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 0.000000 -0.500000
|
||||
v -0.500000 0.000000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
vt 0.0000 0.5000
|
||||
vt 0.0000 0.0000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 0.5000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
s off
|
||||
f 22/21/7 21/22/7 24/23/7 23/24/7
|
9
mods/moreblocks/stairsplus/resources/craft_materials.lua
Normal file
9
mods/moreblocks/stairsplus/resources/craft_materials.lua
Normal file
|
@ -0,0 +1,9 @@
|
|||
local table_set_all = futil.table.set_all
|
||||
|
||||
stairsplus.resources.craft_materials = {}
|
||||
|
||||
if stairsplus.has.default then
|
||||
table_set_all(stairsplus.resources.craft_materials, {
|
||||
steel_ingot = "default:steel_ingot",
|
||||
})
|
||||
end
|
|
@ -0,0 +1,6 @@
|
|||
stairsplus.resources.formspec_style = ""
|
||||
|
||||
if stairsplus.has.default then
|
||||
-- prepend background and slot styles from default if available
|
||||
stairsplus.resources.formspec_style = default.gui_bg .. default.gui_bg_img .. default.gui_slots
|
||||
end
|
4
mods/moreblocks/stairsplus/resources/init.lua
Normal file
4
mods/moreblocks/stairsplus/resources/init.lua
Normal file
|
@ -0,0 +1,4 @@
|
|||
stairsplus.resources = {}
|
||||
|
||||
stairsplus.dofile("resources", "craft_materials")
|
||||
stairsplus.dofile("resources", "sounds")
|
9
mods/moreblocks/stairsplus/resources/sounds.lua
Normal file
9
mods/moreblocks/stairsplus/resources/sounds.lua
Normal file
|
@ -0,0 +1,9 @@
|
|||
local table_set_all = futil.table.set_all
|
||||
|
||||
stairsplus.resources.sounds = {}
|
||||
|
||||
if stairsplus.has.default then
|
||||
table_set_all(stairsplus.resources.sounds, {
|
||||
wood = default.node_sound_wood_defaults(),
|
||||
})
|
||||
end
|
83
mods/moreblocks/stairsplus/scripts/create_whitelist.py
Normal file
83
mods/moreblocks/stairsplus/scripts/create_whitelist.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
import argparse
|
||||
import math
|
||||
import multiprocessing
|
||||
import pathlib
|
||||
import time
|
||||
|
||||
import progressbar
|
||||
|
||||
import pymtdb
|
||||
from whitelist_helpers import create_whitelist, write_whitelist, create_filter, count_blocks, existing_file, get_cursor, \
|
||||
get_all_nodes
|
||||
|
||||
|
||||
def process_chunk(args, offset, limit, completed, results):
|
||||
cursor = get_cursor(args)
|
||||
cursor.execute(f'SELECT data FROM blocks LIMIT {limit} OFFSET {offset}')
|
||||
node_names = set()
|
||||
i = 0
|
||||
for i, row in enumerate(cursor, 1):
|
||||
node_names.update(pymtdb.MapBlockSimple.import_from_serialized(row[0]).node_names)
|
||||
if i % args.chunk_size == 0:
|
||||
completed.value = i
|
||||
completed.value = i
|
||||
results.put(node_names, False)
|
||||
|
||||
|
||||
def main(args):
|
||||
num_blocks, count_blocks_elapsed = count_blocks(args) # 345104538, 13*60
|
||||
work_size = math.ceil(num_blocks / args.workers)
|
||||
offsets = range(0, num_blocks, work_size)
|
||||
completeds = tuple(multiprocessing.Value('Q', 0, lock=False) for _ in range(args.workers))
|
||||
# because we want to terminate the processes before we remove the results from the queue, use a manager
|
||||
# see warnings in https://docs.python.org/3/library/multiprocessing.html#pipes-and-queues
|
||||
results = multiprocessing.Manager().Queue()
|
||||
processes = tuple(
|
||||
multiprocessing.Process(target=process_chunk, name=f'processor {i}',
|
||||
args=(args, offsets[i], work_size, completeds[i], results))
|
||||
for i in range(args.workers)
|
||||
)
|
||||
for process in processes:
|
||||
process.start()
|
||||
|
||||
print(f'NOTICE: not all jobs will start at the same time due to the nature of ranged queries. actual runtime will '
|
||||
f'be closer to 1/{min(args.workers, multiprocessing.cpu_count())}th the early estimate, plus '
|
||||
f'{count_blocks_elapsed}s.')
|
||||
# TODO: if we know how long it takes to count the blocks, and how many workers there are, we can estimate how long
|
||||
# before a process starts producing results, and resize the jobs to maximize processor usage.
|
||||
# proper estimation requires differential equations, ugh.
|
||||
|
||||
with progressbar.ProgressBar(max_value=num_blocks) as bar:
|
||||
while True:
|
||||
time.sleep(1)
|
||||
total_completed = sum(completed.value for completed in completeds)
|
||||
bar.update(total_completed)
|
||||
if total_completed == num_blocks:
|
||||
break
|
||||
|
||||
print('joining...')
|
||||
for process in processes:
|
||||
process.join()
|
||||
|
||||
print('compiling results...')
|
||||
all_nodes = get_all_nodes(results)
|
||||
|
||||
filter_ = create_filter(args.stairsplus_dump)
|
||||
whitelist = create_whitelist(filter_, all_nodes)
|
||||
write_whitelist(args, whitelist)
|
||||
|
||||
|
||||
def parse_args(args=None, namespace=None):
|
||||
p = argparse.ArgumentParser()
|
||||
g = p.add_mutually_exclusive_group(required=True)
|
||||
g.add_argument('--pg_connection', '-c')
|
||||
g.add_argument('--sqlite_file', '-s', type=existing_file)
|
||||
p.add_argument('--chunk_size', type=int, default=64)
|
||||
p.add_argument('--workers', type=int, default=multiprocessing.cpu_count())
|
||||
p.add_argument('--output', '-o', type=pathlib.Path)
|
||||
p.add_argument('stairsplus_dump', type=existing_file)
|
||||
return p.parse_args(args=args, namespace=namespace)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(parse_args())
|
33
mods/moreblocks/stairsplus/scripts/init.lua
Normal file
33
mods/moreblocks/stairsplus/scripts/init.lua
Normal file
|
@ -0,0 +1,33 @@
|
|||
local f = string.format
|
||||
local S = stairsplus.S
|
||||
|
||||
minetest.register_chatcommand("dump_stairsplus_registered_nodes", {
|
||||
description = S("create a list of stairsplus nodes, including aliases, to use as a filter in creating a whitelist"),
|
||||
privs = { server = true },
|
||||
func = function()
|
||||
local shaped_nodes = {}
|
||||
for shaped_node, shape in pairs(stairsplus.api.shape_by_shaped_node) do
|
||||
if shape ~= "node" then
|
||||
shaped_nodes[shaped_node] = true
|
||||
end
|
||||
end
|
||||
local aliases = {}
|
||||
for original in pairs(minetest.registered_aliases) do
|
||||
local resolved = futil.resolve_item(original)
|
||||
if resolved and shaped_nodes[resolved] then
|
||||
aliases[original] = resolved
|
||||
end
|
||||
end
|
||||
local filename = futil.path_concat(minetest.get_worldpath(), "stairsplus_dump.json")
|
||||
local contents = minetest.write_json({
|
||||
aliases = aliases,
|
||||
shaped_nodes = shaped_nodes,
|
||||
}, true)
|
||||
|
||||
if not futil.write_file(filename, contents) then
|
||||
return false, f("error writing file @ %s", filename)
|
||||
end
|
||||
|
||||
return true, f("dump created @ %s.", filename)
|
||||
end,
|
||||
})
|
239
mods/moreblocks/stairsplus/scripts/pymtdb.py
Normal file
239
mods/moreblocks/stairsplus/scripts/pymtdb.py
Normal file
|
@ -0,0 +1,239 @@
|
|||
# https://github.com/minetest/minetest/blob/master/doc/world_format.txt#L301
|
||||
# https://docs.python.org/3/library/struct.html
|
||||
import collections
|
||||
|
||||
import pyzstd
|
||||
|
||||
from stream import StreamReader
|
||||
|
||||
MAP_BLOCKSIZE = 16
|
||||
|
||||
|
||||
vector = collections.namedtuple('vector', ('x', 'y', 'z'))
|
||||
|
||||
|
||||
def unpack_pos(packed_pos):
|
||||
# 16*(16*z + y) + x
|
||||
zy, x = divmod(packed_pos, 16)
|
||||
z, y = divmod(zy, 16)
|
||||
return vector(x, y, z)
|
||||
|
||||
|
||||
class Inventory:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def from_bytes(data: bytes):
|
||||
inv = Inventory()
|
||||
return inv
|
||||
|
||||
|
||||
class MetaData:
|
||||
def __init__(self):
|
||||
self._meta = {}
|
||||
self._private = set()
|
||||
|
||||
def __getitem__(self, key: bytes):
|
||||
return self._meta[key]
|
||||
|
||||
def __setitem__(self, key: bytes, value: bytes):
|
||||
self._meta[key] = value
|
||||
|
||||
def mark_as_private(self, key: bytes, private: bool):
|
||||
if private:
|
||||
self._private.add(key)
|
||||
else:
|
||||
self._private.discard(key)
|
||||
|
||||
|
||||
class StaticObject:
|
||||
def __init__(self, type_, pos, data):
|
||||
self._type = type_
|
||||
self._pos = pos
|
||||
self._data = data
|
||||
|
||||
|
||||
class Timer:
|
||||
def __init__(self, timeout: int, elapsed: int):
|
||||
self._timeout = timeout
|
||||
self._elapsed = elapsed
|
||||
|
||||
|
||||
class MapBlock:
|
||||
def __init__(self):
|
||||
self._flags = 0
|
||||
self._lighting_complete = 0
|
||||
self._timestamp = 0
|
||||
self._nodes = tuple(
|
||||
tuple(
|
||||
["ignore" for _ in range(MAP_BLOCKSIZE)]
|
||||
for _ in range(MAP_BLOCKSIZE)
|
||||
) for _ in range(MAP_BLOCKSIZE)
|
||||
)
|
||||
self._param1 = tuple(
|
||||
tuple(
|
||||
[0 for _ in range(MAP_BLOCKSIZE)]
|
||||
for _ in range(MAP_BLOCKSIZE)
|
||||
) for _ in range(MAP_BLOCKSIZE)
|
||||
)
|
||||
self._param2 = tuple(
|
||||
tuple(
|
||||
[0 for _ in range(MAP_BLOCKSIZE)]
|
||||
for _ in range(MAP_BLOCKSIZE)
|
||||
) for _ in range(MAP_BLOCKSIZE)
|
||||
)
|
||||
self._metadata = tuple(
|
||||
tuple(
|
||||
[None for _ in range(MAP_BLOCKSIZE)]
|
||||
for _ in range(MAP_BLOCKSIZE)
|
||||
) for _ in range(MAP_BLOCKSIZE)
|
||||
)
|
||||
self._inventory = tuple(
|
||||
tuple(
|
||||
[None for _ in range(MAP_BLOCKSIZE)]
|
||||
for _ in range(MAP_BLOCKSIZE)
|
||||
) for _ in range(MAP_BLOCKSIZE)
|
||||
)
|
||||
self._timer = tuple(
|
||||
tuple(
|
||||
[None for _ in range(MAP_BLOCKSIZE)]
|
||||
for _ in range(MAP_BLOCKSIZE)
|
||||
) for _ in range(MAP_BLOCKSIZE)
|
||||
)
|
||||
|
||||
def iter_nodes(self):
|
||||
for plane in self._nodes:
|
||||
for row in plane:
|
||||
yield from row
|
||||
|
||||
@staticmethod
|
||||
def import_from_serialized(serialized_data: bytes):
|
||||
mapblock = MapBlock()
|
||||
version = serialized_data[0] # struct.unpack('>b', serialized_data)
|
||||
if version != 29:
|
||||
raise RuntimeError(f'can\'t parse version {version}')
|
||||
|
||||
stream = StreamReader(pyzstd.decompress(serialized_data[1:]))
|
||||
mapblock._flags = stream.u8()
|
||||
mapblock._lighting_complete = stream.u16()
|
||||
mapblock._timestamp = stream.u32()
|
||||
name_id_mapping_version = stream.u8()
|
||||
num_name_id_mappings = stream.u16()
|
||||
|
||||
if name_id_mapping_version != 0:
|
||||
raise RuntimeError(f'can\'t grok name_id_mapping_version {name_id_mapping_version}')
|
||||
|
||||
name_by_id = {}
|
||||
for _ in range(num_name_id_mappings):
|
||||
id_ = stream.u16()
|
||||
name_len = stream.u16()
|
||||
|
||||
name_by_id[id_] = stream.bytes(name_len)
|
||||
|
||||
content_width = stream.u8()
|
||||
if content_width != 2:
|
||||
raise RuntimeError(f'invalid content_width {content_width}')
|
||||
|
||||
params_width = stream.u8()
|
||||
|
||||
if params_width != 2:
|
||||
raise RuntimeError(f'invalid params_width {params_width}')
|
||||
|
||||
for z in range(MAP_BLOCKSIZE):
|
||||
for y in range(MAP_BLOCKSIZE):
|
||||
for x in range(MAP_BLOCKSIZE):
|
||||
mapblock._nodes[z][y][x] = name_by_id[stream.u16()]
|
||||
|
||||
for z in range(MAP_BLOCKSIZE):
|
||||
for y in range(MAP_BLOCKSIZE):
|
||||
for x in range(MAP_BLOCKSIZE):
|
||||
mapblock._param1[z][y][x] = stream.u8()
|
||||
|
||||
for z in range(MAP_BLOCKSIZE):
|
||||
for y in range(MAP_BLOCKSIZE):
|
||||
for x in range(MAP_BLOCKSIZE):
|
||||
mapblock._param2[z][y][x] = stream.u8()
|
||||
|
||||
ib = ''
|
||||
node_metadata_version = stream.u8()
|
||||
if node_metadata_version > 0:
|
||||
|
||||
if node_metadata_version != 2:
|
||||
raise RuntimeError(f'unexpected node_metadata_version {node_metadata_version}')
|
||||
|
||||
node_metadata_count = stream.u16()
|
||||
|
||||
for _ in range(node_metadata_count):
|
||||
pos = unpack_pos(stream.u16())
|
||||
meta = MetaData()
|
||||
num_vars = stream.u32()
|
||||
for _ in range(num_vars):
|
||||
key_len = stream.u16()
|
||||
key = stream.bytes(key_len)
|
||||
val_len = stream.u32()
|
||||
meta[key] = stream.bytes(val_len)
|
||||
meta.mark_as_private(key, stream.u8() == 1)
|
||||
|
||||
mapblock._metadata[pos.z][pos.y][pos.x] = meta
|
||||
mapblock._inventory[pos.z][pos.y][pos.x] = Inventory.from_bytes(stream.inventory_bytes())
|
||||
|
||||
static_object_version = stream.u8()
|
||||
|
||||
if static_object_version != 0:
|
||||
raise RuntimeError(f'unexpected static_object_version {static_object_version} {ib} {stream._data}')
|
||||
|
||||
static_object_count = stream.u16()
|
||||
static_objects = []
|
||||
|
||||
for _ in range(static_object_count):
|
||||
type_ = stream.u8()
|
||||
pos_x_nodes = stream.s32() / 1e5
|
||||
pos_y_nodes = stream.s32() / 1e5
|
||||
pos_z_nodes = stream.s32() / 1e5
|
||||
data_size = stream.u16()
|
||||
data = stream.bytes(data_size)
|
||||
static_objects.append(StaticObject(type_, vector(pos_x_nodes, pos_y_nodes, pos_z_nodes), data))
|
||||
|
||||
timers_length = stream.u8()
|
||||
if timers_length != 10:
|
||||
raise RuntimeError(f'unexpected timers_length {timers_length}')
|
||||
num_of_timers = stream.u16()
|
||||
for _ in range(num_of_timers):
|
||||
pos = unpack_pos(stream.u16())
|
||||
timeout = stream.s32()
|
||||
elapsed = stream.s32()
|
||||
mapblock._timer[pos.z][pos.y][pos.x] = Timer(timeout, elapsed)
|
||||
|
||||
return mapblock
|
||||
|
||||
|
||||
class MapBlockSimple:
|
||||
def __init__(self):
|
||||
self.node_names = []
|
||||
|
||||
@staticmethod
|
||||
def import_from_serialized(serialized_data: bytes):
|
||||
mapblock = MapBlockSimple()
|
||||
version = serialized_data[0]
|
||||
if type(version) is bytes:
|
||||
version = ord(version)
|
||||
if version != 29:
|
||||
raise RuntimeError(f'can\'t parse version {version}')
|
||||
|
||||
stream = StreamReader(pyzstd.decompress(serialized_data[1:]))
|
||||
stream.u8() # flags
|
||||
stream.u16() # lighting_complete
|
||||
stream.u32() # timestamp
|
||||
name_id_mapping_version = stream.u8()
|
||||
num_name_id_mappings = stream.u16()
|
||||
|
||||
if name_id_mapping_version != 0:
|
||||
raise RuntimeError(f'can\'t grok name_id_mapping_version {name_id_mapping_version}')
|
||||
|
||||
for _ in range(num_name_id_mappings):
|
||||
stream.u16() # id
|
||||
name_len = stream.u16()
|
||||
mapblock.node_names.append(stream.bytes(name_len))
|
||||
|
||||
return mapblock
|
3
mods/moreblocks/stairsplus/scripts/requirements.txt
Normal file
3
mods/moreblocks/stairsplus/scripts/requirements.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
progressbar2
|
||||
psycopg2
|
||||
pyzstd
|
72
mods/moreblocks/stairsplus/scripts/stream.py
Normal file
72
mods/moreblocks/stairsplus/scripts/stream.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
import struct
|
||||
|
||||
|
||||
class StreamReader:
|
||||
def __init__(self, data: bytes):
|
||||
self._data = data
|
||||
self._start = 0
|
||||
|
||||
def u8(self) -> int:
|
||||
sformat = '>B'
|
||||
ssize = struct.calcsize(sformat)
|
||||
rv = struct.unpack(sformat, self._data[self._start:self._start + ssize])
|
||||
self._start = self._start + ssize
|
||||
return rv[0]
|
||||
|
||||
def u16(self) -> int:
|
||||
sformat = '>H'
|
||||
ssize = struct.calcsize(sformat)
|
||||
rv = struct.unpack(sformat, self._data[self._start:self._start + ssize])
|
||||
self._start = self._start + ssize
|
||||
return rv[0]
|
||||
|
||||
def s32(self) -> int:
|
||||
sformat = '>i'
|
||||
ssize = struct.calcsize(sformat)
|
||||
rv = struct.unpack(sformat, self._data[self._start:self._start + ssize])
|
||||
self._start = self._start + ssize
|
||||
return rv[0]
|
||||
|
||||
def u32(self) -> int:
|
||||
sformat = '>I'
|
||||
ssize = struct.calcsize(sformat)
|
||||
rv = struct.unpack(sformat, self._data[self._start:self._start + ssize])
|
||||
self._start = self._start + ssize
|
||||
return rv[0]
|
||||
|
||||
def bytes(self, count: int) -> bytes:
|
||||
rv = self._data[self._start:self._start + count]
|
||||
self._start = self._start + count
|
||||
return rv
|
||||
|
||||
def inventory_bytes(self) -> bytes:
|
||||
start_of_end = self._data.find(b'EndInventory\n', self._start)
|
||||
if start_of_end == -1:
|
||||
return
|
||||
actual_end = start_of_end + len(b'EndInventory\n')
|
||||
rv = self._data[self._start:actual_end]
|
||||
self._start = actual_end
|
||||
return rv
|
||||
|
||||
def rest(self) -> bytes:
|
||||
return self._data[self._start:]
|
||||
|
||||
|
||||
class StreamWriter:
|
||||
def __init__(self, fh):
|
||||
self._fh = fh
|
||||
|
||||
def u8(self, value):
|
||||
sformat = '>B'
|
||||
self._fh.write(struct.pack(sformat, value))
|
||||
|
||||
def u16(self, value):
|
||||
sformat = '>H'
|
||||
self._fh.write(struct.pack(sformat, value))
|
||||
|
||||
def u32(self, value):
|
||||
sformat = '>I'
|
||||
self._fh.write(struct.pack(sformat, value))
|
||||
|
||||
def bytes(self, value: bytes):
|
||||
self._fh.write(value)
|
162
mods/moreblocks/stairsplus/scripts/translate_schems.py
Normal file
162
mods/moreblocks/stairsplus/scripts/translate_schems.py
Normal file
|
@ -0,0 +1,162 @@
|
|||
# https://gitlab.com/bztsrc/mtsedit/blob/master/docs/mts_format.md
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import pathlib
|
||||
|
||||
import lupa
|
||||
|
||||
from stream import StreamReader, StreamWriter
|
||||
|
||||
lua = lupa.LuaRuntime(unpack_returned_tuples=True)
|
||||
|
||||
|
||||
def is_schem(file: pathlib.Path):
|
||||
return file.suffix == '.mts'
|
||||
|
||||
|
||||
def convert_schem(child, alias_map):
|
||||
print(f'processing {child}')
|
||||
with child.open('rb') as fh:
|
||||
contents = fh.read()
|
||||
|
||||
reader = StreamReader(contents)
|
||||
magic = reader.bytes(4)
|
||||
if magic != b'MTSM':
|
||||
raise RuntimeError(f'invalid magic number {magic}')
|
||||
version = reader.u16()
|
||||
if version != 4:
|
||||
raise RuntimeError(f'unexpected version {version}')
|
||||
x = reader.u16()
|
||||
y = reader.u16()
|
||||
z = reader.u16()
|
||||
layer_probability_values = reader.bytes(y)
|
||||
name_id_length = reader.u16()
|
||||
names = []
|
||||
any_changed = False
|
||||
for _ in range(name_id_length):
|
||||
name = reader.bytes(reader.u16())
|
||||
alias = alias_map.get(name.decode())
|
||||
if alias:
|
||||
any_changed = True
|
||||
names.append(alias.encode())
|
||||
else:
|
||||
names.append(name)
|
||||
|
||||
if any_changed:
|
||||
print('writing changes...')
|
||||
rest = reader.rest()
|
||||
with child.open('wb') as fh:
|
||||
writer = StreamWriter(fh)
|
||||
writer.bytes(b'MTSM')
|
||||
writer.u16(4)
|
||||
writer.u16(x)
|
||||
writer.u16(y)
|
||||
writer.u16(z)
|
||||
writer.bytes(layer_probability_values)
|
||||
writer.u16(name_id_length)
|
||||
for name in names:
|
||||
writer.u16(len(name))
|
||||
writer.bytes(name)
|
||||
writer.bytes(rest)
|
||||
|
||||
|
||||
def is_we(file: pathlib.Path):
|
||||
return file.suffix == '.we'
|
||||
|
||||
|
||||
def lua_dump(value):
|
||||
if type(value) is str:
|
||||
return repr(value)
|
||||
elif type(value) in {int, float}:
|
||||
return str(value)
|
||||
elif type(value) in {list, tuple}:
|
||||
return f'{{{", ".join(map(lua_dump, value))}}}'
|
||||
elif type(value) is dict:
|
||||
return '{' + ', '.join(f'[{lua_dump(k)}] = {lua_dump(v)}' for k, v in value.items()) + '}'
|
||||
elif value is None:
|
||||
return 'nil'
|
||||
elif value is True:
|
||||
return 'true'
|
||||
elif value is False:
|
||||
return 'false'
|
||||
elif lupa.lua_type(value) == 'table':
|
||||
return lua_dump(dict(value.items()))
|
||||
else:
|
||||
raise RuntimeError(f'value {value!r} w/ unexpected type {type(value)}')
|
||||
|
||||
|
||||
def convert_we(child, alias_map):
|
||||
print(f'processing {child}')
|
||||
with child.open('r') as fh:
|
||||
contents = fh.read()
|
||||
|
||||
assert(contents[:9] == '5:return ')
|
||||
table = lua.eval(contents[9:])
|
||||
data = tuple(map(dict, table.values()))
|
||||
any_changed = False
|
||||
for point in data:
|
||||
alias = alias_map.get(point['name'])
|
||||
if alias:
|
||||
point['name'] = alias
|
||||
any_changed = True
|
||||
|
||||
if any_changed:
|
||||
print('writing changes...')
|
||||
output = f'5:return {lua_dump(data)}'
|
||||
with child.open('w') as fh:
|
||||
fh.write(output)
|
||||
|
||||
|
||||
def create_alias_map(stairsplus_dump: pathlib.Path):
|
||||
print('reading aliases from dump')
|
||||
aliases = {}
|
||||
with stairsplus_dump.open() as fh:
|
||||
data = json.load(fh)
|
||||
|
||||
for alias, shaped_node in data['aliases'].items():
|
||||
aliases[alias] = shaped_node
|
||||
|
||||
return aliases
|
||||
|
||||
|
||||
def main(args):
|
||||
alias_map = create_alias_map(args.stairsplus_dump)
|
||||
|
||||
for child in args.schems.iterdir():
|
||||
if child.is_file():
|
||||
if is_schem(child):
|
||||
convert_schem(child, alias_map)
|
||||
elif is_we(child):
|
||||
convert_we(child, alias_map)
|
||||
else:
|
||||
print(f'unknown file type {child.suffix}')
|
||||
|
||||
|
||||
def existing_file(path: str) -> pathlib.Path:
|
||||
file_path = pathlib.Path(path)
|
||||
if not file_path.exists():
|
||||
raise argparse.ArgumentTypeError(f'{path!r} does not exist.')
|
||||
if not file_path.is_file():
|
||||
raise argparse.ArgumentTypeError(f'{path!r} is not a file.')
|
||||
return file_path
|
||||
|
||||
|
||||
def existing_directory(path: str) -> pathlib.Path:
|
||||
file_path = pathlib.Path(path)
|
||||
if not file_path.exists():
|
||||
raise argparse.ArgumentTypeError(f'{path!r} does not exist.')
|
||||
if not file_path.is_dir():
|
||||
raise argparse.ArgumentTypeError(f'{path!r} is not a directory.')
|
||||
return file_path
|
||||
|
||||
|
||||
def parse_args(args=None, namespace=None):
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument('stairsplus_dump', type=existing_file)
|
||||
p.add_argument('schems', type=existing_directory)
|
||||
return p.parse_args(args=args, namespace=namespace)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(parse_args())
|
87
mods/moreblocks/stairsplus/scripts/whitelist_helpers.py
Normal file
87
mods/moreblocks/stairsplus/scripts/whitelist_helpers.py
Normal file
|
@ -0,0 +1,87 @@
|
|||
import argparse
|
||||
import json
|
||||
import multiprocessing
|
||||
import pathlib
|
||||
import queue
|
||||
import time
|
||||
|
||||
|
||||
def existing_file(path: str) -> pathlib.Path:
|
||||
file_path = pathlib.Path(path)
|
||||
if not file_path.exists():
|
||||
raise argparse.ArgumentTypeError(f'{path!r} does not exist.')
|
||||
if not file_path.is_file():
|
||||
raise argparse.ArgumentTypeError(f'{path!r} is not a file.')
|
||||
return file_path
|
||||
|
||||
|
||||
def get_cursor(args):
|
||||
if args.pg_connection:
|
||||
import psycopg2
|
||||
conn = psycopg2.connect(args.pg_connection)
|
||||
cursor = conn.cursor(name='blocks')
|
||||
cursor.itersize = args.chunk_size
|
||||
|
||||
else:
|
||||
import sqlite3
|
||||
conn = sqlite3.connect(args.sqlite_file)
|
||||
cursor = conn.cursor()
|
||||
|
||||
return cursor
|
||||
|
||||
|
||||
def create_filter(stairsplus_dump: pathlib.Path):
|
||||
print('creating filter from dump...')
|
||||
start = time.time()
|
||||
f = {}
|
||||
with stairsplus_dump.open() as fh:
|
||||
data = json.load(fh)
|
||||
|
||||
for shaped_node in data['shaped_nodes'].keys():
|
||||
f[shaped_node.encode()] = shaped_node.encode()
|
||||
|
||||
for alias, shaped_node in data['aliases'].items():
|
||||
f[alias.encode()] = shaped_node.encode()
|
||||
print(f'created in {time.time() - start}')
|
||||
|
||||
return f
|
||||
|
||||
|
||||
def count_blocks(args):
|
||||
cursor = get_cursor(args)
|
||||
|
||||
# just shy of 12 minutes for postgres w/ a 150GiB map dump, an opteron 6376, and 4 encrypted raid6 5400 RPM disks
|
||||
print('counting mapblocks - this can take a while...')
|
||||
start = time.time()
|
||||
cursor.execute('SELECT COUNT(data) FROM blocks')
|
||||
num_blocks = cursor.fetchone()[0]
|
||||
elapsed = time.time() - start
|
||||
print(f'num_blocks: {num_blocks} (fetched in {elapsed}s)')
|
||||
return num_blocks, elapsed
|
||||
|
||||
|
||||
def create_whitelist(filter_, all_nodes):
|
||||
print('creating whitelist')
|
||||
return set(
|
||||
shaped_node for shaped_node in map(filter_.get, all_nodes) if shaped_node
|
||||
)
|
||||
|
||||
|
||||
def write_whitelist(args, whitelist):
|
||||
if args.output:
|
||||
output = args.output
|
||||
else:
|
||||
output = args.stairsplus_dump.parent / 'stairsplus.whitelist'
|
||||
|
||||
with output.open('wb') as fh:
|
||||
print(f'writing whitelist to {output!r}')
|
||||
fh.write(b'\n'.join(sorted(whitelist)))
|
||||
|
||||
|
||||
def get_all_nodes(results: multiprocessing.Queue):
|
||||
all_nodes = set()
|
||||
try:
|
||||
while True:
|
||||
all_nodes.update(results.get(False))
|
||||
except queue.Empty:
|
||||
return all_nodes
|
40
mods/moreblocks/stairsplus/settingtypes.txt
Normal file
40
mods/moreblocks/stairsplus/settingtypes.txt
Normal file
|
@ -0,0 +1,40 @@
|
|||
# I guess if you want the saw to be creative-only?
|
||||
stairsplus.circular_saw_crafting (Allow crafting the circular saw) bool true
|
||||
|
||||
# Defaults to true if creative_mode is enabled.
|
||||
stairsplus.ex_nihilo (Saw gives infinite nodes) bool false
|
||||
|
||||
# If enabled, Stairs+ nodes will be displayed in the inventory when playing in creative mode.
|
||||
# Disabling this can speed up loading times for clients as fewer nodes need to be registered in the creative inventory.
|
||||
stairsplus.in_creative_inventory (Display Stairs+ nodes in creative inventory) bool true
|
||||
|
||||
# Whether to show crafting recipes involving Stairs+ nodes (in compatible inventory managers)
|
||||
stairsplus.in_craft_guide (Show crafting recipes) bool true
|
||||
|
||||
# "user" or "world" cause things to look nicer in general, but some nodes look better w/ the "node" style
|
||||
stairsplus.default_align_style (World align style) enum user node,user,world
|
||||
|
||||
# regular stairs shapes. if you can't view all of these in the minetest settings GUI, please edit your minetest.conf by hand.
|
||||
stairsplus.basic_shapes (basic shapes) flags micro_8,slab_8,stair,stair_inner,stair_outer panel_1,slope,slope_half,slope_half_raised,panel_2,slope_inner_cut,slope_inner_half,panel_4,slope_inner_half_raised,slope_inner_cut_half_raised,slope_outer,slope_outer_cut,slope_cut,slope_outer_half,panel_12,slope_outer_half_raised,slope_outer_cut_half_raised,panel_14,panel_15,micro_1,slab_15,slab_two_sides,stair_half,slab_three_sides,stair_right_half,slab_three_sides_u,micro_12,micro_14,slab_2,micro_15,slab_4,micro_2,stair_alt_4,stair_alt_2,stair_alt_1,stair_alt_8,slab_1,slab_12,stair,slope_outer_cut_half,slope_inner_cut_half,slab_14,micro_4,micro_8,slab_8,stair_inner,stair_outer,slope_inner,panel_8
|
||||
|
||||
# the most commonly used variants. if you can't view all of these in the minetest settings GUI, please edit your minetest.conf by hand.
|
||||
stairsplus.common_shapes (common shapes) flags micro_8,panel_8,slab_1,slab_8,stair,stair_inner,stair_outer,slope,slope_half,slope_half_raised,slope_inner,slope_inner_cut,slope_inner_half,slope_inner_cut_half,slope_inner_half_raised,slope_inner_cut_half_raised,slope_outer,slope_outer_cut,slope_cut,slope_outer_half,slope_outer_cut_half,slope_outer_half_raised,slope_outer_cut_half_raised panel_1,slope,slope_half,slope_half_raised,panel_2,slope_inner_cut,slope_inner_half,panel_4,slope_inner_half_raised,slope_inner_cut_half_raised,slope_outer,slope_outer_cut,slope_cut,slope_outer_half,panel_12,slope_outer_half_raised,slope_outer_cut_half_raised,panel_14,panel_15,micro_1,slab_15,slab_two_sides,stair_half,slab_three_sides,stair_right_half,slab_three_sides_u,micro_12,micro_14,slab_2,micro_15,slab_4,micro_2,stair_alt_4,stair_alt_2,stair_alt_1,stair_alt_8,slab_1,slab_12,stair,slope_outer_cut_half,slope_inner_cut_half,slab_14,micro_4,micro_8,slab_8,stair_inner,stair_outer,slope_inner,panel_8
|
||||
|
||||
# default to registering *all* variants, and some other stuff.
|
||||
# it is only "safe" to disable this on new servers.
|
||||
stairsplus.legacy_mode (legacy mode) bool true
|
||||
|
||||
# automatically try to rotate nodes when placed. the mechanic is sometimes confusing.
|
||||
stairsplus.legacy_place_mechanic (use legacy place mecahnic) bool true
|
||||
|
||||
# allows crafting shaped nodes in addition to cutting them
|
||||
stairsplus.crafting_schemata_enabled (enable crafting schemata) bool true
|
||||
|
||||
# when set to true, will only register nodes specified in $WORLD_PATH/stairsplus.whitelist
|
||||
stairsplus.whitelist_mode (whitelist mode) bool false
|
||||
|
||||
# this fork changes how groups for stairsplus derivative nodes are computed. normally this is logged, because i don't
|
||||
# have a better way to communicate this. however, these changes don't cause any actual incompatibility that i'm aware
|
||||
# of. if you don't want to fix the mods that use moreblocks to be aware of this fork, you can enable this setting
|
||||
# to remove those log messages.
|
||||
stairsplus.silence_group_overrides (silence group override log messages) bool false
|
8
mods/moreblocks/stairsplus/shapes/init.lua
Normal file
8
mods/moreblocks/stairsplus/shapes/init.lua
Normal file
|
@ -0,0 +1,8 @@
|
|||
stairsplus.dofile("shapes", "micros")
|
||||
stairsplus.dofile("shapes", "panels")
|
||||
stairsplus.dofile("shapes", "slabs")
|
||||
stairsplus.dofile("shapes", "slopes")
|
||||
stairsplus.dofile("shapes", "stairs")
|
||||
|
||||
stairsplus.api.register_shape_group("basic", stairsplus.settings.basic_shapes)
|
||||
stairsplus.api.register_shape_group("common", stairsplus.settings.common_shapes)
|
85
mods/moreblocks/stairsplus/shapes/micros.lua
Normal file
85
mods/moreblocks/stairsplus/shapes/micros.lua
Normal file
|
@ -0,0 +1,85 @@
|
|||
stairsplus.api.register_shape("micro_1", {
|
||||
name_format = "micro_%s_1",
|
||||
description = "@1 1/16 Microblock",
|
||||
shape_groups = { micro = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/64 nodes, complement of micro_15 to make panel_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0, -0.4375, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("micro_2", {
|
||||
name_format = "micro_%s_2",
|
||||
description = "@1 1/8 Microblock",
|
||||
shape_groups = { micro = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/32 nodes, complement of micro_14 to make panel_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0, -0.375, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("micro_4", {
|
||||
name_format = "micro_%s_4",
|
||||
description = "@1 1/4 Microblock",
|
||||
shape_groups = { micro = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/16 nodes, complement of micro_12 to make panel_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0, -0.25, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("micro_8", {
|
||||
name_format = "micro_%s_8",
|
||||
aliases = { "micro_%s", "micro_%s_bottom" },
|
||||
description = "@1 Microblock", -- leave out the 1/2 to not confuse people too much...
|
||||
shape_groups = { micro = 1, obligatory = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/8 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0, 0, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("micro_12", {
|
||||
name_format = "micro_%s_12",
|
||||
description = "@1 3/4 Microblock",
|
||||
shape_groups = { micro = 1, legacy = 1 },
|
||||
eighths = 1, -- 3/16 nodes, complement of micro_4 to make panel_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0, 0.25, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("micro_14", {
|
||||
name_format = "micro_%s_14",
|
||||
description = "@1 7/8 Microblock",
|
||||
shape_groups = { micro = 1, legacy = 1 },
|
||||
eighths = 1, -- 7/32 nodes, complement of micro_2 to make panel_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0, 0.375, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("micro_15", {
|
||||
name_format = "micro_%s_15",
|
||||
aliases = { "micro_%s_5" },
|
||||
description = "@1 15/16 Microblock",
|
||||
shape_groups = { micro = 1, legacy = 1 },
|
||||
eighths = 1, -- 15/64 nodes, complement of micro_1 to make panel_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0, 0.4375, 0.5 },
|
||||
},
|
||||
})
|
84
mods/moreblocks/stairsplus/shapes/panels.lua
Normal file
84
mods/moreblocks/stairsplus/shapes/panels.lua
Normal file
|
@ -0,0 +1,84 @@
|
|||
stairsplus.api.register_shape("panel_1", {
|
||||
name_format = "panel_%s_1",
|
||||
description = "@1 1/16 Panel",
|
||||
shape_groups = { panel = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/32 nodes, complement of panel_15 to make slab_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0.5, -0.4375, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("panel_2", {
|
||||
name_format = "panel_%s_2",
|
||||
description = "@1 1/8 Panel",
|
||||
shape_groups = { panel = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/16 nodes, complement of panel_14 to make slab_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0.5, -0.375, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("panel_4", {
|
||||
name_format = "panel_%s_4",
|
||||
description = "@1 1/4 Panel",
|
||||
shape_groups = { panel = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/8 nodes, complement of panel_12 to make slab_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0.5, -0.25, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("panel_8", {
|
||||
name_format = "panel_%s_8",
|
||||
aliases = { "panel_%s", "panel_bottom_%s" },
|
||||
description = "@1 1/2 Panel",
|
||||
shape_groups = { panel = 1, legacy = 1 },
|
||||
eighths = 2, -- 1/4 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0.5, 0, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("panel_12", {
|
||||
name_format = "panel_%s_12",
|
||||
description = "@1 3/4 Panel",
|
||||
shape_groups = { panel = 1, legacy = 1 },
|
||||
eighths = 3, -- 3/8 nodes, complement of panel_4 to make slab_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0.5, 0.25, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("panel_14", {
|
||||
name_format = "panel_%s_14",
|
||||
description = "@1 7/8 Panel",
|
||||
shape_groups = { panel = 1, legacy = 1 },
|
||||
eighths = 3, -- 7/16 nodes, complement of panel_2 to make slab_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0.5, 0.375, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("panel_15", {
|
||||
name_format = "panel_%s_15",
|
||||
description = "@1 15/16 Panel",
|
||||
shape_groups = { panel = 1, legacy = 1 },
|
||||
eighths = 3, -- 15/32 nodes, complement of panel_1 to make slab_8
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, 0, 0.5, 0.4375, 0.5 },
|
||||
},
|
||||
})
|
135
mods/moreblocks/stairsplus/shapes/slabs.lua
Normal file
135
mods/moreblocks/stairsplus/shapes/slabs.lua
Normal file
|
@ -0,0 +1,135 @@
|
|||
stairsplus.api.register_shape("slab_1", {
|
||||
name_format = "slab_%s_1",
|
||||
description = "@1 1/16 Slab",
|
||||
shape_groups = { slab = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/16 nodes, complement of slab_15 to make node
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, -0.5, 0.5, -0.4375, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slab_2", {
|
||||
name_format = "slab_%s_2",
|
||||
description = "@1 1/8 Slab",
|
||||
shape_groups = { slab = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/8 nodes, complement of slab_14 to make node
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, -0.5, 0.5, -0.375, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slab_4", {
|
||||
name_format = "slab_%s_4",
|
||||
aliases = { "slab_%s_quarter" },
|
||||
description = "@1 1/4 Slab",
|
||||
shape_groups = { slab = 1, legacy = 1 },
|
||||
eighths = 2, -- 1/4 nodes, complement of slab_12 to make node
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slab_8", {
|
||||
name_format = "slab_%s_8",
|
||||
aliases = { "slab_%s" },
|
||||
description = "@1 1/2 Slab",
|
||||
shape_groups = { slab = 1, legacy = 1, stairs_legacy = 1 },
|
||||
eighths = 4, -- 1/2 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slab_12", {
|
||||
name_format = "slab_%s_12",
|
||||
aliases = { "slab_%s_three_quarter" },
|
||||
description = "@1 3/4 Slab",
|
||||
shape_groups = { slab = 1, legacy = 1 },
|
||||
eighths = 6, -- 3/4 nodes, complement of slab_4 to make node
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, -0.5, 0.5, 0.25, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slab_14", {
|
||||
name_format = "slab_%s_14",
|
||||
description = "@1 7/8 Slab",
|
||||
shape_groups = { slab = 1, legacy = 1 },
|
||||
eighths = 7, -- 7/8 nodes, complement of slab_2 to make node
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, -0.5, 0.5, 0.375, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slab_15", {
|
||||
name_format = "slab_%s_15",
|
||||
description = "@1 15/16 Slab",
|
||||
shape_groups = { slab = 1, legacy = 1 },
|
||||
eighths = 7, -- 15/16 nodes, complement of slab_1 to make node
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, -0.5, 0.5, 0.4375, 0.5 },
|
||||
},
|
||||
})
|
||||
|
||||
--- these terrible things
|
||||
|
||||
stairsplus.api.register_shape("slab_two_sides", {
|
||||
name_format = "slab_%s_two_sides",
|
||||
description = "@1 1/16 Slab Two Sides",
|
||||
shape_groups = { slab = 1, legacy = 1 },
|
||||
eighths = 1, -- 31/256 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, -7 / 16, 7 / 16 },
|
||||
{ -0.5, -0.5, 7 / 16, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slab_three_sides", {
|
||||
name_format = "slab_%s_three_sides",
|
||||
description = "@1 1/16 Slab Three Sides",
|
||||
shape_groups = { slab = 1, legacy = 1 },
|
||||
eighths = 1, -- 361/2048 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -7 / 16, -0.5, -0.5, 0.5, -7 / 16, 7 / 16 },
|
||||
{ -7 / 16, -0.5, 7 / 16, 0.5, 0.5, 0.5 },
|
||||
{ -0.5, -0.5, -0.5, -7 / 16, 0.5, 0.5 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slab_three_sides_u", {
|
||||
name_format = "slab_%s_three_sides_u",
|
||||
description = "@1 1/16 Slab Three Sides U",
|
||||
shape_groups = { slab = 1, legacy = 1 },
|
||||
eighths = 1, -- 23/128 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, 0.5, -7 / 16 },
|
||||
{ -0.5, -0.5, -7 / 16, 0.5, -7 / 16, 7 / 16 },
|
||||
{ -0.5, -0.5, 7 / 16, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
},
|
||||
})
|
274
mods/moreblocks/stairsplus/shapes/slopes.lua
Normal file
274
mods/moreblocks/stairsplus/shapes/slopes.lua
Normal file
|
@ -0,0 +1,274 @@
|
|||
local box_slope = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 },
|
||||
{ -0.5, -0.25, -0.25, 0.5, 0, 0.5 },
|
||||
{ -0.5, 0, 0, 0.5, 0.25, 0.5 },
|
||||
{ -0.5, 0.25, 0.25, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
}
|
||||
|
||||
local box_slope_half = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, -0.375, 0.5 },
|
||||
{ -0.5, -0.375, -0.25, 0.5, -0.25, 0.5 },
|
||||
{ -0.5, -0.25, 0, 0.5, -0.125, 0.5 },
|
||||
{ -0.5, -0.125, 0.25, 0.5, 0, 0.5 },
|
||||
},
|
||||
}
|
||||
|
||||
local box_slope_half_raised = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, 0.125, 0.5 },
|
||||
{ -0.5, 0.125, -0.25, 0.5, 0.25, 0.5 },
|
||||
{ -0.5, 0.25, 0, 0.5, 0.375, 0.5 },
|
||||
{ -0.5, 0.375, 0.25, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
}
|
||||
|
||||
local box_slope_inner = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 },
|
||||
{ -0.5, -0.5, -0.25, 0.5, 0, 0.5 },
|
||||
{ -0.5, -0.5, -0.5, 0.25, 0, 0.5 },
|
||||
{ -0.5, 0, -0.5, 0, 0.25, 0.5 },
|
||||
{ -0.5, 0, 0, 0.5, 0.25, 0.5 },
|
||||
{ -0.5, 0.25, 0.25, 0.5, 0.5, 0.5 },
|
||||
{ -0.5, 0.25, -0.5, -0.25, 0.5, 0.5 },
|
||||
},
|
||||
}
|
||||
|
||||
local box_slope_inner_half = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, -0.375, 0.5 },
|
||||
{ -0.5, -0.375, -0.25, 0.5, -0.25, 0.5 },
|
||||
{ -0.5, -0.375, -0.5, 0.25, -0.25, 0.5 },
|
||||
{ -0.5, -0.25, -0.5, 0, -0.125, 0.5 },
|
||||
{ -0.5, -0.25, 0, 0.5, -0.125, 0.5 },
|
||||
{ -0.5, -0.125, 0.25, 0.5, 0, 0.5 },
|
||||
{ -0.5, -0.125, -0.5, -0.25, 0, 0.5 },
|
||||
},
|
||||
}
|
||||
|
||||
local box_slope_inner_half_raised = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, 0.125, 0.5 },
|
||||
{ -0.5, 0.125, -0.25, 0.5, 0.25, 0.5 },
|
||||
{ -0.5, 0.125, -0.5, 0.25, 0.25, 0.5 },
|
||||
{ -0.5, 0.25, -0.5, 0, 0.375, 0.5 },
|
||||
{ -0.5, 0.25, 0, 0.5, 0.375, 0.5 },
|
||||
{ -0.5, 0.375, 0.25, 0.5, 0.5, 0.5 },
|
||||
{ -0.5, 0.375, -0.5, -0.25, 0.5, 0.5 },
|
||||
},
|
||||
}
|
||||
|
||||
local box_slope_outer = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 },
|
||||
{ -0.5, -0.25, -0.25, 0.25, 0, 0.5 },
|
||||
{ -0.5, 0, 0, 0, 0.25, 0.5 },
|
||||
{ -0.5, 0.25, 0.25, -0.25, 0.5, 0.5 },
|
||||
},
|
||||
}
|
||||
|
||||
local box_slope_outer_half = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, -0.375, 0.5 },
|
||||
{ -0.5, -0.375, -0.25, 0.25, -0.25, 0.5 },
|
||||
{ -0.5, -0.25, 0, 0, -0.125, 0.5 },
|
||||
{ -0.5, -0.125, 0.25, -0.25, 0, 0.5 },
|
||||
},
|
||||
}
|
||||
|
||||
local box_slope_outer_half_raised = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, 0.125, 0.5 },
|
||||
{ -0.5, 0.125, -0.25, 0.25, 0.25, 0.5 },
|
||||
{ -0.5, 0.25, 0, 0, 0.375, 0.5 },
|
||||
{ -0.5, 0.375, 0.25, -0.25, 0.5, 0.5 },
|
||||
},
|
||||
}
|
||||
|
||||
stairsplus.api.register_shape("slope", {
|
||||
name_format = "slope_%s",
|
||||
description = "@1 Slope",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 4, -- 1/2 node
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope.obj",
|
||||
collision_box = box_slope,
|
||||
selection_box = box_slope,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_half", {
|
||||
name_format = "slope_%s_half",
|
||||
description = "@1 1/2 Slope",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 2, -- 1/4 node, complement of slope_half_raised
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_half.obj",
|
||||
collision_box = box_slope_half,
|
||||
selection_box = box_slope_half,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_half_raised", {
|
||||
name_format = "slope_%s_half_raised",
|
||||
description = "@1 1/2 Slope Raised",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 6, -- 3/4 node, complement of slope_half
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_half_raised.obj",
|
||||
collision_box = box_slope_half_raised,
|
||||
selection_box = box_slope_half_raised,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_inner", {
|
||||
name_format = "slope_%s_inner",
|
||||
description = "@1 Slope Inner",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 5, -- 2/3 nodes, complement of slope_outer
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_inner.obj",
|
||||
collision_box = box_slope_inner,
|
||||
selection_box = box_slope_inner,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_outer", {
|
||||
name_format = "slope_%s_outer",
|
||||
description = "@1 Slope Outer",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 3, -- 1/3 nodes, complement of slope_inner
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_outer.obj",
|
||||
collision_box = box_slope_outer,
|
||||
selection_box = box_slope_outer,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_inner_cut", {
|
||||
name_format = "slope_%s_inner_cut",
|
||||
description = "@1 Slope Inner Cut",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 7, -- 5/6 nodes, complement of slope_outer_cut
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_inner_cut.obj",
|
||||
collision_box = box_slope_inner,
|
||||
selection_box = box_slope_inner,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_outer_cut", {
|
||||
name_format = "slope_%s_outer_cut",
|
||||
description = "@1 Slope Outer Cut",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/6 nodes, complement of slope_inner_cut
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_outer_cut.obj",
|
||||
collision_box = box_slope_outer,
|
||||
selection_box = box_slope_outer,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_inner_half", {
|
||||
name_format = "slope_%s_inner_half",
|
||||
description = "@1 Slope Inner Half",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 3, -- 1/3 nodes, complement of slope_outer_half to make slab_8
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_inner_half.obj",
|
||||
collision_box = box_slope_inner_half,
|
||||
selection_box = box_slope_inner_half,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_outer_half", {
|
||||
name_format = "slope_%s_outer_half",
|
||||
description = "@1 Slope Outer Half",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/6 nodes, complement of slope_inner_half to make slab_8
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_outer_half.obj",
|
||||
collision_box = box_slope_outer_half,
|
||||
selection_box = box_slope_outer_half,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_inner_cut_half", {
|
||||
name_format = "slope_%s_inner_cut_half",
|
||||
description = "@1 Slope Inner Cut Half",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 3, -- 11/12 nodes, complement of slope_outer_cut_half to make slab_8
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_inner_cut_half.obj",
|
||||
collision_box = box_slope_inner_half,
|
||||
selection_box = box_slope_inner_half,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_outer_cut_half", {
|
||||
name_format = "slope_%s_outer_cut_half",
|
||||
description = "@1 Slope Outer Cut Half",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/12 nodes, complement of slope_inner_cut_half to make slab_8
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_outer_cut_half.obj",
|
||||
collision_box = box_slope_outer_half,
|
||||
selection_box = box_slope_outer_half,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_inner_half_raised", {
|
||||
name_format = "slope_%s_inner_half_raised",
|
||||
description = "@1 Slope Inner Half Raised",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 7, -- 5/6 nodes, complement of slope_outer_half to make node
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_inner_half_raised.obj",
|
||||
collision_box = box_slope_inner_half_raised,
|
||||
selection_box = box_slope_inner_half_raised,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_inner_cut_half_raised", {
|
||||
name_format = "slope_%s_inner_cut_half_raised",
|
||||
description = "@1 Slope Inner Cut Half Raised",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 7, -- 11/12 nodes, complement of slope_outer_cut_half to make node
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_inner_cut_half_raised.obj",
|
||||
collision_box = box_slope_inner_half_raised,
|
||||
selection_box = box_slope_inner_half_raised,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_outer_half_raised", {
|
||||
name_format = "slope_%s_outer_half_raised",
|
||||
description = "@1 Slope Outer Half Raised",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 5, -- 2/3 nodes, BUT slab_8 + slope_outer_half, complement of slope_inner_half to make node
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_outer_half_raised.obj",
|
||||
collision_box = box_slope_outer_half_raised,
|
||||
selection_box = box_slope_outer_half_raised,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_outer_cut_half_raised", {
|
||||
name_format = "slope_%s_outer_cut_half_raised",
|
||||
description = "@1 Slope Outer Cut Half Raised",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 3, -- 1/3 nodes, complement of slope_outer_cut_half to make slope
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_outer_cut_half_raised.obj",
|
||||
collision_box = box_slope_outer_half_raised,
|
||||
selection_box = box_slope_outer_half_raised,
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("slope_cut", {
|
||||
name_format = "slope_%s_cut",
|
||||
description = "@1 Slope Cut",
|
||||
shape_groups = { slope = 1, legacy = 1 },
|
||||
eighths = 4, -- 1/2 nodes, self complement
|
||||
drawtype = "mesh",
|
||||
mesh = "stairsplus_slope_cut.obj",
|
||||
collision_box = box_slope_outer,
|
||||
selection_box = box_slope_outer,
|
||||
})
|
141
mods/moreblocks/stairsplus/shapes/stairs.lua
Normal file
141
mods/moreblocks/stairsplus/shapes/stairs.lua
Normal file
|
@ -0,0 +1,141 @@
|
|||
stairsplus.api.register_shape("stair_half", {
|
||||
name_format = "stair_%s_half",
|
||||
description = "@1 Half Stair",
|
||||
shape_groups = { stair = 1, legacy = 1 },
|
||||
eighths = 3, -- 3/8 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0, 0, 0.5 },
|
||||
{ -0.5, 0, 0, 0, 0.5, 0.5 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("stair_right_half", {
|
||||
name_format = "stair_%s_right_half",
|
||||
description = "@1 Right Half Stair",
|
||||
shape_groups = { stair = 1, legacy = 1 },
|
||||
eighths = 3, -- 3/8 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ 0, -0.5, -0.5, 0.5, 0, 0.5 },
|
||||
{ 0, 0, 0, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("stair", {
|
||||
name_format = "stair_%s",
|
||||
description = "@1 Stair",
|
||||
groups = { morelights_supports_stairlight = 1 },
|
||||
shape_groups = { stair = 1, legacy = 1, stairs_legacy = 1 },
|
||||
eighths = 6, -- 3/4 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, 0, 0.5 },
|
||||
{ -0.5, 0, 0, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("stair_inner", {
|
||||
name_format = "stair_%s_inner",
|
||||
description = "@1 Inner Stair",
|
||||
shape_groups = { stair = 1, legacy = 1, stairs_legacy = 1 },
|
||||
eighths = 7, -- 7/8 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, 0, 0.5 },
|
||||
{ -0.5, 0, 0, 0.5, 0.5, 0.5 },
|
||||
{ -0.5, 0, -0.5, 0, 0.5, 0 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("stair_outer", {
|
||||
name_format = "stair_%s_outer",
|
||||
description = "@1 Outer Stair",
|
||||
shape_groups = { stair = 1, legacy = 1, stairs_legacy = 1 },
|
||||
eighths = 5, -- 5/8 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, 0, 0.5 },
|
||||
{ -0.5, 0, 0, 0, 0.5, 0.5 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("stair_alt_1", {
|
||||
name_format = "stair_%s_alt_1",
|
||||
description = "@1 1/16 Alt Stair",
|
||||
groups = { morelights_supports_stairlight = 1 },
|
||||
shape_groups = { stair = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/16 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.0625, -0.5, 0.5, 0, 0 },
|
||||
{ -0.5, 0.4375, 0, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("stair_alt_2", {
|
||||
name_format = "stair_%s_alt_2",
|
||||
description = "@1 1/8 Alt Stair",
|
||||
groups = { morelights_supports_stairlight = 1 },
|
||||
shape_groups = { stair = 1, legacy = 1 },
|
||||
eighths = 1, -- 1/8 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.125, -0.5, 0.5, 0, 0 },
|
||||
{ -0.5, 0.375, 0, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("stair_alt_4", {
|
||||
name_format = "stair_%s_alt_4",
|
||||
description = "@1 1/4 Alt Stair",
|
||||
groups = { morelights_supports_stairlight = 1 },
|
||||
shape_groups = { stair = 1, legacy = 1 },
|
||||
eighths = 2, -- 1/4 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.25, -0.5, 0.5, 0, 0 },
|
||||
{ -0.5, 0.25, 0, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
stairsplus.api.register_shape("stair_alt_8", {
|
||||
name_format = "stair_%s_alt_8",
|
||||
aliases = { "stair_%s_alt" },
|
||||
description = "@1 1/2 Alt Stair",
|
||||
groups = { morelights_supports_stairlight = 1 },
|
||||
shape_groups = { stair = 1, legacy = 1 },
|
||||
eighths = 4, -- 1/2 nodes
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -0.5, -0.5, -0.5, 0.5, 0, 0 },
|
||||
{ -0.5, 0, 0, 0.5, 0.5, 0.5 },
|
||||
},
|
||||
},
|
||||
})
|
Binary file not shown.
After Width: | Height: | Size: 574 B |
Binary file not shown.
After Width: | Height: | Size: 474 B |
Binary file not shown.
After Width: | Height: | Size: 439 B |
BIN
mods/moreblocks/stairsplus/textures/stairsplus_saw_button.png
Normal file
BIN
mods/moreblocks/stairsplus/textures/stairsplus_saw_button.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
12
mods/moreblocks/stairsplus/util.lua
Normal file
12
mods/moreblocks/stairsplus/util.lua
Normal file
|
@ -0,0 +1,12 @@
|
|||
local util = {}
|
||||
|
||||
local table_is_empty = futil.table.is_empty
|
||||
|
||||
function util.item_has_metadata(item)
|
||||
item = type(item) == "userdata" and item or ItemStack(item)
|
||||
local meta = item:get_meta()
|
||||
|
||||
return not table_is_empty(meta:to_table().fields)
|
||||
end
|
||||
|
||||
stairsplus.util = util
|
Loading…
Add table
Add a link
Reference in a new issue