Advertisement
Guest User

npc

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