diff --git a/cev_eris.dme b/cev_eris.dme index eff9506c3c3..445138e0ad9 100644 --- a/cev_eris.dme +++ b/cev_eris.dme @@ -1144,6 +1144,7 @@ #include "code\game\objects\items\weapons\tools\crowbars.dm" #include "code\game\objects\items\weapons\tools\hammer.dm" #include "code\game\objects\items\weapons\tools\hemostats.dm" +#include "code\game\objects\items\weapons\tools\karl.dm" #include "code\game\objects\items\weapons\tools\knives.dm" #include "code\game\objects\items\weapons\tools\misc.dm" #include "code\game\objects\items\weapons\tools\multitool.dm" diff --git a/code/game/objects/items/weapons/tools/karl.dm b/code/game/objects/items/weapons/tools/karl.dm new file mode 100644 index 00000000000..698819df5b3 --- /dev/null +++ b/code/game/objects/items/weapons/tools/karl.dm @@ -0,0 +1,188 @@ +/obj/item/tool/karl + name = "K.A.R.L" + desc = "Kinetic Acceleration Reconfigurable Lodebreaker. Rock and stone to the bone, miner!" + flags = CONDUCT + slot_flags = SLOT_BELT + icon = 'icons/obj/karl_mining.dmi' + icon_state = "karl_axe" + item_state = "karl_axe" + w_class = ITEM_SIZE_BULKY + price_tag = 2500 + matter = list(MATERIAL_STEEL = 6) + origin_tech = list(TECH_MATERIAL = 1, TECH_ENGINEERING = 1) + attack_verb = list("hit", "pierced", "sliced", "attacked") + hitsound = 'sound/weapons/melee/heavystab.ogg' + + // Damage related + force = WEAPON_FORCE_DANGEROUS + armor_divisor = ARMOR_PEN_HALF // It's a pickaxe. It's destined to poke holes in things, even armor. + throwforce = WEAPON_FORCE_NORMAL + sharp = TRUE + structure_damage_factor = STRUCTURE_DAMAGE_DESTRUCTIVE // Drills and picks are made for getting through hard materials + embed_mult = 1.2 // Digs deep + + // Spawn and value related + spawn_blacklisted = TRUE + rarity_value = 24 + + // Turn on-off related + toggleable = TRUE + tool_qualities = list(QUALITY_DIGGING = 10, QUALITY_PRYING = 10, QUALITY_CUTTING = 5) // So it still shares its switch off quality despite not yet being used. + switched_off_qualities = list(QUALITY_DIGGING = 10, QUALITY_PRYING = 10, QUALITY_CUTTING = 5) + switched_on_qualities = list(QUALITY_DIGGING = 30, QUALITY_WELDING = 10) + suitable_cell = /obj/item/cell/medium/high + use_power_cost = 1.5 + passive_power_cost = 0.01 + glow_color = COLOR_BLUE_LIGHT + + // Gun-mode related + action_button_name = "Switch K.A.R.L Mode" + var/gunmode = FALSE // TRUE when KARL is in gun mode + var/obj/item/gun/energy/plasma/installation = /obj/item/gun/energy/plasma // The inbuilt gun. Store as path to initialize a new gun on creation. + var/projectile // Holder for bullettype + var/shot_sound // What sound should play when the gun fires + var/reqpower = 10 // Power needed to shoot + +/obj/item/tool/karl/New() + . = ..() + + // Init inbuilt gun + if(ispath(installation)) + installation = new installation + projectile = installation.projectile_type + shot_sound = installation.fire_sound + +/obj/item/tool/karl/Initialize() + . = ..() + verbs += /obj/item/tool/karl/proc/toggle_mode_verb + +/obj/item/tool/karl/Destroy() + QDEL_NULL(installation) + . = ..() + +/obj/item/tool/karl/update_icon() + cut_overlays() + + var/karl_icon = "karl" + if(gunmode) + karl_icon += "_gun" + else + karl_icon += "_axe" + if(switched_on) + karl_icon += "_on" + + icon_state = karl_icon // Item sprite + + if(wielded) + karl_icon += "_wielded" + + item_state = karl_icon // On-suit sprite + +/obj/item/tool/karl/equipped(mob/user) + ..() + update_icon() + +/obj/item/tool/karl/dropped(mob/user) + ..() + update_icon() + +/obj/item/tool/karl/attack_self(mob/user) + if(isBroken) + to_chat(user, SPAN_WARNING("\The [src] is broken.")) + return + if(gunmode) + if(cell) + if(!cell.fully_charged()) + var/pumping_time = wielded ? 1 SECOND : 2 SECONDS + if(do_after(user, pumping_time)) + if(cell) // Check the cell is still there in case big brain player chose to remove it during pumping + cell.give(use_power_cost * 1 SECOND) // Enough to use the tool during 1 second + to_chat(user, SPAN_NOTICE("You recharge \the [src] by pumping it, cell charge at [round(cell.percent())]%.")) + // Continue pumping till user cancels the pumping + attack_self(user) + else + to_chat(user, SPAN_NOTICE("\The [src]\'cell is fully charged'.")) + else + to_chat(user, SPAN_NOTICE("\The [src] is missing a cell to recharge.")) + return + ..() + return + +/obj/item/tool/karl/turn_on(mob/user) + . = ..() + if(.) + to_chat(user, SPAN_NOTICE("A dangerous energy blade now covers the edges of the tool.")) + +/obj/item/tool/karl/turn_off(mob/user) + to_chat(user, SPAN_NOTICE("The energy blade swiftly retracts.")) + ..() + +// Same values than /obj/item/proc/use_tool +/obj/item/tool/karl/use_tool(mob/living/user, atom/target, base_time, required_quality, fail_chance, required_stat, instant_finish_tier = 110, forced_sound = null, sound_repeat = 2.5 SECONDS) + . = ..() // That proc will return TRUE only when everything was done right, and FALSE if something went wrong, ot user was unlucky. + + // Recharge upon successfull use when switched off + if(. && !switched_on && cell) + cell.give(use_power_cost * 1 SECOND) // Enough to use the tool during 1 second + +/obj/item/tool/karl/proc/toggle_mode_verb() + set name = "Unique Action" + set category = "Object" + set src in view(1) + + toggle_karl_mode(usr) + +/obj/item/tool/karl/proc/toggle_karl_mode(mob/user) + gunmode = !gunmode + to_chat(user, SPAN_NOTICE("\The [src] switches to [gunmode ? "gun" : "tool"] mode.")) + update_icon() + update_wear_icon() + +/obj/item/tool/karl/afterattack(atom/target, mob/user, proximity, params) + + if(isBroken) + to_chat(user, SPAN_WARNING("\The [src] is broken.")) + return + + if(gunmode) + if(!wielded) + to_chat(user, SPAN_WARNING("\The [src] must be wielded to shoot.")) + return + if(!cell?.checked_use(reqpower)) + to_chat(user, SPAN_WARNING("[src] battery is dead or missing.")) + return + shootAt(target, user.targeted_organ) + user.setClickCooldown(1 SECOND) + return + + return ..() + +/obj/item/tool/karl/proc/shootAt(var/mob/living/target, def_zone) + + // Check source and destination + var/turf/T = get_turf(src) + var/turf/U = get_turf(target) + if(!istype(T) || !istype(U)) + return + + // Launching projectile + var/obj/item/projectile/A = new projectile(loc) + playsound(loc, shot_sound, 75, 1) + + // Local pressure affect damages + var/datum/gas_mixture/environment = T.return_air() + var/env_pressure = environment ? environment.return_pressure() : ONE_ATMOSPHERE + // Full damage if pressure < 0.5 atmosphere, one-fourth of damage in > 1 atmosphere, linear between those values + var/dmg = WEAPON_FORCE_DANGEROUS * clamp(1 - 0.75 * (env_pressure - 0.5 * ONE_ATMOSPHERE) / (0.5 * ONE_ATMOSPHERE), 0.25, 1) + // Burn because it's a plasma shot (installation gun) + A.damage_types[BURN] = dmg + + // Shooting Code + A.launch(target, def_zone) + +/obj/item/tool/karl/ui_action_click(mob/user, actiontype) + switch(actiontype) + if("Tool information") + nano_ui_interact(user) + else + toggle_karl_mode(user) diff --git a/code/modules/trade/datums/trade_stations_presets/1-common/asterstradecapital.dm b/code/modules/trade/datums/trade_stations_presets/1-common/asterstradecapital.dm index 1bac265881b..a73acc4799a 100644 --- a/code/modules/trade/datums/trade_stations_presets/1-common/asterstradecapital.dm +++ b/code/modules/trade/datums/trade_stations_presets/1-common/asterstradecapital.dm @@ -52,6 +52,7 @@ ), "Mining Gear" = list( /obj/machinery/mining/deep_drill, + /obj/item/tool/karl, /obj/item/tool/pickaxe, /obj/item/tool/pickaxe/excavation, /obj/item/storage/bag/ore, diff --git a/icons/mob/items/lefthand.dmi b/icons/mob/items/lefthand.dmi index 0d71a43c56e..371b4415c80 100644 Binary files a/icons/mob/items/lefthand.dmi and b/icons/mob/items/lefthand.dmi differ diff --git a/icons/mob/items/righthand.dmi b/icons/mob/items/righthand.dmi index 7af168d9676..ce1173402f3 100644 Binary files a/icons/mob/items/righthand.dmi and b/icons/mob/items/righthand.dmi differ diff --git a/icons/obj/karl_mining.dmi b/icons/obj/karl_mining.dmi new file mode 100644 index 00000000000..87f0475c730 Binary files /dev/null and b/icons/obj/karl_mining.dmi differ diff --git a/maps/CEVEris/_CEV_Eris.dmm b/maps/CEVEris/_CEV_Eris.dmm index 982dee97da9..4e465b64dd8 100644 --- a/maps/CEVEris/_CEV_Eris.dmm +++ b/maps/CEVEris/_CEV_Eris.dmm @@ -52009,8 +52009,8 @@ /obj/machinery/button/remote/blast_door{ id = "last_shelter"; name = "Last shelter lock control"; - req_access = list(74); - pixel_x = -24 + pixel_x = -24; + req_access = list(74) }, /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 @@ -59945,6 +59945,7 @@ /obj/item/clothing/suit/space/void/mining, /obj/item/clothing/mask/breath, /obj/item/device/scanner/mining, +/obj/item/tool/karl, /turf/simulated/shuttle/floor/mining{ icon_state = "2,21" }, @@ -60209,6 +60210,7 @@ /obj/item/clothing/suit/space/void/mining, /obj/item/clothing/mask/breath, /obj/item/device/scanner/mining, +/obj/item/tool/karl, /turf/simulated/shuttle/floor/mining{ icon_state = "2,20" }, @@ -60472,6 +60474,7 @@ /obj/item/clothing/suit/space/void/mining, /obj/item/clothing/mask/breath, /obj/item/device/scanner/mining, +/obj/item/tool/karl, /turf/simulated/shuttle/floor/mining{ icon_state = "2,19" }, @@ -100121,8 +100124,8 @@ dir = 4; id = "maint_hatch_acolyte"; name = "Maintenance Hatch Control"; - req_access = null; - pixel_x = -24 + pixel_x = -24; + req_access = null }, /obj/structure/table/woodentable, /obj/structure/sign/faction/neotheology_cross/gold{ @@ -104768,10 +104771,10 @@ "sfv" = ( /obj/machinery/door/firedoor, /obj/machinery/door/blast/shutters{ + dir = 2; id = "maint_hatch_church_preacher"; layer = 3.3; - name = "Maintenance Hatch"; - dir = 2 + name = "Maintenance Hatch" }, /obj/structure/disposalpipe/segment, /obj/effect/window_lwall_spawn/smartspawn,