spider.lua 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. local S = mobs.intllib
  2. local get_velocity = function(self)
  3. local v = self.object:get_velocity()
  4. -- sanity check
  5. if not v then return 0 end
  6. return (v.x * v.x + v.z * v.z) ^ 0.5
  7. end
  8. -- Spider by AspireMint (CC-BY-SA 3.0 license)
  9. mobs:register_mob("mobs_monster:spider", {
  10. --docile_by_day = true,
  11. group_attack = true,
  12. type = "monster",
  13. passive = false,
  14. attack_type = "dogfight",
  15. reach = 2,
  16. damage = 3,
  17. hp_min = 10,
  18. hp_max = 30,
  19. armor = 200,
  20. collisionbox = {-0.8, -0.5, -0.8, 0.8, 0, 0.8},
  21. visual_size = {x = 1, y = 1},
  22. visual = "mesh",
  23. mesh = "mobs_spider.b3d",
  24. textures = {
  25. {"mobs_spider_mese.png"},
  26. {"mobs_spider_orange.png"},
  27. {"mobs_spider_snowy.png"},
  28. {"mobs_spider_grey.png"},
  29. {"mobs_spider_crystal.png"},
  30. },
  31. makes_footstep_sound = false,
  32. sounds = {
  33. random = "mobs_spider",
  34. attack = "mobs_spider",
  35. },
  36. walk_velocity = 1,
  37. run_velocity = 3,
  38. jump = true,
  39. view_range = 15,
  40. floats = 0,
  41. drops = {
  42. {name = "farming:string", chance = 1, min = 0, max = 2},
  43. },
  44. water_damage = 5,
  45. lava_damage = 5,
  46. light_damage = 0,
  47. animation = {
  48. speed_normal = 15,
  49. speed_run = 20,--15,
  50. stand_start = 0,
  51. stand_end = 0,
  52. walk_start = 1,
  53. walk_end = 21,
  54. run_start = 1,
  55. run_end = 21,
  56. punch_start = 25,
  57. punch_end = 45,
  58. },
  59. -- what kind of spider are we spawning?
  60. on_spawn = function(self)
  61. local pos = self.object:get_pos() ; pos.y = pos.y - 1
  62. -- snowy spider
  63. if minetest.find_node_near(pos, 1,
  64. {"default:snow", "default:snowblock", "default:dirt_with_snow"}) then
  65. self.base_texture = {"mobs_spider_snowy.png"}
  66. self.object:set_properties({textures = self.base_texture})
  67. self.docile_by_day = true
  68. -- tarantula
  69. elseif minetest.find_node_near(pos, 1,
  70. {"default:dirt_with_rainforest_litter", "default:jungletree"}) then
  71. self.base_texture = {"mobs_spider_orange.png"}
  72. self.object:set_properties({textures = self.base_texture})
  73. self.docile_by_day = true
  74. -- grey spider
  75. elseif minetest.find_node_near(pos, 1,
  76. {"default:stone", "default:gravel"}) then
  77. self.base_texture = {"mobs_spider_grey.png"}
  78. self.object:set_properties({textures = self.base_texture})
  79. -- mese spider
  80. elseif minetest.find_node_near(pos, 1,
  81. {"default:mese", "default:stone_with_mese"}) then
  82. self.base_texture = {"mobs_spider_mese.png"}
  83. self.object:set_properties({textures = self.base_texture})
  84. elseif minetest.find_node_near(pos, 1,
  85. {"ethereal:crystal_dirt", "ethereal:crystal_spike"}) then
  86. self.base_texture = {"mobs_spider_crystal.png"}
  87. self.object:set_properties({textures = self.base_texture})
  88. self.docile_by_day = true
  89. self.drops = {
  90. {name = "farming:string", chance = 1, min = 0, max = 2},
  91. {name = "ethereal:crystal_spike", chance = 15, min = 1, max = 2},
  92. }
  93. end
  94. return true -- run only once, false/nil runs every activation
  95. end,
  96. -- custom function to make spiders climb vertical facings
  97. do_custom = function(self, dtime)
  98. -- quarter second timer
  99. self.spider_timer = (self.spider_timer or 0) + dtime
  100. if self.spider_timer < 0.25 then
  101. return
  102. end
  103. self.spider_timer = 0
  104. -- need to be stopped to go onwards
  105. if get_velocity(self) > 0.5 then
  106. self.disable_falling = nil
  107. return
  108. end
  109. local pos = self.object:get_pos()
  110. local yaw = self.object:get_yaw()
  111. -- sanity check
  112. if not yaw then return end
  113. pos.y = pos.y + self.collisionbox[2] - 0.2
  114. local dir_x = -math.sin(yaw) * (self.collisionbox[4] + 0.5)
  115. local dir_z = math.cos(yaw) * (self.collisionbox[4] + 0.5)
  116. local nod = minetest.get_node_or_nil({
  117. x = pos.x + dir_x,
  118. y = pos.y + 0.5,
  119. z = pos.z + dir_z
  120. })
  121. -- get current velocity
  122. local v = self.object:get_velocity()
  123. -- can only climb solid facings
  124. if not nod or not minetest.registered_nodes[nod.name]
  125. or not minetest.registered_nodes[nod.name].walkable then
  126. self.disable_falling = nil
  127. v.y = 0
  128. self.object:set_velocity(v)
  129. return
  130. end
  131. --print ("----", nod.name, self.disable_falling, dtime)
  132. -- turn off falling if attached to facing
  133. self.disable_falling = true
  134. -- move up facing
  135. v.x = 0 ; v.y = 0
  136. v.y = self.jump_height
  137. mobs:set_animation(self, "jump")
  138. self.object:set_velocity(v)
  139. end,
  140. -- make spiders jump at you on attack
  141. custom_attack = function(self, pos)
  142. local vel = self.object:get_velocity()
  143. self.object:set_velocity({
  144. x = vel.x * self.run_velocity,
  145. y = self.jump_height * 1.5,
  146. z = vel.z * self.run_velocity
  147. })
  148. self.pausetimer = 0.5
  149. return true -- continue rest of attack function
  150. end
  151. })
  152. if not mobs.custom_spawn_monster then
  153. -- above ground spawn
  154. mobs:spawn({
  155. name = "mobs_monster:spider",
  156. nodes = {
  157. "default:dirt_with_rainforest_litter", "default:snowblock",
  158. "default:snow", "ethereal:crystal_dirt", "ethereal:cold_dirt"
  159. },
  160. min_light = 0,
  161. max_light = 8,
  162. chance = 7000,
  163. active_object_count = 1,
  164. min_height = 25,
  165. max_height = 31000,
  166. })
  167. -- below ground spawn
  168. mobs:spawn({
  169. name = "mobs_monster:spider",
  170. nodes = {"default:stone_with_mese", "default:mese", "default:stone"},
  171. min_light = 0,
  172. max_light = 7,
  173. chance = 7000,
  174. active_object_count = 1,
  175. min_height = -31000,
  176. max_height = -40,
  177. })
  178. end
  179. mobs:register_egg("mobs_monster:spider", S("Spider"), "mobs_cobweb.png", 1)
  180. mobs:alias_mob("mobs_monster:spider2", "mobs_monster:spider") -- compatibility
  181. mobs:alias_mob("mobs:spider", "mobs_monster:spider")
  182. -- cobweb
  183. minetest.register_node(":mobs:cobweb", {
  184. description = S("Cobweb"),
  185. drawtype = "plantlike",
  186. visual_scale = 1.2,
  187. tiles = {"mobs_cobweb.png"},
  188. inventory_image = "mobs_cobweb.png",
  189. paramtype = "light",
  190. sunlight_propagates = true,
  191. liquid_viscosity = 11,
  192. liquidtype = "source",
  193. liquid_alternative_flowing = "mobs:cobweb",
  194. liquid_alternative_source = "mobs:cobweb",
  195. liquid_renewable = false,
  196. liquid_range = 0,
  197. walkable = false,
  198. groups = {snappy = 1, disable_jump = 1},
  199. drop = "farming:string",
  200. sounds = default.node_sound_leaves_defaults(),
  201. })
  202. minetest.register_craft({
  203. output = "mobs:cobweb",
  204. recipe = {
  205. {"farming:string", "", "farming:string"},
  206. {"", "farming:string", ""},
  207. {"farming:string", "", "farming:string"},
  208. }
  209. })