123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- local function goblin_debug(obj)
- local pos = core.pos_to_string(obj.last_job)
- local formspec =
- 'formspec_version[7]'..
- 'size[12,8]'..
- 'background[-1,-1;14,10;lobby_button_bg.png]'..
- 'label[3,1;Goblin state: '..obj.state..'.]'..
- 'label[3,2;Goblin health: '..obj.health..'.]'..
- 'label[3,3;Goblin old pos: '..pos..'.]'..
- 'button_exit[6,4;4,1;exit;Exit]'
- return formspec
- end
- core.register_entity('kobo:goblin_rogue', {
- initial_properties = {
- visual = 'mesh',
- mesh = 'kobo_goblin.obj',
- visual_size = {x=10, y=10},
- physical = true,
- collide_with_objects = false,
- collisionbox = {-.125, -.5, -.125, .125, -.125, .125},
- textures = {'kobo_goblin_rogue.png'},
- automatic_face_movement_dir = 0.0,
- },
- on_activate = function(self, staticdata, dtime_s)
- local data = core.deserialize(staticdata)
- if data then
- self.node_timer = data.node_timer
- self.state = data.state
- self.path = data.path
- self.step = data.step
- self.last_job = data.last_job
- self.health = data.health
- self.wander_count = data.wander_count
- else
- self.last_job = self.object:get_pos()
- self.state = 'idle'
- self.step = 0
- self.health = 40
- self.wander_count = 0
- end
- local dir = vector.random_direction()
- local clean_dir = vector.multiply(dir, {x=1, y=0, z=1})
- self.object:set_velocity(clean_dir)
- self.last_job = self.object:get_pos()
- end,
- get_staticdata = function(self)
- local data = {}
- data.node_timer = self.node_timer
- data.state = self.state
- data.path = self.path
- data.step = self.step
- data.last_job = self.last_job
- data.health = self.health
- data.wander_count = self.wander_count
- return core.serialize(data)
- end,
- on_step = function(self, dtime, moveresults)
- self.node_timer = (self.node_timer or 0) + dtime
- if self.node_timer > 1 then
- self.node_timer = 0
- if self.state == 'idle' then --Find a building to ravage
- local self_pos = vector.add(self.object:get_pos(), {x=0, y=1, z=0})
- local player_building = core.find_node_near(self_pos, 25, 'group:player_building')
- if player_building then
- local looting_spot = core.find_node_near(player_building, 1, 'air', true)
- local path = core.find_path(self_pos, vector.add(looting_spot, {x=0, y=1, z=0}), 5, 1, 1)
- if path then
- self.path = path
- self.step = 2
- self.state = 'traveling'
- else --Make the unit wander around for a while.
- self.state = 'idle'
- end
- else --Didn't find a player building, look for a goblin base
- local self_pos = vector.add(self.object:get_pos(), {x=0, y=1, z=0})
- local goblin_base = core.find_node_near(self_pos, 25, 'kobo:goblin_base')
- if goblin_base then
- local home = core.find_node_near(goblin_base, 1, 'air', true)
- local path = core.find_path(self_pos, vector.add(home, {x=0, y=1, z=0}), 5, 1, 1)
- if path then
- self.path = path
- self.step = 2
- self.state = 'traveling'
- else --Make the unit wander around for a while.
- self.state = 'idle'
- end
- else
- local dir = vector.random_direction()
- local clean_dir = vector.multiply(dir, {x=1, y=0, z=1})
- self.object:set_velocity(clean_dir)
- self.state = 'wandering'
- self.last_job = self_pos
- end
- end
- elseif self.state == 'traveling' then
- if #self.path > (self.step - 1) then
- local pos = self.object:get_pos()
- local perhaps = vector.direction(pos, self.path[self.step])
- self.object:set_velocity({x = perhaps.x, y = 0, z = perhaps.z})
- self.step = self.step + 1
- else
- local self_pos = vector.round(self.object:get_pos())
- local building = core.find_node_near(self_pos, 1, 'group:player_building', true)
- local goblin_base = core.find_node_near(self_pos, 1, 'kobo:goblin_base', true)
- if building then
- self.object:set_velocity({x=0, y=0, z=0})
- self.state = 'working'
- self.last_job = building
- elseif goblin_base then
- local goblin_resources = kobo.goblins
- goblin_resources.food = goblin_resources.food + 25
- goblin_resources.lumber= goblin_resources.lumber + 5
- self.object:remove()
- else
- self.state = 'idle'
- end
- end
- elseif self.state == 'working' then
- self.wander_count = 0
- local pos = self.last_job
- local node = core.get_node(pos)
- if core.get_item_group(node.name, 'player_building') > 0 then
- local meta = core.get_meta(pos)
- local health = meta:get_int('health')
- if health > 1 then
- meta:set_int('health', health - 1)
- elseif health <= 1 then
- core.remove_node(pos)
- local goblin_resources = kobo.goblins
- goblin_resources.xp = goblin_resources.xp + 5
- self.state = 'idle'
- end
- end
- elseif self.state == 'wandering' then
- self.wander_count = self.wander_count or 1
- self.step = self.step + 1
- if self.step > 20 then
- self.state = 'idle'
- self.step = 0
- self.wander_count = self.wander_count + 1
- end
- local self_pos = self.object:get_pos()
- if vector.distance(self.last_job, self_pos) < .25 then
- self.state = 'idle'
- end
- if self.wander_count > 20 then
- self.object:remove()
- end
- end
- elseif moveresults.collides then
- local hit_node = moveresults.collisions[1] and moveresults.collisions[1].type == 'node'
- if hit_node then
- local node_pos = moveresults.collisions[1].node_pos
- local node = core.get_node(node_pos)
- if core.get_item_group(node.name, 'player_building') > 0 then
- self.state = 'working'
- self.object:set_velocity({x=0, y=0, z=0})
- self.last_job = node_pos
- elseif node.name == 'kobo:goblin_base' then
- local goblin_resources = kobo.goblins
- goblin_resources.food = goblin_resources.food + 25
- goblin_resources.lumber= goblin_resources.lumber + 5
- self.object:remove()
- else
- local yaw = self.object:get_yaw()
- local x_yaw_random = math.random()
- local z_yaw_random = math.random()
- local new_vel = {
- x = (math.sin(yaw + x_yaw_random) * -1),
- y = 0,
- z = (math.cos(yaw + z_yaw_random) * 1)
- }
- self.object:set_velocity(new_vel)
- self.state = 'idle'
- end
- end
- end
- end,
- on_punch = function(self, puncher)
- self.health = self.health - 1
- if self.health <= 0 then
- self.object:remove()
- end
- end,
- on_deactivate = function(self, removal)
- if removal then
- local pos = self.object:get_pos()
- local tombstone = minetest.add_entity(pos, 'kobo:goblin_tombstone')
- local tombstone_entity = tombstone:get_luaentity()
- tombstone_entity.node_timer = 0
- end
- end,
- on_rightclick = function(self, clicker)
- if core.check_player_privs(clicker, {server = true}) then
- local player_name = clicker:get_player_name()
- core.show_formspec(player_name, 'kobo:goblin_debug', goblin_debug(self))
- end
- end,
- })
|