diff --git a/mods/rp_mobs_mobs/mineturtle.lua b/mods/rp_mobs_mobs/mineturtle.lua index d4e23ad5..bb5abe06 100644 --- a/mods/rp_mobs_mobs/mineturtle.lua +++ b/mods/rp_mobs_mobs/mineturtle.lua @@ -3,10 +3,25 @@ -- TODO: Change to rp_mobs_mobs when ready local S = minetest.get_translator("mobs") --- Boar constants +-- Constants local VIEW_RANGE = 10 +-- Time until mine goes boom (seconds) +local BOOM_TIMER = 3 + +-- Time until mob blinks on/off (seconds) +local BLINK_TIMER = 0.2 + +-- Radius of explosion +local EXPLODE_RADIUS = 3 + +-- Max. distance required to activate mine +local MINE_ACTIVATION_RANGE = 2 + +-- Min. distance required to deactivate mine +local MINE_DEACTIVATION_RANGE = 3 + local task_queue_roam_settings = { walk_speed = 2, liquid_rise_speed = 2, @@ -24,9 +39,100 @@ local task_queue_roam_settings = { view_range = VIEW_RANGE, follow_reach_distance = 1, follow_give_up_time = 10.0, - no_follow_time = 6.0, + no_follow_time = 4.0, } +local function find_closest_player_in_range(pos, range) + local objs = minetest.get_objects_inside_radius(pos, range) + local c_player, c_dist + for o=1, #objs do + if objs[o]:is_player() then + local dist = vector.distance(objs[o]:get_pos(), pos) + if (not c_player) or (dist < c_dist) then + c_player = objs[o] + c_dist = dist + end + end + end + return c_player +end + +local function explode(mob) + local pos = mob.object:get_pos() + mob.object:remove() + pos.y = pos.y - 1 + tnt.boom_notnt(pos, EXPLODE_RADIUS) + minetest.log("action", "[rp_mobs_mobs] "..mob.name.." exploded at "..minetest.pos_to_string(pos, 1)) +end + +local function microtask_mine() + return rp_mobs.create_microtask({ + label = "Trigger mine", + on_start = function(self, mob) + mob._temp_custom_state.mine_timer = 0 + mob._temp_custom_state.mine_notifications = 0 + mob._temp_custom_state.mine_blink_timer = 0 + mob._temp_custom_state.mine_blink_state = false + mob._temp_custom_state.mine_active = false + end, + on_step = function(self, mob, dtime) + local mobpos = mob.object:get_pos() + local range + if mob._temp_custom_state.mine_active then + local closest = find_closest_player_in_range(mobpos, MINE_DEACTIVATION_RANGE) + if not closest then + mob._temp_custom_state.mine_active = false + mob._temp_custom_state.mine_timer = 0 + mob._temp_custom_state.mine_blink_timer = 0 + mob._temp_custom_state.mine_blink_state = false + mob._temp_custom_state.mine_notifications = 0 + mob.object:set_texture_mod("") + else + mob._temp_custom_state.mine_timer = mob._temp_custom_state.mine_timer + dtime + mob._temp_custom_state.mine_blink_timer = mob._temp_custom_state.mine_blink_timer + dtime + if mob._temp_custom_state.mine_timer >= BOOM_TIMER then + explode(mob) + return + end + if mob._temp_custom_state.mine_blink_timer >= BLINK_TIMER then + mob._temp_custom_state.mine_blink_state = not mob._temp_custom_state.mine_blink_state + if mob._temp_custom_state.mine_blink_state == true then + mob.object:set_texture_mod("^[brighten") + else + mob.object:set_texture_mod("") + end + mob._temp_custom_state.mine_blink_timer = 0 + end + if mob._temp_custom_state.mine_notifications < math.floor(mob._temp_custom_state.mine_timer) then + rp_mobs.default_mob_sound(mob, "war_cry", false) + mob._temp_custom_state.mine_notifications = math.floor(mob._temp_custom_state.mine_timer) + end + end + else + local closest = find_closest_player_in_range(mobpos, MINE_ACTIVATION_RANGE) + if closest then + mob._temp_custom_state.mine_active = true + mob._temp_custom_state.mine_timer = 0 + mob._temp_custom_state.mine_blink_timer = 0 + mob._temp_custom_state.mine_blink_state = false + mob._temp_custom_state.mine_notifications = 0 + rp_mobs.default_mob_sound(mob, "war_cry", false) + end + end + end, + is_finished = function() + return false + end, + }) +end + +local function mine_decider(task_queue, mob) + local task = rp_mobs.create_task({label="Trigger mine"}) + local mtask = microtask_mine() + rp_mobs.add_microtask_to_task(mob, mtask, task) + rp_mobs.add_task_to_task_queue(task_queue, task) +end + rp_mobs.register_mob("rp_mobs_mobs:mineturtle", { description = S("Mine Turtle"), is_animal = false, @@ -74,6 +180,7 @@ rp_mobs.register_mob("rp_mobs_mobs:mineturtle", { rp_mobs.init_tasks(self) rp_mobs.add_task_queue(self, rp_mobs_mobs.task_queue_land_animal_roam(task_queue_roam_settings)) rp_mobs.add_task_queue(self, rp_mobs_mobs.task_queue_follow_scan(VIEW_RANGE, {})) + rp_mobs.add_task_queue(self, rp_mobs.create_task_queue(mine_decider)) end, get_staticdata = rp_mobs.get_staticdata_default, on_step = function(self, dtime, moveresult) diff --git a/mods/rp_mobs_mobs/mod.conf b/mods/rp_mobs_mobs/mod.conf index 5fb0595a..5b294a07 100644 --- a/mods/rp_mobs_mobs/mod.conf +++ b/mods/rp_mobs_mobs/mod.conf @@ -1,5 +1,5 @@ name = rp_mobs_mobs title = Repixture Mobs description = Repixture Mobs: Mob definitions, behavior, graphics, models, sounds -depends = rp_mobs, rp_achievements +depends = rp_mobs, rp_achievements, rp_tnt optional_depends = rp_nav