mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-22 10:31:06 +01:00
Overhaul arrow register, implement basic blaze, break parts of arrow register for now, remove fallback for detecting players
This commit is contained in:
parent
08c90c34e8
commit
29305f548d
9 changed files with 245 additions and 54 deletions
|
@ -48,6 +48,9 @@ local math_floor = math.floor
|
|||
-- localize vector functions
|
||||
local vector_new = vector.new
|
||||
local vector_length = vector.length
|
||||
local vector_direction = vector.direction
|
||||
local vector_normalize = vector.normalize
|
||||
local vector_multiply = vector.multiply
|
||||
|
||||
-- mob constants
|
||||
local MAX_MOB_NAME_LENGTH = 30
|
||||
|
@ -324,7 +327,7 @@ function mobs:register_mob(name, def)
|
|||
attacking = nil,
|
||||
visual_size_origin = def.visual_size or {x = 1, y = 1, z = 1},
|
||||
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
|
||||
|
||||
-- MCL2 extensions
|
||||
|
@ -439,9 +442,13 @@ end -- END mobs:register_mob function
|
|||
-- register arrow for shoot attack
|
||||
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,
|
||||
visual = def.visual,
|
||||
|
@ -458,15 +465,17 @@ function mobs:register_arrow(name, def)
|
|||
switch = 0,
|
||||
owner_id = def.owner_id,
|
||||
rotate = def.rotate,
|
||||
on_punch = function(self)
|
||||
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()
|
||||
speed = def.speed or nil,
|
||||
on_step = function(self)
|
||||
|
||||
if self.switch == 0
|
||||
or self.timer > 150
|
||||
or not within_limits(pos, 0) then
|
||||
local vel = self.object:get_velocity()
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
if self.timer > 150
|
||||
or not mobs.within_limits(pos, 0) then
|
||||
mcl_burning.extinguish(self.object)
|
||||
print("removing 1")
|
||||
self.object:remove();
|
||||
|
||||
return
|
||||
|
@ -491,7 +500,7 @@ function mobs:register_arrow(name, def)
|
|||
|
||||
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
|
||||
|
||||
|
@ -519,32 +528,42 @@ function mobs:register_arrow(name, def)
|
|||
if self.hit_player
|
||||
and player:is_player() then
|
||||
|
||||
self.hit_player(self, player)
|
||||
mobs.arrow_hit(self, player)
|
||||
|
||||
print("wow everything is fucked")
|
||||
self.object:remove();
|
||||
return
|
||||
end
|
||||
|
||||
--[[
|
||||
local entity = player:get_luaentity()
|
||||
|
||||
if entity
|
||||
and self.hit_mob
|
||||
and entity._cmi_is_mob == true
|
||||
and tostring(player) ~= self.owner_id
|
||||
and entity.name ~= self.object:get_luaentity().name then
|
||||
self.hit_mob(self, player)
|
||||
and entity.name ~= self.object:get_luaentity().name
|
||||
and (self._shooter and entity.name ~= self._shooter:get_luaentity().name) then
|
||||
|
||||
--self.hit_mob(self, player)
|
||||
self.object:remove();
|
||||
return
|
||||
end
|
||||
]]--
|
||||
|
||||
--[[
|
||||
if entity
|
||||
and self.hit_object
|
||||
and (not entity._cmi_is_mob)
|
||||
and tostring(player) ~= self.owner_id
|
||||
and entity.name ~= self.object:get_luaentity().name then
|
||||
self.hit_object(self, player)
|
||||
and entity.name ~= self.object:get_luaentity().name
|
||||
and (self._shooter and entity.name ~= self._shooter:get_luaentity().name) then
|
||||
|
||||
--self.hit_object(self, player)
|
||||
self.object:remove();
|
||||
return
|
||||
end
|
||||
]]--
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -338,6 +338,12 @@ ______ _
|
|||
local fly_state_list_wandering = {"stand", "fly"}
|
||||
|
||||
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
|
||||
if self.state_timer <= 0 then
|
||||
self.state_timer = math.random(4,10) + math.random()
|
||||
|
@ -440,6 +446,22 @@ local fly_state_execution = function(self,dtime)
|
|||
end
|
||||
|
||||
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
|
||||
else
|
||||
--make the mob float
|
||||
|
|
|
@ -3,6 +3,17 @@ local minetest_dir_to_yaw = minetest.dir_to_yaw
|
|||
local vector_distance = vector.distance
|
||||
local vector_multiply = vector.multiply
|
||||
|
||||
--[[
|
||||
_ _ _ _
|
||||
| | | | | | | |
|
||||
| | | | __ _ _ __ __| | | |
|
||||
| | | | / _` | '_ \ / _` | | |
|
||||
|_| | |___| (_| | | | | (_| | |_|
|
||||
(_) \_____/\__,_|_| |_|\__,_| (_)
|
||||
]]--
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
_____ _ _
|
||||
| ___| | | | |
|
||||
|
@ -215,4 +226,78 @@ mobs.projectile_attack_walk = function(self,dtime)
|
|||
mobs.jump(self)
|
||||
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
|
|
@ -1565,25 +1565,7 @@ local function update_roll(self)
|
|||
self.object:set_properties({collisionbox = cbox})
|
||||
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
|
||||
local is_at_cliff_or_danger = function(self)
|
||||
|
@ -1661,19 +1643,7 @@ local is_at_water_danger = function(self)
|
|||
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.)
|
||||
|
|
|
@ -3,6 +3,8 @@ local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius
|
|||
local math_random = math.random
|
||||
local vector_multiply = vector.multiply
|
||||
|
||||
local vector_direction = vector.direction
|
||||
|
||||
local integer_test = {-1,1}
|
||||
|
||||
mobs.collision = function(self)
|
||||
|
@ -107,4 +109,30 @@ mobs.collision = function(self)
|
|||
|
||||
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
|
|
@ -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
|
|
@ -4,6 +4,8 @@ local minetest_yaw_to_dir = minetest.yaw_to_dir
|
|||
local minetest_get_node = minetest.get_node
|
||||
local minetest_get_item_group = minetest.get_item_group
|
||||
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_multiply = vector.multiply
|
||||
|
@ -24,10 +26,6 @@ end
|
|||
--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)
|
||||
|
||||
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 players_in_area = {}
|
||||
local winner_player = nil
|
||||
|
@ -165,4 +163,38 @@ mobs.group_attack_initialization = function(self)
|
|||
--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
|
|
@ -2,14 +2,17 @@ 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
|
||||
|
@ -236,6 +239,27 @@ mobs.set_fly_velocity = function(self, v)
|
|||
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
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
___
|
||||
|
|
|
@ -18,6 +18,8 @@ mobs:register_mob("mobs_mc:blaze", {
|
|||
xp_min = 10,
|
||||
xp_max = 10,
|
||||
tilt_fly = false,
|
||||
hostile = true,
|
||||
rotate = 270,
|
||||
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3},
|
||||
rotate = -180,
|
||||
visual = "mesh",
|
||||
|
@ -36,7 +38,7 @@ mobs:register_mob("mobs_mc:blaze", {
|
|||
walk_velocity = .8,
|
||||
run_velocity = 1.6,
|
||||
damage = 6,
|
||||
reach = 2,
|
||||
reach = 4, -- don't want blaze getting too close
|
||||
pathfinding = 1,
|
||||
drops = {
|
||||
{name = mobs_mc.items.blaze_rod,
|
||||
|
@ -76,6 +78,13 @@ mobs:register_mob("mobs_mc:blaze", {
|
|||
fear_height = 0,
|
||||
glow = 14,
|
||||
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)
|
||||
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)
|
||||
|
@ -148,6 +157,7 @@ mobs:register_arrow("mobs_mc:blaze_fireball", {
|
|||
visual_size = {x = 0.3, y = 0.3},
|
||||
textures = {"mcl_fire_fire_charge.png"},
|
||||
velocity = 15,
|
||||
speed = 5,
|
||||
|
||||
-- Direct hit, no fire... just plenty of pain
|
||||
hit_player = function(self, player)
|
||||
|
@ -180,7 +190,9 @@ mobs:register_arrow("mobs_mc:blaze_fireball", {
|
|||
|
||||
-- Node hit, make fire
|
||||
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})
|
||||
else
|
||||
local v = self.object:get_velocity()
|
||||
|
|
Loading…
Reference in a new issue