Added Sussy Imposter (he's very sussy and he wants to kill you) and improved jumping of every entity
This commit is contained in:
@@ -120,14 +120,20 @@ local entity = {
|
||||
pos.z = pos.z + dir_sin
|
||||
|
||||
local bnode = minetest.get_node(pos)
|
||||
if bnode.name == "air" or bnode.name == "amogus_blocks:water_source" or bnode.name == "amogus_blocks:water_flowing" then
|
||||
--if bnode.name == "air" or bnode.name == "amogus_blocks:water_source" or bnode.name == "amogus_blocks:water_flowing" then
|
||||
-- if node is not solid OR is a liquid
|
||||
if minetest.registered_nodes[bnode.name].walkable == false or minetest.registered_nodes[bnode.name].liquidtype ~= "none" then
|
||||
self.block_lastly_in_front = false
|
||||
-- if node next to the entity is a solid block
|
||||
else
|
||||
if self.block_lastly_in_front == false then
|
||||
self.block_lastly_in_front = true
|
||||
local vel = self.object:get_velocity()
|
||||
vel.y = vel.y + (math.random() * self.min_max_jump_force_diff + self.min_jump_force)
|
||||
self.object:set_velocity(vel)
|
||||
-- randomly jump in the next iteration even if theres still a block in front
|
||||
elseif math.random(10) == 1 then
|
||||
self.block_lastly_in_front = false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -66,11 +66,11 @@ local entity = {
|
||||
|
||||
player = nil,
|
||||
player_pos = nil,
|
||||
mini_crewmate_pos = nil,
|
||||
crewmate_player_vector = nil,
|
||||
entity_pos = nil,
|
||||
entity_player_vector = nil,
|
||||
distance = nil,
|
||||
current_distance = nil,
|
||||
current_crewmate_player_vector = nil,
|
||||
current_entity_player_vector = nil,
|
||||
|
||||
|
||||
|
||||
@@ -136,30 +136,29 @@ local entity = {
|
||||
self.player = minetest.get_connected_players()[1]
|
||||
|
||||
self.player_pos = self.player:get_pos()
|
||||
self.mini_crewmate_pos = self.object:get_pos()
|
||||
self.crewmate_player_vector = vector.subtract(self.player_pos, self.mini_crewmate_pos)
|
||||
self.distance = vector.length(self.crewmate_player_vector)
|
||||
self.entity_pos = self.object:get_pos()
|
||||
self.entity_player_vector = vector.subtract(self.player_pos, self.entity_pos)
|
||||
self.distance = vector.length(self.entity_player_vector)
|
||||
-- if on multiplayer mode, calculate distance between nearest player and mini crewmate
|
||||
else
|
||||
self.player = minetest.get_connected_players()
|
||||
|
||||
self.distance = nil
|
||||
self.crewmate_player_vector = nil
|
||||
self.entity_player_vector = nil
|
||||
|
||||
self.mini_crewmate_pos = self.object:get_pos()
|
||||
self.entity_pos = self.object:get_pos()
|
||||
|
||||
-- iterate over all players
|
||||
for i = 1, #self.player do
|
||||
minetest.chat_send_all("player " .. i)
|
||||
self.player_pos = self.player[i]:get_pos()
|
||||
--self.crewmate_player_vector = vector.subtract(self.player_pos, self.mini_crewmate_pos)
|
||||
self.current_crewmate_player_vector = vector.subtract(self.player_pos, self.mini_crewmate_pos)
|
||||
self.current_distance = vector.length(self.current_crewmate_player_vector)
|
||||
--self.entity_player_vector = vector.subtract(self.player_pos, self.entity_pos)
|
||||
self.current_entity_player_vector = vector.subtract(self.player_pos, self.entity_pos)
|
||||
self.current_distance = vector.length(self.current_entity_player_vector)
|
||||
|
||||
-- if distance is nil or current_distance is smaller than distance, set distance to current_distance
|
||||
if self.distance == nil or self.current_distance < self.distance then
|
||||
self.distance = self.current_distance
|
||||
self.crewmate_player_vector = self.current_crewmate_player_vector
|
||||
self.entity_player_vector = self.current_entity_player_vector
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -240,10 +239,10 @@ local entity = {
|
||||
-- if mode is 3 (run away) set rotation so mini crewmate is facing either at the player or away from the player depending on situation
|
||||
if self.mode == 3 then
|
||||
-- look away from the player
|
||||
self.object:set_yaw(math.atan2(-self.crewmate_player_vector.z, -self.crewmate_player_vector.x))
|
||||
self.object:set_yaw(math.atan2(-self.entity_player_vector.z, -self.entity_player_vector.x))
|
||||
else
|
||||
-- look at the player
|
||||
self.object:set_yaw(math.atan2(self.crewmate_player_vector.z, self.crewmate_player_vector.x))
|
||||
self.object:set_yaw(math.atan2(self.entity_player_vector.z, self.entity_player_vector.x))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -281,14 +280,20 @@ local entity = {
|
||||
pos.z = pos.z + dir_sin
|
||||
|
||||
local bnode = minetest.get_node(pos)
|
||||
if bnode.name == "air" or bnode.name == "amogus_blocks:water_source" or bnode.name == "amogus_blocks:water_flowing" then
|
||||
--if bnode.name == "air" or bnode.name == "amogus_blocks:water_source" or bnode.name == "amogus_blocks:water_flowing" then
|
||||
-- if node is not solid OR is a liquid
|
||||
if minetest.registered_nodes[bnode.name].walkable == false or minetest.registered_nodes[bnode.name].liquidtype ~= "none" then
|
||||
self.block_lastly_in_front = false
|
||||
-- if node next to the entity is a solid block
|
||||
else
|
||||
if self.block_lastly_in_front == false then
|
||||
self.block_lastly_in_front = true
|
||||
local vel = self.object:get_velocity()
|
||||
vel.y = vel.y + self.jump_force
|
||||
self.object:set_velocity(vel)
|
||||
-- randomly jump in the next iteration even if theres still a block in front
|
||||
elseif math.random(10) == 1 then
|
||||
self.block_lastly_in_front = false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
281
mods/amogus_entities/entities/sussy_imposter_entity.lua
Normal file
281
mods/amogus_entities/entities/sussy_imposter_entity.lua
Normal file
@@ -0,0 +1,281 @@
|
||||
--local textures_b = {
|
||||
-- "amogus_entity.png",
|
||||
-- "amogus_entity_b.png",
|
||||
-- "amogus_entity_g.png",
|
||||
-- "amogus_entity_br.png"
|
||||
--}
|
||||
|
||||
local entity = {
|
||||
physical = true,
|
||||
collisionbox = {-0.75, 0, -0.75, 0.75, 1.5, 0.75},
|
||||
|
||||
visual = "mesh",
|
||||
visual_size = {x=15, y=15, z=15},
|
||||
|
||||
mesh = "sussy_imposter_entity.obj",
|
||||
textures = {"sussy_imposter_entity.png"},
|
||||
|
||||
on_rightclick = function(self, clicker)
|
||||
minetest.chat_send_player(clicker:get_player_name(), "YOU MET THE MOST SUS THING IN THE WORLD!")
|
||||
|
||||
amogus_general.play_random_sound(
|
||||
"sus_sound",
|
||||
self.object:get_pos(),
|
||||
1.0, -- gain
|
||||
40, -- max_hear_distance
|
||||
1.0 -- pitch
|
||||
)
|
||||
end,
|
||||
|
||||
-- impostor config --
|
||||
walk_acceleration_speed = 0.08, -- acceleration speed when no panic, no stress
|
||||
run_acceleration_speed = 0.15, -- acceleration speed when chasing player
|
||||
|
||||
rotation_acceleration_speed = 0.5, -- self explainatory
|
||||
|
||||
gravity = 9.81, -- m/s^2
|
||||
|
||||
jump_force = 8, -- self explainatory
|
||||
|
||||
friction = 0.6, -- friction (0.0 - no friction like perfectly smooth ice | 1.0 - full friction and can't even move)
|
||||
rotation_friction = 0.8, -- the same but for rotation
|
||||
|
||||
|
||||
largest_distance_to_find_player = 12, -- largest distance to find player
|
||||
smallest_distance_to_lost_player = 16, -- smallest distance to lost player
|
||||
|
||||
largest_distance_to_hurt_player = 1.5, -- largest distance to hurt player
|
||||
|
||||
--------------------------
|
||||
|
||||
block_lastly_in_front = false,
|
||||
rotation_velocity = 0,
|
||||
rotation_direction = nil,
|
||||
|
||||
sound_pitch = nil,
|
||||
sound_propability = nil,
|
||||
|
||||
-- player detection variables
|
||||
|
||||
player = nil,
|
||||
player_pos = nil,
|
||||
entity_pos = nil,
|
||||
entity_player_vector = nil,
|
||||
distance = nil,
|
||||
current_distance = nil,
|
||||
current_entity_player_vector = nil,
|
||||
|
||||
nearest_player_index = nil,
|
||||
|
||||
|
||||
|
||||
|
||||
mode = 0, -- | 0 - stand still | 1 - walk | 2 - chase
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_yaw(math.random() * 2 * math.pi)
|
||||
self.rotation_direction = math.random(-1, 1)
|
||||
end,
|
||||
|
||||
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
|
||||
amogus_general.play_random_sound(
|
||||
"sus_sound",
|
||||
self.object:get_pos(),
|
||||
1.0, -- gain
|
||||
40, -- max_hear_distance
|
||||
1.5 -- pitch
|
||||
)
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
|
||||
-- play sus sound randomly with different pitch depending on situation
|
||||
|
||||
if self.mode == 0 or self.mode == 1 then -- stand still or walk
|
||||
sound_pitch = 0.8
|
||||
sound_propability = 100
|
||||
|
||||
else -- chase (2)
|
||||
sound_pitch = 1.2
|
||||
sound_propability = 50
|
||||
end
|
||||
|
||||
|
||||
if math.random(sound_propability) == 1 then
|
||||
amogus_general.play_random_sound(
|
||||
"sus_sound",
|
||||
self.object:get_pos(),
|
||||
1.0, -- gain
|
||||
40, -- max_hear_distance
|
||||
sound_pitch -- pitch
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- if on singpleplayer mode or only one player is connected, calculate distance between player and mini crewmate
|
||||
if minetest.is_singleplayer() or #minetest.get_connected_players() == 1 then
|
||||
-- get first player
|
||||
self.player = minetest.get_connected_players()[1]
|
||||
|
||||
self.player_pos = self.player:get_pos()
|
||||
self.entity_pos = self.object:get_pos()
|
||||
self.entity_player_vector = vector.subtract(self.player_pos, self.entity_pos)
|
||||
self.distance = vector.length(self.entity_player_vector)
|
||||
-- if on multiplayer mode, calculate distance between nearest player and mini crewmate
|
||||
else
|
||||
self.player = minetest.get_connected_players()
|
||||
|
||||
self.distance = nil
|
||||
self.entity_player_vector = nil
|
||||
|
||||
self.nearest_player_index = nil
|
||||
|
||||
self.entity_pos = self.object:get_pos()
|
||||
|
||||
-- iterate over all players
|
||||
for i = 1, #self.player do
|
||||
self.player_pos = self.player[i]:get_pos()
|
||||
--self.entity_player_vector = vector.subtract(self.player_pos, self.entity_pos)
|
||||
self.current_entity_player_vector = vector.subtract(self.player_pos, self.entity_pos)
|
||||
self.current_distance = vector.length(self.current_entity_player_vector)
|
||||
|
||||
-- if distance is nil or current_distance is smaller than distance, set distance to current_distance
|
||||
if self.distance == nil or self.current_distance < self.distance then
|
||||
self.distance = self.current_distance
|
||||
self.entity_player_vector = self.current_entity_player_vector
|
||||
self.nearest_player_index = i
|
||||
end
|
||||
end
|
||||
|
||||
-- get nearest player
|
||||
self.player = self.player[self.nearest_player_index]
|
||||
end
|
||||
|
||||
|
||||
-- if mode is 0 or 1 (stand still or walk) and distance is smaller or equal to largest_distance_to_find_player, set mode to 2 (chase)
|
||||
if (self.mode == 0 or self.mode == 1) and self.distance <= self.largest_distance_to_find_player then
|
||||
self.mode = 2
|
||||
-- elseif mode is 2 (chase)
|
||||
elseif self.mode == 2 then
|
||||
-- if distance is greater or equal to smallest_distance_to_lost_player, set mode to 0 (stand still)
|
||||
if self.distance >= self.smallest_distance_to_lost_player then
|
||||
self.mode = 0
|
||||
-- else if distance is smaller or equal to largest_distance_to_hurt_player, hurt player
|
||||
elseif self.distance <= self.largest_distance_to_hurt_player then
|
||||
if math.random(10) == 1 then
|
||||
self.player:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = 1},
|
||||
}, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- if if not performing an action related to the player
|
||||
if self.mode ~= 2 then
|
||||
|
||||
-- make mini crewmate sometimes stand still and sometimes walk
|
||||
if math.random(100) == 1 then
|
||||
if self.mode == 0 then
|
||||
self.mode = 1
|
||||
else
|
||||
self.mode = 0
|
||||
end
|
||||
end
|
||||
|
||||
-- some chance of chaning rotation_direction to random value
|
||||
if math.random(10) == 1 then
|
||||
--self.rotation_direction = math.random(-1, 1)
|
||||
local rand = math.random()
|
||||
|
||||
if rand < 0.2 then
|
||||
self.rotation_direction = 1
|
||||
elseif rand < 0.4 then
|
||||
self.rotation_direction = -1
|
||||
else
|
||||
self.rotation_direction = 0
|
||||
end
|
||||
end
|
||||
|
||||
-- update rotation_velocity
|
||||
self.rotation_velocity = self.rotation_velocity + self.rotation_direction * self.rotation_acceleration_speed * dtime
|
||||
|
||||
-- update rotation
|
||||
self.object:set_yaw(self.object:get_yaw() + self.rotation_velocity * dtime)
|
||||
|
||||
-- apply rotation_friction
|
||||
self.rotation_velocity = self.rotation_velocity * (1 - self.rotation_friction * dtime)
|
||||
|
||||
else -- else performing an action related to the player
|
||||
self.rotation_velocity = 0;
|
||||
|
||||
-- set rotation so entity is facing at the player
|
||||
self.object:set_yaw(math.atan2(self.entity_player_vector.z, self.entity_player_vector.x))
|
||||
end
|
||||
|
||||
-- perform calculations on direction
|
||||
local dir = self.object:get_yaw()
|
||||
local dir_cos = math.cos(dir)
|
||||
local dir_sin = math.sin(dir)
|
||||
|
||||
-- if not standing still
|
||||
if self.mode ~= 0 then
|
||||
-- make mini crewmate walk or run
|
||||
local vel = self.object:get_velocity()
|
||||
-- if walking
|
||||
if self.mode == 1 then
|
||||
vel.x = vel.x + dir_cos * self.walk_acceleration_speed
|
||||
vel.z = vel.z + dir_sin * self.walk_acceleration_speed
|
||||
else -- chasing (2)
|
||||
vel.x = vel.x + dir_cos * self.run_acceleration_speed
|
||||
vel.z = vel.z + dir_sin * self.run_acceleration_speed
|
||||
end
|
||||
|
||||
self.object:set_velocity(vel)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Make it also jump when some block is in front of it
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
pos.x = pos.x + dir_cos
|
||||
pos.z = pos.z + dir_sin
|
||||
|
||||
local bnode = minetest.get_node(pos)
|
||||
--if bnode.name == "air" or bnode.name == "amogus_blocks:water_source" or bnode.name == "amogus_blocks:water_flowing" then
|
||||
-- if node is not solid OR is a liquid
|
||||
if minetest.registered_nodes[bnode.name].walkable == false or minetest.registered_nodes[bnode.name].liquidtype ~= "none" then
|
||||
self.block_lastly_in_front = false
|
||||
-- if node next to the entity is a solid block
|
||||
else
|
||||
if self.block_lastly_in_front == false then
|
||||
self.block_lastly_in_front = true
|
||||
local vel = self.object:get_velocity()
|
||||
vel.y = vel.y + self.jump_force
|
||||
self.object:set_velocity(vel)
|
||||
-- randomly jump in the next iteration even if theres still a block in front
|
||||
elseif math.random(10) == 1 then
|
||||
self.block_lastly_in_front = false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local vel = self.object:get_velocity()
|
||||
|
||||
-- change velocity by gravity
|
||||
vel.y = vel.y - self.gravity * dtime * 2
|
||||
|
||||
-- change velocity by friction
|
||||
vel.x = vel.x * (1 - self.friction * dtime)
|
||||
vel.z = vel.z * (1 - self.friction * dtime)
|
||||
|
||||
self.object:set_velocity(vel)
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
minetest.register_entity("amogus_entities:sussy_imposter", entity)
|
||||
Reference in New Issue
Block a user