hardware_fw.lua 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. laptop.node_config = {}
  2. local function on_construct(pos)
  3. laptop.mtos_cache:free(pos)
  4. local mtos = laptop.os_get(pos)
  5. local node = minetest.get_node(pos)
  6. local hwdef = laptop.node_config[node.name]
  7. if hwdef.custom_theme then -- initial only
  8. mtos:set_theme(hwdef.custom_theme)
  9. end
  10. if hwdef.hw_state then
  11. mtos[hwdef.hw_state](mtos)
  12. else
  13. mtos:power_off()
  14. end
  15. end
  16. local function on_punch(pos, node, puncher)
  17. local mtos = laptop.os_get(pos)
  18. local punch_item = puncher:get_wielded_item()
  19. local is_compatible = false
  20. if punch_item then
  21. local def = punch_item:get_definition()
  22. for group, _ in pairs(def.groups) do
  23. if mtos.bdev:is_hw_capability(group) then
  24. is_compatible = true
  25. end
  26. end
  27. end
  28. if is_compatible then
  29. local slot = mtos.bdev:get_removable_disk()
  30. -- swap
  31. puncher:set_wielded_item(slot.stack)
  32. -- reload OS
  33. slot:reload(punch_item)
  34. laptop.mtos_cache:sync_and_free(mtos)
  35. for k,v in pairs(laptop.os_get(mtos.pos)) do
  36. mtos[k] = v
  37. end
  38. mtos:pass_to_app("punched_by_removable", true, puncher, punch_item)
  39. return
  40. end
  41. local hwdef = laptop.node_config[node.name]
  42. if hwdef.next_node then
  43. local hwdef_next = laptop.node_config[hwdef.next_node]
  44. if hwdef_next.hw_state then
  45. mtos[hwdef_next.hw_state](mtos, hwdef.next_node)
  46. else
  47. mtos:swap_node(hwdef.next_node)
  48. mtos:save()
  49. end
  50. end
  51. end
  52. local function on_receive_fields(pos, formname, fields, sender)
  53. local mtos = laptop.os_get(pos)
  54. mtos:pass_to_app("receive_fields_func", true, sender, fields)
  55. end
  56. local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
  57. local mtos = laptop.os_get(pos)
  58. return mtos:pass_to_app("allow_metadata_inventory_move", false, player, from_list, from_index, to_list, to_index, count) or 0
  59. end
  60. local function allow_metadata_inventory_put(pos, listname, index, stack, player)
  61. local mtos = laptop.os_get(pos)
  62. local def = stack:get_definition()
  63. local allowed_stacksize = 0
  64. if def then
  65. for group, _ in pairs(def.groups) do
  66. if mtos.bdev:is_hw_capability(group) then
  67. allowed_stacksize = 1
  68. end
  69. end
  70. end
  71. return mtos:pass_to_app("allow_metadata_inventory_put", false, player, listname, index, stack) or allowed_stacksize
  72. end
  73. local function allow_metadata_inventory_take(pos, listname, index, stack, player)
  74. local mtos = laptop.os_get(pos)
  75. return mtos:pass_to_app("allow_metadata_inventory_take", false, player, listname, index, stack) or 1 -- by default removal allowed
  76. end
  77. local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
  78. local mtos = laptop.os_get(pos)
  79. mtos:pass_to_app("on_metadata_inventory_move", true, player, from_list, from_index, to_list, to_index, count)
  80. end
  81. local function on_metadata_inventory_put(pos, listname, index, stack, player)
  82. local mtos = laptop.os_get(pos)
  83. mtos:pass_to_app("on_metadata_inventory_put", true, player, listname, index, stack)
  84. end
  85. local function on_metadata_inventory_take(pos, listname, index, stack, player)
  86. local mtos = laptop.os_get(pos)
  87. mtos:pass_to_app("on_metadata_inventory_take", true, player, listname, index, stack)
  88. end
  89. local function on_timer(pos, elapsed)
  90. local mtos = laptop.os_get(pos)
  91. return mtos:pass_to_app("on_timer", true, nil, elapsed)
  92. end
  93. local function after_place_node(pos, placer, itemstack, pointed_thing)
  94. local save = minetest.deserialize(itemstack:get_meta():get_string("laptop_metadata"))
  95. if not save then
  96. return
  97. end
  98. -- Backwards compatibility code
  99. if not save.ram_disk and not save.hard_disk then
  100. laptop.mtos_cache:free(pos)
  101. local meta = minetest.get_meta(pos)
  102. meta:from_table({fields = save.fields})
  103. for invname, inv in pairs(save.invlist) do
  104. meta:get_inventory():set_list(invname, inv)
  105. end
  106. itemstack:clear()
  107. return
  108. end
  109. -- Backwards compatibility code end
  110. local mtos = laptop.os_get(pos)
  111. mtos.bdev.ram_disk = save.ram_disk or mtos.bdev.ram_disk
  112. mtos.bdev.hard_disk = save.hard_disk or mtos.bdev.hard_disk
  113. if save.removable_disk then
  114. local removable = mtos.bdev:get_removable_disk()
  115. removable:reload(ItemStack(save.removable_disk))
  116. end
  117. mtos.bdev:sync()
  118. itemstack:clear()
  119. end
  120. local function preserve_metadata(pos, oldnode, oldmetadata, drops)
  121. local mtos = laptop.os_get(pos)
  122. if not mtos then
  123. return
  124. end
  125. laptop.mtos_cache:sync_and_free(mtos)
  126. local removable = mtos.bdev:get_removable_disk()
  127. local save = {
  128. laptop_ram = mtos.bdev:get_ram_disk(),
  129. hard_disk = mtos.bdev:get_hard_disk(),
  130. removable_disk = removable.stack and removable.stack:to_string()
  131. }
  132. local item_name = minetest.registered_items[oldnode.name].drop or oldnode.name
  133. for _, stack in pairs(drops) do
  134. if stack:get_name() == item_name then
  135. stack:get_meta():set_string("laptop_metadata", minetest.serialize(save))
  136. end
  137. end
  138. end
  139. function laptop.register_hardware(name, hwdef)
  140. local default_nodename = name.."_"..hwdef.sequence[1]
  141. for idx, variant in ipairs(hwdef.sequence) do
  142. local nodename = name.."_"..variant
  143. local def = table.copy(hwdef.node_defs[variant])
  144. def.description = hwdef.description
  145. -- drop the item visible in inventory
  146. if def.groups then
  147. def.groups = table.copy(def.groups)
  148. else
  149. def.groups = {choppy=2, oddly_breakably_by_hand=2, dig_immediate = 2}
  150. end
  151. if nodename ~= default_nodename then
  152. def.drop = default_nodename
  153. def.groups.not_in_creative_inventory = 1
  154. end
  155. if def.paramtype2 == "colorfacedir" and not def.palette then
  156. def.palette = "unifieddyes_palette_redviolets.png" --TODO: Replace by own laptop specific PNG file
  157. end
  158. -- needed to transfer content to item if place or dig laptop
  159. def.stack_max = 1
  160. def.after_place_node = after_place_node
  161. def.preserve_metadata = preserve_metadata
  162. def.on_punch = on_punch
  163. def.on_construct = on_construct
  164. def.on_receive_fields = on_receive_fields
  165. def.allow_metadata_inventory_move = allow_metadata_inventory_move
  166. def.allow_metadata_inventory_put = allow_metadata_inventory_put
  167. def.allow_metadata_inventory_take = allow_metadata_inventory_take
  168. def.on_metadata_inventory_move = on_metadata_inventory_move
  169. def.on_metadata_inventory_put = on_metadata_inventory_put
  170. def.on_metadata_inventory_take = on_metadata_inventory_take
  171. def.on_timer = on_timer
  172. minetest.register_node(nodename, def)
  173. -- set node configuration for hooks
  174. local merged_hwdef = table.copy(hwdef)
  175. merged_hwdef.name = name
  176. merged_hwdef.nodename = nodename
  177. for k,v in pairs(hwdef.node_defs[variant]) do
  178. merged_hwdef[k] = v
  179. end
  180. local next_seq = hwdef.sequence[idx+1] or hwdef.sequence[1]
  181. local next_node = name.."_"..next_seq
  182. if next_node ~= nodename then
  183. merged_hwdef.next_node = next_node
  184. end
  185. -- Defaults
  186. merged_hwdef.hw_capabilities = merged_hwdef.hw_capabilities or {"hdd", "floppy", "usb", "net", "liveboot"}
  187. laptop.node_config[nodename] = merged_hwdef
  188. end
  189. end