mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-25 17:07:15 +01:00
mining module reorganization (#6739)
Reorganizes the module in prep for refactoring and development.
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
var/global/list/total_extraction_beacons = list()
|
||||
|
||||
// todo: this should be included in the air-support module being added later, not just a mining exclusive
|
||||
|
||||
/obj/item/extraction_pack
|
||||
name = "fulton extraction pack"
|
||||
desc = "A balloon pack that can be used to extract equipment or personnel to a Fulton Recovery Beacon. Anything not bolted down can be moved. Link the pack to a beacon by using the pack in hand."
|
||||
icon = 'icons/obj/fulton.dmi'
|
||||
icon_state = "extraction_pack"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/obj/structure/extraction_point/beacon
|
||||
var/list/beacon_networks = list("station")
|
||||
var/uses_left = 3
|
||||
var/can_use_indoors = FALSE
|
||||
var/safe_for_living_creatures = 1
|
||||
var/stuntime = 15
|
||||
|
||||
/obj/item/extraction_pack/wormhole
|
||||
name = "wormhole fulton extraction pack"
|
||||
desc = "A balloon pack with integrated wormhole technology and less disruptive movement that can be used to extract equipment or personnel to a Fulton Recovery Beacon. Anything not bolted down can be moved. Link the pack to a beacon by using the pack in hand."
|
||||
can_use_indoors = TRUE
|
||||
stuntime = 3
|
||||
|
||||
/obj/item/extraction_holdercrate
|
||||
name = "extraction crate"
|
||||
desc = "A regular old crate."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "phoroncrate"
|
||||
|
||||
/obj/item/extraction_pack/examine(mob/user, dist)
|
||||
. = ..()
|
||||
. +="It has [uses_left] use\s remaining."
|
||||
|
||||
/obj/item/extraction_pack/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/list/possible_beacons = list()
|
||||
for(var/B in global.total_extraction_beacons)
|
||||
var/obj/structure/extraction_point/EP = B
|
||||
if(EP.beacon_network in beacon_networks)
|
||||
possible_beacons += EP
|
||||
|
||||
if(!possible_beacons.len)
|
||||
to_chat(user, "There are no extraction beacons in existence!")
|
||||
return
|
||||
|
||||
else
|
||||
var/A
|
||||
|
||||
A = input("Select a beacon to connect to", "Balloon Extraction Pack", A) as null|anything in possible_beacons
|
||||
|
||||
if(!A)
|
||||
return
|
||||
beacon = A
|
||||
to_chat(user, "You link the extraction pack to the beacon system.")
|
||||
|
||||
/obj/item/extraction_pack/afterattack(atom/movable/target, mob/user, clickchain_flags, list/params)
|
||||
if(!beacon)
|
||||
to_chat(user, "[src] is not linked to a beacon, and cannot be used.")
|
||||
return
|
||||
if(!can_use_indoors)
|
||||
var/turf/T = get_turf(target)
|
||||
if(T && !T.outdoors)
|
||||
to_chat(user, "[src] can only be used on things that are outdoors!")
|
||||
return
|
||||
if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY))
|
||||
return
|
||||
if(!istype(target))
|
||||
return
|
||||
else
|
||||
if(!safe_for_living_creatures && check_for_living_mobs(target))
|
||||
to_chat(user, "[src] is not safe for use with living creatures, they wouldn't survive the trip back!")
|
||||
return
|
||||
if(!isturf(target.loc)) // no extracting stuff inside other stuff
|
||||
return
|
||||
if(target.anchored)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start attaching the pack to [target]...</span>")
|
||||
if(do_after(user,50,target=target))
|
||||
to_chat(user, "<span class='notice'>You attach the pack to [target] and activate it.</span>")
|
||||
/* No components, sorry. No convienence for you!
|
||||
if(loc == user && istype(user.back, /obj/item/storage/backpack))
|
||||
var/obj/item/storage/backpack/B = user.back
|
||||
B.SendSignal(COMSIG_TRY_STORAGE_INSERT, src, user, FALSE, FALSE)
|
||||
*/
|
||||
uses_left--
|
||||
if(uses_left <= 0)
|
||||
user.temporarily_remove_from_inventory(src, INV_OP_FORCE | INV_OP_SHOULD_NOT_INTERCEPT | INV_OP_SILENT)
|
||||
var/mutable_appearance/balloon
|
||||
var/mutable_appearance/balloon2
|
||||
var/mutable_appearance/balloon3
|
||||
if(isliving(target))
|
||||
var/mob/living/M = target
|
||||
M.adjust_stunned(20 * 10) // Keep them from moving during the duration of the extraction
|
||||
if(M.buckled)
|
||||
M.buckled.unbuckle_mob(M)
|
||||
else
|
||||
target.anchored = TRUE
|
||||
target.density = FALSE
|
||||
var/obj/effect/extraction_holder/holder_obj = new(target.loc)
|
||||
holder_obj.appearance = /obj/item/extraction_holdercrate
|
||||
target.forceMove(holder_obj)
|
||||
balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand")
|
||||
balloon2.pixel_y = 18
|
||||
balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
holder_obj.add_overlay(balloon2)
|
||||
sleep(4)
|
||||
balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon")
|
||||
balloon.pixel_y = 18
|
||||
balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
holder_obj.cut_overlay(balloon2)
|
||||
holder_obj.add_overlay(balloon)
|
||||
playsound(holder_obj.loc, 'sound/items/fulext_deploy.wav', 50, 1, -3)
|
||||
animate(holder_obj, pixel_z = 10, time = 20)
|
||||
sleep(20)
|
||||
animate(holder_obj, pixel_z = 15, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 10, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 15, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 10, time = 10)
|
||||
sleep(10)
|
||||
playsound(holder_obj.loc, 'sound/items/fultext_launch.wav', 50, 1, -3)
|
||||
animate(holder_obj, pixel_z = 1000, time = 30)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/L = target
|
||||
L.adjust_stunned(20 * stuntime)
|
||||
L.drowsyness = 0
|
||||
sleep(30)
|
||||
var/list/flooring_near_beacon = list()
|
||||
for(var/turf/T in range(1, beacon))
|
||||
if(T.density)
|
||||
continue
|
||||
flooring_near_beacon += T
|
||||
if(!length(flooring_near_beacon))
|
||||
holder_obj.forceMove(get_turf(beacon))
|
||||
else
|
||||
holder_obj.forceMove(pick(flooring_near_beacon))
|
||||
animate(holder_obj, pixel_z = 10, time = 50)
|
||||
sleep(50)
|
||||
animate(holder_obj, pixel_z = 15, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 10, time = 10)
|
||||
sleep(10)
|
||||
balloon3 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract")
|
||||
balloon3.pixel_y = 10
|
||||
balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
holder_obj.cut_overlay(balloon)
|
||||
holder_obj.add_overlay(balloon3)
|
||||
sleep(4)
|
||||
holder_obj.cut_overlay(balloon3)
|
||||
target.anchored = FALSE // An item has to be unanchored to be extracted in the first place.
|
||||
target.density = initial(target.density)
|
||||
animate(holder_obj, pixel_z = 0, time = 5)
|
||||
sleep(5)
|
||||
target.forceMove(holder_obj.loc)
|
||||
qdel(holder_obj)
|
||||
if(uses_left <= 0)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/fulton_core
|
||||
name = "extraction beacon signaller"
|
||||
desc = "Emits a signal which fulton recovery devices can lock onto. Activate in hand to create a beacon."
|
||||
icon = 'icons/obj/stock_parts.dmi'
|
||||
icon_state = "subspace_amplifier"
|
||||
|
||||
/obj/item/fulton_core/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(do_after(user,15,target = user) && !QDELETED(src))
|
||||
new /obj/structure/extraction_point(get_turf(user))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/extraction_point
|
||||
name = "fulton recovery beacon"
|
||||
desc = "A beacon for the fulton recovery system. Activate a pack in your hand to link it to a beacon."
|
||||
icon = 'icons/obj/fulton.dmi'
|
||||
icon_state = "extraction_point"
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
var/beacon_network = "station"
|
||||
|
||||
/obj/structure/extraction_point/Initialize(mapload)
|
||||
. = ..()
|
||||
name += " ([rand(100,999)]) ([get_area_name(src, TRUE)])"
|
||||
global.total_extraction_beacons += src
|
||||
|
||||
/obj/structure/extraction_point/Destroy()
|
||||
global.total_extraction_beacons -= src
|
||||
..()
|
||||
|
||||
/obj/effect/extraction_holder
|
||||
name = "extraction holder"
|
||||
desc = "you shouldnt see this"
|
||||
var/atom/movable/stored_obj
|
||||
|
||||
/obj/item/extraction_pack/proc/check_for_living_mobs(atom/A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(L.stat != DEAD)
|
||||
return 1
|
||||
for(var/thing in A.get_all_contents())
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
update_icon()
|
||||
if(L.stat != DEAD)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/effect/extraction_holder/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/extraction_holder/singularity_pull()
|
||||
return
|
||||
@@ -0,0 +1,639 @@
|
||||
/**
|
||||
* This is here for now
|
||||
*/
|
||||
/proc/lavaland_environment_check(turf/simulated/T)
|
||||
. = TRUE
|
||||
if(!istype(T))
|
||||
return
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
if(!istype(environment))
|
||||
return
|
||||
var/pressure = environment.return_pressure()
|
||||
if(pressure > LAVALAND_EQUIPMENT_EFFECT_PRESSURE)
|
||||
. = FALSE
|
||||
if(environment.temperature < (T20C - 30))
|
||||
. = TRUE
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator
|
||||
name = "proto-kinetic accelerator"
|
||||
desc = "A self-recharging mining tool that fires unstable blasts of kinetic energy, because management wouldn't let you have the ripper saws or line cutters. Especially effective in low-pressure environments."
|
||||
icon = 'icons/obj/gun/energy.dmi'
|
||||
icon_state = "kineticgun"
|
||||
item_state = "kineticgun"
|
||||
cell_type = /obj/item/cell/device/weapon/empproof
|
||||
clothing_flags = NONE
|
||||
charge_meter = FALSE
|
||||
|
||||
projectile_type = /obj/projectile/kinetic
|
||||
charge_cost = 1200
|
||||
battery_lock = TRUE
|
||||
fire_sound = 'sound/weapons/kenetic_accel.ogg'
|
||||
render_use_legacy_by_default = FALSE
|
||||
var/overheat_time = 16
|
||||
var/holds_charge = FALSE
|
||||
var/unique_frequency = FALSE // modified by KA modkits
|
||||
var/overheat = FALSE
|
||||
var/emptystate = "kineticgun_empty"
|
||||
|
||||
var/max_mod_capacity = 100
|
||||
var/list/modkits = list()
|
||||
|
||||
var/recharge_timerid
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/consume_next_projectile()
|
||||
if(overheat)
|
||||
return
|
||||
. = ..()
|
||||
if(.)
|
||||
var/obj/projectile/P = .
|
||||
modify_projectile(P)
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/handle_post_fire(mob/user, atom/target, pointblank, reflex)
|
||||
. = ..()
|
||||
attempt_reload()
|
||||
|
||||
/*
|
||||
/obj/item/gun/energy/kinetic_accelerator/premiumka
|
||||
name = "premium accelerator"
|
||||
desc = "A premium kinetic accelerator fitted with an extended barrel and increased pressure tank."
|
||||
icon_state = "premiumgun"
|
||||
item_state = "premiumgun"
|
||||
projectile_type = /obj/projectile/kinetic/premium
|
||||
*/
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/examine(mob/user, dist)
|
||||
. = ..()
|
||||
if(max_mod_capacity)
|
||||
. += "<b>[get_remaining_mod_capacity()]%</b> mod capacity remaining."
|
||||
for(var/A in get_modkits())
|
||||
var/obj/item/ka_modkit/M = A
|
||||
. += "<span class='notice'>There is \a [M] installed, using <b>[M.cost]%</b> capacity.</span>"
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/Exited(atom/movable/AM)
|
||||
. = ..()
|
||||
if((AM in modkits) && istype(AM, /obj/item/ka_modkit))
|
||||
var/obj/item/ka_modkit/M = AM
|
||||
M.uninstall(src, FALSE)
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/tool/crowbar))
|
||||
if(modkits.len)
|
||||
to_chat(user, "<span class='notice'>You pry the modifications out.</span>")
|
||||
playsound(loc, I.tool_sound, 100, 1)
|
||||
for(var/obj/item/ka_modkit/M in modkits)
|
||||
M.uninstall(src)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There are no modifications currently installed.</span>")
|
||||
if(istype(I, /obj/item/ka_modkit))
|
||||
var/obj/item/ka_modkit/MK = I
|
||||
MK.install(src, user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/proc/get_remaining_mod_capacity()
|
||||
var/current_capacity_used = 0
|
||||
for(var/A in get_modkits())
|
||||
var/obj/item/ka_modkit/M = A
|
||||
current_capacity_used += M.cost
|
||||
return max_mod_capacity - current_capacity_used
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/proc/get_modkits()
|
||||
. = list()
|
||||
for(var/A in modkits)
|
||||
. += A
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/proc/modify_projectile(obj/projectile/kinetic/K)
|
||||
K.kinetic_gun = src //do something special on-hit, easy!
|
||||
for(var/A in get_modkits())
|
||||
var/obj/item/ka_modkit/M = A
|
||||
M.modify_projectile(K)
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/cyborg
|
||||
holds_charge = TRUE
|
||||
unique_frequency = TRUE
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/cyborg/Destroy()
|
||||
for(var/obj/item/ka_modkit/M in modkits)
|
||||
M.uninstall(src)
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg
|
||||
holds_charge = TRUE
|
||||
unique_frequency = TRUE
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg/Destroy()
|
||||
for(var/obj/item/ka_modkit/M in modkits)
|
||||
M.uninstall(src)
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/minebot
|
||||
// trigger_guard = TRIGGER_GUARD_ALLOW_ALL
|
||||
overheat_time = 20
|
||||
holds_charge = TRUE
|
||||
unique_frequency = TRUE
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!holds_charge)
|
||||
empty()
|
||||
AddElement(/datum/element/conflict_checking, CONFLICT_ELEMENT_KA)
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/equipped(mob/user, slot, flags)
|
||||
. = ..()
|
||||
if(power_supply.charge < charge_cost)
|
||||
attempt_reload()
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/dropped(mob/user, flags, atom/newLoc)
|
||||
. = ..()
|
||||
if(!QDELING(src) && !holds_charge)
|
||||
// Put it on a delay because moving item from slot to hand
|
||||
// calls dropped().
|
||||
addtimer(CALLBACK(src, PROC_REF(empty_if_not_held)), 2)
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/proc/empty_if_not_held()
|
||||
if(!ismob(loc) && !istype(loc, /obj/item/integrated_circuit))
|
||||
empty()
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/proc/empty()
|
||||
if(power_supply)
|
||||
power_supply.use(power_supply.charge)
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/proc/attempt_reload(recharge_time)
|
||||
if(!power_supply)
|
||||
return
|
||||
if(overheat)
|
||||
return
|
||||
if(!recharge_time)
|
||||
recharge_time = overheat_time
|
||||
overheat = TRUE
|
||||
update_icon()
|
||||
|
||||
var/carried = max(1, loc.ConflictElementCount(CONFLICT_ELEMENT_KA))
|
||||
|
||||
deltimer(recharge_timerid)
|
||||
recharge_timerid = addtimer(CALLBACK(src, PROC_REF(reload)), recharge_time * carried, TIMER_STOPPABLE)
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/emp_act(severity)
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/proc/reload()
|
||||
power_supply.give(power_supply.maxcharge)
|
||||
// process_chamber()
|
||||
// if(!suppressed)
|
||||
playsound(src, 'sound/weapons/kenetic_reload.ogg', 60, 1)
|
||||
// else
|
||||
// to_chat(loc, "<span class='warning'>[src] silently charges up.</span>")
|
||||
overheat = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/update_overlays()
|
||||
. = ..()
|
||||
if(overheat || (power_supply.charge == 0))
|
||||
. += emptystate
|
||||
|
||||
//Projectiles
|
||||
/obj/projectile/kinetic
|
||||
name = "kinetic force"
|
||||
icon_state = null
|
||||
damage_force = 30
|
||||
damage_type = BRUTE
|
||||
damage_flag = ARMOR_BOMB
|
||||
range = WORLD_ICON_SIZE * 4
|
||||
// log_override = TRUE
|
||||
|
||||
var/pressure_decrease_active = FALSE
|
||||
var/pressure_decrease = 1/3
|
||||
var/obj/item/gun/energy/kinetic_accelerator/kinetic_gun
|
||||
|
||||
/obj/projectile/kinetic/premium
|
||||
damage_force = 40
|
||||
damage_type = BRUTE
|
||||
range = 5
|
||||
|
||||
/obj/projectile/kinetic/Destroy()
|
||||
kinetic_gun = null
|
||||
return ..()
|
||||
|
||||
/obj/projectile/kinetic/pre_impact(atom/target, impact_flags, def_zone)
|
||||
if(kinetic_gun)
|
||||
var/list/mods = kinetic_gun.get_modkits()
|
||||
for(var/obj/item/ka_modkit/M in mods)
|
||||
M.projectile_prehit(src, target, kinetic_gun)
|
||||
if(!pressure_decrease_active && !lavaland_environment_check(get_turf(src)))
|
||||
name = "weakened [name]"
|
||||
damage_force = damage_force * pressure_decrease
|
||||
pressure_decrease_active = TRUE
|
||||
return ..()
|
||||
|
||||
/obj/projectile/kinetic/legacy_on_range()
|
||||
strike_thing()
|
||||
..()
|
||||
|
||||
/obj/projectile/kinetic/on_impact(atom/target, impact_flags, def_zone, efficiency)
|
||||
. = ..()
|
||||
if(. & PROJECTILE_IMPACT_FLAGS_UNCONDITIONAL_ABORT)
|
||||
return
|
||||
strike_thing(target)
|
||||
|
||||
/obj/projectile/kinetic/proc/strike_thing(atom/target)
|
||||
if(!pressure_decrease_active && !lavaland_environment_check(get_turf(src)))
|
||||
name = "weakened [name]"
|
||||
damage_force = damage_force * pressure_decrease
|
||||
pressure_decrease_active = TRUE
|
||||
var/turf/target_turf = get_turf(target)
|
||||
if(!target_turf)
|
||||
target_turf = get_turf(src)
|
||||
if(kinetic_gun) //hopefully whoever shot this was not very, very unfortunate.
|
||||
var/list/mods = kinetic_gun.get_modkits()
|
||||
for(var/obj/item/ka_modkit/M in mods)
|
||||
M.projectile_strike_predamage(src, target_turf, target, kinetic_gun)
|
||||
for(var/obj/item/ka_modkit/M in mods)
|
||||
M.projectile_strike(src, target_turf, target, kinetic_gun)
|
||||
if(ismineralturf(target_turf))
|
||||
var/turf/simulated/mineral/M = target_turf
|
||||
M.GetDrilled(TRUE)
|
||||
var/obj/effect/temp_visual/kinetic_blast/K = new /obj/effect/temp_visual/kinetic_blast(target_turf)
|
||||
K.color = color
|
||||
|
||||
|
||||
//Modkits
|
||||
/obj/item/ka_modkit
|
||||
name = "kinetic accelerator modification kit"
|
||||
desc = "An upgrade for kinetic accelerators."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "modkit"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/require_module = 1
|
||||
// module_type = list(/obj/item/robot_module/miner)
|
||||
var/denied_type = null
|
||||
var/maximum_of_type = 1
|
||||
var/cost = 30
|
||||
var/modifier = 1 //For use in any mod kit that has numerical modifiers
|
||||
var/minebot_upgrade = TRUE
|
||||
var/minebot_exclusive = FALSE
|
||||
|
||||
/obj/item/ka_modkit/examine(mob/user, dist)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Occupies <b>[cost]%</b> of mod capacity.</span>"
|
||||
|
||||
/obj/item/ka_modkit/attackby(obj/item/A, mob/user)
|
||||
if(istype(A, /obj/item/gun/energy/kinetic_accelerator))
|
||||
install(A, user)
|
||||
else
|
||||
..()
|
||||
|
||||
/*
|
||||
/obj/item/ka_modkit/afterInstall(mob/living/silicon/robot/R)
|
||||
for(var/obj/item/gun/energy/kinetic_accelerator/H in R.module.modules)
|
||||
if(install(H, R)) //It worked
|
||||
return
|
||||
to_chat(R, "<span class='alert'>Upgrade error - Aborting Kinetic Accelerator linking.</span>") //No applicable KA found, insufficient capacity, or some other problem.
|
||||
*/
|
||||
|
||||
/obj/item/ka_modkit/proc/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user)
|
||||
. = TRUE
|
||||
if(src in KA.modkits) // Sanity check to prevent installing the same modkit twice thanks to occasional click/lag delays.
|
||||
return FALSE
|
||||
// if(minebot_upgrade)
|
||||
// if(minebot_exclusive && !istype(KA.loc, /mob/living/simple_animal/hostile/mining_drone))
|
||||
// to_chat(user, "<span class='notice'>The modkit you're trying to install is only rated for minebot use.</span>")
|
||||
// return FALSE
|
||||
// else if(istype(KA.loc, /mob/living/simple_animal/hostile/mining_drone))
|
||||
// to_chat(user, "<span class='notice'>The modkit you're trying to install is not rated for minebot use.</span>")
|
||||
// return FALSE
|
||||
if(denied_type)
|
||||
var/number_of_denied = 0
|
||||
for(var/A in KA.get_modkits())
|
||||
var/obj/item/ka_modkit/M = A
|
||||
if(istype(M, denied_type))
|
||||
number_of_denied++
|
||||
if(number_of_denied >= maximum_of_type)
|
||||
. = FALSE
|
||||
break
|
||||
if(KA.get_remaining_mod_capacity() >= cost)
|
||||
if(.)
|
||||
if(user.is_in_inventory(src))
|
||||
if(!user.attempt_insert_item_for_installation(src, KA))
|
||||
return FALSE
|
||||
else
|
||||
forceMove(KA)
|
||||
to_chat(user, "<span class='notice'>You install the modkit.</span>")
|
||||
playsound(loc, 'sound/items/screwdriver.ogg', 100, 1)
|
||||
KA.modkits += src
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The modkit you're trying to install would conflict with an already installed modkit. Use a crowbar to remove existing modkits.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You don't have room(<b>[KA.get_remaining_mod_capacity()]%</b> remaining, [cost]% needed) to install this modkit. Use a crowbar to remove existing modkits.</span>")
|
||||
. = FALSE
|
||||
|
||||
/obj/item/ka_modkit/proc/uninstall(obj/item/gun/energy/kinetic_accelerator/KA, forcemove = TRUE)
|
||||
KA.modkits -= src
|
||||
if(forcemove)
|
||||
forceMove(get_turf(KA))
|
||||
|
||||
/obj/item/ka_modkit/proc/modify_projectile(obj/projectile/kinetic/K)
|
||||
|
||||
//use this one for effects you want to trigger before any damage is done at all and before damage is decreased by pressure
|
||||
/obj/item/ka_modkit/proc/projectile_prehit(obj/projectile/kinetic/K, atom/target, obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
//use this one for effects you want to trigger before mods that do damage
|
||||
/obj/item/ka_modkit/proc/projectile_strike_predamage(obj/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
//and this one for things that don't need to trigger before other damage-dealing mods
|
||||
/obj/item/ka_modkit/proc/projectile_strike(obj/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
|
||||
//Range
|
||||
/obj/item/ka_modkit/range
|
||||
name = "range increase"
|
||||
desc = "Increases the range of a kinetic accelerator when installed."
|
||||
modifier = 1
|
||||
cost = 25
|
||||
|
||||
/obj/item/ka_modkit/range/modify_projectile(obj/projectile/kinetic/K)
|
||||
K.range += modifier * WORLD_ICON_SIZE
|
||||
//Cooldown
|
||||
/obj/item/ka_modkit/cooldown
|
||||
name = "cooldown decrease"
|
||||
desc = "Decreases the cooldown of a kinetic accelerator. Not rated for minebot use."
|
||||
modifier = 2.5
|
||||
minebot_upgrade = FALSE
|
||||
var/decreased
|
||||
|
||||
/obj/item/ka_modkit/cooldown/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
var/old = KA.overheat_time
|
||||
KA.overheat_time = max(0, KA.overheat_time - modifier)
|
||||
decreased = old - KA.overheat_time
|
||||
|
||||
|
||||
/obj/item/ka_modkit/cooldown/uninstall(obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
KA.overheat_time += decreased
|
||||
..()
|
||||
|
||||
/obj/item/ka_modkit/cooldown/minebot
|
||||
name = "minebot cooldown decrease"
|
||||
desc = "Decreases the cooldown of a kinetic accelerator. Only rated for minebot use."
|
||||
icon_state = "door_electronics"
|
||||
icon = 'icons/obj/module.dmi'
|
||||
denied_type = /obj/item/ka_modkit/cooldown/minebot
|
||||
modifier = 10
|
||||
cost = 0
|
||||
minebot_upgrade = TRUE
|
||||
minebot_exclusive = TRUE
|
||||
|
||||
|
||||
//Capacity
|
||||
/obj/item/ka_modkit/capacity
|
||||
name = "capacity increase"
|
||||
desc = "A cutdown accelerator frame that increases mod capacity while reducing damage. Not compatible with minebots."
|
||||
modifier = -6
|
||||
cost = -15
|
||||
maximum_of_type = 2
|
||||
minebot_upgrade = FALSE
|
||||
denied_type = /obj/item/ka_modkit/capacity
|
||||
|
||||
/obj/item/ka_modkit/capacity/modify_projectile(obj/projectile/kinetic/K)
|
||||
K.damage_force += modifier
|
||||
|
||||
|
||||
//AoE blasts
|
||||
/obj/item/ka_modkit/aoe
|
||||
modifier = 0
|
||||
var/turf_aoe = FALSE
|
||||
var/stats_stolen = FALSE
|
||||
|
||||
/obj/item/ka_modkit/aoe/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
for(var/obj/item/ka_modkit/aoe/AOE in KA.modkits) //make sure only one of the aoe modules has values if somebody has multiple
|
||||
if(AOE.stats_stolen || AOE == src)
|
||||
continue
|
||||
modifier += AOE.modifier //take its modifiers
|
||||
AOE.modifier = 0
|
||||
turf_aoe += AOE.turf_aoe
|
||||
AOE.turf_aoe = FALSE
|
||||
AOE.stats_stolen = TRUE
|
||||
|
||||
/obj/item/ka_modkit/aoe/uninstall(obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
..()
|
||||
modifier = initial(modifier) //get our modifiers back
|
||||
turf_aoe = initial(turf_aoe)
|
||||
stats_stolen = FALSE
|
||||
|
||||
/obj/item/ka_modkit/aoe/modify_projectile(obj/projectile/kinetic/K)
|
||||
K.name = "kinetic explosion"
|
||||
|
||||
/obj/item/ka_modkit/aoe/projectile_strike(obj/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
if(stats_stolen)
|
||||
return
|
||||
new /obj/effect/temp_visual/explosion/fast(target_turf)
|
||||
if(turf_aoe)
|
||||
for(var/T in RANGE_TURFS(1, target_turf) - target_turf)
|
||||
if(ismineralturf(T))
|
||||
var/turf/simulated/mineral/M = T
|
||||
M.GetDrilled(TRUE)
|
||||
if(modifier)
|
||||
for(var/mob/living/L in range(1, target_turf) - K.firer - target)
|
||||
var/armor = L.run_armor_check(K.def_zone, K.damage_flag)
|
||||
// var/armor = L.run_armor_check(K.def_zone, K.flag, null, null, K.armour_penetration)
|
||||
L.apply_damage(K.damage_force*modifier, K.damage_type, K.def_zone, armor)
|
||||
// L.apply_damage(K.damage_force*modifier, K.damage_type, K.def_zone, armor)
|
||||
to_chat(L, "<span class='userdanger'>You're struck by a [K.name]!</span>")
|
||||
|
||||
/obj/item/ka_modkit/aoe/turfs
|
||||
name = "mining explosion"
|
||||
desc = "Causes the kinetic accelerator to destroy rock in an AoE."
|
||||
denied_type = /obj/item/ka_modkit/aoe/turfs
|
||||
turf_aoe = TRUE
|
||||
|
||||
/obj/item/ka_modkit/aoe/turfs/andmobs
|
||||
name = "offensive mining explosion"
|
||||
desc = "Causes the kinetic accelerator to destroy rock and damage mobs in an AoE."
|
||||
maximum_of_type = 3
|
||||
modifier = 0.25
|
||||
|
||||
/obj/item/ka_modkit/aoe/mobs
|
||||
name = "offensive explosion"
|
||||
desc = "Causes the kinetic accelerator to damage mobs in an AoE."
|
||||
modifier = 0.2
|
||||
|
||||
//Minebot passthrough
|
||||
/obj/item/ka_modkit/minebot_passthrough
|
||||
name = "minebot passthrough"
|
||||
desc = "Causes kinetic accelerator shots to pass through minebots."
|
||||
cost = 0
|
||||
|
||||
//Tendril-unique modules
|
||||
/obj/item/ka_modkit/cooldown/repeater
|
||||
name = "rapid repeater"
|
||||
desc = "Quarters the kinetic accelerator's cooldown on striking a living target, but greatly increases the base cooldown."
|
||||
denied_type = /obj/item/ka_modkit/cooldown/repeater
|
||||
modifier = -14 //Makes the cooldown 3 seconds(with no cooldown mods) if you miss. Don't miss.
|
||||
cost = 50
|
||||
|
||||
/obj/item/ka_modkit/cooldown/repeater/projectile_strike_predamage(obj/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
var/valid_repeat = FALSE
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.stat != DEAD)
|
||||
valid_repeat = TRUE
|
||||
if(ismineralturf(target_turf))
|
||||
valid_repeat = TRUE
|
||||
if(valid_repeat)
|
||||
KA.overheat = FALSE
|
||||
KA.attempt_reload(KA.overheat_time * 0.25) //If you hit, the cooldown drops to 0.75 seconds.
|
||||
|
||||
/*
|
||||
/obj/item/ka_modkit/lifesteal
|
||||
name = "lifesteal crystal"
|
||||
desc = "Causes kinetic accelerator shots to slightly heal the firer on striking a living target."
|
||||
icon_state = "modkit_crystal"
|
||||
modifier = 2.5 //Not a very effective method of healing.
|
||||
cost = 20
|
||||
var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
|
||||
|
||||
/obj/item/ka_modkit/lifesteal/projectile_prehit(obj/projectile/kinetic/K, atom/target, obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
if(isliving(target) && isliving(K.firer))
|
||||
var/mob/living/L = target
|
||||
if(L.stat == DEAD)
|
||||
return
|
||||
L = K.firer
|
||||
L.heal_ordered_damage(modifier, damage_heal_order)
|
||||
*/
|
||||
|
||||
/obj/item/ka_modkit/resonator_blasts
|
||||
name = "resonator blast"
|
||||
desc = "Causes kinetic accelerator shots to leave and detonate resonator blasts."
|
||||
denied_type = /obj/item/ka_modkit/resonator_blasts
|
||||
cost = 30
|
||||
modifier = 0.25 //A bonus 15 damage if you burst the field on a target, 60 if you lure them into it.
|
||||
|
||||
/obj/item/ka_modkit/resonator_blasts/projectile_strike(obj/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
if(target_turf && !ismineralturf(target_turf)) //Don't make fields on mineral turfs.
|
||||
var/obj/effect/resonance/R = locate(/obj/effect/resonance) in target_turf
|
||||
if(R)
|
||||
R.resonance_damage *= modifier
|
||||
R.burst()
|
||||
return
|
||||
new /obj/effect/resonance(target_turf, K.firer, 30)
|
||||
|
||||
/*
|
||||
/obj/item/ka_modkit/bounty
|
||||
name = "death syphon"
|
||||
desc = "Killing or assisting in killing a creature permanently increases your damage against that type of creature."
|
||||
denied_type = /obj/item/ka_modkit/bounty
|
||||
modifier = 1.25
|
||||
cost = 30
|
||||
var/maximum_bounty = 25
|
||||
var/list/bounties_reaped = list()
|
||||
|
||||
/obj/item/ka_modkit/bounty/projectile_prehit(obj/projectile/kinetic/K, atom/target, obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
var/list/existing_marks = L.has_status_effect_list(STATUS_EFFECT_SYPHONMARK)
|
||||
for(var/i in existing_marks)
|
||||
var/datum/status_effect/syphon_mark/SM = i
|
||||
if(SM.reward_target == src) //we want to allow multiple people with bounty modkits to use them, but we need to replace our own marks so we don't multi-reward
|
||||
SM.reward_target = null
|
||||
qdel(SM)
|
||||
L.apply_status_effect(STATUS_EFFECT_SYPHONMARK, src)
|
||||
|
||||
/obj/item/ka_modkit/bounty/projectile_strike(obj/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(bounties_reaped[L.type])
|
||||
var/kill_modifier = 1
|
||||
if(K.pressure_decrease_active)
|
||||
kill_modifier *= K.pressure_decrease
|
||||
var/armor = L.run_armor_check(K.def_zone, K.flag, null, null, K.armour_penetration)
|
||||
L.apply_damage(bounties_reaped[L.type]*kill_modifier, K.damage_type, K.def_zone, armor)
|
||||
|
||||
/obj/item/ka_modkit/bounty/proc/get_kill(mob/living/L)
|
||||
var/bonus_mod = 1
|
||||
if(ismegafauna(L)) //megafauna reward
|
||||
bonus_mod = 4
|
||||
if(!bounties_reaped[L.type])
|
||||
bounties_reaped[L.type] = min(modifier * bonus_mod, maximum_bounty)
|
||||
else
|
||||
bounties_reaped[L.type] = min(bounties_reaped[L.type] + (modifier * bonus_mod), maximum_bounty)
|
||||
*/
|
||||
|
||||
//Indoors
|
||||
/obj/item/ka_modkit/indoors
|
||||
name = "decrease pressure penalty"
|
||||
desc = "A syndicate modification kit that increases the damage a kinetic accelerator does in high pressure environments."
|
||||
modifier = 2
|
||||
denied_type = /obj/item/ka_modkit/indoors
|
||||
maximum_of_type = 2
|
||||
cost = 35
|
||||
|
||||
/obj/item/ka_modkit/indoors/modify_projectile(obj/projectile/kinetic/K)
|
||||
K.pressure_decrease *= modifier
|
||||
|
||||
|
||||
//Trigger Guard
|
||||
|
||||
/*
|
||||
/obj/item/ka_modkit/trigger_guard
|
||||
name = "modified trigger guard"
|
||||
desc = "Allows creatures normally incapable of firing guns to operate the weapon when installed."
|
||||
cost = 20
|
||||
denied_type = /obj/item/ka_modkit/trigger_guard
|
||||
|
||||
/obj/item/ka_modkit/trigger_guard/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
KA.trigger_guard = TRIGGER_GUARD_ALLOW_ALL
|
||||
|
||||
/obj/item/ka_modkit/trigger_guard/uninstall(obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
KA.trigger_guard = TRIGGER_GUARD_NORMAL
|
||||
..()
|
||||
*/
|
||||
|
||||
//Cosmetic
|
||||
|
||||
/obj/item/ka_modkit/chassis_mod
|
||||
name = "super chassis"
|
||||
desc = "Makes your KA yellow. All the fun of having a more powerful KA without actually having a more powerful KA."
|
||||
cost = 0
|
||||
denied_type = /obj/item/ka_modkit/chassis_mod
|
||||
var/chassis_icon = "kineticgun_u"
|
||||
var/chassis_name = "super-kinetic accelerator"
|
||||
|
||||
/obj/item/ka_modkit/chassis_mod/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
KA.icon_state = chassis_icon
|
||||
KA.name = chassis_name
|
||||
|
||||
/obj/item/ka_modkit/chassis_mod/uninstall(obj/item/gun/energy/kinetic_accelerator/KA)
|
||||
KA.icon_state = initial(KA.icon_state)
|
||||
KA.name = initial(KA.name)
|
||||
..()
|
||||
|
||||
/obj/item/ka_modkit/chassis_mod/orange
|
||||
name = "hyper chassis"
|
||||
desc = "Makes your KA orange. All the fun of having explosive blasts without actually having explosive blasts."
|
||||
chassis_icon = "kineticgun_h"
|
||||
chassis_name = "hyper-kinetic accelerator"
|
||||
|
||||
/obj/item/ka_modkit/tracer
|
||||
name = "white tracer bolts"
|
||||
desc = "Causes kinetic accelerator bolts to have a white tracer trail and explosion."
|
||||
cost = 0
|
||||
denied_type = /obj/item/ka_modkit/tracer
|
||||
var/bolt_color = "#FFFFFF"
|
||||
|
||||
/obj/item/ka_modkit/tracer/modify_projectile(obj/projectile/kinetic/K)
|
||||
K.icon_state = "ka_tracer"
|
||||
K.color = bolt_color
|
||||
|
||||
/obj/item/ka_modkit/tracer/adjustable
|
||||
name = "adjustable tracer bolts"
|
||||
desc = "Causes kinetic accelerator bolts to have an adjustable-colored tracer trail and explosion. Use in-hand to change color."
|
||||
|
||||
/obj/item/ka_modkit/tracer/adjustable/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
bolt_color = input(user,"","Choose Color",bolt_color) as color|null
|
||||
@@ -0,0 +1,587 @@
|
||||
/*********************Mining Hammer****************/
|
||||
/obj/item/kinetic_crusher
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "crusher"
|
||||
item_state = "crusher0"
|
||||
item_icons = list(
|
||||
SLOT_ID_LEFT_HAND = 'icons/mob/inhands/weapons/hammers_lefthand.dmi',
|
||||
SLOT_ID_RIGHT_HAND = 'icons/mob/inhands/weapons/hammers_righthand.dmi'
|
||||
)
|
||||
name = "proto-kinetic crusher"
|
||||
desc = "An early design of the proto-kinetic accelerator, it is little more than an combination of various mining tools cobbled together, forming a high-tech club. \
|
||||
While it is an effective mining tool, it did little to aid any but the most skilled and/or suicidal miners against local fauna."
|
||||
damage_force = 0 //You can't hit stuff unless wielded
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = SLOT_BACK
|
||||
throw_force = 5
|
||||
throw_speed = 4
|
||||
/*
|
||||
armour_penetration = 10
|
||||
custom_materials = list(/datum/material/iron=1150, /datum/material/glass=2075)
|
||||
*/
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("smashed", "crushed", "cleaved", "chopped", "pulped")
|
||||
sharp = TRUE
|
||||
edge = TRUE
|
||||
// sharpness = SHARP_EDGED
|
||||
item_action_name = "Toggle Light"
|
||||
light_wedge = LIGHT_WIDE
|
||||
// actions_types = list(/datum/action/item_action/toggle_light)
|
||||
// var/list/trophies = list()
|
||||
var/charged = TRUE
|
||||
var/charge_time = 15
|
||||
var/detonation_damage = 50
|
||||
var/backstab_bonus = 30
|
||||
var/light_on = FALSE
|
||||
var/brightness_on = 7
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
/// Damage penalty factor to detonation damage to non simple mobs
|
||||
var/human_damage_nerf = 0.25
|
||||
/// Damage penalty factor to backstab bonus damage to non simple mobs
|
||||
var/human_backstab_nerf = 0.25
|
||||
/// damage buff for throw impacts
|
||||
var/thrown_bonus = 35
|
||||
/// do we need to be wielded?
|
||||
var/requires_wield = TRUE
|
||||
/// do we have a charge overlay?
|
||||
var/charge_overlay = TRUE
|
||||
/// do we update item state?
|
||||
var/update_item_state = FALSE
|
||||
|
||||
/obj/item/kinetic_crusher/cyborg //probably give this a unique sprite later
|
||||
desc = "An integrated version of the standard kinetic crusher with a grinded down axe head to dissuade mis-use against crewmen. Deals damage equal to the standard crusher against creatures, however."
|
||||
damage_force = 10 //wouldn't want to give a borg a 20 brute melee weapon unemagged now would we
|
||||
detonation_damage = 60
|
||||
wielded = 1
|
||||
|
||||
/obj/item/kinetic_crusher/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/conflict_checking, CONFLICT_ELEMENT_CRUSHER)
|
||||
|
||||
/*
|
||||
/obj/item/kinetic_crusher/Initialize(mapload)
|
||||
. = ..()
|
||||
if(requires_Wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, PROC_REF(on_wield))
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, PROC_REF(on_unwield))
|
||||
/obj/item/kinetic_crusher/ComponentInitialize()
|
||||
. = ..()
|
||||
if(requires_wield)
|
||||
AddComponent(/datum/component/butchering, 60, 110) //technically it's huge and bulky, but this provides an incentive to use it
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=20)
|
||||
*/
|
||||
|
||||
/obj/item/kinetic_crusher/Destroy()
|
||||
// QDEL_LIST(trophies)
|
||||
return ..()
|
||||
|
||||
/obj/item/kinetic_crusher/emag_act()
|
||||
. = ..()
|
||||
if(obj_flags & OBJ_EMAGGED)
|
||||
return
|
||||
obj_flags |= OBJ_EMAGGED
|
||||
|
||||
/obj/item/kinetic_crusher/proc/can_mark(mob/living/victim)
|
||||
if(obj_flags & OBJ_EMAGGED)
|
||||
return TRUE
|
||||
return !ishuman(victim) && !issilicon(victim)
|
||||
|
||||
/obj/item/kinetic_crusher/examine(mob/living/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Mark a large creature with the destabilizing force, then hit them in melee to do <b>[damage_force + detonation_damage]</b> damage.</span>"
|
||||
. += "<span class='notice'>Does <b>[damage_force + detonation_damage + backstab_bonus]</b> damage if the target is backstabbed, instead of <b>[damage_force + detonation_damage]</b>.</span>"
|
||||
/*
|
||||
for(var/t in trophies)
|
||||
var/obj/item/crusher_trophy/T = t
|
||||
. += "<span class='notice'>It has \a [T] attached, which causes [T.effect_desc()].</span>"
|
||||
*/
|
||||
|
||||
/*
|
||||
/obj/item/kinetic_crusher/attackby(obj/item/I, mob/living/user)
|
||||
if(I.tool_behaviour == TOOL_CROWBAR)
|
||||
if(LAZYLEN(trophies))
|
||||
to_chat(user, "<span class='notice'>You remove [src]'s trophies.</span>")
|
||||
I.play_tool_sound(src)
|
||||
for(var/t in trophies)
|
||||
var/obj/item/crusher_trophy/T = t
|
||||
T.remove_from(src, user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There are no trophies on [src].</span>")
|
||||
else if(istype(I, /obj/item/crusher_trophy))
|
||||
var/obj/item/crusher_trophy/T = I
|
||||
T.add_to(src, user)
|
||||
else
|
||||
return ..()
|
||||
*/
|
||||
|
||||
/obj/item/kinetic_crusher/attack_mob(mob/target, mob/user, clickchain_flags, list/params, mult, target_zone, intent)
|
||||
var/mob/living/L = target
|
||||
if(!istype(L))
|
||||
return ..()
|
||||
if(!wielded && requires_wield)
|
||||
to_chat(user, "<span class='warning'>[src] is too heavy to use with one hand.")
|
||||
return
|
||||
var/datum/status_effect/crusher_damage/C = L.has_status_effect(/datum/status_effect/crusher_damage)
|
||||
var/target_health = L.health
|
||||
. = ..()
|
||||
/*
|
||||
for(var/t in trophies)
|
||||
if(!QDELETED(L))
|
||||
var/obj/item/crusher_trophy/T = t
|
||||
T.on_melee_hit(L, user)
|
||||
*/
|
||||
if(!QDELETED(C) && !QDELETED(L))
|
||||
C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did
|
||||
|
||||
/obj/item/kinetic_crusher/afterattack(atom/target, mob/user, clickchain_flags, list/params)
|
||||
. = ..()
|
||||
/*
|
||||
if(istype(target, /obj/item/crusher_trophy))
|
||||
var/obj/item/crusher_trophy/T = target
|
||||
T.add_to(src, user)
|
||||
*/
|
||||
if(requires_wield && !wielded)
|
||||
return
|
||||
if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY) && charged)//Mark a target, or mine a tile.
|
||||
var/turf/proj_turf = user.loc
|
||||
if(!isturf(proj_turf))
|
||||
return
|
||||
var/obj/projectile/destabilizer/D = new /obj/projectile/destabilizer(proj_turf)
|
||||
/*
|
||||
for(var/t in trophies)
|
||||
var/obj/item/crusher_trophy/T = t
|
||||
T.on_projectile_fire(D, user)
|
||||
*/
|
||||
D.preparePixelProjectile(target, user, list2params(params))
|
||||
D.firer = user
|
||||
D.hammer_synced = src
|
||||
playsound(user, 'sound/weapons/plasma_cutter.ogg', 100, 1)
|
||||
D.fire()
|
||||
charged = FALSE
|
||||
update_icon()
|
||||
addtimer(CALLBACK(src, PROC_REF(Recharge)), charge_time * (user?.ConflictElementCount(CONFLICT_ELEMENT_CRUSHER) || 1))
|
||||
return
|
||||
if((clickchain_flags & CLICKCHAIN_HAS_PROXIMITY) && isliving(target))
|
||||
detonate(target, user)
|
||||
|
||||
/obj/item/kinetic_crusher/proc/detonate(mob/living/L, mob/living/user, thrown = FALSE)
|
||||
var/datum/status_effect/grouped/crusher_mark/CM = L.has_status_effect(/datum/status_effect/grouped/crusher_mark)
|
||||
if(!CM || (CM.has_source(WEAKREF(src))) || !L.remove_status_effect(/datum/status_effect/grouped/crusher_mark))
|
||||
return
|
||||
var/datum/status_effect/crusher_damage/C = L.has_status_effect(/datum/status_effect/crusher_damage)
|
||||
var/target_health = L.health
|
||||
/*
|
||||
for(var/t in trophies)
|
||||
var/obj/item/crusher_trophy/T = t
|
||||
T.on_mark_detonation(target, user)
|
||||
*/
|
||||
if(!QDELETED(L))
|
||||
if(!QDELETED(C))
|
||||
C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did
|
||||
new /obj/effect/temp_visual/kinetic_blast(get_turf(L))
|
||||
var/backstab_dir = get_dir(user, L)
|
||||
var/def_check = L.legacy_mob_armor(type = "bomb")
|
||||
var/detonation_damage = src.detonation_damage * (!ishuman(L)? 1 : human_damage_nerf)
|
||||
var/backstab_bonus = src.backstab_bonus * (!ishuman(L)? 1 : human_backstab_nerf)
|
||||
var/thrown_bonus = thrown? (src.thrown_bonus * (!ishuman(L)? 1 : human_damage_nerf)) : 0
|
||||
if(thrown? (get_dir(src, L) & L.dir) : ((user.dir & backstab_dir) && (L.dir & backstab_dir)))
|
||||
if(!QDELETED(C))
|
||||
C.total_damage += detonation_damage + backstab_bonus + thrown_bonus //cheat a little and add the total before killing it, so certain mobs don't have much lower chances of giving an item
|
||||
L.apply_damage(detonation_damage + backstab_bonus + thrown_bonus, BRUTE, blocked = def_check)
|
||||
playsound(src, 'sound/weapons/kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong
|
||||
else
|
||||
if(!QDELETED(C))
|
||||
C.total_damage += detonation_damage + thrown_bonus
|
||||
L.apply_damage(detonation_damage + thrown_bonus, BRUTE, blocked = def_check)
|
||||
|
||||
/obj/item/kinetic_crusher/throw_impact(atom/A, datum/thrownthing/TT)
|
||||
. = ..()
|
||||
if(!isliving(A))
|
||||
return
|
||||
var/mob/living/L = A
|
||||
if(!L.has_status_effect(/datum/status_effect/grouped/crusher_mark))
|
||||
detonate(L, TT.thrower, TRUE)
|
||||
|
||||
/obj/item/kinetic_crusher/proc/Recharge()
|
||||
if(!charged)
|
||||
charged = TRUE
|
||||
update_icon()
|
||||
playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
|
||||
|
||||
/obj/item/kinetic_crusher/ui_action_click(datum/action/action, datum/event_args/actor/actor)
|
||||
light_on = !light_on
|
||||
playsound(src, 'sound/weapons/empty.ogg', 100, TRUE)
|
||||
update_brightness(actor.performer)
|
||||
update_icon()
|
||||
|
||||
/obj/item/kinetic_crusher/proc/update_brightness(mob/user = null)
|
||||
if(light_on)
|
||||
set_light(brightness_on)
|
||||
else
|
||||
set_light(0)
|
||||
|
||||
/obj/item/kinetic_crusher/update_icon_state()
|
||||
. = ..()
|
||||
if(update_item_state)
|
||||
item_state = "crusher[wielded]" // this is not icon_state and not supported by 2hcomponent
|
||||
|
||||
/obj/item/kinetic_crusher/update_overlays()
|
||||
. = ..()
|
||||
if(!charged && charge_overlay)
|
||||
. += "[icon_state]_uncharged"
|
||||
if(light_on)
|
||||
. += "[icon_state]_lit"
|
||||
|
||||
/*
|
||||
/obj/item/kinetic_crusher/glaive
|
||||
name = "proto-kinetic glaive"
|
||||
desc = "A modified design of a proto-kinetic crusher, it is still little more of a combination of various mining tools cobbled together \
|
||||
and kit-bashed into a high-tech cleaver on a stick - with a handguard and a goliath hide grip. While it is still of little use to any \
|
||||
but the most skilled and/or suicidal miners against local fauna, it's an elegant weapon for a more civilized hunter."
|
||||
attack_verb = list("stabbed", "diced", "sliced", "cleaved", "chopped", "lacerated", "cut", "jabbed", "punctured")
|
||||
icon_state = "crusher-glaive"
|
||||
item_state = "crusher0-glaive"
|
||||
block_parry_data = /datum/block_parry_data/crusherglaive
|
||||
//ideas: altclick that lets you pummel people with the handguard/handle?
|
||||
//parrying functionality?
|
||||
/datum/block_parry_data/crusherglaive // small perfect window, active for a fair while, time it right or use the Forbidden Technique
|
||||
parry_time_windup = 0
|
||||
parry_time_active = 8
|
||||
parry_time_spindown = 0
|
||||
parry_time_perfect = 1
|
||||
parry_time_perfect_leeway = 2
|
||||
parry_imperfect_falloff_percent = 20
|
||||
parry_efficiency_to_counterattack = 100 // perfect parry or you're cringe
|
||||
parry_failed_stagger_duration = 1.5 SECONDS // a good time to reconsider your actions...
|
||||
parry_failed_clickcd_duration = 1.5 SECONDS // or your failures
|
||||
/obj/item/kinetic_crusher/glaive/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time) // if you're dumb enough to go for a parry...
|
||||
var/turf/proj_turf = owner.loc // destabilizer bolt, ignoring cooldown
|
||||
if(!isturf(proj_turf))
|
||||
return
|
||||
var/obj/projectile/destabilizer/D = new /obj/projectile/destabilizer(proj_turf)
|
||||
for(var/t in trophies)
|
||||
var/obj/item/crusher_trophy/T = t
|
||||
T.on_projectile_fire(D, owner)
|
||||
D.preparePixelProjectile(attacker, owner)
|
||||
D.firer = owner
|
||||
D.hammer_synced = src
|
||||
playsound(owner, 'sound/weapons/plasma_cutter.ogg', 100, 1)
|
||||
D.fire()
|
||||
/obj/item/kinetic_crusher/glaive/active_parry_reflex_counter(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list, parry_efficiency, list/effect_text)
|
||||
if(owner.Adjacent(attacker) && (!attacker.anchored || ismegafauna(attacker))) // free backstab, if you perfect parry
|
||||
attacker.dir = get_dir(owner,attacker)
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/kinetic_crusher/glaive/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
item_flags |= (ITEM_CAN_PARRY)
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/kinetic_crusher/glaive/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
item_flags &= ~(ITEM_CAN_PARRY)
|
||||
/obj/item/kinetic_crusher/glaive/update_icon_state()
|
||||
item_state = "crusher[wielded]-glaive" // this is not icon_state and not supported by 2hcomponent
|
||||
*/
|
||||
|
||||
/obj/item/kinetic_crusher/dagger
|
||||
name = "proto-kinetic dagger"
|
||||
desc = "A scaled down version of a protokinetic crusher, usually used in a last ditch scenario."
|
||||
icon_state = "glaive-dagger"
|
||||
item_icons = list(
|
||||
SLOT_ID_LEFT_HAND = 'icons/mob/items/lefthand_material.dmi',
|
||||
SLOT_ID_RIGHT_HAND = 'icons/mob/items/righthand_material.dmi',
|
||||
)
|
||||
item_state = "machete"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
damage_force = 15
|
||||
requires_wield = FALSE
|
||||
charge_overlay = FALSE
|
||||
// yeah yeah buff but rp mobs are tough as fuck.
|
||||
backstab_bonus = 35
|
||||
detonation_damage = 25
|
||||
// woohoo
|
||||
thrown_bonus = 35
|
||||
update_item_state = FALSE
|
||||
|
||||
//destablizing force
|
||||
/obj/projectile/destabilizer
|
||||
name = "destabilizing force"
|
||||
icon_state = "pulse1"
|
||||
nodamage = TRUE
|
||||
damage_force = 0 //We're just here to mark people. This is still a melee weapon.
|
||||
damage_type = BRUTE
|
||||
damage_flag = ARMOR_BOMB
|
||||
range = WORLD_ICON_SIZE * 6
|
||||
accuracy_disabled = TRUE
|
||||
// log_override = TRUE
|
||||
var/obj/item/kinetic_crusher/hammer_synced
|
||||
|
||||
/obj/projectile/destabilizer/Destroy()
|
||||
hammer_synced = null
|
||||
return ..()
|
||||
|
||||
/obj/projectile/destabilizer/on_impact(atom/target, impact_flags, def_zone, efficiency)
|
||||
. = ..()
|
||||
if(. & PROJECTILE_IMPACT_FLAGS_UNCONDITIONAL_ABORT)
|
||||
return
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(hammer_synced.can_mark(L))
|
||||
L.apply_grouped_effect(
|
||||
/datum/status_effect/grouped/crusher_mark,
|
||||
WEAKREF(src),
|
||||
TRUE,
|
||||
)
|
||||
// var/had_effect = (L.has_status_effect(/datum/status_effect/grouped/crusher_mark)) //used as a boolean
|
||||
// var/datum/status_effect/grouped/crusher_mark/CM = L.apply_status_effect(/datum/status_effect/grouped/crusher_mark, hammer_synced)
|
||||
/*
|
||||
if(hammer_synced)
|
||||
for(var/t in hammer_synced.trophies)
|
||||
var/obj/item/crusher_trophy/T = t
|
||||
T.on_mark_application(target, CM, had_effect)
|
||||
*/
|
||||
var/target_turf = get_turf(target)
|
||||
if(ismineralturf(target_turf))
|
||||
var/turf/simulated/mineral/M = target_turf
|
||||
new /obj/effect/temp_visual/kinetic_blast(M)
|
||||
M.GetDrilled(firer)
|
||||
|
||||
/*
|
||||
//trophies
|
||||
/obj/item/crusher_trophy
|
||||
name = "tail spike"
|
||||
desc = "A strange spike with no usage."
|
||||
icon = 'icons/obj/lavaland/artefacts.dmi'
|
||||
icon_state = "tail_spike"
|
||||
var/bonus_value = 10 //if it has a bonus effect, this is how much that effect is
|
||||
var/denied_type = /obj/item/crusher_trophy
|
||||
/obj/item/crusher_trophy/examine(mob/living/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Causes [effect_desc()] when attached to a kinetic crusher.</span>"
|
||||
/obj/item/crusher_trophy/proc/effect_desc()
|
||||
return "errors"
|
||||
/obj/item/crusher_trophy/attackby(obj/item/A, mob/living/user)
|
||||
if(istype(A, /obj/item/kinetic_crusher))
|
||||
add_to(A, user)
|
||||
else
|
||||
..()
|
||||
/obj/item/crusher_trophy/proc/add_to(obj/item/kinetic_crusher/H, mob/living/user)
|
||||
for(var/t in H.trophies)
|
||||
var/obj/item/crusher_trophy/T = t
|
||||
if(istype(T, denied_type) || istype(src, T.denied_type))
|
||||
to_chat(user, "<span class='warning'>You can't seem to attach [src] to [H]. Maybe remove a few trophies?</span>")
|
||||
return FALSE
|
||||
if(!user.transferItemToLoc(src, H))
|
||||
return
|
||||
H.trophies += src
|
||||
to_chat(user, "<span class='notice'>You attach [src] to [H].</span>")
|
||||
return TRUE
|
||||
/obj/item/crusher_trophy/proc/remove_from(obj/item/kinetic_crusher/H, mob/living/user)
|
||||
forceMove(get_turf(H))
|
||||
H.trophies -= src
|
||||
return TRUE
|
||||
/obj/item/crusher_trophy/proc/on_melee_hit(mob/living/target, mob/living/user) //the target and the user
|
||||
/obj/item/crusher_trophy/proc/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user) //the projectile fired and the user
|
||||
/obj/item/crusher_trophy/proc/on_mark_application(mob/living/target, datum/status_effect/crusher_mark/mark, had_mark) //the target, the mark applied, and if the target had a mark before
|
||||
/obj/item/crusher_trophy/proc/on_mark_detonation(mob/living/target, mob/living/user) //the target and the user
|
||||
//goliath
|
||||
/obj/item/crusher_trophy/goliath_tentacle
|
||||
name = "goliath tentacle"
|
||||
desc = "A sliced-off goliath tentacle. Suitable as a trophy for a kinetic crusher."
|
||||
icon_state = "goliath_tentacle"
|
||||
denied_type = /obj/item/crusher_trophy/goliath_tentacle
|
||||
bonus_value = 2
|
||||
var/missing_health_ratio = 0.1
|
||||
var/missing_health_desc = 10
|
||||
/obj/item/crusher_trophy/goliath_tentacle/effect_desc()
|
||||
return "mark detonation to do <b>[bonus_value]</b> more damage for every <b>[missing_health_desc]</b> health you are missing"
|
||||
/obj/item/crusher_trophy/goliath_tentacle/on_mark_detonation(mob/living/target, mob/living/user)
|
||||
var/missing_health = user.health - user.maxHealth
|
||||
missing_health *= missing_health_ratio //bonus is active at all times, even if you're above 90 health
|
||||
missing_health *= bonus_value //multiply the remaining amount by bonus_value
|
||||
if(missing_health > 0)
|
||||
target.adjustBruteLoss(missing_health) //and do that much damage
|
||||
/*
|
||||
//watcher
|
||||
/obj/item/crusher_trophy/watcher_wing
|
||||
name = "watcher wing"
|
||||
desc = "A wing ripped from a watcher. Suitable as a trophy for a kinetic crusher."
|
||||
icon_state = "watcher_wing"
|
||||
denied_type = /obj/item/crusher_trophy/watcher_wing
|
||||
bonus_value = 10
|
||||
/obj/item/crusher_trophy/watcher_wing/effect_desc()
|
||||
return "mark detonation to prevent certain creatures from using certain attacks for <b>[bonus_value*0.1]</b> second\s"
|
||||
/obj/item/crusher_trophy/watcher_wing/on_mark_detonation(mob/living/target, mob/living/user)
|
||||
if(ishostile(target))
|
||||
var/mob/living/simple_animal/hostile/H = target
|
||||
if(H.ranged) //briefly delay ranged attacks
|
||||
if(H.ranged_cooldown >= world.time)
|
||||
H.ranged_cooldown += bonus_value
|
||||
else
|
||||
H.ranged_cooldown = bonus_value + world.time
|
||||
//magmawing watcher
|
||||
/obj/item/crusher_trophy/blaster_tubes/magma_wing
|
||||
name = "magmawing watcher wing"
|
||||
desc = "A still-searing wing from a magmawing watcher. Suitable as a trophy for a kinetic crusher."
|
||||
icon_state = "magma_wing"
|
||||
gender = NEUTER
|
||||
bonus_value = 5
|
||||
/obj/item/crusher_trophy/blaster_tubes/magma_wing/effect_desc()
|
||||
return "mark detonation to make the next destabilizer shot deal <b>[bonus_value]</b> damage"
|
||||
/obj/item/crusher_trophy/blaster_tubes/magma_wing/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user)
|
||||
if(deadly_shot)
|
||||
marker.name = "heated [marker.name]"
|
||||
marker.icon_state = "lava"
|
||||
marker.damage = bonus_value
|
||||
marker.nodamage = FALSE
|
||||
deadly_shot = FALSE
|
||||
//icewing watcher
|
||||
/obj/item/crusher_trophy/watcher_wing/ice_wing
|
||||
name = "icewing watcher wing"
|
||||
desc = "A carefully preserved frozen wing from an icewing watcher. Suitable as a trophy for a kinetic crusher."
|
||||
icon_state = "ice_wing"
|
||||
bonus_value = 8
|
||||
*/
|
||||
//legion
|
||||
/obj/item/crusher_trophy/legion_skull
|
||||
name = "legion skull"
|
||||
desc = "A dead and lifeless legion skull. Suitable as a trophy for a kinetic crusher."
|
||||
icon_state = "legion_skull"
|
||||
denied_type = /obj/item/crusher_trophy/legion_skull
|
||||
bonus_value = 3
|
||||
/obj/item/crusher_trophy/legion_skull/effect_desc()
|
||||
return "a kinetic crusher to recharge <b>[bonus_value*0.1]</b> second\s faster"
|
||||
/obj/item/crusher_trophy/legion_skull/add_to(obj/item/kinetic_crusher/H, mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
H.charge_time -= bonus_value
|
||||
/obj/item/crusher_trophy/legion_skull/remove_from(obj/item/kinetic_crusher/H, mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
H.charge_time += bonus_value
|
||||
/*
|
||||
//blood-drunk hunter
|
||||
/obj/item/crusher_trophy/miner_eye
|
||||
name = "eye of a blood-drunk hunter"
|
||||
desc = "Its pupil is collapsed and turned to mush. Suitable as a trophy for a kinetic crusher."
|
||||
icon_state = "hunter_eye"
|
||||
denied_type = /obj/item/crusher_trophy/miner_eye
|
||||
/obj/item/crusher_trophy/miner_eye/effect_desc()
|
||||
return "mark detonation to grant stun immunity and <b>90%</b> damage reduction for <b>1</b> second"
|
||||
/obj/item/crusher_trophy/miner_eye/on_mark_detonation(mob/living/target, mob/living/user)
|
||||
user.apply_status_effect(STATUS_EFFECT_BLOODDRUNK)
|
||||
*/
|
||||
/*
|
||||
//ash drake
|
||||
/obj/item/crusher_trophy/tail_spike
|
||||
desc = "A spike taken from an ash drake's tail. Suitable as a trophy for a kinetic crusher."
|
||||
denied_type = /obj/item/crusher_trophy/tail_spike
|
||||
bonus_value = 5
|
||||
/obj/item/crusher_trophy/tail_spike/effect_desc()
|
||||
return "mark detonation to do <b>[bonus_value]</b> damage to nearby creatures and push them back"
|
||||
/obj/item/crusher_trophy/tail_spike/on_mark_detonation(mob/living/target, mob/living/user)
|
||||
for(var/mob/living/L in oview(2, user))
|
||||
if(L.stat == DEAD)
|
||||
continue
|
||||
playsound(L, 'sound/magic/fireball.ogg', 20, 1)
|
||||
new /obj/effect/temp_visual/fire(L.loc)
|
||||
addtimer(CALLBACK(src, PROC_REF(pushback), L, user), 1) //no free backstabs, we push AFTER module stuff is done
|
||||
L.adjustFireLoss(bonus_value, forced = TRUE)
|
||||
/obj/item/crusher_trophy/tail_spike/proc/pushback(mob/living/target, mob/living/user)
|
||||
if(!QDELETED(target) && !QDELETED(user) && (!target.anchored || ismegafauna(target))) //megafauna will always be pushed
|
||||
step(target, get_dir(user, target))
|
||||
*/
|
||||
//bubblegum
|
||||
/obj/item/crusher_trophy/demon_claws
|
||||
name = "demon claws"
|
||||
desc = "A set of blood-drenched claws from a massive demon's hand. Suitable as a trophy for a kinetic crusher."
|
||||
icon_state = "demon_claws"
|
||||
gender = PLURAL
|
||||
denied_type = /obj/item/crusher_trophy/demon_claws
|
||||
bonus_value = 10
|
||||
var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
|
||||
/obj/item/crusher_trophy/demon_claws/effect_desc()
|
||||
return "melee hits to do <b>[bonus_value * 0.2]</b> more damage and heal you for <b>[bonus_value * 0.1]</b>, with <b>5X</b> effect on mark detonation"
|
||||
/obj/item/crusher_trophy/demon_claws/add_to(obj/item/kinetic_crusher/H, mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
H.damage_force += bonus_value * 0.2
|
||||
H.detonation_damage += bonus_value * 0.8
|
||||
if(requires_wield)
|
||||
AddComponent(/datum/component/two_handed, force_wielded=(20 + bonus_value * 0.2))
|
||||
/obj/item/crusher_trophy/demon_claws/remove_from(obj/item/kinetic_crusher/H, mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
H.damage_force -= bonus_value * 0.2
|
||||
H.detonation_damage -= bonus_value * 0.8
|
||||
if(requires_wield)
|
||||
AddComponent(/datum/component/two_handed, force_wielded=20)
|
||||
/*
|
||||
/obj/item/crusher_trophy/demon_claws/on_melee_hit(mob/living/target, mob/living/user)
|
||||
user.heal_ordered_damage(bonus_value * 0.1, damage_heal_order)
|
||||
/obj/item/crusher_trophy/demon_claws/on_mark_detonation(mob/living/target, mob/living/user)
|
||||
user.heal_ordered_damage(bonus_value * 0.4, damage_heal_order)
|
||||
*/
|
||||
//colossus
|
||||
/obj/item/crusher_trophy/blaster_tubes
|
||||
name = "blaster tubes"
|
||||
desc = "The blaster tubes from a colossus's arm. Suitable as a trophy for a kinetic crusher."
|
||||
icon_state = "blaster_tubes"
|
||||
gender = PLURAL
|
||||
denied_type = /obj/item/crusher_trophy/blaster_tubes
|
||||
bonus_value = 15
|
||||
var/deadly_shot = FALSE
|
||||
/obj/item/crusher_trophy/blaster_tubes/effect_desc()
|
||||
return "mark detonation to make the next destabilizer shot deal <b>[bonus_value]</b> damage but move slower"
|
||||
/obj/item/crusher_trophy/blaster_tubes/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user)
|
||||
if(deadly_shot)
|
||||
marker.name = "deadly [marker.name]"
|
||||
marker.icon_state = "chronobolt"
|
||||
marker.damage = bonus_value
|
||||
marker.nodamage = FALSE
|
||||
marker.speed = 2
|
||||
deadly_shot = FALSE
|
||||
/obj/item/crusher_trophy/blaster_tubes/on_mark_detonation(mob/living/target, mob/living/user)
|
||||
deadly_shot = TRUE
|
||||
addtimer(CALLBACK(src, PROC_REF(reset_deadly_shot)), 300, TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||
/obj/item/crusher_trophy/blaster_tubes/proc/reset_deadly_shot()
|
||||
deadly_shot = FALSE
|
||||
//hierophant
|
||||
/obj/item/crusher_trophy/vortex_talisman
|
||||
name = "vortex talisman"
|
||||
desc = "A glowing trinket that was originally the Hierophant's beacon. Suitable as a trophy for a kinetic crusher."
|
||||
icon_state = "vortex_talisman"
|
||||
denied_type = /obj/item/crusher_trophy/vortex_talisman
|
||||
var/vortex_cd
|
||||
/obj/item/crusher_trophy/vortex_talisman/effect_desc()
|
||||
return "mark detonation to create a barrier you can pass that lasts for <b>7.5 seconds</b>, with a cooldown of <b>9 seconds</b> after creation."
|
||||
/obj/item/crusher_trophy/vortex_talisman/on_mark_detonation(mob/living/target, mob/living/user)
|
||||
if(vortex_cd >= world.time)
|
||||
return
|
||||
var/turf/T = get_turf(user)
|
||||
var/obj/effect/temp_visual/hierophant/wall/crusher/W = new (T, user) //a wall only you can pass!
|
||||
var/turf/otherT = get_step(T, turn(user.dir, 90))
|
||||
if(otherT)
|
||||
new /obj/effect/temp_visual/hierophant/wall/crusher(otherT, user)
|
||||
otherT = get_step(T, turn(user.dir, -90))
|
||||
if(otherT)
|
||||
new /obj/effect/temp_visual/hierophant/wall/crusher(otherT, user)
|
||||
vortex_cd = world.time + W.duration * 1.2
|
||||
/obj/effect/temp_visual/hierophant/wall/crusher
|
||||
duration = 75
|
||||
*/
|
||||
|
||||
//Crusher Glaives
|
||||
/obj/item/kinetic_crusher/glaive
|
||||
name = "kinetic crusher glaive"
|
||||
desc = "A refinement on the original Crusher's design, this high-tech glaive was modeled after observed weaponry carried by Ashlander hunters. \
|
||||
Still an effective mining tool, it provides marginally better support as a defensive weapon."
|
||||
icon_state = "crusher-glaive"
|
||||
item_state = "crusher0-glaive"
|
||||
throw_force = 10
|
||||
|
||||
/obj/item/kinetic_crusher/glaive/bone
|
||||
name = "bone crusher glaive"
|
||||
desc = "Crusher glaives were utilized by the Ashlanders long before the colonization of Surt. However, through rare cultural exchanges and trades, \
|
||||
the tribes have learned how to enhance the basic bone glaive with their own curious technology - effectively mimicking the kinetic crusher's utility."
|
||||
icon_state = "crusher-bone"
|
||||
throw_force = 10
|
||||
@@ -0,0 +1,426 @@
|
||||
/******************************Lantern*******************************/
|
||||
|
||||
/obj/item/flashlight/lantern
|
||||
name = "lantern"
|
||||
icon_state = "lantern"
|
||||
desc = "A mining lantern."
|
||||
brightness_on = 6 // luminosity when on
|
||||
light_color = "#ff9933" // A slight yellow/orange color.
|
||||
light_wedge = LIGHT_OMNI
|
||||
worth_intrinsic = 45
|
||||
|
||||
/*****************************Pickaxe********************************/
|
||||
|
||||
/obj/item/pickaxe
|
||||
name = "mining drill"
|
||||
desc = "The most basic of mining drills, for short excavations and small mineral extractions."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
slot_flags = SLOT_BELT
|
||||
damage_force = 15.0
|
||||
throw_force = 4.0
|
||||
icon_state = "pickaxe"
|
||||
item_state = "jackhammer"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
materials_base = list(MAT_STEEL = 3750)
|
||||
worth_intrinsic = 75
|
||||
var/digspeed = 40 //moving the delay to an item var so R&D can make improved picks. --NEO
|
||||
var/sand_dig = FALSE
|
||||
origin_tech = list(TECH_MATERIAL = 1, TECH_ENGINEERING = 1)
|
||||
attack_verb = list("hit", "pierced", "sliced", "attacked")
|
||||
var/drill_sound = 'sound/weapons/Genhit.ogg'
|
||||
var/drill_verb = "drilling"
|
||||
sharp = 1
|
||||
var/active = 1
|
||||
|
||||
var/excavation_amount = 200
|
||||
var/destroy_artefacts = FALSE // some mining tools will destroy artefacts completely while avoiding side-effects.
|
||||
|
||||
/obj/item/pickaxe/bone
|
||||
name = "bone pickaxe"
|
||||
icon_state = "bpickaxe"
|
||||
item_state = "bpickaxe"
|
||||
digspeed = 30
|
||||
origin_tech = list(TECH_MATERIAL = 1)
|
||||
desc = "A sturdy pick fashioned from some animal's bone, wound with powerful sinew."
|
||||
|
||||
/obj/item/pickaxe/bronze
|
||||
name = "bronze pickaxe"
|
||||
icon_state = "brpickaxe"
|
||||
item_state = "brpickaxe"
|
||||
digspeed = 30
|
||||
origin_tech = list(TECH_MATERIAL = 1)
|
||||
desc = "A primitive pickaxe made of bronze, and a handle of bone."
|
||||
|
||||
/obj/item/pickaxe/silver
|
||||
name = "silver pickaxe"
|
||||
icon_state = "spickaxe"
|
||||
item_state = "spickaxe"
|
||||
digspeed = 30
|
||||
origin_tech = list(TECH_MATERIAL = 3)
|
||||
desc = "This makes no metallurgic sense."
|
||||
|
||||
/obj/item/pickaxe/drill
|
||||
name = "advanced mining drill" // Can dig sand as well!
|
||||
icon_state = "handdrill"
|
||||
item_state = "jackhammer"
|
||||
digspeed = 30
|
||||
origin_tech = list(TECH_MATERIAL = 2, TECH_POWER = 3, TECH_ENGINEERING = 2)
|
||||
desc = "Yours is the drill that will pierce through the rock walls."
|
||||
drill_verb = "drilling"
|
||||
sand_dig = TRUE
|
||||
worth_intrinsic = 125
|
||||
|
||||
/obj/item/pickaxe/jackhammer
|
||||
name = "sonic jackhammer"
|
||||
icon_state = "jackhammer"
|
||||
item_state = "jackhammer"
|
||||
digspeed = 20 //faster than drill, but cannot dig
|
||||
origin_tech = list(TECH_MATERIAL = 3, TECH_POWER = 2, TECH_ENGINEERING = 2)
|
||||
desc = "Cracks rocks with sonic blasts, perfect for killing cave lizards."
|
||||
drill_verb = "hammering"
|
||||
worth_intrinsic = 250
|
||||
|
||||
/obj/item/pickaxe/gold
|
||||
name = "golden pickaxe"
|
||||
icon_state = "gpickaxe"
|
||||
item_state = "gpickaxe"
|
||||
digspeed = 20
|
||||
origin_tech = list(TECH_MATERIAL = 4)
|
||||
desc = "This makes no metallurgic sense."
|
||||
drill_verb = "picking"
|
||||
|
||||
/obj/item/pickaxe/plasmacutter
|
||||
name = "plasma cutter"
|
||||
icon_state = "plasmacutter"
|
||||
item_state = "gun"
|
||||
w_class = WEIGHT_CLASS_NORMAL //it is smaller than the pickaxe
|
||||
damtype = "fire"
|
||||
digspeed = 20 //Can slice though normal walls, all girders, or be used in reinforced wall deconstruction/ light thermite on fire
|
||||
origin_tech = list(TECH_MATERIAL = 4, TECH_PHORON = 3, TECH_ENGINEERING = 3)
|
||||
desc = "A rock cutter that uses bursts of hot plasma. You could use it to cut limbs off of xenos! Or, you know, mine stuff."
|
||||
drill_verb = "cutting"
|
||||
drill_sound = 'sound/items/Welder.ogg'
|
||||
sharp = 1
|
||||
edge = 1
|
||||
worth_intrinsic = 175
|
||||
|
||||
/obj/item/pickaxe/diamond
|
||||
name = "diamond pickaxe"
|
||||
icon_state = "dpickaxe"
|
||||
item_state = "dpickaxe"
|
||||
digspeed = 10
|
||||
origin_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 4)
|
||||
desc = "A pickaxe with a diamond pick head."
|
||||
drill_verb = "picking"
|
||||
|
||||
/obj/item/pickaxe/diamonddrill // When people ask about the badass leader of the mining tools, they are talking about ME!
|
||||
name = "diamond mining drill"
|
||||
icon_state = "diamonddrill"
|
||||
item_state = "jackhammer"
|
||||
digspeed = 5 //Digs through walls, girders, and can dig up sand
|
||||
origin_tech = list(TECH_MATERIAL = 6, TECH_POWER = 4, TECH_ENGINEERING = 5)
|
||||
desc = "Yours is the drill that will pierce the heavens!"
|
||||
drill_verb = "drilling"
|
||||
sand_dig = TRUE
|
||||
worth_intrinsic = 350
|
||||
|
||||
/obj/item/pickaxe/borgdrill
|
||||
name = "enhanced sonic jackhammer"
|
||||
icon_state = "jackhammer"
|
||||
item_state = "jackhammer"
|
||||
digspeed = 15
|
||||
desc = "Cracks rocks with sonic blasts. This one seems like an improved design."
|
||||
drill_verb = "hammering"
|
||||
sand_dig = TRUE
|
||||
|
||||
/obj/item/pickaxe/icepick //Cannot actually lobotomize people. Yet.
|
||||
name = "icepick"
|
||||
desc = "A simple icepick, for all your digging, climbing, and lobotomizing needs."
|
||||
slot_flags = SLOT_BELT
|
||||
damage_force = 12
|
||||
throw_force = 15 //Discount shuriken.
|
||||
icon_state = "icepick"
|
||||
item_state = "spickaxe" //im lazy fuck u
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
materials_base = list(MAT_STEEL = 2750, MAT_TITANIUM = 2000)
|
||||
digspeed = 25 //More expensive than a diamond pick, a lot smaller but decently slower.
|
||||
origin_tech = list(TECH_MATERIAL = 1, TECH_ENGINEERING = 1)
|
||||
attack_verb = list("mined", "pierced", "stabbed", "attacked")
|
||||
drill_verb = "picking"
|
||||
sharp = 1
|
||||
worth_intrinsic = 75
|
||||
|
||||
//Snowflake drill that works like a chainsaw! How fun. Honestly they should probably all work like this or something. I dunno. Might be a fun mining overhaul later.
|
||||
/obj/item/pickaxe/tyrmalin
|
||||
name = "\improper Tyrmalin excavator"
|
||||
desc = "A mining drill build from scrap parts, often found on Tyrmalin mining operations. No two are alike."
|
||||
icon_state = "goblindrill"
|
||||
item_state = "goblindrill"
|
||||
destroy_artefacts = TRUE
|
||||
var/max_fuel = 100
|
||||
active = 0
|
||||
var/jam_chance = TRUE
|
||||
worth_intrinsic = 75
|
||||
|
||||
/obj/item/pickaxe/tyrmalin/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/reagents/R = new/datum/reagents(max_fuel)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
R.add_reagent("fuel", max_fuel)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/pickaxe/tyrmalin/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/pickaxe/tyrmalin/proc/turnOn(mob/user as mob)
|
||||
if(active)
|
||||
return
|
||||
|
||||
to_chat(user, "You start pulling the string on \the [src].")
|
||||
//visible_message("[usr] starts pulling the string on the [src].")
|
||||
|
||||
if(max_fuel <= 0)
|
||||
if(do_after(user, 15))
|
||||
to_chat(user, "\The [src] won't start!")
|
||||
else
|
||||
to_chat(user, "You fumble with the string.")
|
||||
else
|
||||
if(do_after(user, 15))
|
||||
to_chat(user, "You start \the [src] up with a loud grinding!")
|
||||
//visible_message("[usr] starts \the [src] up with a loud grinding!")
|
||||
attack_verb = list("shredded", "ripped", "torn")
|
||||
playsound(src, 'sound/weapons/chainsaw_startup.ogg',40,1)
|
||||
damage_force = 15
|
||||
damage_mode |= DAMAGE_MODE_SHARP | DAMAGE_MODE_EDGE
|
||||
edge = TRUE
|
||||
sharp = TRUE
|
||||
active = TRUE
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "You fumble with the string.")
|
||||
|
||||
/obj/item/pickaxe/tyrmalin/proc/turnOff(mob/user as mob)
|
||||
if(!active) return
|
||||
to_chat(user, "You switch the gas nozzle on the drill, turning it off.")
|
||||
attack_verb = list("bluntly hit", "beat", "knocked")
|
||||
playsound(user, 'sound/weapons/chainsaw_turnoff.ogg',40,1)
|
||||
damage_force = 3
|
||||
damage_mode = initial(damage_mode)
|
||||
edge = FALSE
|
||||
sharp = FALSE
|
||||
active = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/pickaxe/tyrmalin/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!active)
|
||||
turnOn(user)
|
||||
else
|
||||
turnOff(user)
|
||||
|
||||
/obj/item/pickaxe/tyrmalin/afterattack(atom/target, mob/user, clickchain_flags, list/params)
|
||||
if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY)) return
|
||||
..()
|
||||
if(active)
|
||||
playsound(src, 'sound/weapons/chainsaw_attack.ogg',40,1)
|
||||
if(target && active)
|
||||
if(get_fuel() > 0)
|
||||
reagents.remove_reagent("fuel", 1)
|
||||
if(istype(target, /obj/structure/window) || istype(target, /obj/structure/grille))
|
||||
target.atom_destruction()
|
||||
if(jam_chance && active)
|
||||
switch(rand(1,100))
|
||||
if(1 to 30)
|
||||
turnOff()
|
||||
if(31 to 100)
|
||||
return
|
||||
if (istype(target, /obj/structure/reagent_dispensers/fueltank) || istype(target, /obj/item/reagent_containers/portable_fuelcan) && get_dist(src,target) <= 1)
|
||||
to_chat(usr, "<span class='notice'>You begin filling the tank on the [src].</span>")
|
||||
if(do_after(usr, 15))
|
||||
target.reagents.trans_to_obj(src, max_fuel)
|
||||
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
|
||||
to_chat(usr, "<span class='notice'>[src] succesfully refueled.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>Don't move while you're refilling the [src].</span>")
|
||||
|
||||
/obj/item/pickaxe/tyrmalin/process(delta_time)
|
||||
if(!active)
|
||||
return
|
||||
|
||||
if(get_fuel() > 0)
|
||||
reagents.remove_reagent("fuel", 1)
|
||||
playsound(src, 'sound/weapons/chainsaw_turnoff.ogg',15,1)
|
||||
if(get_fuel() <= 0)
|
||||
to_chat(usr, "\The [src] sputters to a stop!")
|
||||
turnOff()
|
||||
|
||||
/obj/item/pickaxe/tyrmalin/proc/get_fuel()
|
||||
return reagents.get_reagent_amount("fuel")
|
||||
|
||||
/obj/item/pickaxe/tyrmalin/examine(mob/user, dist)
|
||||
. = ..()
|
||||
if(max_fuel)
|
||||
. += "<span class = 'notice'>The [src] feels like it contains roughtly [get_fuel()] units of fuel left.</span>"
|
||||
|
||||
/obj/item/pickaxe/tyrmalin/update_icon()
|
||||
if(active)
|
||||
icon_state = "goblindrill1"
|
||||
item_state = "goblindrill1"
|
||||
else
|
||||
icon_state = "goblindrill"
|
||||
item_state = "goblindrill"
|
||||
|
||||
|
||||
/*****************************Shovel********************************/
|
||||
|
||||
/obj/item/shovel
|
||||
name = "shovel"
|
||||
desc = "A large tool for digging and moving dirt."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "shovel"
|
||||
slot_flags = SLOT_BELT
|
||||
damage_force = 8.0
|
||||
throw_force = 4.0
|
||||
item_state = "shovel"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = list(TECH_MATERIAL = 1, TECH_ENGINEERING = 1)
|
||||
materials_base = list(MAT_STEEL = 50)
|
||||
attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked")
|
||||
sharp = 0
|
||||
edge = 1
|
||||
worth_intrinsic = 50
|
||||
var/digspeed = 40
|
||||
|
||||
/obj/item/shovel/bone
|
||||
name = "serrated bone shovel"
|
||||
desc = "A wicked tool that cleaves through dirt just as easily as it does flesh. The design was styled after ancient tribal designs."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "shovel_bone"
|
||||
damage_force = 15
|
||||
throw_force = 12
|
||||
tool_speed = 0.7
|
||||
attack_verb = list("slashed", "impaled", "stabbed", "sliced")
|
||||
sharp = 1
|
||||
|
||||
/obj/item/shovel/bronze
|
||||
name = "bronze shovel"
|
||||
desc = "A simple shovel made of bronze. Its wide head seems to be much simpler then modern shovels."
|
||||
icon = 'icons/obj/lavaland.dmi'
|
||||
icon_state = "shovel_bronze"
|
||||
|
||||
/obj/item/shovel/spade
|
||||
name = "spade"
|
||||
desc = "A small tool for digging and moving dirt."
|
||||
icon_state = "spade"
|
||||
item_state = "spade"
|
||||
damage_force = 5.0
|
||||
throw_force = 7.0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/shovel/spade/bone
|
||||
name = "primitive spade"
|
||||
desc = "A small shove cruedly fashioned out of some beast's scapula."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "spade_bone"
|
||||
|
||||
/obj/item/shovel/spade/bronze
|
||||
name = "primitive spade"
|
||||
desc = "A small shovel made of bronze. The design seems to have some ritual purposes."
|
||||
icon = 'icons/obj/lavaland.dmi'
|
||||
icon_state = "spade_bronze"
|
||||
|
||||
/**********************Mining car (Crate like thing, not the rail car)**************************/
|
||||
|
||||
/obj/structure/closet/crate/miningcar
|
||||
desc = "A mining car. This one doesn't work on rails, but has to be dragged."
|
||||
name = "Mining car (not for rails)"
|
||||
closet_appearance = null
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "miningcar"
|
||||
density = 1
|
||||
icon_opened = "miningcaropen"
|
||||
icon_closed = "miningcar"
|
||||
|
||||
/obj/structure/closet/crate/miningcar/update_icon()
|
||||
|
||||
// Flags.
|
||||
|
||||
/obj/item/stack/flag
|
||||
name = "flags"
|
||||
desc = "Some colourful flags."
|
||||
singular_name = "flag"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
amount = 10
|
||||
max_amount = 10
|
||||
zmm_flags = ZMM_MANGLE_PLANES
|
||||
|
||||
var/upright = 0
|
||||
var/base_state
|
||||
|
||||
/obj/item/stack/flag/Initialize(mapload, new_amount, merge)
|
||||
. = ..()
|
||||
base_state = icon_state
|
||||
|
||||
/obj/item/stack/flag/blue
|
||||
name = "blue flags"
|
||||
singular_name = "blue flag"
|
||||
icon_state = "blueflag"
|
||||
|
||||
/obj/item/stack/flag/red
|
||||
name = "red flags"
|
||||
singular_name = "red flag"
|
||||
icon_state = "redflag"
|
||||
|
||||
/obj/item/stack/flag/yellow
|
||||
name = "yellow flags"
|
||||
singular_name = "yellow flag"
|
||||
icon_state = "yellowflag"
|
||||
|
||||
/obj/item/stack/flag/green
|
||||
name = "green flags"
|
||||
singular_name = "green flag"
|
||||
icon_state = "greenflag"
|
||||
|
||||
/obj/item/stack/flag/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(upright && istype(W,src.type))
|
||||
src.attack_hand(user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/stack/flag/attack_hand(mob/user, datum/event_args/actor/clickchain/e_args)
|
||||
if(upright)
|
||||
upright = 0
|
||||
icon_state = base_state
|
||||
anchored = 0
|
||||
src.visible_message("<b>[user]</b> knocks down [src].")
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/stack/flag/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/obj/item/stack/flag/F = locate() in get_turf(src)
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T || !istype(T,/turf/simulated/mineral))
|
||||
to_chat(user, "The flag won't stand up in this terrain.")
|
||||
return
|
||||
|
||||
if(F && F.upright)
|
||||
to_chat(user, "There is already a flag here.")
|
||||
return
|
||||
|
||||
var/obj/item/stack/flag/newflag = new src.type(T)
|
||||
newflag.amount = 1
|
||||
newflag.upright = 1
|
||||
newflag.anchored = 1
|
||||
newflag.name = newflag.singular_name
|
||||
newflag.icon_state = "[newflag.base_state]_open"
|
||||
newflag.visible_message("<b>[user]</b> plants [newflag] firmly in the ground.")
|
||||
src.use(1)
|
||||
@@ -0,0 +1,30 @@
|
||||
//upgrades the speed of all drills and pickaxes.
|
||||
|
||||
/obj/item/pickaxe
|
||||
digspeed = 36
|
||||
|
||||
/obj/item/pickaxe/silver
|
||||
digspeed = 27
|
||||
|
||||
/obj/item/pickaxe/drill
|
||||
digspeed = 27
|
||||
|
||||
/obj/item/pickaxe/jackhammer
|
||||
digspeed = 18
|
||||
destroy_artefacts = TRUE
|
||||
|
||||
/obj/item/pickaxe/gold
|
||||
digspeed = 18
|
||||
|
||||
/obj/item/pickaxe/plasmacutter
|
||||
digspeed = 18
|
||||
|
||||
/obj/item/pickaxe/diamond
|
||||
digspeed = 9
|
||||
|
||||
/obj/item/pickaxe/diamonddrill
|
||||
digspeed = 4
|
||||
|
||||
/obj/item/pickaxe/borgdrill
|
||||
digspeed = 13
|
||||
destroy_artefacts = TRUE
|
||||
@@ -0,0 +1,120 @@
|
||||
|
||||
/**********************Ore box**************************/
|
||||
|
||||
/obj/structure/ore_box
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "orebox0"
|
||||
name = "ore box"
|
||||
desc = "A heavy box used for storing ore."
|
||||
density = 1
|
||||
climb_allowed = TRUE //it's a fuckin' box.
|
||||
var/last_update = 0
|
||||
var/list/stored_ore = list()
|
||||
|
||||
/obj/structure/ore_box/attackby(obj/item/I, mob/user, list/params, clickchain_flags, damage_multiplier)
|
||||
if (istype(I, /obj/item/stack/ore))
|
||||
if(!user.attempt_insert_item_for_installation(I, src))
|
||||
return
|
||||
user.visible_message(SPAN_NOTICE("[user] drops [I] into [src]."), SPAN_NOTICE("You drop [I] into [src]."))
|
||||
else if (istype(I, /obj/item/storage/bag/ore)) //it works differently now
|
||||
var/offloaded = FALSE
|
||||
for(var/obj/item/stack/ore/ore in I)
|
||||
ore.forceMove(src)
|
||||
offloaded = TRUE
|
||||
I.obj_storage?.ui_queue_refresh()
|
||||
if(offloaded)
|
||||
user.visible_message(SPAN_NOTICE("[user] offloads ores from [I] into [src]."), SPAN_NOTICE("You offload the ores in [I] into [src]."))
|
||||
else if (istype(I, /obj/item/storage))
|
||||
var/obj/item/storage/S = I
|
||||
if(!S.contents.len)
|
||||
return
|
||||
S.obj_storage?.hide(user)
|
||||
for(var/obj/item/stack/ore/O in S.contents)
|
||||
S.forceMove(src)
|
||||
user.visible_message(SPAN_NOTICE("[user] offloads ores from [I] into [src]."), SPAN_NOTICE("You offload the ores in [I] into [src]."))
|
||||
|
||||
/obj/structure/ore_box/examine(mob/user, dist)
|
||||
. = ..()
|
||||
if(isEmpty())
|
||||
. += SPAN_NOTICE("It is empty.")
|
||||
return
|
||||
. += SPAN_NOTICE("It holds:")
|
||||
for(var/ore in stored_ore)
|
||||
var/obj/item/stack/ore/O = ore
|
||||
. += SPAN_NOTICE("- [stored_ore[ore]] [initial(O.name)]")
|
||||
|
||||
/// Sigh.
|
||||
/obj/structure/ore_box/Entered(atom/movable/AM, atom/oldLoc)
|
||||
. = ..()
|
||||
if(istype(AM, /obj/item/stack/ore))
|
||||
take(AM)
|
||||
|
||||
/obj/structure/ore_box/drop_products(method, atom/where)
|
||||
. = ..()
|
||||
var/i = 0
|
||||
while(!isEmpty() && i < 200) //may be laggy as hell if they're carrying 2,000+ sand, so capping it at 200 items dropped.
|
||||
deposit(where, 50)
|
||||
i++
|
||||
|
||||
new /obj/item/stack/material/wood/hard(where, 5)
|
||||
|
||||
/obj/structure/ore_box/proc/take(obj/item/stack/ore/O)
|
||||
if(!istype(O))
|
||||
return
|
||||
if(!stored_ore[O.type])
|
||||
stored_ore[O.type] = O.amount
|
||||
else
|
||||
stored_ore[O.type] += O.amount
|
||||
qdel(O)
|
||||
|
||||
/obj/structure/ore_box/proc/deposit(atom/newloc, amount = 50)
|
||||
if(isEmpty())
|
||||
return FALSE
|
||||
var/path = stored_ore[1]
|
||||
if(amount > stored_ore[path])
|
||||
amount = stored_ore[path]
|
||||
new path(newloc, amount)
|
||||
stored_ore[path] -= amount
|
||||
if(stored_ore[path] <= 0)
|
||||
stored_ore -= path
|
||||
return TRUE
|
||||
|
||||
/obj/structure/ore_box/proc/isEmpty()
|
||||
return !length(stored_ore)
|
||||
|
||||
/obj/structure/ore_box/verb/empty_box()
|
||||
set name = "Empty Ore Box"
|
||||
set category = VERB_CATEGORY_OBJECT
|
||||
set src in view(1)
|
||||
|
||||
if(!istype(usr, /mob/living/carbon/human) && !istype(usr, /mob/living/silicon/robot)) //Only living, intelligent creatures with gripping aparatti can empty ore boxes.
|
||||
to_chat(usr,"<span class='warning'>You are physically incapable of emptying the ore box.</span>")
|
||||
return
|
||||
|
||||
if( usr.stat || usr.restrained() )
|
||||
return
|
||||
|
||||
if(!Adjacent(usr)) //You can only empty the box if you can physically reach it
|
||||
to_chat(usr,"You cannot reach the ore box.")
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(isEmpty())
|
||||
to_chat(usr, SPAN_WARNING("[src] is empty."))
|
||||
return
|
||||
|
||||
var/mob/living/user = usr
|
||||
to_chat(user, SPAN_NOTICE("You begin emptying [src]."))
|
||||
|
||||
if(do_after(usr,10,src))
|
||||
while(!isEmpty())
|
||||
if(!do_after(user, 2, src))
|
||||
to_chat(user,SPAN_NOTICE("You stop emptying [src]."))
|
||||
return
|
||||
var/atom/A = drop_location()
|
||||
if(!A || (length(A.contents) > 200))
|
||||
to_chat(user, SPAN_WARNING("The area under [src] is too full."))
|
||||
return
|
||||
deposit(A,50)
|
||||
to_chat(user,SPAN_NOTICE("You finish emptying [src]."))
|
||||
@@ -0,0 +1,113 @@
|
||||
/**********************Resonator**********************/
|
||||
|
||||
/obj/item/resonator
|
||||
name = "resonator"
|
||||
icon = 'icons/obj/mining_vr.dmi'
|
||||
icon_state = "resonator"
|
||||
item_state = "resonator"
|
||||
item_icons = list(
|
||||
SLOT_ID_LEFT_HAND = 'icons/mob/items/lefthand.dmi',
|
||||
SLOT_ID_RIGHT_HAND = 'icons/mob/items/righthand.dmi',
|
||||
)
|
||||
origin_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3)
|
||||
desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It can also be activated without a target to create a field at the user's location, to act as a delayed time trap. It's more effective in low temperature."
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
damage_force = 8
|
||||
throw_force = 10
|
||||
var/cooldown = 0
|
||||
var/fieldsactive = 0
|
||||
var/burst_time = 50
|
||||
var/fieldlimit = 3
|
||||
|
||||
/obj/item/resonator/upgraded
|
||||
name = "upgraded resonator"
|
||||
desc = "An upgraded version of the resonator that can produce more fields at once."
|
||||
icon_state = "resonator_u"
|
||||
origin_tech = list(TECH_MATERIAL = 4, TECH_POWER = 3, TECH_MAGNET = 3, TECH_ENGINEERING = 3)
|
||||
fieldlimit = 5
|
||||
|
||||
/obj/item/resonator/proc/CreateResonance(var/target, var/creator)
|
||||
var/turf/T = get_turf(target)
|
||||
if(locate(/obj/effect/resonance) in T)
|
||||
return
|
||||
if(fieldsactive < fieldlimit)
|
||||
playsound(src,'sound/weapons/resonator_fire.ogg',50,1)
|
||||
new /obj/effect/resonance(T, creator, burst_time)
|
||||
fieldsactive++
|
||||
spawn(burst_time)
|
||||
fieldsactive--
|
||||
|
||||
/obj/item/resonator/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(burst_time == 50)
|
||||
burst_time = 30
|
||||
to_chat(user, "<span class='info'>You set the resonator's fields to detonate after 3 seconds.</span>")
|
||||
else
|
||||
burst_time = 50
|
||||
to_chat(user, "<span class='info'>You set the resonator's fields to detonate after 5 seconds.</span>")
|
||||
|
||||
/obj/item/resonator/afterattack(atom/target, mob/user, clickchain_flags, list/params)
|
||||
if((clickchain_flags & CLICKCHAIN_HAS_PROXIMITY))
|
||||
if(!check_allowed_items(target, 1))
|
||||
return
|
||||
CreateResonance(target, user)
|
||||
|
||||
/obj/effect/resonance
|
||||
name = "resonance field"
|
||||
desc = "A resonating field that significantly damages anything inside of it when the field eventually ruptures."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "shield1"
|
||||
plane = MOB_PLANE
|
||||
layer = ABOVE_MOB_LAYER
|
||||
mouse_opacity = 0
|
||||
var/resonance_damage = 20
|
||||
|
||||
/obj/effect/resonance/Initialize(mapload, var/creator = null, var/timetoburst)
|
||||
. = ..()
|
||||
// Start small and grow to big size as we are about to burst
|
||||
transform = matrix()*0.75
|
||||
animate(src, transform = matrix()*1.5, time = timetoburst)
|
||||
// Queue the actual bursting
|
||||
spawn(timetoburst)
|
||||
if(!QDELETED(src))
|
||||
burst(creator)
|
||||
|
||||
/obj/effect/resonance/proc/burst(var/creator = null)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return
|
||||
playsound(src, 'sound/weapons/resonator_blast.ogg', 50, 1)
|
||||
// Make the collapsing effect
|
||||
new /obj/effect/temp_visual/resonance_crush(T)
|
||||
|
||||
// Mineral turfs get drilled!
|
||||
if(istype(T, /turf/simulated/mineral))
|
||||
var/turf/simulated/mineral/M = T
|
||||
M.GetDrilled()
|
||||
qdel(src)
|
||||
return
|
||||
// Otherwise we damage mobs! Boost damage if low tempreature
|
||||
if(T.return_temperature() < 250)
|
||||
name = "strong resonance field"
|
||||
resonance_damage = 50
|
||||
|
||||
for(var/mob/living/L in src.loc)
|
||||
if(creator)
|
||||
add_attack_logs(creator, L, "used a resonator field on")
|
||||
to_chat(L, "<span class='danger'>\The [src] ruptured with you in it!</span>")
|
||||
L.apply_damage(resonance_damage, BRUTE)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/effect/temp_visual/resonance_crush
|
||||
icon_state = "shield1"
|
||||
plane = MOB_PLANE
|
||||
layer = ABOVE_MOB_LAYER
|
||||
duration = 4
|
||||
|
||||
/obj/effect/temp_visual/resonance_crush/Initialize(mapload)
|
||||
. = ..()
|
||||
transform = matrix()*1.5
|
||||
animate(src, transform = matrix()*0.1, alpha = 50, time = 4)
|
||||
@@ -0,0 +1,315 @@
|
||||
/*****************************Survival Pod********************************/
|
||||
/area/survivalpod
|
||||
name = "\improper Emergency Shelter"
|
||||
icon_state = "away"
|
||||
dynamic_lighting = TRUE
|
||||
requires_power = FALSE
|
||||
has_gravity = TRUE
|
||||
|
||||
//Survival Capsule
|
||||
/obj/item/survivalcapsule
|
||||
name = "surfluid shelter capsule"
|
||||
desc = "An emergency shelter programmed into construction nanomachines. It has a license for use printed on the bottom."
|
||||
icon_state = "houseball"
|
||||
icon = 'icons/obj/device_alt.dmi'
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/template_id = "shelter_alpha"
|
||||
var/datum/map_template/shelter/template
|
||||
var/used = FALSE
|
||||
|
||||
/obj/item/survivalcapsule/proc/get_template()
|
||||
if(template)
|
||||
return
|
||||
template = SSmapping.shelter_templates[template_id]
|
||||
if(!template)
|
||||
throw EXCEPTION("Shelter template ([template_id]) not found!")
|
||||
qdel(src)
|
||||
|
||||
/obj/item/survivalcapsule/Destroy()
|
||||
template = null // without this, capsules would be one use. per round.
|
||||
. = ..()
|
||||
|
||||
/obj/item/survivalcapsule/examine(mob/user, dist)
|
||||
. = ..()
|
||||
get_template()
|
||||
. += "This capsule has the [template.name] stored."
|
||||
. += template.description
|
||||
|
||||
/obj/item/survivalcapsule/attack_self(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 class='warning'>\The [src] begins to shake. Stand back!</span>")
|
||||
used = TRUE
|
||||
|
||||
sleep(5 SECONDS)
|
||||
|
||||
var/turf/deploy_location = get_turf(src)
|
||||
var/status = template.check_deploy(deploy_location)
|
||||
var/turf/above_location = deploy_location.above()
|
||||
if(above_location && status == SHELTER_DEPLOY_ALLOWED)
|
||||
status = template.check_deploy(above_location)
|
||||
|
||||
switch(status)
|
||||
//Not allowed due to /area technical reasons
|
||||
if(SHELTER_DEPLOY_BAD_AREA)
|
||||
src.loc.visible_message("<span class='warning'>\The [src] will not function in this area.</span>")
|
||||
|
||||
//Anchored objects or no space
|
||||
if(SHELTER_DEPLOY_BAD_TURFS, SHELTER_DEPLOY_ANCHORED_OBJECTS)
|
||||
var/width = template.width
|
||||
var/height = template.height
|
||||
src.loc.visible_message("<span class='warning'>\The [src] doesn't have room to deploy! You need to clear a [width]x[height] area!</span>")
|
||||
|
||||
if(status != SHELTER_DEPLOY_ALLOWED)
|
||||
used = FALSE
|
||||
return
|
||||
|
||||
var/turf/T = deploy_location
|
||||
var/datum/effect_system/smoke_spread/smoke = new /datum/effect_system/smoke_spread()
|
||||
smoke.attach(T)
|
||||
smoke.set_up(10, 0, T)
|
||||
smoke.start()
|
||||
sleep(4 SECONDS)
|
||||
|
||||
playsound(get_turf(src), 'sound/effects/phasein.ogg', 100, 1)
|
||||
|
||||
log_and_message_admins("[key_name_admin(usr)] activated a bluespace capsule at [get_area(T)]!")
|
||||
if(above_location)
|
||||
template.add_roof(above_location)
|
||||
template.annihilate_plants(deploy_location)
|
||||
template.load(deploy_location, centered = TRUE)
|
||||
template.update_lighting(deploy_location)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/survivalcapsule/luxury
|
||||
name = "luxury surfluid shelter capsule"
|
||||
desc = "An exorbitantly expensive luxury suite programmed into construction nanomachines. There's a license for use printed on the bottom."
|
||||
template_id = "shelter_beta"
|
||||
|
||||
/obj/item/survivalcapsule/luxurybar
|
||||
name = "luxury surfluid bar capsule"
|
||||
desc = "A luxury bar in a capsule. Bartender required and not included. There's a license for use printed on the bottom."
|
||||
template_id = "shelter_gamma"
|
||||
|
||||
/obj/item/survivalcapsule/military
|
||||
name = "military surfluid shelter capsule"
|
||||
desc = "A prefabricated firebase in a capsule. Contains basic weapons, building materials, and combat suits. There's a license for use printed on the bottom."
|
||||
template_id = "shelter_delta"
|
||||
|
||||
//Custom Shelter Capsules
|
||||
/obj/item/survivalcapsule/tabiranth
|
||||
name = "silver-trimmed surfluid shelter capsule"
|
||||
desc = "An exorbitantly expensive luxury suite programmed into construction nanomachines. This one is a particularly rare and expensive model. There's a license for use printed on the bottom."
|
||||
template_id = "shelter_phi"
|
||||
|
||||
//Pod objects
|
||||
//Walls
|
||||
/turf/simulated/shuttle/wall/voidcraft/survival
|
||||
name = "survival shelter"
|
||||
stripe_color = "#efbc3b"
|
||||
|
||||
/turf/simulated/shuttle/wall/voidcraft/survival/hard_corner
|
||||
hard_corner = 1
|
||||
|
||||
//Doors
|
||||
/obj/machinery/door/airlock/voidcraft/survival_pod
|
||||
name = "survival airlock"
|
||||
block_air_zones = 1
|
||||
|
||||
//Door access setter button
|
||||
/obj/machinery/button/remote/airlock/survival_pod
|
||||
name = "shelter privacy control"
|
||||
desc = "You can secure yourself inside the shelter here."
|
||||
specialfunctions = 4 // 4 is bolts
|
||||
id = "placeholder_id_do_not_use" //This has to be this way, otherwise it will control ALL doors if left blank.
|
||||
var/obj/machinery/door/airlock/voidcraft/survival_pod/door
|
||||
|
||||
/obj/machinery/button/remote/airlock/survival_pod/attack_hand(mob/user, datum/event_args/actor/clickchain/e_args)
|
||||
if(..()) return 1 //1 is failure on machines (for whatever reason)
|
||||
if(!door)
|
||||
var/turf/dT = get_step(src,dir)
|
||||
door = locate() in dT
|
||||
if(door)
|
||||
door.glass = !door.glass
|
||||
door.opacity = !door.opacity
|
||||
|
||||
//Windows
|
||||
/obj/structure/window/reinforced/survival_pod
|
||||
name = "pod window"
|
||||
icon = 'icons/obj/survival_pod.dmi'
|
||||
icon_state = "pwindow"
|
||||
fulltile = FALSE
|
||||
|
||||
|
||||
//Windoor
|
||||
/obj/machinery/door/window/survival_pod
|
||||
icon = 'icons/obj/survival_pod.dmi'
|
||||
icon_state = "windoor"
|
||||
base_state = "windoor"
|
||||
|
||||
//Table
|
||||
/obj/structure/table/survival_pod
|
||||
name = "table"
|
||||
icon = 'icons/obj/survival_pod.dmi'
|
||||
icon_state = "table"
|
||||
can_reinforce = FALSE
|
||||
can_plate = FALSE
|
||||
material_base = /datum/material/steel
|
||||
|
||||
/obj/structure/table/survival_pod/update_icon()
|
||||
. = ..()
|
||||
if(!isnull(material_base))
|
||||
icon_state = "table" //this table doesn't care about your material nonsense. just ignore the overlays.
|
||||
|
||||
/obj/structure/table/survival_pod/update_icon_state()
|
||||
if(!isnull(material_base))
|
||||
icon_state = "table"
|
||||
return ..()
|
||||
|
||||
/obj/structure/table/survival_pod/Initialize(mapload)
|
||||
remove_obj_verb(src, /obj/structure/table/verb/do_flip)
|
||||
remove_obj_verb(src, /obj/structure/table/proc/do_put)
|
||||
return ..()
|
||||
|
||||
//Sleeper
|
||||
/obj/machinery/sleeper/survival_pod
|
||||
desc = "A limited functionality sleeper, all it can do is put patients into stasis. It lacks the medication and configuration of the larger units."
|
||||
icon = 'icons/obj/survival_pod.dmi'
|
||||
icon_state = "sleeper"
|
||||
stasis_level = 100 //Just one setting
|
||||
|
||||
/obj/machinery/sleeper/survival_pod/update_icon()
|
||||
overlays.Cut()
|
||||
if(occupant)
|
||||
add_overlay("sleeper_cover")
|
||||
|
||||
//Computer
|
||||
/obj/item/gps/computer
|
||||
name = "pod computer"
|
||||
icon_state = "pod_computer"
|
||||
icon = 'icons/obj/survival_pod_comp.dmi'
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
pixel_y = -32
|
||||
gps_tag = "SHELTER"
|
||||
tracking = TRUE
|
||||
|
||||
/obj/item/gps/computer/attackby(obj/item/I, mob/living/user)
|
||||
if(I.is_wrench())
|
||||
user.visible_message("<span class='warning'>[user] disassembles [src].</span>",
|
||||
"<span class='notice'>You start to disassemble [src]...</span>", "You hear clanking and banging noises.")
|
||||
if(do_after(user,4 SECONDS,src))
|
||||
new /obj/item/gps(loc)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/item/gps/computer/attack_hand(mob/user, datum/event_args/actor/clickchain/e_args)
|
||||
attack_self(user)
|
||||
|
||||
//Bed
|
||||
/obj/structure/bed/pod
|
||||
icon = 'icons/obj/survival_pod.dmi'
|
||||
icon_state = "bed"
|
||||
|
||||
/obj/structure/bed/pod/Initialize(mapload)
|
||||
return ..(mapload, MAT_STEEL, "cotton")
|
||||
|
||||
//Survival Storage Unit
|
||||
/obj/machinery/smartfridge/survival_pod
|
||||
name = "survival pod storage"
|
||||
desc = "A heated storage unit."
|
||||
icon_state = "donkvendor"
|
||||
icon = 'icons/obj/survival_pod_vend.dmi'
|
||||
light_range = 5
|
||||
light_power = 1.2
|
||||
light_color = "#DDFFD3"
|
||||
pixel_y = -4
|
||||
max_n_of_items = 100
|
||||
icon_base = "donkvendor"
|
||||
|
||||
/obj/machinery/smartfridge/survival_pod/Initialize(mapload)
|
||||
. = ..()
|
||||
for(var/obj/item/O in loc)
|
||||
if(accept_check(O))
|
||||
stock(O)
|
||||
|
||||
/obj/machinery/smartfridge/survival_pod/accept_check(obj/item/O)
|
||||
return isitem(O)
|
||||
|
||||
/obj/machinery/smartfridge/survival_pod/update_icon() //survival pod smartfridges don't have the content nonsense, so this is mainly bandaid fix.
|
||||
overlays.Cut()
|
||||
if(inoperable())
|
||||
icon_state = "[icon_base]-off"
|
||||
else
|
||||
icon_state = icon_base
|
||||
|
||||
if(panel_open)
|
||||
icon_state = "[icon_base]_open"
|
||||
|
||||
|
||||
/obj/machinery/smartfridge/survival_pod/empty
|
||||
name = "dusty survival pod storage"
|
||||
desc = "A heated storage unit. This one's seen better days."
|
||||
|
||||
//Fans
|
||||
/obj/structure/fans
|
||||
icon = 'icons/obj/survival_pod.dmi'
|
||||
icon_state = "fans"
|
||||
name = "environmental regulation system"
|
||||
desc = "A large machine releasing a constant gust of air."
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
CanAtmosPass = ATMOS_PASS_AIR_BLOCKED
|
||||
var/buildstacktype = /obj/item/stack/material/steel
|
||||
var/buildstackamount = 5
|
||||
|
||||
/obj/structure/fans/drop_products(method, atom/where)
|
||||
. = ..()
|
||||
new buildstacktype(drop_location(), buildstackamount)
|
||||
|
||||
/obj/structure/fans/attackby(obj/item/I, mob/living/user)
|
||||
if(I.is_wrench())
|
||||
user.visible_message("<span class='warning'>[user] disassembles [src].</span>",
|
||||
"<span class='notice'>You start to disassemble [src]...</span>", "You hear clanking and banging noises.")
|
||||
if(do_after(user,4 SECONDS,src))
|
||||
deconstruct()
|
||||
return TRUE
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/structure/fans/tiny
|
||||
name = "tiny fan"
|
||||
desc = "A tiny fan, releasing a thin gust of air."
|
||||
plane = TURF_PLANE
|
||||
layer = ABOVE_TURF_LAYER
|
||||
density = FALSE
|
||||
icon_state = "fan_tiny"
|
||||
buildstackamount = 2
|
||||
|
||||
//Signs
|
||||
/obj/structure/sign/mining
|
||||
name = "nanotrasen mining corps sign"
|
||||
desc = "A sign of relief for weary miners, and a warning for would-be competitors to Nanotrasen's mining claims."
|
||||
icon = 'icons/obj/survival_pod.dmi'
|
||||
icon_state = "ntpod"
|
||||
|
||||
/obj/structure/sign/mining/survival
|
||||
name = "shelter sign"
|
||||
desc = "A high visibility sign designating a safe shelter."
|
||||
icon = 'icons/obj/survival_pod.dmi'
|
||||
icon_state = "survival"
|
||||
|
||||
//Fluff
|
||||
/obj/structure/tubes
|
||||
icon_state = "tubes"
|
||||
icon = 'icons/obj/survival_pod.dmi'
|
||||
name = "tubes"
|
||||
anchored = TRUE
|
||||
layer = BELOW_MOB_LAYER
|
||||
density = FALSE
|
||||
@@ -0,0 +1,13 @@
|
||||
/obj/structure/fans/hardlight
|
||||
name = "hardlight shield"
|
||||
desc = "Retains air, allows passage."
|
||||
plane = TURF_PLANE
|
||||
layer = ABOVE_TURF_LAYER
|
||||
density = FALSE
|
||||
icon = 'icons/effects/effects_vr.dmi'
|
||||
icon_state = "hardlight"
|
||||
buildstackamount = 2
|
||||
|
||||
light_range = 3
|
||||
light_power = 1
|
||||
light_color = "#FFFFFF"
|
||||
@@ -0,0 +1,101 @@
|
||||
/datum/map_template/shelter
|
||||
var/shelter_id
|
||||
var/description
|
||||
var/blacklisted_turfs
|
||||
var/whitelisted_turfs
|
||||
var/banned_areas
|
||||
var/banned_objects
|
||||
|
||||
/datum/map_template/shelter/New()
|
||||
. = ..()
|
||||
blacklisted_turfs = typecacheof(list(/turf/unsimulated, /turf/simulated/floor))
|
||||
// todo: if you have to modify this list again ping silicons and yell at them to code AREA_IMMUTABLE, AREA_FORBID_MAPLOADING_ITEMS, wnd maybe, just maybe, subareas.
|
||||
banned_areas = typecacheof(/area/shuttle, /area/rift/surfacebase/shuttle)
|
||||
banned_objects = list()
|
||||
|
||||
/datum/map_template/shelter/proc/check_deploy(turf/deploy_location)
|
||||
var/affected = get_affecting_turfs(deploy_location, centered=TRUE)
|
||||
for(var/turf/T in affected)
|
||||
var/area/A = get_area(T)
|
||||
if(is_type_in_typecache(A, banned_areas))
|
||||
return SHELTER_DEPLOY_BAD_AREA
|
||||
|
||||
var/banned = is_type_in_typecache(T, blacklisted_turfs)
|
||||
var/permitted = !whitelisted_turfs || is_type_in_typecache(T, whitelisted_turfs)
|
||||
if(banned && !permitted)
|
||||
return SHELTER_DEPLOY_BAD_TURFS
|
||||
|
||||
for(var/obj/O in T)
|
||||
if((O.density && O.anchored && !istype(O, /obj/structure/flora)) || is_type_in_typecache(O, banned_objects))
|
||||
return SHELTER_DEPLOY_ANCHORED_OBJECTS
|
||||
return SHELTER_DEPLOY_ALLOWED
|
||||
|
||||
/datum/map_template/shelter/proc/add_roof(turf/deploy_location)
|
||||
var/affected = get_affecting_turfs(deploy_location, centered=TRUE)
|
||||
for(var/turf/T in affected)
|
||||
if(isopenturf(T))
|
||||
T.ChangeTurf(/turf/simulated/shuttle/floor/voidcraft)
|
||||
|
||||
/datum/map_template/shelter/proc/annihilate_plants(turf/deploy_location)
|
||||
var/deleted_atoms = 0
|
||||
var/affected = get_affecting_turfs(deploy_location, centered=TRUE)
|
||||
for(var/turf/T in affected)
|
||||
for(var/obj/structure/flora/AM in T)
|
||||
++deleted_atoms
|
||||
qdel(AM)
|
||||
admin_notice("<span class='danger'>Annihilated [deleted_atoms] plants.</span>", R_DEBUG)
|
||||
|
||||
/datum/map_template/shelter/proc/update_lighting(turf/deploy_location)
|
||||
// var/affected = get_affecting_turfs(deploy_location, centered=TRUE)
|
||||
// for(var/turf/T in affected)
|
||||
// T.lighting_build_overlay()
|
||||
return // todo: refactor and verify???
|
||||
|
||||
/datum/map_template/shelter/alpha
|
||||
name = "Shelter Alpha"
|
||||
shelter_id = "shelter_alpha"
|
||||
description = "A cosy self-contained pressurized shelter, with \
|
||||
built-in navigation, entertainment, medical facilities and a \
|
||||
sleeping area! Order now, and we'll throw in a TINY FAN, \
|
||||
absolutely free!"
|
||||
map_path = "maps/templates/shelters/shelter_1.dmm"
|
||||
|
||||
/datum/map_template/shelter/beta
|
||||
name = "Shelter Beta"
|
||||
shelter_id = "shelter_beta"
|
||||
description = "An extremely luxurious shelter, containing all \
|
||||
the amenities of home, including carpeted floors, hot and cold \
|
||||
running water, a gourmet three course meal, cooking facilities, \
|
||||
and a deluxe companion to keep you from getting lonely during \
|
||||
an ash storm."
|
||||
map_path = "maps/templates/shelters/shelter_2.dmm"
|
||||
|
||||
/datum/map_template/shelter/gamma
|
||||
name = "Shelter Gamma"
|
||||
shelter_id = "shelter_gamma"
|
||||
description = "A luxury elite bar which holds an entire bar \
|
||||
along with two vending machines, tables, and a restroom that \
|
||||
also has a sink. This isn't a survival capsule and so you can \
|
||||
expect that this won't save you if you're bleeding out to \
|
||||
death."
|
||||
map_path = "maps/templates/shelters/shelter_3.dmm"
|
||||
|
||||
/datum/map_template/shelter/delta
|
||||
name = "Shelter Delta"
|
||||
shelter_id = "shelter_delta"
|
||||
description = "A small firebase that contains equipment and supplies \
|
||||
for roughly a squad of military troops. Large quantities of \
|
||||
supplies allow it to hold out for an extended period of time\
|
||||
and a built in medical facility allows field treatment to be \
|
||||
possible."
|
||||
map_path = "maps/templates/shelters/shelter_4.dmm"
|
||||
|
||||
/datum/map_template/shelter/phi
|
||||
name = "Shelter Phi"
|
||||
shelter_id = "shelter_phi"
|
||||
description = "An heavily modified variant of the luxury shelter, \
|
||||
this particular model has extra food, drinks, and other supplies. \
|
||||
Originally designed for use by colonists on worlds with little to \
|
||||
to no contact, the expense of these shelters have prevented them \
|
||||
from seeing common use."
|
||||
map_path = "maps/templates/shelters/shelter_a.dmm"
|
||||
@@ -0,0 +1,92 @@
|
||||
|
||||
/obj/item/vertibore
|
||||
name = "portable shaft excavation device"
|
||||
desc = "A heavily modified shaft bore utilizing phorogenic blasts to tunnel vertically through rock. Much faster than a large industrial drill unit, but is very resource- and power-intensive."
|
||||
description_fluff = "A phoron bore used for rapidly digging through rock that has been modified to allow it to fire straight down at a much higher power. However, this has resulted in a loss of power and resource efficiency, compactness, and modularity as the proprietary capacitor and manipulator cannot be swapped."
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "vertibore"
|
||||
item_state = "vertibore"
|
||||
|
||||
|
||||
var/obj/item/cell/cell //loaded cell
|
||||
var/power_cost = 1000 //10 shots off a highcap
|
||||
var/load_type = /obj/item/stack/material
|
||||
var/mat_storage = 0 // How much material is stored inside? Input in multiples of 2000 as per auto/protolathe.
|
||||
var/max_mat_storage = 50000 // 25 sheets
|
||||
var/mat_cost = 1000 // 100 shots off of a full stack.
|
||||
var/ammo_material = MAT_PHORON
|
||||
var/loading = FALSE
|
||||
|
||||
/obj/item/vertibore/examine(mob/user, dist)
|
||||
. = ..()
|
||||
. += "<span class='notice'>The shaft excavator has [mat_storage]cm^3 of phoron inside, and can hold a maximum of [max_mat_storage].</span>"
|
||||
if(cell)
|
||||
. += "<span class='notice'>The installed [cell.name] has a charge level of [round((cell.charge/cell.maxcharge)*100)]%.</span>"
|
||||
|
||||
/obj/item/vertibore/attackby(var/obj/item/thing, var/mob/user)
|
||||
if(istype(thing, /obj/item/cell))
|
||||
if(cell)
|
||||
to_chat(user, "<span class='warning'>\The [src] already has \a [cell] installed.</span>")
|
||||
return
|
||||
if(!user.attempt_insert_item_for_installation(cell, src))
|
||||
return
|
||||
cell = thing
|
||||
playsound(loc, 'sound/machines/click.ogg', 10, 1)
|
||||
user.visible_message("<span class='notice'>\The [user] slots \the [cell] into \the [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
if(thing.is_screwdriver())
|
||||
if(!cell)
|
||||
to_chat(user, "<span class='warning'>\The [src] has no cell installed.</span>")
|
||||
return
|
||||
cell.forceMove(get_turf(src))
|
||||
user.put_in_hands(cell)
|
||||
user.visible_message("<span class='notice'>\The [user] unscrews \the [cell.name] from \the [src].</span>")
|
||||
playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
cell = null
|
||||
update_icon()
|
||||
return
|
||||
if(istype(thing, load_type))
|
||||
loading = TRUE
|
||||
var/obj/item/stack/material/M = thing
|
||||
if(!M.material || M.material.name != ammo_material)
|
||||
return
|
||||
if(mat_storage + 2000 > max_mat_storage)
|
||||
to_chat(user, "<span class='warning'>\The [src] cannot hold more [ammo_material].</span>")
|
||||
return
|
||||
var/can_hold_val = 0
|
||||
while(can_hold_val < round(max_mat_storage / 2000))
|
||||
if(mat_storage + 2000 <= max_mat_storage && do_after(user,1.5 SECONDS))
|
||||
can_hold_val ++
|
||||
mat_storage += 2000
|
||||
playsound(loc, 'sound/effects/phasein.ogg', 15, 1)
|
||||
else
|
||||
loading = FALSE
|
||||
break
|
||||
M.use(can_hold_val)
|
||||
user.visible_message("<span class='notice'>\The [user] loads \the [src] with \the [M].</span>")
|
||||
playsound(loc, 'sound/weapons/flipblade.ogg', 50, 1)
|
||||
update_icon()
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/vertibore/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(mat_cost > mat_storage)
|
||||
to_chat(user, "<span class='notice'>The [src] shudders, the phoron feeding mechanism attempting to move things that aren't there.</span>")
|
||||
return
|
||||
if(power_cost > cell.charge)
|
||||
to_chat(user, "<span class='notice'>The [src] flashes a warning light, it doesn't have enough charge to dig.</span>")
|
||||
return
|
||||
if(cell.use(power_cost) && do_after(user, 2.5 SECONDS))
|
||||
var/turf/T = get_turf(user)
|
||||
LEGACY_EX_ACT(T, 1, null)
|
||||
|
||||
/obj/item/vertibore/update_icon()
|
||||
var/list/overlays_to_add = list()
|
||||
if(cell)
|
||||
overlays_to_add += image(icon, "[icon_state]_cell")
|
||||
..()
|
||||
Reference in New Issue
Block a user