diff --git a/code/citadel/dogborgs.dm b/code/citadel/dogborgs.dm new file mode 100644 index 0000000000..351f8aca3b --- /dev/null +++ b/code/citadel/dogborgs.dm @@ -0,0 +1,76 @@ +/obj/item/weapon/robot_module/loader + name = "loader robot module" +/obj/item/weapon/robot_module/loader/New() + ..() + emag = new /obj/item/borg/stun(src) + modules += new /obj/item/weapon/extinguisher(src) + modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src) + modules += new /obj/item/weapon/screwdriver(src) + modules += new /obj/item/weapon/wrench(src) + modules += new /obj/item/weapon/crowbar(src) + modules += new /obj/item/weapon/wirecutters(src) + modules += new /obj/item/device/multitool(src) + modules += new /obj/item/device/t_scanner(src) + modules += new /obj/item/device/analyzer(src) + modules += new /obj/item/device/assembly/signaler + modules += new /obj/item/weapon/soap/nanotrasen(src) + + fix_modules() + +/obj/item/weapon/robot_module/k9 + name = "Security K-9 Unit module" +/obj/item/weapon/robot_module/k9/New() + ..() + modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg/dog(src) + modules += new /obj/item/weapon/dogborg/jaws/big(src) + modules += new /obj/item/weapon/dogborg/pounce(src) + modules += new /obj/item/clothing/mask/gas/sechailer/cyborg(src) + modules += new /obj/item/weapon/soap/tongue(src) + modules += new /obj/item/device/analyzer/nose(src) + modules += new /obj/item/weapon/storage/bag/borgdelivery(src) + //modules += new /obj/item/device/assembly/signaler(src) + //modules += new /obj/item/device/detective_scanner(src) + modules += new /obj/item/weapon/gun/energy/disabler/cyborg(src) + emag = new /obj/item/weapon/gun/energy/laser/cyborg(src) + fix_modules() + +/obj/item/weapon/robot_module/security/respawn_consumable(mob/living/silicon/robot/R, coeff = 1) + ..() + var/obj/item/weapon/gun/energy/gun/advtaser/cyborg/T = locate(/obj/item/weapon/gun/energy/gun/advtaser/cyborg) in get_usable_modules() + if(T) + if(T.power_supply.charge < T.power_supply.maxcharge) + var/obj/item/ammo_casing/energy/S = T.ammo_type[T.select] + T.power_supply.give(S.e_cost * coeff) + T.update_icon() + else + T.charge_tick = 0 + fix_modules() + +/obj/item/weapon/robot_module/borgi + name = "Borgi module" + +/obj/item/weapon/robot_module/borgi/New() + ..() + modules += new /obj/item/weapon/dogborg/jaws/small(src) + modules += new /obj/item/weapon/storage/bag/borgdelivery(src) + modules += new /obj/item/weapon/soap/tongue(src) + modules += new /obj/item/device/healthanalyzer(src) + modules += new /obj/item/device/analyzer/nose(src) + emag = new /obj/item/weapon/dogborg/pounce(src) + fix_modules() + +/obj/item/weapon/robot_module/medihound + name = "MediHound module" + +/obj/item/weapon/robot_module/medihound/New() + ..() + modules += new /obj/item/weapon/dogborg/jaws/small(src) + modules += new /obj/item/weapon/storage/bag/borgdelivery(src) + modules += new /obj/item/device/analyzer/nose(src) + modules += new /obj/item/weapon/soap/tongue(src) + modules += new /obj/item/device/healthanalyzer(src) + modules += new /obj/item/weapon/dogborg/sleeper(src) + modules += new /obj/item/weapon/twohanded/shockpaddles/hound(src) + modules += new /obj/item/device/sensor_device(src) + emag = new /obj/item/weapon/dogborg/pounce(src) + fix_modules() \ No newline at end of file diff --git a/code/citadel/dogborgstuff.dm b/code/citadel/dogborgstuff.dm new file mode 100644 index 0000000000..0eeae3fa97 --- /dev/null +++ b/code/citadel/dogborgstuff.dm @@ -0,0 +1,568 @@ +// Special tools and items for "Borgi" and "K-9 Unit" +// PASTA SPAGHETTI FEST WOOHOOO!!! var/regrets = null + +/obj/item/weapon/dogborg/jaws/big + name = "combat jaws" + icon = 'icons/mob/dogborg.dmi' + icon_state = "jaws" + desc = "The jaws of the law." + flags = CONDUCT + force = 10 + throwforce = 0 + hitsound = 'sound/weapons/bite.ogg' + attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") + w_class = 3 + sharpness = IS_SHARP + +/obj/item/weapon/dogborg/jaws/small + name = "puppy jaws" + icon = 'icons/mob/dogborg.dmi' + icon_state = "smalljaws" + desc = "The jaws of a small dog." + flags = CONDUCT + force = 5 + throwforce = 0 + hitsound = 'sound/weapons/bite.ogg' + attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") + w_class = 3 + sharpness = IS_SHARP + var/emagged = 0 + +/obj/item/weapon/dogborg/jaws/small/attack_self(mob/user) + var/mob/living/silicon/robot.R = user + if(R.emagged) + emagged = !emagged + if(emagged) + name = "combat jaws" + icon = 'icons/mob/dogborg.dmi' + icon_state = "jaws" + desc = "The jaws of the law." + flags = CONDUCT + force = 10 + throwforce = 0 + hitsound = 'sound/weapons/bite.ogg' + attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced") + w_class = 3 + sharpness = IS_SHARP + else + name = "puppy jaws" + icon = 'icons/mob/dogborg.dmi' + icon_state = "smalljaws" + desc = "The jaws of a small dog." + flags = CONDUCT + force = 5 + throwforce = 0 + hitsound = 'sound/weapons/bite.ogg' + attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed") + w_class = 3 + sharpness = IS_SHARP + update_icon() + + +//Cuffs + +/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg/dog/attack(mob/living/carbon/C, mob/user) + if(isrobot(user)) + if(!C.handcuffed) + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + C.visible_message("[user] is trying to put zipties on [C]!", \ + "[user] is trying to put zipties on [C]!") + if(do_mob(user, C, 30)) + if(!C.handcuffed) + C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C) + C.update_inv_handcuffed(0) + user << "You handcuff [C]." + playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0) + add_logs(user, C, "handcuffed") + else + user << "You fail to handcuff [C]!" + + +//Boop + +/obj/item/device/analyzer/nose + name = "boop module" + icon = 'icons/mob/dogborg.dmi' + icon_state = "nose" + desc = "The BOOP module" + flags = CONDUCT + force = 0 + throwforce = 0 + attack_verb = list("nuzzled", "nosed", "booped") + w_class = 1 + +/obj/item/device/analyzer/nose/attack_self(mob/user) + user.visible_message("[user] sniffs around the air.", "You sniff the air for gas traces.") + + var/turf/location = user.loc + if (!( istype(location, /turf) )) + return + + var/datum/gas_mixture/environment = location.return_air() + + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles() + + user.show_message("Results:", 1) + if(abs(pressure - ONE_ATMOSPHERE) < 10) + user.show_message("Pressure: [round(pressure,0.1)] kPa", 1) + else + user.show_message("Pressure: [round(pressure,0.1)] kPa", 1) + if(total_moles) + var/list/env_gases = environment.gases + + environment.assert_gases(arglist(hardcoded_gases)) + var/o2_concentration = env_gases["o2"][MOLES]/total_moles + var/n2_concentration = env_gases["n2"][MOLES]/total_moles + var/co2_concentration = env_gases["co2"][MOLES]/total_moles + var/plasma_concentration = env_gases["plasma"][MOLES]/total_moles + environment.garbage_collect() + + if(abs(n2_concentration - N2STANDARD) < 20) + user << "Nitrogen: [round(n2_concentration*100, 0.01)] %" + else + user << "Nitrogen: [round(n2_concentration*100, 0.01)] %" + + if(abs(o2_concentration - O2STANDARD) < 2) + user << "Oxygen: [round(o2_concentration*100, 0.01)] %" + else + user << "Oxygen: [round(o2_concentration*100, 0.01)] %" + + if(co2_concentration > 0.01) + user << "CO2: [round(co2_concentration*100, 0.01)] %" + else + user << "CO2: [round(co2_concentration*100, 0.01)] %" + + if(plasma_concentration > 0.005) + user << "Plasma: [round(plasma_concentration*100, 0.01)] %" + else + user << "Plasma: [round(plasma_concentration*100, 0.01)] %" + + user.show_message("Temperature: [round(environment.temperature-T0C)] °C", 1) + return + + +//Delivery + +/obj/item/weapon/storage/bag/borgdelivery + name = "fetching storage" + desc = "Fetch the thing!" + icon = 'icons/mob/dogborg.dmi' + icon_state = "dbag" + //Can hold one big item at a time. Drops contents on unequip.(see inventory.dm) + w_class = 5 + max_w_class = 2 + max_combined_w_class = 2 + storage_slots = 1 + collection_mode = 0 + can_hold = list() // any + cant_hold = list(/obj/item/weapon/disk/nuclear) + + +//Tongue stuff + +/obj/item/weapon/soap/tongue + name = "synthetic tongue" + desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." + icon = 'icons/mob/dogborg.dmi' + icon_state = "synthtongue" + hitsound = 'sound/effects/attackblob.ogg' + cleanspeed = 80 + var/emagged = 0 + +/obj/item/trash/rkibble + name = "robo kibble" + desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge." + icon = 'icons/mob/dogborg.dmi' + icon_state= "kibble" + +/obj/item/weapon/soap/tongue/attack_self(mob/user) + var/mob/living/silicon/robot.R = user + if(R.emagged) + emagged = !emagged + if(emagged) + name = "hacked tongue of doom" + desc = "Your tongue has been upgraded successfully. Congratulations." + icon = 'icons/mob/dogborg.dmi' + icon_state = "syndietongue" + cleanspeed = 60 //(nerf'd)tator soap stat + else + name = "synthetic tongue" + desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face." + icon = 'icons/mob/dogborg.dmi' + icon_state = "synthtongue" + cleanspeed = 80 + update_icon() + +/obj/item/weapon/soap/tongue/afterattack(atom/target, mob/user, proximity) + if(!proximity || !check_allowed_items(target)) + return + if(user.client && (target in user.client.screen)) + user << "You need to take that [target.name] off before cleaning it!" + else if(istype(target,/obj/effect/decal/cleanable)) + user.visible_message("[user] begins to lick off \the [target.name].", "You begin to lick off \the [target.name]...") + if(do_after(user, src.cleanspeed, target = target)) + user << "You finish licking off \the [target.name]." + qdel(target) + var/mob/living/silicon/robot.R = user + R.cell.charge = R.cell.charge + 50 + else if(istype(target,/obj/item)) //hoo boy. danger zone man + if(istype(target,/obj/item/trash)) + user.visible_message("[user] nibbles away at \the [target.name].", "You begin to nibble away at \the [target.name]...") + if(do_after(user, src.cleanspeed, target = target)) + user << "You finish off \the [target.name]." + qdel(target) + var/mob/living/silicon/robot.R = user + R.cell.charge = R.cell.charge + 250 + return + if(istype(target,/obj/item/weapon/stock_parts/cell)) + user.visible_message("[user] begins cramming \the [target.name] down its throat.", "You begin cramming \the [target.name] down your throat...") + if(do_after(user, 50, target = target)) + user << "You finish off \the [target.name]." + var/mob/living/silicon/robot.R = user + var/obj/item/weapon/stock_parts/cell.C = target + R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf + qdel(target) + return + var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT + if(!I.anchored && src.emagged) + user.visible_message("[user] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "You begin chewing up \the [target.name]...") + if(do_after(user, 100, target = I)) //Nerf dat time yo + visible_message("[user] chews up \the [target.name] and cleans off the debris!") + user << "You finish off \the [target.name]." + qdel(I) + var/mob/living/silicon/robot.R = user + R.cell.charge = R.cell.charge + 500 + return + user.visible_message("[user] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") + if(do_after(user, src.cleanspeed, target = target)) + user << "You clean \the [target.name]." + var/obj/effect/decal/cleanable/C = locate() in target + qdel(C) + target.clean_blood() + else if(ishuman(target)) + if(src.emagged) + var/mob/living/silicon/robot.R = user + var/mob/living/L = target + if(R.cell.charge <= 666) + return + L.Stun(4) // normal stunbaton is force 7 gimme a break good sir! + L.Weaken(4) + L.apply_effect(STUTTER, 4) + L.visible_message("[user] has shocked [L] with its tongue!", \ + "[user] has shocked you with its tongue! You can feel the betrayal.") + playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) + R.cell.charge = R.cell.charge - 666 + else + user.visible_message("\the [user] affectionally licks \the [target]'s face!", "You affectionally lick \the [target]'s face!") + playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) + return + else if(istype(target, /obj/structure/window)) + user.visible_message("[user] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") + if(do_after(user, src.cleanspeed, target = target)) + user << "You clean \the [target.name]." + target.color = initial(target.color) + target.SetOpacity(initial(target.opacity)) + else + user.visible_message("[user] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...") + if(do_after(user, src.cleanspeed, target = target)) + user << "You clean \the [target.name]." + var/obj/effect/decal/cleanable/C = locate() in target + qdel(C) + target.clean_blood() + return + + + +//Defibs + +/obj/item/weapon/twohanded/shockpaddles/hound + name = "defibrillator paws" + desc = "MediHound specific shock paws." + icon = 'icons/mob/dogborg.dmi' + icon_state = "defibpaddles0" + item_state = "defibpaddles0" + req_defib = 0 + wielded = 1 + +/obj/item/weapon/twohanded/shockpaddles/hound/attack(mob/M, mob/user) + ...() + var/mob/living/silicon/robot.R = user + if(R.cell.charge < 1000) + user_visible_message("You don't have enough charge for this operation!") + return + if(src.cooldown == 0) + R.cell.charge = R.cell.charge - 1000 + return ..() + + +//Sleeper + +/obj/item/weapon/dogborg/sleeper + name = "mounted sleeper" + desc = "Equipment for medical hound. A mounted sleeper that stabilizes patients and can inject reagents in the borg's reserves." + icon = 'icons/mob/dogborg.dmi' + icon_state = "sleeper" + var/mob/living/carbon/patient = null + var/mob/living/silicon/hound = null + var/inject_amount = 10 + var/min_health = -100 + var/occupied = 0 + var/list/injection_chems = list("morphine", "salbutamol", "bicaridine", "kelotane","antitoxin") + +/obj/item/weapon/dogborg/sleeper/Exit(atom/movable/O) + return 0 + +/obj/item/weapon/dogborg/sleeper/afterattack(mob/living/carbon/target, mob/living/silicon/user, proximity) + if(!proximity) + return + if(!ishuman(target)) + return + if(!patient_insertion_check(target)) + return + user.visible_message("[user] starts putting [target] into \the [src].", "You start putting [target] into [src]...") + if(do_after(user, 50, target = target)) + if(!patient_insertion_check(target)) + return + target.forceMove(src) + patient = target + hound = user + target.reset_perspective(src) + user << "[target] successfully loaded into [src]. Life support functions engaged." + user.visible_message("[user] loads [target] into [src].") + user.visible_message("[target] loaded. Life support functions engaged.") + src.occupied = 1 + var/mob/living/silicon/robot.R = user + if(patient.stat < 2) + R.sleeper_r = 0 + R.sleeper_g = 1 + R.update_icons() + else + R.sleeper_g = 0 + R.sleeper_r = 1 + R.update_icons() + SSobj.processing |= src + +/obj/item/weapon/dogborg/sleeper/proc/patient_insertion_check(mob/living/carbon/target, mob/user) + if(target.anchored) + user << "[target] will not fit into the sleeper because they are buckled to [target.buckled]!" + return + if(patient) + user << "The sleeper is already occupied!" + return + return 1 + +/obj/item/weapon/dogborg/sleeper/proc/go_out() + if(src.occupied == 0) + return + var/mob/living/silicon/robot.R = hound + hound << "[patient] ejected. Life support functions disabled." + R.sleeper_r = 0 + R.sleeper_g = 0 + R.update_icons() + patient.forceMove(get_turf(src)) + patient.reset_perspective() + patient = null + src.occupied = 0 + src.occupied = 0 //double check just in case + +/obj/item/weapon/dogborg/sleeper/proc/drain() + var/mob/living/silicon/robot.R = hound + R.cell.charge = R.cell.charge - 10 + +/obj/item/weapon/dogborg/sleeper/attack_self(mob/user) + if(..()) + return + sleeperUI(user) + +/obj/item/weapon/dogborg/sleeper/proc/sleeperUI(mob/user) + var/dat + dat += "