diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index a7bd41999e..fc2d9f1e3f 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -338,7 +338,7 @@ update_label("John Doe", "Clowny") /obj/item/card/id/mining name = "mining ID" - access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM) + access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM) /obj/item/card/id/away name = "a perfectly generic identification card" diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index fae8985a73..e06e4d844a 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -45,11 +45,12 @@ new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500), new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 3000), - new /datum/data/mining_equipment("Mining Drone", /mob/living/simple_animal/hostile/mining_drone, 800), - new /datum/data/mining_equipment("Drone Melee Upgrade", /obj/item/device/mine_bot_upgrade, 400), - new /datum/data/mining_equipment("Drone Health Upgrade", /obj/item/device/mine_bot_upgrade/health, 400), - new /datum/data/mining_equipment("Drone Ranged Upgrade", /obj/item/device/mine_bot_upgrade/cooldown, 600), - new /datum/data/mining_equipment("Drone AI Upgrade", /obj/item/slimepotion/slime/sentience/mining, 1000), + new /datum/data/mining_equipment("Nanotrasen Minebot", /mob/living/simple_animal/hostile/mining_drone, 800), + new /datum/data/mining_equipment("Minebot Melee Upgrade", /obj/item/device/mine_bot_upgrade, 400), + new /datum/data/mining_equipment("Minebot Armor Upgrade", /obj/item/device/mine_bot_upgrade/health, 400), + new /datum/data/mining_equipment("Minebot Cooldown Upgrade", /obj/item/borg/upgrade/modkit/cooldown/minebot, 600), + new /datum/data/mining_equipment("Minebot AI Upgrade", /obj/item/slimepotion/slime/sentience/mining, 1000), + new /datum/data/mining_equipment("KA Minebot Passthrough", /obj/item/borg/upgrade/modkit/minebot_passthrough, 100), new /datum/data/mining_equipment("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 100), new /datum/data/mining_equipment("KA Adjustable Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer/adjustable, 150), new /datum/data/mining_equipment("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250), @@ -166,31 +167,36 @@ return ..() /obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/mining_voucher/voucher, mob/redeemer) - var/items = list("Survival Capsule and Explorer's Webbing", "Resonator and Advanced Scanner", "Mining Drone", "Extraction and Rescue Kit", "Crusher Kit", "Mining Conscription Kit") + var/items = list("Survival Capsule and Explorer's Webbing", "Resonator Kit", "Minebot Kit", "Extraction and Rescue Kit", "Crusher Kit", "Mining Conscription Kit") var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in items if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) return + var/drop_location = drop_location() switch(selection) if("Survival Capsule and Explorer's Webbing") - new /obj/item/storage/belt/mining/vendor(src.loc) - if("Resonator and Advanced Scanner") - new /obj/item/resonator(src.loc) - new /obj/item/device/t_scanner/adv_mining_scanner(src.loc) - if("Mining Drone") - new /mob/living/simple_animal/hostile/mining_drone(src.loc) - new /obj/item/weldingtool/hugetank(src.loc) - new /obj/item/clothing/glasses/welding(src.loc) + new /obj/item/storage/belt/mining/vendor(drop_location) + if("Resonator Kit") + new /obj/item/storage/belt/mining/alt(drop_location) + new /obj/item/device/t_scanner/adv_mining_scanner(drop_location) + new /obj/item/extinguisher/mini(drop_location) + new /obj/item/resonator(drop_location) + if("Minebot Kit") + new /mob/living/simple_animal/hostile/mining_drone(drop_location) + new /obj/item/weldingtool/hugetank(drop_location) + new /obj/item/clothing/head/welding(drop_location) + new /obj/item/borg/upgrade/modkit/minebot_passthrough(drop_location) if("Extraction and Rescue Kit") - new /obj/item/extraction_pack(loc) - new /obj/item/fulton_core(loc) - new /obj/item/stack/marker_beacon/thirty(loc) + new /obj/item/extraction_pack(drop_location) + new /obj/item/fulton_core(drop_location) + new /obj/item/stack/marker_beacon/thirty(drop_location) if("Crusher Kit") - new /obj/item/twohanded/required/kinetic_crusher(loc) - new /obj/item/storage/belt/mining/alt(loc) - new /obj/item/extinguisher/mini(loc) + new /obj/item/storage/belt/mining/alt(drop_location) + new /obj/item/device/t_scanner/adv_mining_scanner(drop_location) + new /obj/item/extinguisher/mini(drop_location) + new /obj/item/twohanded/required/kinetic_crusher(drop_location) if("Mining Conscription Kit") - new /obj/item/storage/backpack/duffelbag/mining_conscript(loc) + new /obj/item/storage/backpack/duffelbag/mining_conscript(drop_location) SSblackbox.record_feedback("tally", "mining_voucher_redeemed", 1, selection) qdel(voucher) diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index 3ab7b2dc5c..51358c6818 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -4,7 +4,8 @@ /mob/living/simple_animal/hostile/mining_drone name = "nanotrasen minebot" - desc = "The instructions printed on the side read: This is a small robot used to support miners, can be set to search and collect loose ore, or to help fend off wildlife. A mining scanner can instruct it to drop loose ore. Field repairs can be done with a welder." + desc = "The instructions printed on the side read: This is a small robot used to support miners, can be set to search and collect loose ore, or to help fend off wildlife." + gender = NEUTER icon = 'icons/mob/aibots.dmi' icon_state = "mining_drone" icon_living = "mining_drone" @@ -14,47 +15,48 @@ a_intent = INTENT_HARM atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 - wander = 0 - idle_vision_range = 5 move_to_delay = 10 - retreat_distance = 1 - minimum_distance = 2 health = 125 maxHealth = 125 melee_damage_lower = 15 melee_damage_upper = 15 - obj_damage = 0 + obj_damage = 10 environment_smash = ENVIRONMENT_SMASH_NONE - check_friendly_fire = 1 - stop_automated_movement_when_pulled = 1 + check_friendly_fire = TRUE + stop_automated_movement_when_pulled = TRUE attacktext = "drills" attack_sound = 'sound/weapons/circsawhit.ogg' - ranged = 1 sentience_type = SENTIENCE_MINEBOT - ranged_message = "shoots" - ranged_cooldown_time = 30 - projectiletype = /obj/item/projectile/kinetic - projectilesound = 'sound/weapons/gunshot4.ogg' speak_emote = list("states") wanted_objects = list(/obj/item/stack/ore/diamond, /obj/item/stack/ore/gold, /obj/item/stack/ore/silver, - /obj/item/stack/ore/plasma, /obj/item/stack/ore/uranium, /obj/item/stack/ore/iron, + /obj/item/stack/ore/plasma, /obj/item/stack/ore/uranium, /obj/item/stack/ore/iron, /obj/item/stack/ore/bananium, /obj/item/stack/ore/titanium) healable = 0 + loot = list(/obj/effect/decal/cleanable/robot_debris) + del_on_death = TRUE var/mode = MINEDRONE_COLLECT var/light_on = 0 var/datum/action/innate/minedrone/toggle_light/toggle_light_action var/datum/action/innate/minedrone/toggle_mode/toggle_mode_action var/datum/action/innate/minedrone/dump_ore/dump_ore_action + var/obj/item/gun/energy/kinetic_accelerator/minebot/stored_gun /mob/living/simple_animal/hostile/mining_drone/Initialize() . = ..() + stored_gun = new(src) toggle_light_action = new() toggle_light_action.Grant(src) toggle_mode_action = new() toggle_mode_action.Grant(src) dump_ore_action = new() dump_ore_action.Grant(src) + var/obj/item/implant/radio/mining/imp = new(src) + imp.implant(src) + + access_card = new /obj/item/card/id(src) + var/datum/job/mining/M = new + access_card.access = M.get_access() SetCollectBehavior() @@ -62,36 +64,55 @@ ..() check_friendly_fire = 0 -/mob/living/simple_animal/hostile/mining_drone/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/weldingtool)) - if(stat) - return - if(AIStatus != AI_OFF && AIStatus != AI_IDLE) - to_chat(user, "[src] is moving around too much to repair!") - return +/mob/living/simple_animal/hostile/mining_drone/examine(mob/user) + ..() + var/t_He = p_they(TRUE) + var/t_him = p_them() + var/t_s = p_s() + if(health < maxHealth) + if(health >= maxHealth * 0.5) + to_chat(user, "[t_He] look[t_s] slightly dented.") + else + to_chat(user, "[t_He] look[t_s] severely dented!") + to_chat(user, "Using a mining scanner on [t_him] will instruct [t_him] to drop stored ore. [max(0, LAZYLEN(contents) - 1)] Stored Ore\n\ + Field repairs can be done with a welder.") + if(stored_gun && stored_gun.max_mod_capacity) + to_chat(user, "[stored_gun.get_remaining_mod_capacity()]% mod capacity remaining.") + for(var/A in stored_gun.get_modkits()) + var/obj/item/borg/upgrade/modkit/M = A + to_chat(user, "There is \a [M] installed, using [M.cost]% capacity.") - if(maxHealth == health) - to_chat(user, "[src] is at full integrity.") - return - - if(I.use_tool(src, user, 0, volume=40)) - adjustBruteLoss(-10) - to_chat(user, "You repair some of the armor on [src].") +/mob/living/simple_animal/hostile/mining_drone/welder_act(mob/living/user, obj/item/I) + . = TRUE + if(mode == MINEDRONE_ATTACK) + to_chat(user, "[src] can't be repaired while in attack mode!") return + if(maxHealth == health) + to_chat(user, "[src] is at full integrity.") + return + + if(I.use_tool(src, user, 0, volume=40)) + adjustBruteLoss(-15) + to_chat(user, "You repair some of the armor on [src].") + +/mob/living/simple_animal/hostile/mining_drone/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/device/mining_scanner) || istype(I, /obj/item/device/t_scanner/adv_mining_scanner)) to_chat(user, "You instruct [src] to drop any collected ore.") DropOre() return + if(istype(I, /obj/item/crowbar) || istype(I, /obj/item/borg/upgrade/modkit)) + I.melee_attack_chain(user, stored_gun, params) + return ..() /mob/living/simple_animal/hostile/mining_drone/death() - ..() - visible_message("[src] is destroyed!") - new /obj/effect/decal/cleanable/robot_debris(loc) DropOre(0) - qdel(src) - return + if(stored_gun) + for(var/obj/item/borg/upgrade/modkit/M in stored_gun.modkits) + M.uninstall(stored_gun) + deathmessage = "blows apart!" + ..() /mob/living/simple_animal/hostile/mining_drone/attack_hand(mob/living/carbon/human/M) if(M.a_intent == INTENT_HELP) @@ -104,12 +125,24 @@ return ..() +/mob/living/simple_animal/hostile/mining_drone/CanPass(atom/movable/O) + if(istype(O, /obj/item/projectile/kinetic)) + var/obj/item/projectile/kinetic/K = O + if(K.kinetic_gun) + for(var/A in K.kinetic_gun.get_modkits()) + var/obj/item/borg/upgrade/modkit/M = A + if(istype(M, /obj/item/borg/upgrade/modkit/minebot_passthrough)) + return TRUE + if(istype(O, /obj/item/projectile/destabilizer)) + return TRUE + return ..() + /mob/living/simple_animal/hostile/mining_drone/proc/SetCollectBehavior() mode = MINEDRONE_COLLECT idle_vision_range = 9 search_objects = 2 - wander = 1 - ranged = 0 + wander = TRUE + ranged = FALSE minimum_distance = 1 retreat_distance = null icon_state = "mining_drone" @@ -119,19 +152,26 @@ mode = MINEDRONE_ATTACK idle_vision_range = 7 search_objects = 0 - wander = 0 - ranged = 1 - retreat_distance = 1 - minimum_distance = 2 + wander = FALSE + ranged = TRUE + retreat_distance = 2 + minimum_distance = 1 icon_state = "mining_drone_offense" to_chat(src, "You are set to attack mode. You can now attack from range.") /mob/living/simple_animal/hostile/mining_drone/AttackingTarget() - if(istype(target, /obj/item/stack/ore) && mode == MINEDRONE_COLLECT) + if(istype(target, /obj/item/stack/ore) && mode == MINEDRONE_COLLECT) CollectOre() return + if(isliving(target)) + SetOffenseBehavior() return ..() +/mob/living/simple_animal/hostile/mining_drone/OpenFire(atom/A) + if(CheckFriendlyFire(A)) + return + stored_gun.afterattack(A, src) //of the possible options to allow minebots to have KA mods, would you believe this is the best? + /mob/living/simple_animal/hostile/mining_drone/proc/CollectOre() for(var/obj/item/stack/ore/O in range(1, src)) O.forceMove(src) @@ -144,9 +184,7 @@ if(message) to_chat(src, "You dump your stored ore.") for(var/obj/item/stack/ore/O in contents) - contents -= O O.forceMove(drop_location()) - return /mob/living/simple_animal/hostile/mining_drone/adjustHealth(amount) if(mode != MINEDRONE_ATTACK && amount > 0) @@ -155,13 +193,10 @@ /mob/living/simple_animal/hostile/mining_drone/proc/toggle_mode() switch(mode) - if(MINEDRONE_COLLECT) - SetOffenseBehavior() if(MINEDRONE_ATTACK) SetCollectBehavior() - else //This should never happen. - mode = MINEDRONE_COLLECT - SetCollectBehavior() + else + SetOffenseBehavior() //Actions for sentient minebots @@ -220,51 +255,45 @@ if(M.melee_damage_upper != initial(M.melee_damage_upper)) to_chat(user, "[src] already has a combat upgrade installed!") return - M.melee_damage_lower = 22 - M.melee_damage_upper = 22 + M.melee_damage_lower += 7 + M.melee_damage_upper += 7 qdel(src) //Health /obj/item/device/mine_bot_upgrade/health - name = "minebot chassis upgrade" + name = "minebot armor upgrade" /obj/item/device/mine_bot_upgrade/health/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user) if(M.maxHealth != initial(M.maxHealth)) - to_chat(user, "[src] already has a reinforced chassis!") + to_chat(user, "[src] already has reinforced armor!") return - M.maxHealth = 170 + M.maxHealth += 45 + M.updatehealth() qdel(src) - -//Cooldown - -/obj/item/device/mine_bot_upgrade/cooldown - name = "minebot cooldown upgrade" - -/obj/item/device/mine_bot_upgrade/cooldown/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user) - name = "minebot cooldown upgrade" - if(M.ranged_cooldown_time != initial(M.ranged_cooldown_time)) - to_chat(user, "[src] already has a decreased weapon cooldown!") - return - M.ranged_cooldown_time = 10 - qdel(src) - - //AI + /obj/item/slimepotion/slime/sentience/mining name = "minebot AI upgrade" - desc = "Can be used to grant sentience to minebots." + desc = "Can be used to grant sentience to minebots. Is incompatable with minebot armor and melee upgrades, and will override them." icon_state = "door_electronics" icon = 'icons/obj/module.dmi' sentience_type = SENTIENCE_MINEBOT + var/base_health_add = 5 //sentient minebots are penalized for beign sentient; they have their stats reset to normal plus these values + var/base_damage_add = 1 //this thus disables other minebot upgrades + var/base_speed_add = 1 + var/base_cooldown_add = 10 //base cooldown isn't reset to normal, it's just added on, since it's not practical to disable the cooldown module /obj/item/slimepotion/slime/sentience/mining/after_success(mob/living/user, mob/living/simple_animal/SM) - var/obj/item/implant/radio/mining/imp = new(src) - imp.implant(SM, user) - - SM.access_card = new /obj/item/card/id/mining(SM) - SM.access_card.flags_1 |= NODROP_1 + if(istype(SM, /mob/living/simple_animal/hostile/mining_drone)) + var/mob/living/simple_animal/hostile/mining_drone/M = SM + M.maxHealth = initial(M.maxHealth) + base_health_add + M.melee_damage_lower = initial(M.melee_damage_lower) + base_damage_add + M.melee_damage_upper = initial(M.melee_damage_upper) + base_damage_add + M.move_to_delay = initial(M.move_to_delay) + base_speed_add + if(M.stored_gun) + M.stored_gun.overheat_time += base_cooldown_add #undef MINEDRONE_COLLECT #undef MINEDRONE_ATTACK diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 15186d63a8..8207f321cd 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -324,14 +324,18 @@ else M.Goto(src,M.move_to_delay,M.minimum_distance) -/mob/living/simple_animal/hostile/proc/OpenFire(atom/A) +/mob/living/simple_animal/hostile/proc/CheckFriendlyFire(atom/A) if(check_friendly_fire) for(var/turf/T in getline(src,A)) // Not 100% reliable but this is faster than simulating actual trajectory for(var/mob/living/L in T) if(L == src || L == A) continue if(faction_check_mob(L) && !attack_same) - return + return TRUE + +/mob/living/simple_animal/hostile/proc/OpenFire(atom/A) + if(CheckFriendlyFire(A)) + return visible_message("[src] [ranged_message] at [A]!") if(rapid) diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index e3fc09f270..63d3736eba 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -33,16 +33,18 @@ var/obj/item/borg/upgrade/modkit/M = A to_chat(user, "There is \a [M] installed, using [M.cost]% capacity.") +/obj/item/gun/energy/kinetic_accelerator/crowbar_act(mob/living/user, obj/item/I) + . = TRUE + if(modkits.len) + to_chat(user, "You pry the modifications out.") + I.play_tool_sound(src, 100) + for(var/obj/item/borg/upgrade/modkit/M in modkits) + M.uninstall(src) + else + to_chat(user, "There are no modifications currently installed.") + /obj/item/gun/energy/kinetic_accelerator/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/crowbar)) - if(modkits.len) - to_chat(user, "You pry the modifications out.") - I.play_tool_sound(src, 100) - for(var/obj/item/borg/upgrade/modkit/M in modkits) - M.uninstall(src) - else - to_chat(user, "There are no modifications currently installed.") - else if(istype(I, /obj/item/borg/upgrade/modkit)) + if(istype(I, /obj/item/borg/upgrade/modkit)) var/obj/item/borg/upgrade/modkit/MK = I MK.install(src, user) else @@ -71,6 +73,12 @@ unique_frequency = TRUE max_mod_capacity = 80 +/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() . = ..() if(!holds_charge) @@ -222,6 +230,8 @@ 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/borg/upgrade/modkit/examine(mob/user) ..() @@ -242,6 +252,13 @@ /obj/item/borg/upgrade/modkit/proc/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user) . = TRUE + if(minebot_upgrade) + if(minebot_exclusive && !istype(KA.loc, /mob/living/simple_animal/hostile/mining_drone)) + to_chat(user, "The modkit you're trying to install is only rated for minebot use.") + return FALSE + else if(istype(KA.loc, /mob/living/simple_animal/hostile/mining_drone)) + to_chat(user, "The modkit you're trying to install is not rated for minebot use.") + return FALSE if(denied_type) var/number_of_denied = 0 for(var/A in KA.get_modkits()) @@ -301,8 +318,9 @@ //Cooldown /obj/item/borg/upgrade/modkit/cooldown name = "cooldown decrease" - desc = "Decreases the cooldown of a kinetic accelerator." + desc = "Decreases the cooldown of a kinetic accelerator. Not rated for minebot use." modifier = 2.5 + minebot_upgrade = FALSE /obj/item/borg/upgrade/modkit/cooldown/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user) . = ..() @@ -313,6 +331,17 @@ KA.overheat_time += modifier ..() +/obj/item/borg/upgrade/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/borg/upgrade/modkit/cooldown/minebot + modifier = 10 + cost = 0 + minebot_upgrade = TRUE + minebot_exclusive = TRUE + //AoE blasts /obj/item/borg/upgrade/modkit/aoe @@ -373,6 +402,12 @@ desc = "Causes the kinetic accelerator to damage mobs in an AoE." modifier = 0.2 +//Minebot passthrough +/obj/item/borg/upgrade/modkit/minebot_passthrough + name = "minebot passthrough" + desc = "Causes kinetic accelerator shots to pass through minebots." + cost = 0 + //Tendril-unique modules /obj/item/borg/upgrade/modkit/cooldown/repeater name = "rapid repeater"