local math_pi = math.pi local math_sin = math.sin local math_cos = math.cos local math_random = math.random local HALF_PI = math_pi / 2 local DOUBLE_PI = math_pi * 2 -- localize vector functions local vector_new = vector.new local vector_length = vector.length local vector_multiply = vector.multiply local vector_distance = vector.distance local minetest_yaw_to_dir = minetest.yaw_to_dir local minetest_dir_to_yaw = minetest.dir_to_yaw local DEFAULT_JUMP_HEIGHT = 5 local DEFAULT_FLOAT_SPEED = 4 local DEFAULT_CLIMB_SPEED = 3 --this is a generic float function mobs.float = function(self) local current_velocity = self.object:get_velocity() local goal_velocity = { x = 0, y = DEFAULT_FLOAT_SPEED, z = 0, } local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) new_velocity_addition.x = 0 new_velocity_addition.z = 0 --smooths out mobs a bit if vector_length(new_velocity_addition) >= 0.0001 then self.object:add_velocity(new_velocity_addition) end end --this is a generic climb function mobs.climb = function(self) local current_velocity = self.object:get_velocity() local goal_velocity = { x = 0, y = DEFAULT_CLIMB_SPEED, z = 0, } local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) new_velocity_addition.x = 0 new_velocity_addition.z = 0 --smooths out mobs a bit if vector_length(new_velocity_addition) >= 0.0001 then self.object:add_velocity(new_velocity_addition) end end --[[ _ _ | | | | | | __ _ _ __ __| | | | / _` | '_ \ / _` | | |___| (_| | | | | (_| | \_____/\__,_|_| |_|\__,_| ]] -- move mob in facing direction --this has been modified to be internal --internal = lua (self.yaw) --engine = c++ (self.object:get_yaw()) mobs.set_velocity = function(self, v) local yaw = (self.yaw or 0) local current_velocity = self.object:get_velocity() local goal_velocity = { x = (math_sin(yaw) * -v), y = 0, z = (math_cos(yaw) * v), } local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) if vector_length(new_velocity_addition) > vector_length(goal_velocity) then vector.multiply(new_velocity_addition, (vector_length(goal_velocity) / vector_length(new_velocity_addition))) end new_velocity_addition.y = 0 --smooths out mobs a bit if vector_length(new_velocity_addition) >= 0.0001 then self.object:add_velocity(new_velocity_addition) end end -- calculate mob velocity mobs.get_velocity = function(self) local v = self.object:get_velocity() v.y = 0 if v then return vector_length(v) end return 0 end --make mobs jump mobs.jump = function(self, velocity) if self.object:get_velocity().y ~= 0 or not self.old_velocity or (self.old_velocity and self.old_velocity.y > 0) then return end --fallback velocity to allow modularity velocity = velocity or DEFAULT_JUMP_HEIGHT self.object:add_velocity(vector_new(0,velocity,0)) end --make mobs fall slowly mobs.mob_fall_slow = function(self) local current_velocity = self.object:get_velocity() local goal_velocity = { x = 0, y = -2, z = 0, } local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) new_velocity_addition.x = 0 new_velocity_addition.z = 0 if vector_length(new_velocity_addition) > vector_length(goal_velocity) then vector.multiply(new_velocity_addition, (vector_length(goal_velocity) / vector_length(new_velocity_addition))) end new_velocity_addition.x = 0 new_velocity_addition.z = 0 --smooths out mobs a bit if vector_length(new_velocity_addition) >= 0.0001 then self.object:add_velocity(new_velocity_addition) end end --[[ _____ _ / ___| (_) \ `--.__ ___ _ __ ___ `--. \ \ /\ / / | '_ ` _ \ /\__/ /\ V V /| | | | | | | \____/ \_/\_/ |_|_| |_| |_| ]]-- --make mobs flop mobs.flop = function(self, velocity) if self.object:get_velocity().y ~= 0 or not self.old_velocity or (self.old_velocity and self.old_velocity.y > 0) then return false end mobs.set_velocity(self, 0) --fallback velocity to allow modularity velocity = velocity or DEFAULT_JUMP_HEIGHT --create a random direction (2d yaw) local dir = DOUBLE_PI * math_random() --create a random force value local force = math_random(0,3) + math_random() --convert the yaw to a direction vector then multiply it times the force local final_additional_force = vector_multiply(minetest_yaw_to_dir(dir), force) --place in the "flop" velocity to make the mob flop final_additional_force.y = velocity self.object:add_velocity(final_additional_force) return true end -- move mob in facing direction --this has been modified to be internal --internal = lua (self.yaw) --engine = c++ (self.object:get_yaw()) mobs.set_swim_velocity = function(self, v) local yaw = (self.yaw or 0) local pitch = (self.pitch or 0) if v == 0 then pitch = 0 end local current_velocity = self.object:get_velocity() local goal_velocity = { x = (math_sin(yaw) * -v), y = pitch, z = (math_cos(yaw) * v), } local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) if vector_length(new_velocity_addition) > vector_length(goal_velocity) then vector.multiply(new_velocity_addition, (vector_length(goal_velocity) / vector_length(new_velocity_addition))) end --smooths out mobs a bit if vector_length(new_velocity_addition) >= 0.0001 then self.object:add_velocity(new_velocity_addition) end end --[[ ______ _ | ___| | | |_ | |_ _ | _| | | | | | | | | | |_| | \_| |_|\__, | __/ | |___/ ]]-- -- move mob in facing direction --this has been modified to be internal --internal = lua (self.yaw) --engine = c++ (self.object:get_yaw()) mobs.set_fly_velocity = function(self, v) local yaw = (self.yaw or 0) local pitch = (self.pitch or 0) if v == 0 then pitch = 0 end local current_velocity = self.object:get_velocity() local goal_velocity = { x = (math_sin(yaw) * -v), y = pitch, z = (math_cos(yaw) * v), } local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) if vector_length(new_velocity_addition) > vector_length(goal_velocity) then vector.multiply(new_velocity_addition, (vector_length(goal_velocity) / vector_length(new_velocity_addition))) end --smooths out mobs a bit if vector_length(new_velocity_addition) >= 0.0001 then self.object:add_velocity(new_velocity_addition) end end --a quick and simple pitch calculation between two vector positions mobs.calculate_pitch = function(pos1, pos2) if pos1 == nil or pos2 == nil then return false end return(minetest_dir_to_yaw(vector_new(vector_distance(vector_new(pos1.x,0,pos1.z),vector_new(pos2.x,0,pos2.z)),0,pos1.y - pos2.y)) + HALF_PI) end --make mobs fly up or down based on their y difference mobs.set_pitch_while_attacking = function(self) local pos1 = self.object:get_pos() local pos2 = self.attacking:get_pos() local pitch = mobs.calculate_pitch(pos2,pos1) self.pitch = pitch end --[[ ___ |_ | | |_ _ _ __ ___ _ __ | | | | | '_ ` _ \| '_ \ /\__/ / |_| | | | | | | |_) | \____/ \__,_|_| |_| |_| .__/ | | |_| ]]-- --special mob jump movement mobs.jump_move = function(self, velocity) if self.object:get_velocity().y ~= 0 or not self.old_velocity or (self.old_velocity and self.old_velocity.y > 0) then return end --make the mob stick for a split second mobs.set_velocity(self,0) --fallback velocity to allow modularity jump_height = DEFAULT_JUMP_HEIGHT local yaw = (self.yaw or 0) local current_velocity = self.object:get_velocity() local goal_velocity = { x = (math_sin(yaw) * -velocity), y = jump_height, z = (math_cos(yaw) * velocity), } local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) if vector_length(new_velocity_addition) > vector_length(goal_velocity) then vector.multiply(new_velocity_addition, (vector_length(goal_velocity) / vector_length(new_velocity_addition))) end --smooths out mobs a bit if vector_length(new_velocity_addition) >= 0.0001 then self.object:add_velocity(new_velocity_addition) end end