Overhaul arrow register, implement basic blaze, break parts of arrow register for now, remove fallback for detecting players

This commit is contained in:
jordan4ibanez 2021-04-21 15:08:35 -04:00
parent 08c90c34e8
commit 29305f548d
9 changed files with 245 additions and 54 deletions

View File

@ -48,6 +48,9 @@ local math_floor = math.floor
-- localize vector functions -- localize vector functions
local vector_new = vector.new local vector_new = vector.new
local vector_length = vector.length local vector_length = vector.length
local vector_direction = vector.direction
local vector_normalize = vector.normalize
local vector_multiply = vector.multiply
-- mob constants -- mob constants
local MAX_MOB_NAME_LENGTH = 30 local MAX_MOB_NAME_LENGTH = 30
@ -324,7 +327,7 @@ function mobs:register_mob(name, def)
attacking = nil, attacking = nil,
visual_size_origin = def.visual_size or {x = 1, y = 1, z = 1}, visual_size_origin = def.visual_size or {x = 1, y = 1, z = 1},
punch_timer_cooloff = def.punch_timer_cooloff or 0.5, punch_timer_cooloff = def.punch_timer_cooloff or 0.5,
projectile_cooldown = projectile_cooldown or 2, projectile_cooldown = def.projectile_cooldown or 2,
--end j4i stuff --end j4i stuff
-- MCL2 extensions -- MCL2 extensions
@ -439,9 +442,13 @@ end -- END mobs:register_mob function
-- register arrow for shoot attack -- register arrow for shoot attack
function mobs:register_arrow(name, def) function mobs:register_arrow(name, def)
if not name or not def then return end -- errorcheck -- errorcheck
if not name or not def then
print("failed to register arrow entity")
return
end
minetest.register_entity(name, { minetest.register_entity(name.."_entity", {
physical = false, physical = false,
visual = def.visual, visual = def.visual,
@ -458,15 +465,17 @@ function mobs:register_arrow(name, def)
switch = 0, switch = 0,
owner_id = def.owner_id, owner_id = def.owner_id,
rotate = def.rotate, rotate = def.rotate,
on_punch = function(self) speed = def.speed or nil,
on_step = function(self)
local vel = self.object:get_velocity() local vel = self.object:get_velocity()
--self.object:set_velocity({x=vel.x * -1, y=vel.y * -1, z=vel.z * -1})
local pos = self.object:get_pos() local pos = self.object:get_pos()
if self.switch == 0 if self.timer > 150
or self.timer > 150 or not mobs.within_limits(pos, 0) then
or not within_limits(pos, 0) then
mcl_burning.extinguish(self.object) mcl_burning.extinguish(self.object)
print("removing 1")
self.object:remove(); self.object:remove();
return return
@ -491,7 +500,7 @@ function mobs:register_arrow(name, def)
if self.hit_node then if self.hit_node then
local node = node_ok(pos).name local node = minetest_get_node(pos).name
if minetest_registered_nodes[node].walkable then if minetest_registered_nodes[node].walkable then
@ -519,32 +528,42 @@ function mobs:register_arrow(name, def)
if self.hit_player if self.hit_player
and player:is_player() then and player:is_player() then
self.hit_player(self, player) mobs.arrow_hit(self, player)
print("wow everything is fucked")
self.object:remove(); self.object:remove();
return return
end end
--[[
local entity = player:get_luaentity() local entity = player:get_luaentity()
if entity if entity
and self.hit_mob and self.hit_mob
and entity._cmi_is_mob == true and entity._cmi_is_mob == true
and tostring(player) ~= self.owner_id and tostring(player) ~= self.owner_id
and entity.name ~= self.object:get_luaentity().name then and entity.name ~= self.object:get_luaentity().name
self.hit_mob(self, player) and (self._shooter and entity.name ~= self._shooter:get_luaentity().name) then
--self.hit_mob(self, player)
self.object:remove(); self.object:remove();
return return
end end
]]--
--[[
if entity if entity
and self.hit_object and self.hit_object
and (not entity._cmi_is_mob) and (not entity._cmi_is_mob)
and tostring(player) ~= self.owner_id and tostring(player) ~= self.owner_id
and entity.name ~= self.object:get_luaentity().name then and entity.name ~= self.object:get_luaentity().name
self.hit_object(self, player) and (self._shooter and entity.name ~= self._shooter:get_luaentity().name) then
--self.hit_object(self, player)
self.object:remove(); self.object:remove();
return return
end end
]]--
end end
end end

View File

@ -338,6 +338,12 @@ ______ _
local fly_state_list_wandering = {"stand", "fly"} local fly_state_list_wandering = {"stand", "fly"}
local fly_state_switch = function(self, dtime) local fly_state_switch = function(self, dtime)
if self.hostile and self.attacking then
self.state = "attack"
return
end
self.state_timer = self.state_timer - dtime self.state_timer = self.state_timer - dtime
if self.state_timer <= 0 then if self.state_timer <= 0 then
self.state_timer = math.random(4,10) + math.random() self.state_timer = math.random(4,10) + math.random()
@ -440,6 +446,22 @@ local fly_state_execution = function(self,dtime)
end end
mobs.set_fly_velocity(self,self.walk_velocity) mobs.set_fly_velocity(self,self.walk_velocity)
elseif self.state == "attack" then
--execute mob attack type
--if self.attack_type == "explode" then
--mobs.explode_attack_fly(self, dtime)
--elseif self.attack_type == "punch" then
--mobs.punch_attack_fly(self,dtime)
if self.attack_type == "projectile" then
mobs.projectile_attack_fly(self,dtime)
end
end end
else else
--make the mob float --make the mob float

View File

@ -3,6 +3,17 @@ local minetest_dir_to_yaw = minetest.dir_to_yaw
local vector_distance = vector.distance local vector_distance = vector.distance
local vector_multiply = vector.multiply local vector_multiply = vector.multiply
--[[
_ _ _ _
| | | | | | | |
| | | | __ _ _ __ __| | | |
| | | | / _` | '_ \ / _` | | |
|_| | |___| (_| | | | | (_| | |_|
(_) \_____/\__,_|_| |_|\__,_| (_)
]]--
--[[ --[[
_____ _ _ _____ _ _
| ___| | | | | | ___| | | | |
@ -216,3 +227,77 @@ mobs.projectile_attack_walk = function(self,dtime)
end end
end end
--[[
_ ______ _ _
| | | ___| | | |
| | | |_ | |_ _ | |
| | | _| | | | | | | |
|_| | | | | |_| | |_|
(_) \_| |_|\__, | (_)
__/ |
|___/
]]--
--[[
______ _ _ _ _
| ___ \ (_) | | (_) |
| |_/ / __ ___ _ ___ ___| |_ _| | ___
| __/ '__/ _ \| |/ _ \/ __| __| | |/ _ \
| | | | | (_) | | __/ (__| |_| | | __/
\_| |_| \___/| |\___|\___|\__|_|_|\___|
_/ |
|__/
]]--
mobs.projectile_attack_fly = function(self, dtime)
--this needs an exception
if self.attacking == nil or not self.attacking:is_player() then
self.attacking = nil
return
end
local distance_from_attacking = vector_distance(self.object:get_pos(), self.attacking:get_pos())
if distance_from_attacking >= self.reach then
mobs.set_yaw_while_attacking(self)
mobs.set_pitch_while_attacking(self)
mobs.set_fly_velocity(self, self.run_velocity)
mobs.set_mob_animation(self,"run")
else
mobs.set_yaw_while_attacking(self)
mobs.set_pitch_while_attacking(self)
mobs.set_fly_velocity(self, 0)
mobs.set_mob_animation(self,"stand")
end
--do this to not load data into other mobs
if not self.projectile_timer then
self.projectile_timer = self.projectile_cooldown
end
--run projectile timer
if self.projectile_timer > 0 then
self.projectile_timer = self.projectile_timer - dtime
--shoot
if self.projectile_timer <= 0 then
--reset timer
self.projectile_timer = self.projectile_cooldown
mobs.shoot_projectile(self)
end
end
end

View File

@ -1565,25 +1565,7 @@ local function update_roll(self)
self.object:set_properties({collisionbox = cbox}) self.object:set_properties({collisionbox = cbox})
end end
-- check if within physical map limits (-30911 to 30927)
local within_limits, wmin, wmax = nil, -30913, 30928
within_limits = function(pos, radius)
if mcl_vars then
if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then
wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max
within_limits = function(pos, radius)
return pos
and (pos.x - radius) > wmin and (pos.x + radius) < wmax
and (pos.y - radius) > wmin and (pos.y + radius) < wmax
and (pos.z - radius) > wmin and (pos.z + radius) < wmax
end
end
end
return pos
and (pos.x - radius) > wmin and (pos.x + radius) < wmax
and (pos.y - radius) > wmin and (pos.y + radius) < wmax
and (pos.z - radius) > wmin and (pos.z + radius) < wmax
end
-- is mob facing a cliff or danger -- is mob facing a cliff or danger
local is_at_cliff_or_danger = function(self) local is_at_cliff_or_danger = function(self)
@ -1661,19 +1643,7 @@ local is_at_water_danger = function(self)
end end
-- get node but use fallback for nil or unknown
local node_ok = function(pos, fallback)
fallback = fallback or mobs.fallback_node
local node = minetest_get_node_or_nil(pos)
if node and minetest_registered_nodes[node.name] then
return node
end
return minetest_registered_nodes[fallback]
end
-- environmental damage (water, lava, fire, light etc.) -- environmental damage (water, lava, fire, light etc.)

View File

@ -3,6 +3,8 @@ local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius
local math_random = math.random local math_random = math.random
local vector_multiply = vector.multiply local vector_multiply = vector.multiply
local vector_direction = vector.direction
local integer_test = {-1,1} local integer_test = {-1,1}
mobs.collision = function(self) mobs.collision = function(self)
@ -108,3 +110,29 @@ mobs.collision = function(self)
end end
end end
end end
--this is used for arrow collisions
mobs.arrow_hit = function(self, player)
player:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = self._damage}
}, nil)
--knockback
local pos1 = self.object:get_pos()
pos1.y = 0
local pos2 = player:get_pos()
pos2.y = 0
local dir = vector_direction(pos1,pos2)
dir = vector_multiply(dir,3)
if player:get_velocity().y <= 1 then
dir.y = 5
end
player:add_velocity(dir)
end

View File

@ -1 +0,0 @@
--make mobs scan players and check distance then if direct line of sight then add to list and go after whichever one is closer

View File

@ -4,6 +4,8 @@ local minetest_yaw_to_dir = minetest.yaw_to_dir
local minetest_get_node = minetest.get_node local minetest_get_node = minetest.get_node
local minetest_get_item_group = minetest.get_item_group local minetest_get_item_group = minetest.get_item_group
local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius
local minetest_get_node_or_nil = minetest.get_node_or_nil
local minetest_registered_nodes = minetest.registered_nodes
local vector_new = vector.new local vector_new = vector.new
local vector_multiply = vector.multiply local vector_multiply = vector.multiply
@ -24,10 +26,6 @@ end
--a fast function to be able to detect only players without using objects_in_radius --a fast function to be able to detect only players without using objects_in_radius
mobs.detect_closest_player_within_radius = function(self, line_of_sight, radius, object_height_adder) mobs.detect_closest_player_within_radius = function(self, line_of_sight, radius, object_height_adder)
line_of_sight = line_of_sight or true --fallback line_of_sight
radius = radius or 10 -- fallback radius
object_height_adder = object_height_adder or 0 --fallback entity (y height) addition for line of sight
local pos1 = self.object:get_pos() local pos1 = self.object:get_pos()
local players_in_area = {} local players_in_area = {}
local winner_player = nil local winner_player = nil
@ -166,3 +164,37 @@ mobs.group_attack_initialization = function(self)
end end
end end
end end
-- check if within physical map limits (-30911 to 30927)
-- within_limits, wmin, wmax = nil, -30913, 30928
mobs.within_limits = function(pos, radius)
if mcl_vars then
if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then
wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max
within_limits = function(pos, radius)
return pos
and (pos.x - radius) > wmin and (pos.x + radius) < wmax
and (pos.y - radius) > wmin and (pos.y + radius) < wmax
and (pos.z - radius) > wmin and (pos.z + radius) < wmax
end
end
end
return pos
and (pos.x - radius) > wmin and (pos.x + radius) < wmax
and (pos.y - radius) > wmin and (pos.y + radius) < wmax
and (pos.z - radius) > wmin and (pos.z + radius) < wmax
end
-- get node but use fallback for nil or unknown
mobs.node_ok = function(pos, fallback)
fallback = fallback or mobs.fallback_node
local node = minetest_get_node_or_nil(pos)
if node and minetest_registered_nodes[node.name] then
return node
end
return minetest_registered_nodes[fallback]
end

View File

@ -2,14 +2,17 @@ local math_pi = math.pi
local math_sin = math.sin local math_sin = math.sin
local math_cos = math.cos local math_cos = math.cos
local math_random = math.random local math_random = math.random
local HALF_PI = math_pi / 2
local DOUBLE_PI = math_pi * 2 local DOUBLE_PI = math_pi * 2
-- localize vector functions -- localize vector functions
local vector_new = vector.new local vector_new = vector.new
local vector_length = vector.length local vector_length = vector.length
local vector_multiply = vector.multiply local vector_multiply = vector.multiply
local vector_distance = vector.distance
local minetest_yaw_to_dir = minetest.yaw_to_dir 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_JUMP_HEIGHT = 5
local DEFAULT_FLOAT_SPEED = 4 local DEFAULT_FLOAT_SPEED = 4
@ -236,6 +239,27 @@ mobs.set_fly_velocity = function(self, v)
end end
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
--[[ --[[
___ ___

View File

@ -18,6 +18,8 @@ mobs:register_mob("mobs_mc:blaze", {
xp_min = 10, xp_min = 10,
xp_max = 10, xp_max = 10,
tilt_fly = false, tilt_fly = false,
hostile = true,
rotate = 270,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3}, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3},
rotate = -180, rotate = -180,
visual = "mesh", visual = "mesh",
@ -36,7 +38,7 @@ mobs:register_mob("mobs_mc:blaze", {
walk_velocity = .8, walk_velocity = .8,
run_velocity = 1.6, run_velocity = 1.6,
damage = 6, damage = 6,
reach = 2, reach = 4, -- don't want blaze getting too close
pathfinding = 1, pathfinding = 1,
drops = { drops = {
{name = mobs_mc.items.blaze_rod, {name = mobs_mc.items.blaze_rod,
@ -76,6 +78,13 @@ mobs:register_mob("mobs_mc:blaze", {
fear_height = 0, fear_height = 0,
glow = 14, glow = 14,
fire_resistant = true, fire_resistant = true,
eye_height = 0.75,
shoot_arrow = function(self, pos, dir)
-- 2-4 damage per arrow
local dmg = math.random(2,4)
mcl_bows.shoot_arrow("mobs_mc:blaze_fireball", pos, dir, self.object:get_yaw(), self.object, nil, dmg)
end,
do_custom = function(self) do_custom = function(self)
if self.state == "attack" and vector.distance(self.object:get_pos(), self.attack:get_pos()) < 1.2 then if self.state == "attack" and vector.distance(self.object:get_pos(), self.attack:get_pos()) < 1.2 then
mcl_burning.set_on_fire(self.attack, 5) mcl_burning.set_on_fire(self.attack, 5)
@ -148,6 +157,7 @@ mobs:register_arrow("mobs_mc:blaze_fireball", {
visual_size = {x = 0.3, y = 0.3}, visual_size = {x = 0.3, y = 0.3},
textures = {"mcl_fire_fire_charge.png"}, textures = {"mcl_fire_fire_charge.png"},
velocity = 15, velocity = 15,
speed = 5,
-- Direct hit, no fire... just plenty of pain -- Direct hit, no fire... just plenty of pain
hit_player = function(self, player) hit_player = function(self, player)
@ -180,7 +190,9 @@ mobs:register_arrow("mobs_mc:blaze_fireball", {
-- Node hit, make fire -- Node hit, make fire
hit_node = function(self, pos, node) hit_node = function(self, pos, node)
if node.name == "air" then if node.name ~= "air" then
local pos_above = table.copy(pos)
pos_above.y = pos_above.y + 1
minetest.set_node(pos_above, {name=mobs_mc.items.fire}) minetest.set_node(pos_above, {name=mobs_mc.items.fire})
else else
local v = self.object:get_velocity() local v = self.object:get_velocity()