diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index c221e78d690..f4463434066 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -37,35 +37,83 @@ . += "This capsule has the [template.name] stored." . += template.description -/obj/item/survivalcapsule/attack_self() +/obj/item/survivalcapsule/interact(mob/user) + . = ..() + if(.) + return . + //Can't grab when capsule is New() because templates aren't loaded then get_template() - if(!used) - loc.visible_message(span_warning("\The [src] begins to shake. Stand back!")) - used = TRUE - sleep(5 SECONDS) - var/turf/deploy_location = get_turf(src) - var/status = template.check_deploy(deploy_location) - switch(status) - if(SHELTER_DEPLOY_BAD_AREA) - src.loc.visible_message(span_warning("\The [src] will not function in this area.")) - if(SHELTER_DEPLOY_BAD_TURFS, SHELTER_DEPLOY_ANCHORED_OBJECTS, SHELTER_DEPLOY_OUTSIDE_MAP) - var/width = template.width - var/height = template.height - src.loc.visible_message(span_warning("\The [src] doesn't have room to deploy! You need to clear a [width]x[height] area!")) - if(status != SHELTER_DEPLOY_ALLOWED) - used = FALSE - return + if(used) + return FALSE - template.load(deploy_location, centered = TRUE) - var/turf/T = deploy_location - if(!is_mining_level(T.z)) //only report capsules away from the mining/lavaland level - message_admins("[ADMIN_LOOKUPFLW(usr)] activated a bluespace capsule away from the mining level! [ADMIN_VERBOSEJMP(T)]") - log_admin("[key_name(usr)] activated a bluespace capsule away from the mining level at [AREACOORD(T)]") + loc.visible_message(span_warning("[src] begins to shake. Stand back!")) + used = TRUE + addtimer(CALLBACK(src, PROC_REF(expand), user), 5 SECONDS) + return TRUE - playsound(src, 'sound/effects/phasein.ogg', 100, TRUE) - new /obj/effect/particle_effect/fluid/smoke(get_turf(src)) - qdel(src) +/// Expands the capsule into a full shelter, placing the template at the item's location (NOT triggerer's location) +/obj/item/survivalcapsule/proc/expand(mob/triggerer) + if(QDELETED(src)) + return + + var/turf/deploy_location = get_turf(src) + var/status = template.check_deploy(deploy_location) + switch(status) + if(SHELTER_DEPLOY_BAD_AREA) + loc.visible_message(span_warning("[src] will not function in this area.")) + if(SHELTER_DEPLOY_BAD_TURFS, SHELTER_DEPLOY_ANCHORED_OBJECTS, SHELTER_DEPLOY_OUTSIDE_MAP) + loc.visible_message(span_warning("[src] doesn't have room to deploy! You need to clear a [template.width]x[template.height] area!")) + + if(status != SHELTER_DEPLOY_ALLOWED) + used = FALSE + return + + yote_nearby(deploy_location) + template.load(deploy_location, centered = TRUE) + trigger_admin_alert(triggerer, deploy_location) + playsound(src, 'sound/effects/phasein.ogg', 100, TRUE) + new /obj/effect/particle_effect/fluid/smoke(get_turf(src)) + qdel(src) + +/// Throws any mobs near the deployed location away from the item / shelter +/// Does some math to make closer mobs get thrown further +/obj/item/survivalcapsule/proc/yote_nearby(turf/deploy_location) + var/width = template.width + var/height = template.height + var/base_x_throw_distance = ceil(width / 2) + var/base_y_throw_distance = ceil(height / 2) + for(var/mob/living/did_not_stand_back in range(loc, "[width]x[height]")) + var/dir_to_center = get_dir(deploy_location, did_not_stand_back) || pick(GLOB.alldirs) + // Aiming to throw the target just enough to get them out of the range of the shelter + // IE: Stronger if they're closer, weaker if they're further away + var/throw_dist = 0 + var/x_component = abs(did_not_stand_back.x - deploy_location.x) + var/y_component = abs(did_not_stand_back.y - deploy_location.y) + if(ISDIAGONALDIR(dir_to_center)) + throw_dist = ceil(sqrt(base_x_throw_distance ** 2 + base_y_throw_distance ** 2) - (sqrt(x_component ** 2 + y_component ** 2))) + else if(dir_to_center & (NORTH|SOUTH)) + throw_dist = base_y_throw_distance - y_component + 1 + else if(dir_to_center & (EAST|WEST)) + throw_dist = base_x_throw_distance - x_component + 1 + + did_not_stand_back.Paralyze(3 SECONDS) + did_not_stand_back.Knockdown(6 SECONDS) + did_not_stand_back.throw_at( + target = get_edge_target_turf(did_not_stand_back, dir_to_center), + range = throw_dist, + speed = 3, + force = MOVE_FORCE_VERY_STRONG, + ) + +/// Logs if the capsule was triggered, by default only if it happened on non-lavaland +/obj/item/survivalcapsule/proc/trigger_admin_alert(mob/triggerer, turf/trigger_loc) + //only report capsules away from the mining/lavaland level + if(is_mining_level(trigger_loc.z)) + return + + message_admins("[ADMIN_LOOKUPFLW(triggerer)] activated a bluespace capsule away from the mining level! [ADMIN_VERBOSEJMP(trigger_loc)]") + log_admin("[key_name(triggerer)] activated a bluespace capsule away from the mining level at [AREACOORD(trigger_loc)]") //Non-default pods