Advertisement
Guest User

n

a guest
Dec 22nd, 2012
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.56 KB | None | 0 0
  1. -- NPC max walk speed
  2. walk_limit = 2
  3.  
  4. --npc just walking around
  5. chillaxin_speed = 1.5
  6. -- Player animation speed
  7. animation_speed = 30
  8.  
  9. -- Player animation blending
  10. -- Note: This is currently broken due to a bug in Irrlicht, leave at 0
  11. animation_blend = 0
  12.  
  13. -- Default player appearance
  14. default_model = "character.x"
  15. available_npc_textures = {
  16.     texture_1 = {"katniss.png", },
  17.     texture_2 = {"knightking.png", },
  18.     texture_3 = {"miner.png", },
  19.     texture_4 = {"golem.png", },
  20.     texture_5 = {"archer.png", },
  21.     texture_6 = {"builder.png", },
  22.     texture_7 = {"hunter.png", },
  23.     texture_8 = {"ninja.png", },
  24.     texture_9 = {"ironknight.png", },
  25.     texture_10 = {"tron.png", },
  26.     texture_11 = {"clonetrooper.png", }
  27. }
  28.  
  29.  
  30. -- Frame ranges for each player model
  31. function player_get_animations(model)
  32.     if model == "character.x" then
  33.         return {
  34.         stand_START = 0,
  35.         stand_END = 79,
  36.         sit_START = 81,
  37.         sit_END = 160,
  38.         lay_START = 162,
  39.         lay_END = 166,
  40.         walk_START = 168,
  41.         walk_END = 187,
  42.         mine_START = 189,
  43.         mine_END = 198,
  44.         walk_mine_START = 200,
  45.         walk_mine_END = 219
  46.         }
  47.     end
  48. end
  49.  
  50. local player_model = {}
  51. local player_anim = {}
  52. local player_sneak = {}
  53. local ANIM_STAND = 1
  54. local ANIM_SIT = 2
  55. local ANIM_LAY = 3
  56. local ANIM_WALK  = 4
  57. local ANIM_WALK_MINE = 5
  58. local ANIM_MINE = 6
  59.  
  60. function player_update_visuals(self)
  61.     --local name = get_player_name()
  62.  
  63.     visual = default_model
  64.     player_anim = 0 -- Animation will be set further below immediately
  65.     --player_sneak[name] = false
  66.     prop = {
  67.         mesh = default_model,
  68.         textures = default_textures,
  69.         textures = available_npc_textures["texture_"..math.random(1,11)],
  70.         visual_size = {x=1, y=1},
  71.     }
  72.     self.object:set_properties(prop)
  73. end
  74.  
  75. NPC_ENTITY = {
  76.     physical = true,
  77.     collisionbox = {-0.3,-1.0,-0.3, 0.3,0.8,0.3},
  78.     visual = "mesh",
  79.     mesh = "character.x",
  80.     textures = {"character.png"},
  81.     player_anim = 0,
  82.     timer = 0,
  83.     turn_timer = 0,
  84.     vec = 0,
  85.     yaw = 0,
  86.     yawwer = 0,
  87.     state = 1,
  88.     jump_timer = 0,
  89.     door_timer = 0,
  90.     attacker = "",
  91.     attacking_timer = 0
  92. }
  93.  
  94. NPC_ENTITY.on_activate = function(self)
  95.     player_update_visuals(self)
  96.     self.anim = player_get_animations(visual)
  97.     self.object:set_animation({x=self.anim.stand_START,y=self.anim.stand_END}, animation_speed_mod, animation_blend)
  98.     self.player_anim = ANIM_STAND
  99.     self.object:setacceleration({x=0,y=-10,z=0})
  100.     self.state = 1
  101. end
  102.  
  103. NPC_ENTITY.on_punch = function(self, puncher)
  104.     for  _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 5)) do
  105.         if not object:is_player() then
  106.             if object:get_luaentity().name == "peaceful_npc:npc" then
  107.                 object:get_luaentity().state = 3
  108.                 object:get_luaentity().attacker = puncher:get_player_name()
  109.             end
  110.         end
  111.     end
  112.     if self.state ~= 3 then
  113.         self.state = 3
  114.         self.attacker = puncher:get_player_name()
  115.     end
  116. end
  117.  
  118. NPC_ENTITY.on_step = function(self, dtime)
  119.     self.timer = self.timer + 0.01
  120.     self.turn_timer = self.turn_timer + 0.01
  121.     self.jump_timer = self.jump_timer + 0.01
  122.     self.door_timer = self.door_timer + 0.01
  123.     self.attacking_timer = self.attacking_timer + 0.01
  124.  
  125.     --collision detection prealpha
  126.     --[[
  127.     for  _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 2)) do
  128.         if object:is_player() then
  129.             compare1 = object:getpos()
  130.             compare2 = self.object:getpos()
  131.             newx = compare2.x - compare1.x
  132.             newz = compare2.z - compare1.z
  133.             print(newx)
  134.             print(newz)
  135.             self.object:setacceleration({x=newx,y=self.object:getacceleration().y,z=newz})
  136.         elseif not object:is_player() then
  137.             if object:get_luaentity().name == "peaceful_npc:npc" then
  138.                 print("moo")
  139.             end
  140.         end
  141.     end
  142.     ]]--
  143.     --set npc to hostile in night, and revert npc back to peaceful in daylight
  144.     if minetest.env:get_timeofday() >= 0 and minetest.env:get_timeofday() < 0.25 and self.state ~= 4 then
  145.         self.state = 4
  146.     elseif minetest.env:get_timeofday() > 0.25 and self.state == 4 then
  147.         self.state = 1
  148.     end
  149.     --if mob is not in attack or hostile mode, set mob to walking or standing
  150.     if self.state < 3 then
  151.         if self.timer > math.random(1,20) then
  152.             self.state = math.random(1,2)
  153.             self.timer = 0
  154.         end
  155.     end
  156.     --STANDING
  157.     if self.state == 1 then
  158.         self.yawwer = true
  159.         for  _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 3)) do
  160.             if object:is_player() then
  161.                 self.yawwer = false
  162.                 NPC = self.object:getpos()
  163.                 PLAYER = object:getpos()
  164.                 self.vec = {x=PLAYER.x-NPC.x, y=PLAYER.y-NPC.y, z=PLAYER.z-NPC.z}
  165.                 self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2
  166.                 if PLAYER.x > NPC.x then
  167.                     self.yaw = self.yaw + math.pi
  168.                 end
  169.                 self.yaw = self.yaw - 2
  170.                 self.object:setyaw(self.yaw)
  171.             end
  172.         end
  173.  
  174.         if self.turn_timer > math.random(1,4) and yawwer == true then
  175.             self.yaw = 360 * math.random()
  176.             self.object:setyaw(self.yaw)
  177.             self.turn_timer = 0
  178.         end
  179.         self.object:setvelocity({x=0,y=self.object:getvelocity().y,z=0})
  180.         if self.player_anim ~= ANIM_STAND then
  181.             self.anim = player_get_animations(visual)
  182.             self.object:set_animation({x=self.anim.stand_START,y=self.anim.stand_END}, animation_speed_mod, animation_blend)
  183.             self.player_anim = ANIM_STAND
  184.         end
  185.     end
  186.     --WALKING
  187.     if self.state == 2 then
  188.         if self.present_timer == 1 then
  189.             minetest.env:add_item(self.object:getpos(),"default:coal_lump")
  190.             self.present_timer = 0
  191.         end
  192.         if self.direction ~= nil then
  193.             self.object:setvelocity({x=self.direction.x*chillaxin_speed,y=self.object:getvelocity().y,z=self.direction.z*chillaxin_speed})
  194.         end
  195.         if self.turn_timer > math.random(1,4) then
  196.             self.yaw = 360 * math.random()
  197.             self.object:setyaw(self.yaw)
  198.             self.turn_timer = 0
  199.             self.direction = {x = math.sin(self.yaw)*-1, y = -10, z = math.cos(self.yaw)}
  200.             --self.object:setvelocity({x=self.direction.x,y=self.object:getvelocity().y,z=direction.z})
  201.             --self.object:setacceleration(self.direction)
  202.         end
  203.         if self.player_anim ~= ANIM_WALK then
  204.             self.anim = player_get_animations(visual)
  205.             self.object:set_animation({x=self.anim.walk_START,y=self.anim.walk_END}, animation_speed_mod, animation_blend)
  206.             self.player_anim = ANIM_WALK
  207.         end
  208.         --open a door [alpha]
  209.         if self.direction ~= nil then
  210.             if self.door_timer > 2 then
  211.                 local is_a_door = minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y,z=self.object:getpos().z + self.direction.z}).name
  212.                 if is_a_door == "doors:door_wood_t_1" then
  213.                     minetest.env:punch_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z})
  214.                     self.door_timer = 0
  215.                 end
  216.                 local is_in_door = minetest.env:get_node(self.object:getpos()).name
  217.                 if is_in_door == "doors:door_wood_t_1" then
  218.                     minetest.env:punch_node(self.object:getpos())
  219.                 end
  220.             end
  221.         end
  222.         --jump
  223.         if self.direction ~= nil then
  224.             if self.jump_timer > 0.3 then
  225.                 if minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name ~= "air" then
  226.                     self.object:setvelocity({x=self.object:getvelocity().x,y=5,z=self.object:getvelocity().z})
  227.                     self.jump_timer = 0
  228.                 end
  229.             end
  230.         end
  231.     end
  232.     --WANDERING CONSTANTLY AT NIGHT
  233.     if self.state == 4 then
  234.         if self.player_anim ~= ANIM_WALK then
  235.             self.anim = player_get_animations(visual)
  236.             self.object:set_animation({x=self.anim.walk_START,y=self.anim.walk_END}, animation_speed_mod, animation_blend)
  237.             self.player_anim = ANIM_WALK
  238.         end
  239.         for  _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 12)) do
  240.             if object:is_player() then
  241.                 if object:get_hp() > 0 then
  242.                     NPC = self.object:getpos()
  243.                     PLAYER = object:getpos()
  244.                     self.vec = {x=PLAYER.x-NPC.x, y=PLAYER.y-NPC.y, z=PLAYER.z-NPC.z}
  245.                     self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2
  246.                     if PLAYER.x > NPC.x then
  247.                         self.yaw = self.yaw + math.pi
  248.                     end
  249.                     self.yaw = self.yaw - 2
  250.                     self.object:setyaw(self.yaw)
  251.                     self.direction = {x = math.sin(self.yaw)*-1, y = 0, z = math.cos(self.yaw)}
  252.                     if self.direction ~= nil then
  253.                         self.object:setvelocity({x=self.direction.x*2.5,y=self.object:getvelocity().y,z=self.direction.z*2.5})
  254.                     end
  255.                     --jump over obstacles
  256.                     if self.jump_timer > 0.3 then
  257.                         if minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name ~= "air" then
  258.                             self.object:setvelocity({x=self.object:getvelocity().x,y=5,z=self.object:getvelocity().z})
  259.                             self.jump_timer = 0
  260.                         end
  261.                     end
  262.                     if self.direction ~= nil then
  263.                         if self.door_timer > 2 then
  264.                             local is_a_door = minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y,z=self.object:getpos().z + self.direction.z}).name
  265.                             if is_a_door == "doors:door_wood_t_1" then
  266.                                 minetest.env:punch_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z})
  267.                                 self.door_timer = 0
  268.                             end
  269.                             local is_in_door = minetest.env:get_node(self.object:getpos()).name
  270.                             if is_in_door == "doors:door_wood_t_1" then
  271.                                 minetest.env:punch_node(self.object:getpos())
  272.                             end
  273.                         end
  274.                     end
  275.                 --return
  276.                 end
  277.             elseif not object:is_player() then
  278.                 self.state = 1
  279.                 self.attacker = ""
  280.             end
  281.         end
  282.         if self.direction ~= nil then
  283.             self.object:setvelocity({x=self.direction.x,y=self.object:getvelocity().y,z=self.direction.z})
  284.         end
  285.         if self.turn_timer > math.random(1,4) then
  286.             self.yaw = 360 * math.random()
  287.             self.object:setyaw(self.yaw)
  288.             self.turn_timer = 0
  289.             self.direction = {x = math.sin(self.yaw)*-1, y = -10, z = math.cos(self.yaw)}
  290.         end
  291.         if self.player_anim ~= ANIM_WALK then
  292.             self.anim = player_get_animations(visual)
  293.             self.object:set_animation({x=self.anim.walk_START,y=self.anim.walk_END}, animation_speed_mod, animation_blend)
  294.             self.player_anim = ANIM_WALK
  295.         end
  296.         --open a door [alpha]
  297.         if self.direction ~= nil then
  298.             if self.door_timer > 2 then
  299.                 local is_a_door = minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y,z=self.object:getpos().z + self.direction.z}).name
  300.                 if is_a_door == "doors:door_wood_t_1" then
  301.                     --print("door")
  302.                     minetest.env:punch_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z})
  303.                     self.door_timer = 0
  304.                 end
  305.                 local is_in_door = minetest.env:get_node(self.object:getpos()).name
  306.                 --print(dump(is_in_door))
  307.                 if is_in_door == "doors:door_wood_t_1" then
  308.                     minetest.env:punch_node(self.object:getpos())
  309.                 end
  310.             end
  311.         end
  312.         --jump
  313.         if self.direction ~= nil then
  314.             if self.jump_timer > 0.3 then
  315.                 --print(dump(minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z})))
  316.                 if minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name ~= "air" then
  317.                     self.object:setvelocity({x=self.object:getvelocity().x,y=5,z=self.object:getvelocity().z})
  318.                     self.jump_timer = 0
  319.                 end
  320.             end
  321.         end
  322.     end
  323. end
  324.  
  325. minetest.register_entity("peaceful_npc:npc", NPC_ENTITY)
  326.  
  327. minetest.register_node("peaceful_npc:spawnegg", {
  328.     description = "spawnegg",
  329.     image = "mobspawnegg.png",
  330.     inventory_image = "mobspawnegg.png",
  331.     wield_image = "mobspawnegg.png",
  332.     paramtype = "light",
  333.     tiles = {"spawnegg.png"},
  334.     is_ground_content = true,
  335.     drawtype = "glasslike",
  336.     groups = {crumbly=3},
  337.     selection_box = {
  338.         type = "fixed",
  339.         fixed = {0,0,0,0,0,0}
  340.     },
  341.     sounds = default.node_sound_dirt_defaults(),
  342.     on_place = function(itemstack, placer, pointed)
  343.         pos = pointed.above
  344.         pos.y = pos.y + 1
  345.         minetest.env:add_entity(pointed.above,"peaceful_npc:npc")
  346.     end
  347. })
  348.  
  349. use_mesecons = false
  350.  
  351. function npc_spawner(pos)
  352.     minetest.env:add_entity({x=pos.x+math.random(-1,1),y=pos.y+math.random(2,3),z=pos.z+math.random(-1,1)}, "peaceful_npc:npc")
  353. end
  354. if use_mesecons == true then
  355.     minetest.register_node("peaceful_npc:npc_spawner", {
  356.         description = "NPC Portal",
  357.         drawtype = "glasslike",
  358.         groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
  359.         sounds = default.node_sound_wood_defaults(),
  360.         tiles = {"peaceful_npc_spawner.png"},
  361.         sunlight_propagates = true,
  362.         paramtype = "light",
  363.         mesecons = {effector = {
  364.             action_on = npc_spawner
  365.         }}
  366.     })
  367. end
  368.  
  369. if use_mesecons == false then
  370.     minetest.register_node("peaceful_npc:npc_spawner", {
  371.         description = "NPC Portal",
  372.         drawtype = "glasslike",
  373.         groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
  374.         sounds = default.node_sound_wood_defaults(),
  375.         tiles = {"peaceful_npc_spawner.png"},
  376.         sunlight_propagates = true,
  377.         paramtype = "light",
  378.     })
  379.     minetest.register_abm({
  380.         nodenames = {"peaceful_npc:npc_spawner"},
  381.         interval = 600.0,
  382.         chance = 1,
  383.         action = function(pos)
  384.             npc_spawner(pos)
  385.         end,
  386.     })
  387. end
  388.  
  389. --Make the NPCs die above a limit
  390. local list = minetest.env:get_objects_in_radius(pos, radius);
  391. local count = #list;
  392. local MAX_ENTS = 20;
  393.  
  394. if (count > MAX_ENTS) then
  395.     for i = (MAX_ENTS + 1), count do
  396.         if (list[i]:get_name() == "peaceful_npc:npc") then
  397.             list[i]:remove();
  398.         end
  399.     end
  400. end
  401.  
  402. check list[i]:get_name() ~= "peaceful_npc:npc"
  403. --[[
  404. This causes mobs to cluster together DONTA JLAFGJKAS USE IRT
  405. --use pilzadam's spawning algo
  406. npcs = {}
  407. npcs.spawning_mobs = {}
  408.     function npcs:register_spawn(name, nodes, max_light, min_light, chance, mobs_per_30_block_radius, max_height)
  409.         npcs.spawning_mobs[name] = true
  410.         minetest.register_abm({
  411.         nodenames = nodes,
  412.         neighbors = nodes,
  413.         interval = 30,
  414.         chance = chance,
  415.         action = function(pos, node)
  416.             if not npcs.spawning_mobs[name] then
  417.                 return
  418.             end
  419.             pos.y = pos.y+1
  420.             if not minetest.env:get_node_light(pos) then
  421.                 return
  422.             end
  423.             if minetest.env:get_node_light(pos) > max_light then
  424.                 return
  425.             end
  426.             if minetest.env:get_node_light(pos) < min_light then
  427.                 return
  428.             end
  429.             if pos.y > max_height then
  430.                 return
  431.             end
  432.             if minetest.env:get_node(pos).name ~= "air" then
  433.                 return
  434.             end
  435.             pos.y = pos.y+1
  436.             if minetest.env:get_node(pos).name ~= "air" then
  437.                 return
  438.             end
  439.  
  440.             local count = 0
  441.             for _,obj in pairs(minetest.env:get_objects_inside_radius(pos, 30)) do
  442.                 if obj:is_player() then
  443.                     return
  444.                 elseif obj:get_luaentity() and obj:get_luaentity().name == name then
  445.                     count = count+1
  446.                 end
  447.             end
  448.             if count > mobs_per_30_block_radius then
  449.                 return
  450.             end
  451.  
  452.             if minetest.setting_getbool("display_mob_spawn") then
  453.                 minetest.chat_send_all("[NPCs] Add "..name.." at "..minetest.pos_to_string(pos))
  454.             end
  455.             minetest.env:add_entity(pos, name)
  456.         end
  457.     })
  458. end
  459.  
  460. npcs:register_spawn("peaceful_npc:npc", {"default:dirt_with_grass"}, 16, -1, 500, 10, 31000)
  461. ]]--
  462.  
  463. minetest.register_craft({
  464.     output = 'peaceful_npc:npc_spawner',
  465.     recipe = {
  466.         {'default:mese_block', 'default:glass', 'default:mese_block'},
  467.         {'default:glass', 'default:mese_crystal', 'default:glass'},
  468.         {'default:mese_block', 'default:glass', 'default:mese_block'},
  469.     }
  470. })
  471.  
  472. minetest.register_craft({
  473.     output = 'peaceful_npc:spawnegg',
  474.     recipe = {
  475.         {'default:mese_crystal', 'default:glass', 'default:mese_crystal'},
  476.         {'default:glass', 'default:coal_lump', 'default:glass'},
  477.         {'default:mese_crystal', 'default:glass', 'default:mese_crystal'},
  478.     }
  479. })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement