diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 96c97ec9f6..220f896436 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -235,6 +235,12 @@ Proc for attack log creation, because really why not var/atom/original_loc = user.loc + var/obj/mecha/M = null + + if(istype(user.loc, /obj/mecha)) + original_loc = get_turf(original_loc) + M = user.loc + var/holding = user.get_active_hand() var/datum/progressbar/progbar @@ -253,7 +259,12 @@ Proc for attack log creation, because really why not . = FALSE break - if(user.loc != original_loc && !ignore_movement) + if(M) + if(user.loc != M || (M.loc != original_loc && !ignore_movement)) // Mech coooooode. + . = FALSE + break + + else if(user.loc != original_loc && !ignore_movement) . = FALSE break diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index 54e2b9c87b..a3532a1b32 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -63,6 +63,8 @@ H.reagents.add_reagent("carpotoxin", force) if(H.reagents.get_reagent_amount("cryptobiolin") + force < force*2) H.reagents.add_reagent("cryptobiolin", force) + if("halloss") + H.stun_effect_act(1, force / 2, BP_TORSO, src) else return if(update) H.UpdateDamageIcon() diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 35ee1cd7b6..5df31c4302 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -11,6 +11,7 @@ icon_state = "mecha_equip" force = 5 origin_tech = list(TECH_MATERIAL = 2) + description_info = "Some equipment may gain new abilities or advantages if equipped to certain types of Exosuits." var/equip_cooldown = 0 var/equip_ready = 1 var/energy_drain = 0 @@ -21,6 +22,7 @@ var/equip_type = null //mechaequip2 var/allow_duplicate = FALSE var/ready_sound = 'sound/mecha/mech_reload_default.ogg' //Sound to play once the fire delay passed. + var/enable_special = FALSE // Will the tool do its special? /obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(target=1) sleep(equip_cooldown) @@ -110,6 +112,15 @@ /obj/item/mecha_parts/mecha_equipment/proc/is_melee() return range&MELEE +/obj/item/mecha_parts/mecha_equipment/proc/enable_special_checks(atom/target) + if(ispath(required_type)) + return istype(target, required_type) + + for (var/path in required_type) + if (istype(target, path)) + return 1 + + return 0 /obj/item/mecha_parts/mecha_equipment/proc/action_checks(atom/target) if(!target) @@ -176,6 +187,10 @@ M.equipment += src chassis = M src.loc = M + + if(enable_special_checks(M)) + enable_special = TRUE + M.log_message("[src] initialized.") if(!M.selected) M.selected = src @@ -203,6 +218,7 @@ chassis.log_message("[src] removed from equipment.") chassis = null set_ready_state(1) + enable_special = FALSE return /obj/item/mecha_parts/mecha_equipment/Topic(href,href_list) diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index b621d97cba..0519bf2ca4 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -8,11 +8,13 @@ energy_drain = 10 var/dam_force = 20 var/obj/mecha/working/ripley/cargo_holder - required_type = /obj/mecha/working + required_type = list(/obj/mecha/working) + ready_sound = 'sound/mecha/gasdisconnected.ogg' /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/attach(obj/mecha/M as obj) ..() cargo_holder = M + return /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/action(atom/target) @@ -28,7 +30,48 @@ occupant_message("You can't load living things into the cargo compartment.") return if(O.anchored) - occupant_message("[target] is firmly secured.") + if(enable_special) + if(istype(O, /obj/machinery/door/firedoor)) // I love doors. + var/obj/machinery/door/firedoor/FD = O + if(FD.blocked) + FD.visible_message("\The [chassis] begins prying on \the [FD]!") + if(do_after(chassis.occupant,10 SECONDS,FD)) + playsound(FD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1) + FD.blocked = 0 + FD.update_icon() + FD.open(1) + FD.visible_message("\The [chassis] tears \the [FD] open!") + else if(FD.density) + FD.visible_message("\The [chassis] begins forcing \the [FD] open!") + if(do_after(chassis.occupant, 5 SECONDS,FD)) + playsound(FD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1) + FD.visible_message("\The [chassis] forces \the [FD] open!") + FD.open(1) + else + FD.visible_message("\The [chassis] forces \the [FD] closed!") + FD.close(1) + else if(istype(O, /obj/machinery/door/airlock)) // D o o r s. + var/obj/machinery/door/airlock/AD = O + if(AD.locked) + occupant_message("The airlock's bolts prevent it from being forced.") + else if(!AD.operating) + if(AD.welded) + AD.visible_message("\The [chassis] begins prying on \the [AD]!") + if(do_after(chassis.occupant, 15 SECONDS,AD) && chassis.Adjacent(AD)) + AD.welded = FALSE + AD.update_icon() + playsound(AD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1) + AD.visible_message("\The [chassis] tears \the [AD] open!") + if(!AD.welded) + if(density) + spawn(0) + AD.open(1) + else + spawn(0) + AD.close(1) + return + else + occupant_message("[target] is firmly secured.") return if(cargo_holder.cargo.len >= cargo_holder.cargo_capacity) occupant_message("Not enough room in cargo compartment.") @@ -62,6 +105,15 @@ occupant_message("You squeeze [target] with [src.name]. Something cracks.") playsound(src.loc, "fracture", 5, 1, -2) //CRACK chassis.visible_message("[chassis] squeezes [target].") + else if(chassis.occupant.a_intent == I_DISARM && enable_special) + playsound(src.loc, 'sound/mecha/hydraulic.ogg', 10, 1, -2) + M.take_overall_damage(dam_force/2) + M.adjustOxyLoss(round(dam_force/3)) + M.updatehealth() + occupant_message("You slam [target] with [src.name]. Something cracks.") + playsound(src.loc, "fracture", 3, 1, -2) //CRACK 2 + chassis.visible_message("[chassis] slams [target].") + M.throw_at(get_step(M,get_dir(src, M)), 14, 1.5, chassis) else step_away(M,chassis) occupant_message("You push [target] out of the way.") @@ -73,12 +125,12 @@ /obj/item/mecha_parts/mecha_equipment/tool/drill name = "drill" - desc = "This is the drill that'll pierce the heavens! (Can be attached to: Combat and Engineering Exosuits)" + desc = "This is the drill that'll pierce the heavens!" icon_state = "mecha_drill" equip_cooldown = 30 energy_drain = 10 force = 15 - required_type = list(/obj/mecha/working/ripley, /obj/mecha/combat) + required_type = list(/obj/mecha/working/ripley) /obj/item/mecha_parts/mecha_equipment/tool/drill/action(atom/target) if(!action_checks(target)) return @@ -101,9 +153,13 @@ log_message("Drilled through [target]") target.ex_act(2) else if(istype(target, /turf/simulated/mineral)) - for(var/turf/simulated/mineral/M in range(chassis,1)) - if(get_dir(chassis,M)&chassis.dir) - M.GetDrilled() + if(enable_special) + for(var/turf/simulated/mineral/M in range(chassis,1)) + if(get_dir(chassis,M)&chassis.dir) + M.GetDrilled() + else + var/turf/simulated/mineral/M1 = target + M1.GetDrilled() log_message("Drilled through [target]") if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo @@ -125,7 +181,7 @@ /obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill name = "diamond drill" - desc = "This is an upgraded version of the drill that'll pierce the heavens! (Can be attached to: Combat and Engineering Exosuits)" + desc = "This is an upgraded version of the drill that'll pierce the heavens!" icon_state = "mecha_diamond_drill" origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3) equip_cooldown = 10 @@ -150,9 +206,13 @@ log_message("Drilled through [target]") target.ex_act(3) else if(istype(target, /turf/simulated/mineral)) - for(var/turf/simulated/mineral/M in range(chassis,1)) - if(get_dir(chassis,M)&chassis.dir) - M.GetDrilled() + if(enable_special) + for(var/turf/simulated/mineral/M in range(chassis,1)) + if(get_dir(chassis,M)&chassis.dir) + M.GetDrilled() + else + var/turf/simulated/mineral/M1 = target + M1.GetDrilled() log_message("Drilled through [target]") if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo @@ -165,6 +225,102 @@ target.ex_act(2) return 1 +/obj/item/mecha_parts/mecha_equipment/tool/drill/bore + name = "depth bore" + desc = "This is the drill that'll pierce the depths!" + icon_state = "mecha_bore" + equip_cooldown = 5 SECONDS + energy_drain = 30 + force = 20 + required_type = list(/obj/mecha/working/ripley) + +/obj/item/mecha_parts/mecha_equipment/tool/drill/bore/action(atom/target) + if(!action_checks(target)) return + if(isobj(target)) + var/obj/target_obj = target + if(target_obj.unacidable) return + set_ready_state(0) + chassis.use_power(energy_drain) + chassis.visible_message("[chassis] starts to bore into \the [target]", "You hear the bore.") + occupant_message("You start to bore into \the [target]") + var/T = chassis.loc + var/C = target.loc + if(do_after_cooldown(target)) + if(T == chassis.loc && src == chassis.selected) + if(istype(target, /turf/simulated/wall)) + var/turf/simulated/wall/W = target + if(W.reinf_material) + occupant_message("[target] is too durable to bore through.") + else + log_message("Bored through [target]") + target.ex_act(2) + else if(istype(target, /turf/simulated/mineral)) + var/turf/simulated/mineral/M = target + if(enable_special && !M.density) + M.ex_act(2) + log_message("Bored into [target]") + else + M.GetDrilled() + log_message("Bored through [target]") + if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) + var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo + if(ore_box) + for(var/obj/item/weapon/ore/ore in range(chassis,1)) + if(get_dir(chassis,ore)&chassis.dir) + ore.Move(ore_box) + if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) + var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo + if(ore_box) + for(var/obj/item/weapon/ore/ore in range(chassis,1)) + if(get_dir(chassis,ore)&chassis.dir) + ore.Move(ore_box) + else if(target.loc == C) + log_message("Drilled through [target]") + target.ex_act(2) + return 1 + +/obj/item/mecha_parts/mecha_equipment/tool/orescanner + name = "mounted ore scanner" + desc = "An exosuit-mounted ore scanner." + icon_state = "mecha_analyzer" + origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2, TECH_POWER = 2) + equip_cooldown = 5 + energy_drain = 30 + range = MELEE|RANGED + equip_type = EQUIP_SPECIAL + ready_sound = 'sound/items/goggles_charge.ogg' + required_type = list(/obj/mecha/working/ripley) + + var/obj/item/weapon/mining_scanner/my_scanner = null + var/exact_scan = FALSE + +/obj/item/mecha_parts/mecha_equipment/tool/orescanner/Initialize() + my_scanner = new(src) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/orescanner/Destroy() + QDEL_NULL(my_scanner) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/orescanner/action(var/atom/target) + if(!action_checks(target) || get_dist(chassis, target) > 5) + return FALSE + + if(!enable_special) + target = get_turf(chassis) + + var/datum/beam/ScanBeam = chassis.Beam(target,"g_beam",'icons/effects/beam.dmi',time=2 SECONDS,10,/obj/effect/ebeam,2) + + if(do_after(chassis.occupant, 2 SECONDS)) + my_scanner.ScanTurf(target, chassis.occupant, exact_scan) + + QDEL_NULL(ScanBeam) + +/obj/item/mecha_parts/mecha_equipment/tool/orescanner/advanced + name = "advanced ore scanner" + icon_state = "mecha_analyzer_adv" + exact_scan = TRUE + /obj/item/mecha_parts/mecha_equipment/tool/extinguisher name = "extinguisher" desc = "Exosuit-mounted extinguisher (Can be attached to: Engineering exosuits)" @@ -235,6 +391,48 @@ /obj/item/mecha_parts/mecha_equipment/tool/extinguisher/on_reagent_change() return +/obj/item/mecha_parts/mecha_equipment/tool/powertool + name = "pneumatic wrench" + desc = "An exosuit-mounted hydraulic wrench." + icon_state = "mecha_wrench" + origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2, TECH_POWER = 2) + equip_cooldown = 3 + energy_drain = 15 + range = MELEE + equip_type = EQUIP_UTILITY + ready_sound = 'sound/items/Ratchet.ogg' + required_type = list(/obj/mecha/working/ripley) + + var/obj/item/my_tool = null + var/tooltype = /obj/item/weapon/tool/wrench/power + +/obj/item/mecha_parts/mecha_equipment/tool/powertool/Initialize() + my_tool = new tooltype(src) + my_tool.name = name + my_tool.anchored = TRUE + my_tool.canremove = FALSE + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/powertool/Destroy() + QDEL_NULL(my_tool) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/powertool/action(var/atom/target) + if(!action_checks(target)) + return FALSE + + if(isliving(target)) + my_tool.attack(target, chassis.occupant, BP_TORSO) + + target.attackby(my_tool,chassis.occupant) + +/obj/item/mecha_parts/mecha_equipment/tool/powertool/prybar + name = "pneumatic prybar" + desc = "An exosuit-mounted pneumatic prybar." + icon_state = "mecha_crowbar" + tooltype = /obj/item/weapon/tool/crowbar/power + ready_sound = 'sound/mecha/gasdisconnected.ogg' + /obj/item/mecha_parts/mecha_equipment/tool/rcd name = "mounted RCD" desc = "An exosuit-mounted Rapid Construction Device. (Can be attached to: Any exosuit)" diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 86e3badc6f..43e7e0f90c 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -13,6 +13,10 @@ var/atom/target = null var/open_panel = 0 var/image_overlay = null + var/blast_dev = -1 + var/blast_heavy = -1 + var/blast_light = 2 + var/blast_flash = 3 /obj/item/weapon/plastique/New() wires = new(src) @@ -72,7 +76,7 @@ if(!target) target = src if(location) - explosion(location, -1, -1, 2, 3) + explosion(location, blast_dev, blast_heavy, blast_light, blast_flash) if(target) if (istype(target, /turf/simulated/wall)) @@ -88,3 +92,11 @@ /obj/item/weapon/plastique/attack(mob/M as mob, mob/user as mob, def_zone) return + +/obj/item/weapon/plastique/seismic + name = "seismic charge" + desc = "Used to dig holes in specific areas without too much extra hole." + + blast_heavy = 3 + blast_light = 5 + blast_flash = 8 diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade.dm b/code/game/objects/items/weapons/grenades/spawnergrenade.dm index 7d725c36bb..625fb11e0c 100644 --- a/code/game/objects/items/weapons/grenades/spawnergrenade.dm +++ b/code/game/objects/items/weapons/grenades/spawnergrenade.dm @@ -41,6 +41,19 @@ /obj/item/weapon/grenade/spawnergrenade/manhacks/raider spawner_type = /mob/living/simple_mob/mechanical/viscerator/raider +/obj/item/weapon/grenade/spawnergrenade/manhacks/station + desc = "It is set to detonate in 5 seconds. It will deploy three weaponized survey drones." + deliveryamt = 3 + spawner_type = /mob/living/simple_mob/mechanical/viscerator/station + origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 3, TECH_ILLEGAL = 1) + +/obj/item/weapon/grenade/spawnergrenade/ward + name = "sentry delivery grenade" + desc = "It is set to detonate in 5 seconds. It will deploy a single thermal-optic sentry drone." + spawner_type = /mob/living/simple_mob/mechanical/ward/monitor/crew + deliveryamt = 1 + origin_tech = list(TECH_MATERIAL = 4, TECH_MAGNET = 3, TECH_BLUESPACE = 2) + /obj/item/weapon/grenade/spawnergrenade/spesscarp name = "carp delivery grenade" spawner_type = /mob/living/simple_mob/animal/space/carp diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 2230e14603..e0167527f0 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -200,6 +200,24 @@ BLIND // can't see anything name = "prescription optical material scanner" prescription = 1 +/obj/item/clothing/glasses/graviton + name = "graviton goggles" + desc = "The secrets of space travel are.. not quite yours." + icon_state = "grav" + item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") + origin_tech = list(TECH_MAGNET = 2, TECH_BLUESPACE = 1) + darkness_view = 5 + toggleable = 1 + action_button_name = "Toggle Goggles" + off_state = "denight" + vision_flags = SEE_OBJS | SEE_TURFS + flash_protection = FLASH_PROTECTION_REDUCED + enables_planes = list(VIS_FULLBRIGHT, VIS_MESONS) + +/obj/item/clothing/glasses/graviton/New() + ..() + overlay = global_hud.material + /obj/item/clothing/glasses/regular name = "prescription glasses" desc = "Made by Nerd. Co." diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm index 3e8cb36a6c..890da50468 100644 --- a/code/modules/clothing/spacesuits/rig/modules/combat.dm +++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm @@ -89,6 +89,19 @@ new_grenade.activate(H) new_grenade.throw_at(target,fire_force,fire_distance) +/obj/item/rig_module/grenade_launcher/smoke + name = "mounted smoke-bomb launcher" + desc = "A shoulder-mounted smoke-bomb dispenser." + + interface_name = "integrated smoke-bomb launcher" + interface_desc = "Discharges loaded smoke-bombs against the wearer's location." + + fire_force = 15 + + charges = list( + list("smoke bomb", "smoke bomb", /obj/item/weapon/grenade/smokebomb, 6) + ) + /obj/item/rig_module/mounted name = "mounted laser cannon" diff --git a/code/modules/clothing/spacesuits/rig/modules/ninja.dm b/code/modules/clothing/spacesuits/rig/modules/ninja.dm index b5d58c8da6..704ed7a47b 100644 --- a/code/modules/clothing/spacesuits/rig/modules/ninja.dm +++ b/code/modules/clothing/spacesuits/rig/modules/ninja.dm @@ -192,8 +192,6 @@ smoke = null return ..() - - /obj/item/rig_module/self_destruct/activate() return diff --git a/code/modules/clothing/spacesuits/rig/modules/vision.dm b/code/modules/clothing/spacesuits/rig/modules/vision.dm index 572f861d5a..57ad4026ef 100644 --- a/code/modules/clothing/spacesuits/rig/modules/vision.dm +++ b/code/modules/clothing/spacesuits/rig/modules/vision.dm @@ -15,29 +15,40 @@ /datum/rig_vision/nvg mode = "night vision" + /datum/rig_vision/nvg/New() glasses = new /obj/item/clothing/glasses/night /datum/rig_vision/thermal mode = "thermal scanner" + /datum/rig_vision/thermal/New() glasses = new /obj/item/clothing/glasses/thermal /datum/rig_vision/meson mode = "meson scanner" + /datum/rig_vision/meson/New() glasses = new /obj/item/clothing/glasses/meson /datum/rig_vision/sechud mode = "security HUD" + /datum/rig_vision/sechud/New() glasses = new /obj/item/clothing/glasses/hud/security /datum/rig_vision/medhud mode = "medical HUD" + /datum/rig_vision/medhud/New() glasses = new /obj/item/clothing/glasses/hud/health +/datum/rig_vision/material + mode = "material scanner" + +/datum/rig_vision/material/New() + glasses = new /obj/item/clothing/glasses/material + /obj/item/rig_module/vision name = "hardsuit visor" @@ -76,6 +87,7 @@ interface_desc = "An integrated multi-mode vision system." vision_modes = list(/datum/rig_vision/meson, + /datum/rig_vision/material, /datum/rig_vision/nvg, /datum/rig_vision/thermal, /datum/rig_vision/sechud, @@ -94,6 +106,33 @@ vision_modes = list(/datum/rig_vision/meson) +/obj/item/rig_module/vision/material + + name = "hardsuit material scanner" + desc = "A layered, translucent visor system for a hardsuit." + icon_state = "meson" + + usable = 0 + + interface_name = "material scanner" + interface_desc = "An integrated material scanner." + + vision_modes = list(/datum/rig_vision/material) + +/obj/item/rig_module/vision/mining + + name = "hardsuit mining scanners" + desc = "A layered, translucent visor system for a hardsuit." + icon_state = "optics" + + usable = 0 + + interface_name = "mining scanners" + interface_desc = "An integrated mining scanner array." + + vision_modes = list(/datum/rig_vision/material, + /datum/rig_vision/meson) + /obj/item/rig_module/vision/thermal name = "hardsuit thermal scanner" diff --git a/code/modules/mining/drilling/scanner.dm b/code/modules/mining/drilling/scanner.dm index 56f371fe91..bbcc65cc16 100644 --- a/code/modules/mining/drilling/scanner.dm +++ b/code/modules/mining/drilling/scanner.dm @@ -6,14 +6,18 @@ item_state = "electronic" origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1) matter = list(DEFAULT_WALL_MATERIAL = 150) + var/scan_time = 5 SECONDS /obj/item/weapon/mining_scanner/attack_self(mob/user as mob) user << "You begin sweeping \the [src] about, scanning for metal deposits." playsound(loc, 'sound/items/goggles_charge.ogg', 50, 1, -6) - if(!do_after(user, 50)) + if(!do_after(user, scan_time)) return + ScanTurf(user, get_turf(user)) + +/obj/item/weapon/mining_scanner/proc/ScanTurf(var/atom/target, var/mob/user, var/exact = FALSE) var/list/metals = list( "surface minerals" = 0, "precious metals" = 0, @@ -22,7 +26,9 @@ "anomalous matter" = 0 ) - for(var/turf/simulated/T in range(2, get_turf(user))) + var/turf/Turf = get_turf(target) + + for(var/turf/simulated/T in range(2, Turf)) if(!T.has_resources) continue @@ -39,14 +45,18 @@ if(ore_type) metals[ore_type] += T.resources[metal] - user << "\icon[src] The scanner beeps and displays a readout." + to_chat(user, "\icon[src] The scanner beeps and displays a readout.") for(var/ore_type in metals) var/result = "no sign" - switch(metals[ore_type]) - if(1 to 25) result = "trace amounts" - if(26 to 75) result = "significant amounts" - if(76 to INFINITY) result = "huge quantities" + if(!exact) + switch(metals[ore_type]) + if(1 to 25) result = "trace amounts" + if(26 to 75) result = "significant amounts" + if(76 to INFINITY) result = "huge quantities" - user << "- [result] of [ore_type]." \ No newline at end of file + else + result = metals[ore_type] + + to_chat(user, "- [result] of [ore_type].") diff --git a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm index 2362586051..7f7b896345 100644 --- a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm @@ -19,21 +19,43 @@ new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150), new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 200), new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 900), + new /datum/data/mining_equipment("Geiger Counter", /obj/item/device/geiger, 750), new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 300), + new /datum/data/mining_equipment("Umbrella", /obj/item/weapon/melee/umbrella/random, 200), // new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 500), new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card, 500), // new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1200), new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/weapon/pickaxe/silver, 1200), -// new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c1000, 2000), -// new /datum/data/mining_equipment("Industrial Hardsuit - Control Module", /obj/item/weapon/rig/industrial, 2000), -// new /datum/data/mining_equipment("Industrial Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800), -// new /datum/data/mining_equipment("Industrial Hardsuit - Drill", /obj/item/rig_module/device/drill, 2000), -// new /datum/data/mining_equipment("Industrial Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000), -// new /datum/data/mining_equipment("Industrial Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500), -// new /datum/data/mining_equipment("Industrial Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250), -// new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), + new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 500), - new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000) + new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000), +// new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c1000, 2000), + new /datum/data/mining_equipment("Industrial Hardsuit - Control Module", /obj/item/weapon/rig/industrial, 10000), + new /datum/data/mining_equipment("Industrial Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800), + new /datum/data/mining_equipment("Industrial Hardsuit - Drill", /obj/item/rig_module/device/drill, 2000), + new /datum/data/mining_equipment("Industrial Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000), + new /datum/data/mining_equipment("Industrial Hardsuit - Advanced Optics", /obj/item/rig_module/vision/mining, 1250), + new /datum/data/mining_equipment("Industrial Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250), + new /datum/data/mining_equipment("Hardsuit - Intelligence Storage", /obj/item/rig_module/ai_container, 2500), + new /datum/data/mining_equipment("Hardsuit - Smoke Bomb Deployer", /obj/item/rig_module/grenade_launcher/smoke, 2000), + new /datum/data/mining_equipment("Industrial Equipment - Sheet-Snatcher", /obj/item/weapon/gun/magnetic/matfed, 3000), + new /datum/data/mining_equipment("Industrial Equipment - Phoron Bore",/obj/item/weapon/storage/bag/sheetsnatcher, 500), + new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500), + new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), + new /datum/data/mining_equipment("Fine Excavation Kit - Chisels",/obj/item/weapon/storage/excavation, 500), + new /datum/data/mining_equipment("Fine Excavation Kit - Measuring Tape",/obj/item/device/measuring_tape, 125), + new /datum/data/mining_equipment("Fine Excavation Kit - Hand Pick",/obj/item/weapon/pickaxe/hand, 375), + new /datum/data/mining_equipment("Explosive Excavation Kit - Plastic Charge",/obj/item/weapon/plastique/seismic, 750), + new /datum/data/mining_equipment("Injector (L) - Glucose",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500), + new /datum/data/mining_equipment("Injector (L) - Panacea",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 500), + new /datum/data/mining_equipment("Injector (L) - Trauma",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 500), + new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 1000), + new /datum/data/mining_equipment("Misc: Graviton Visor", /obj/item/clothing/glasses/graviton, 1500), + new /datum/data/mining_equipment("Defense Equipment - Phase Pistol",/obj/item/weapon/gun/energy/phasegun/pistol, 400), + new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 100), + new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station, 1000), + new /datum/data/mining_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/ward, 1500), + new /datum/data/mining_equipment("Defense Equipment - Steel Machete", /obj/item/weapon/material/knife/machete, 500) ) /datum/data/mining_equipment diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm index 347e64c093..03d0c215ca 100644 --- a/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm @@ -63,4 +63,24 @@ . = ..() if(!.) // Not friendly, see if they're a baddie first. if(L.mind && raiders.is_antagonist(L.mind)) - return TRUE \ No newline at end of file + return TRUE + +// Variant that is neutral, and thus on the station's side. It checks records. +/mob/living/simple_mob/mechanical/viscerator/station + icon_state = "viscerator_b_attack" + icon_living = "viscerator_b_attack" + + faction = "station" + maxHealth = 20 + health = 20 + + melee_damage_lower = 2 + melee_damage_upper = 5 + base_attack_cooldown = 8 + +/mob/living/simple_mob/mechanical/viscerator/station/IIsAlly(mob/living/L) + . = ..() + if(!.) + if(isrobot(L)) // They ignore synths. + return TRUE + return L.assess_perp(src, FALSE, FALSE, TRUE, FALSE) <= 4 diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/ward/monitor_ward.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/ward/monitor_ward.dm index 519ad4ce88..3f778d6e2e 100644 --- a/code/modules/mob/living/simple_mob/subtypes/mechanical/ward/monitor_ward.dm +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/ward/monitor_ward.dm @@ -43,7 +43,20 @@ faction = "syndicate" /mob/living/simple_mob/mechanical/ward/monitor/crew - faction = "neutral" + icon_state = "ward-nt" + +/mob/living/simple_mob/mechanical/ward/monitor/crew/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(istype(O, /obj/item/weapon/card/id) && !owner) + owner = user + return + ..() + +/mob/living/simple_mob/mechanical/ward/monitor/crew/IIsAlly(mob/living/L) + . = ..() + if(!.) + if(isrobot(L)) // They ignore synths. + return TRUE + return L.assess_perp(src, FALSE, FALSE, TRUE, FALSE) <= 4 /mob/living/simple_mob/mechanical/ward/monitor/death() if(owner) @@ -55,10 +68,10 @@ /mob/living/simple_mob/mechanical/ward/monitor/update_icon() if(seen_mobs.len) - icon_living = "ward_spotted" + icon_living = "[initial(icon_state)]_spotted" glow_color = "#FF0000" else - icon_living = "ward" + icon_living = "[initial(icon_state)]_ward" glow_color = "#00FF00" handle_light() // Update the light immediately. ..() @@ -118,4 +131,4 @@ return FALSE /datum/ai_holder/simple_mob/monitor/ranged_attack(atom/A) - return FALSE \ No newline at end of file + return FALSE diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 9073ead831..c892175c9a 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -63,7 +63,7 @@ icon_state = "emitter" fire_sound = 'sound/weapons/emitter.ogg' light_color = "#00CC33" - excavation_amount = 70 // 3 shots to mine a turf + excavation_amount = 140 // 2 shots to dig a standard rock turf. Superior due to being a mounted tool beam, to make it actually viable. muzzle_type = /obj/effect/projectile/muzzle/emitter tracer_type = /obj/effect/projectile/tracer/emitter diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 98d3500c6e..8a2e9796cd 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -136,7 +136,7 @@ if(isrobot(user)) return - if(!I) + if(!I || I.anchored || !I.canremove) return user.drop_item() diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm index e67172fa94..436d5e85d9 100644 --- a/code/modules/research/mechfab_designs.dm +++ b/code/modules/research/mechfab_designs.dm @@ -616,6 +616,46 @@ materials = list(DEFAULT_WALL_MATERIAL = 7500, "diamond" = 4875) build_path = /obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill +/datum/design/item/mecha/ground_drill + name = "Surface Bore" + desc = "A heavy duty bore. Bigger, better, stronger than the core sampler, but not quite as good as a large drill." + id = "mech_ground_drill" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 2, TECH_PHORON = 1) + materials = list(DEFAULT_WALL_MATERIAL = 7000, "silver" = 3000, "phoron" = 2000) + build_path = /obj/item/mecha_parts/mecha_equipment/tool/drill/bore + +/datum/design/item/mecha/orescanner + name = "Ore Scanner" + desc = "A hefty device used to scan for subterranean veins of ore." + id = "mech_ore_scanner" + req_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 1000) + build_path = /obj/item/mecha_parts/mecha_equipment/tool/orescanner + +/datum/design/item/mecha/advorescanner + name = "Advanced Ore Scanner" + desc = "A hefty device used to scan for the exact volumes of subterranean veins of ore." + id = "mech_ore_scanner_adv" + req_tech = list(TECH_MATERIAL = 5, TECH_MAGNET = 4, TECH_POWER = 4, TECH_BLUESPACE = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "osmium" = 3000, "silver" = 1000) + build_path = /obj/item/mecha_parts/mecha_equipment/tool/orescanner/advanced + +/datum/design/item/mecha/powerwrench + name = "hydraulic wrench" + desc = "A large, hydraulic wrench." + id = "mech_wrench" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "plastic" = 2000, "glass" = 1250) + build_path = /obj/item/mecha_parts/mecha_equipment/tool/powertool + +/datum/design/item/mecha/powercrowbar + name = "hydraulic prybar" + desc = "A large, hydraulic prybar." + id = "mech_crowbar" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 4000, "osmium" = 3000, "glass" = 1000) + build_path = /obj/item/mecha_parts/mecha_equipment/tool/powertool/prybar + /datum/design/item/mecha/generator_nuclear name = "Nuclear Reactor" desc = "Exosuit-held nuclear reactor. Converts uranium and everyone's health to energy." diff --git a/icons/mecha/mecha_equipment.dmi b/icons/mecha/mecha_equipment.dmi index 2b96c7d492..2f15024c6a 100644 Binary files a/icons/mecha/mecha_equipment.dmi and b/icons/mecha/mecha_equipment.dmi differ diff --git a/icons/mob/critter.dmi b/icons/mob/critter.dmi index 4f249e2e8a..7098d1a3a8 100644 Binary files a/icons/mob/critter.dmi and b/icons/mob/critter.dmi differ diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index 85c5a39320..d2a5879eeb 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index d8418a50a5..da5436c8d7 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ