From 91aa560f0dbb3494e35b3468f12aea9e17d3743d Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 7 Oct 2017 09:42:15 -0400 Subject: [PATCH 01/60] High pop reduced MC processing mode. --- code/__DEFINES/configuration.dm | 1 + .../configuration/entries/config.dm | 25 +++++++++++++++- code/controllers/master.dm | 10 +++++++ code/modules/client/client_procs.dm | 5 ++++ config/config.txt | 29 ++++++++++++++++++- 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm index c78dfb28ab..3db0ca24c2 100644 --- a/code/__DEFINES/configuration.dm +++ b/code/__DEFINES/configuration.dm @@ -2,6 +2,7 @@ #define CONFIG_DEF(X) /datum/config_entry/##X { resident_file = CURRENT_RESIDENT_FILE }; /datum/config_entry/##X #define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X) #define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y) +#define CONFIG_TWEAK(X) /datum/config_entry/##X #define CONFIG_MAPS_FILE "maps.txt" diff --git a/code/controllers/configuration/entries/config.dm b/code/controllers/configuration/entries/config.dm index ec96e88553..eea47b6612 100644 --- a/code/controllers/configuration/entries/config.dm +++ b/code/controllers/configuration/entries/config.dm @@ -351,4 +351,27 @@ CONFIG_DEF(number/error_msg_delay) // How long to wait between messaging admins CONFIG_DEF(flag/irc_announce_new_game) -CONFIG_DEF(flag/debug_admin_hrefs) \ No newline at end of file +CONFIG_DEF(flag/debug_admin_hrefs) + + +CONFIG_DEF(number/mc_tick_rate/base_mc_tick_rate) + integer = FALSE + value = 1 + +CONFIG_DEF(number/mc_tick_rate/high_pop_mc_tick_rate) + integer = FALSE + value = 1.1 + +CONFIG_DEF(number/mc_tick_rate/high_pop_mc_mode_amount) + value = 65 + +CONFIG_DEF(number/mc_tick_rate/disable_high_pop_mc_mode_amount) + value = 60 + +CONFIG_TWEAK(number/mc_tick_rate) + abstract_type = /datum/config_entry/number/mc_tick_rate + +CONFIG_TWEAK(number/mc_tick_rate/ValidateAndSet(str_val)) + . = ..() + if (.) + Master.UpdateTickRate() diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 6ed3121179..b92853a2c4 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -573,3 +573,13 @@ GLOBAL_REAL(Master, /datum/controller/master) = new for(var/S in subsystems) var/datum/controller/subsystem/SS = S SS.StopLoadingMap() + + +/datum/controller/master/proc/UpdateTickRate() + if (!processing) + return + var/client_count = length(GLOB.clients) + if (client_count < CONFIG_GET(number/mc_tick_rate/disable_high_pop_mc_mode_amount)) + processing = CONFIG_GET(number/mc_tick_rate/base_mc_tick_rate) + else if (client_count > CONFIG_GET(number/mc_tick_rate/high_pop_mc_mode_amount)) + processing = CONFIG_GET(number/mc_tick_rate/high_pop_mc_tick_rate) \ No newline at end of file diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 60936aa5fb..8e8361194d 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -351,7 +351,11 @@ GLOBAL_LIST(external_rsc_urls) if (menuitem) menuitem.Load_checked(src) +<<<<<<< HEAD hook_vr("client_new",list(src)) +======= + Master.UpdateTickRate() +>>>>>>> bc4d4e7... Merge pull request #31374 from MrStonedOne/highpopmode ////////////// //DISCONNECT// @@ -399,6 +403,7 @@ GLOBAL_LIST(external_rsc_urls) if(movingmob != null) movingmob.client_mobs_in_contents -= mob UNSETEMPTY(movingmob.client_mobs_in_contents) + Master.UpdateTickRate() return ..() /client/Destroy() diff --git a/config/config.txt b/config/config.txt index 72f168dcce..a81bdf0d8e 100644 --- a/config/config.txt +++ b/config/config.txt @@ -228,9 +228,13 @@ ALLOW_HOLIDAYS ##This is currently a testing optimized setting. A good value for production would be 98. TICK_LIMIT_MC_INIT 500 -##Defines the ticklag for the world. 0.9 is the normal one, 0.5 is smoother. +##Defines the ticklag for the world. Ticklag is the amount of time between game ticks (aka byond ticks) (in 1/10ths of a second). +## This also controls the client network update rate, as well as the default client fps TICKLAG 0.5 +##Can also be set as per-second value, the following value is identical to the above. +#FPS 20 + ## Comment this out to disable automuting #AUTOMUTE_ON @@ -351,3 +355,26 @@ MINUTE_TOPIC_LIMIT 100 ## Allow admin hrefs that don't use the new token system, will eventually be removed DEBUG_ADMIN_HREFS +<<<<<<< HEAD +======= + +###Master Controller High Pop Mode### + +##The Master Controller(MC) is the primary system controlling timed tasks and events in SS13 (lobby timer, game checks, lighting updates, atmos, etc) +##Default base MC tick rate (1 = process every "byond tick" (see: tick_lag/fps config settings), 2 = process every 2 byond ticks, etc) +## Setting this to 0 will prevent the Master Controller from ticking +BASE_MC_TICK_RATE 1 + +##High population MC tick rate +## Byond rounds timer values UP, but the tick rate is modified with heuristics during lag spites so setting this to something like 2 +## will make it run every 2 byond ticks, but will also double the effect of anti-lag heuristics. You can instead set it to something like +## 1.1 to make it run every 2 byond ticks, but only increase the effect of anti-lag heuristics by 10%. or 1.5 for 50%. +## (As an aside, you could in theory also reduce the effect of anti-lag heuristics in the base tick rate by setting it to something like 0.5) +HIGH_POP_MC_TICK_RATE 1.1 + +##Engage high pop mode if player count raises above this (Player in this context means any connected user. Lobby, ghost or in-game all count) +HIGH_POP_MC_MODE_AMOUNT 65 + +##Disengage high pop mode if player count drops below this +DISABLE_HIGH_POP_MC_MODE_AMOUNT 60 +>>>>>>> bc4d4e7... Merge pull request #31374 from MrStonedOne/highpopmode From 075cb673c09ad2db4655d594bf43d70c46d765c1 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 7 Oct 2017 13:36:33 -0400 Subject: [PATCH 02/60] Remove drop_item, drop_item_v, put_in_hands_or_del --- code/_onclick/hud/screen_objects.dm | 3 +- .../datums/diseases/advance/symptoms/cough.dm | 41 ++ code/datums/martial/cqc.dm | 7 +- code/datums/martial/krav_maga.dm | 2 +- code/datums/martial/sleeping_carp.dm | 9 +- code/datums/mutations.dm | 2 +- code/datums/wires/wires.dm | 5 +- code/game/gamemodes/antag_spawner.dm | 2 +- .../gamemodes/changeling/powers/mutations.dm | 7 +- .../gamemodes/changeling/powers/tiny_prick.dm | 5 +- .../clock_effects/spatial_gateway.dm | 2 +- .../clock_items/clock_components.dm | 1 - .../clock_items/clock_weapons/_call_weapon.dm | 1 - .../clock_cult/clock_items/clockwork_slab.dm | 2 +- code/game/gamemodes/cult/talisman.dm | 7 +- .../gamemodes/devil/true_devil/_true_devil.dm | 2 +- .../miniantags/abduction/abduction_surgery.dm | 2 +- .../gamemodes/miniantags/revenant/revenant.dm | 2 +- .../miniantags/slaughter/slaughter.dm | 2 +- code/game/gamemodes/nuclear/nuclear.dm | 5 +- code/game/gamemodes/nuclear/nuclearbomb.dm | 9 +- code/game/gamemodes/wizard/artefact.dm | 4 +- code/game/gamemodes/wizard/wizard.dm | 2 +- code/game/machinery/PDApainter.dm | 56 +++ code/game/machinery/camera/camera.dm | 4 +- code/game/machinery/camera/camera_assembly.dm | 3 +- .../machinery/computer/gulag_teleporter.dm | 15 +- code/game/machinery/computer/medical.dm | 17 +- code/game/machinery/computer/prisoner.dm | 7 +- code/game/machinery/computer/security.dm | 15 +- .../machinery/computer/telecrystalconsoles.dm | 10 +- code/game/machinery/constructable_frame.dm | 239 +++++++++++ code/game/machinery/doors/airlock.dm | 3 +- code/game/machinery/doors/firedoor.dm | 1 - code/game/machinery/flasher.dm | 3 +- code/game/machinery/gulag_item_reclaimer.dm | 18 +- code/game/machinery/iv_drip.dm | 4 +- code/game/machinery/newscaster.dm | 8 +- code/game/machinery/pipe/pipe_dispenser.dm | 2 - .../porta_turret/portable_turret_construct.dm | 5 +- code/game/machinery/recharger.dm | 3 +- code/game/machinery/slotmachine.dm | 5 +- code/game/machinery/spaceheater.dm | 17 +- code/game/machinery/suit_storage_unit.dm | 9 +- code/game/machinery/syndicatebomb.dm | 6 +- code/game/machinery/vending.dm | 6 +- code/game/mecha/mecha_defense.dm | 5 +- .../effects/effect_system/effects_smoke.dm | 3 +- code/game/objects/items.dm | 2 +- code/game/objects/items/handcuffs.dm | 377 ++++++++++++++++- code/game/objects/items/melee/misc.dm | 6 +- code/game/objects/items/paiwire.dm | 15 + code/game/objects/items/pneumaticCannon.dm | 2 +- code/game/objects/items/robot/robot_parts.dm | 2 +- code/game/objects/items/storage/backpack.dm | 2 +- code/game/objects/items/storage/boxes.dm | 6 +- code/game/objects/items/toys.dm | 8 +- code/game/objects/structures.dm | 44 ++ .../objects/structures/beds_chairs/chair.dm | 4 +- code/game/objects/structures/bedsheet_bin.dm | 9 +- .../structures/crates_lockers/closets.dm | 3 +- code/game/objects/structures/door_assembly.dm | 3 +- code/game/objects/structures/extinguisher.dm | 3 +- code/game/objects/structures/fireaxe.dm | 3 +- code/game/objects/structures/girders.dm | 3 +- code/game/objects/structures/guncase.dm | 3 +- code/game/objects/structures/janicart.dm | 3 +- code/game/objects/structures/safe.dm | 3 +- code/game/objects/structures/signs.dm | 1 - code/game/objects/structures/tables_racks.dm | 10 +- .../game/objects/structures/tank_dispenser.dm | 3 +- code/game/objects/structures/target_stake.dm | 49 +++ code/game/objects/structures/watercloset.dm | 6 +- .../objects/structures/windoor_assembly.dm | 3 +- .../game/turfs/simulated/floor/light_floor.dm | 2 +- code/modules/assembly/bomb.dm | 12 +- .../components/unary_devices/cryo.dm | 3 +- .../portable/portable_atmospherics.dm | 3 +- .../awaymissions/mission_code/Academy.dm | 2 +- code/modules/clothing/clothing.dm | 2 +- .../food_and_drinks/drinks/drinks/bottle.dm | 9 +- .../kitchen_machinery/deep_fryer.dm | 3 +- .../kitchen_machinery/food_cart.dm | 5 +- .../kitchen_machinery/microwave.dm | 3 +- .../kitchen_machinery/processor.dm | 3 +- code/modules/food_and_drinks/pizzabox.dm | 6 +- code/modules/holodeck/items.dm | 6 +- code/modules/hydroponics/biogenerator.dm | 3 +- code/modules/hydroponics/gene_modder.dm | 10 +- code/modules/hydroponics/grown/cereals.dm | 3 +- code/modules/hydroponics/grown/nettle.dm | 2 +- code/modules/hydroponics/seed_extractor.dm | 155 +++++++ code/modules/library/lib_items.dm | 3 +- code/modules/library/lib_machines.dm | 6 +- code/modules/mining/fulton.dm | 3 +- code/modules/mining/laborcamp/laborstacker.dm | 103 +++++ .../mining/lavaland/necropolis_chests.dm | 2 +- code/modules/mining/machine_redemption.dm | 3 +- code/modules/mining/machine_vending.dm | 6 +- code/modules/mining/satchel_ore_boxdm.dm | 4 +- code/modules/mob/inventory.dm | 20 +- code/modules/mob/living/brain/brain_item.dm | 3 +- .../carbon/alien/humanoid/humanoid_defense.dm | 2 +- .../mob/living/carbon/human/human_defense.dm | 4 +- .../mob/living/carbon/human/interactive.dm | 2 +- .../mob/living/carbon/human/species.dm | 2 +- .../living/carbon/monkey/monkey_defense.dm | 16 +- .../modules/mob/living/silicon/robot/robot.dm | 8 +- code/modules/mob/living/silicon/silicon.dm | 386 ++++++++++++++++++ .../mob/living/simple_animal/bot/bot.dm | 3 +- .../mob/living/simple_animal/bot/medbot.dm | 3 +- .../mob/living/simple_animal/bot/mulebot.dm | 6 +- .../mob/living/simple_animal/friendly/dog.dm | 13 +- .../simple_animal/friendly/farm_animals.dm | 1 - .../mob/living/simple_animal/parrot.dm | 5 +- code/modules/mob/mob_movement.dm | 9 +- .../file_system/programs/card.dm | 6 +- .../modular_computers/laptop_vendor.dm | 2 +- code/modules/paperwork/filingcabinet.dm | 3 +- code/modules/paperwork/paper_cutter.dm | 5 +- code/modules/paperwork/photocopier.dm | 10 +- code/modules/power/apc.dm | 3 +- code/modules/power/lighting.dm | 2 +- code/modules/power/singularity/collector.dm | 5 +- code/modules/power/solar.dm | 2 +- code/modules/projectiles/box_magazine.dm | 3 +- code/modules/projectiles/gun.dm | 2 +- .../projectiles/guns/ballistic/revolver.dm | 2 +- .../projectiles/guns/ballistic/shotgun.dm | 4 +- .../projectiles/guns/misc/blastcannon.dm | 3 +- .../chemistry/reagents/drug_reagents.dm | 8 +- .../chemistry/reagents/food_reagents.dm | 2 - .../chemistry/reagents/medicine_reagents.dm | 21 +- code/modules/recycling/conveyor2.dm | 3 +- code/modules/recycling/disposal-unit.dm | 2 +- code/modules/research/destructive_analyzer.dm | 3 +- code/modules/research/experimentor.dm | 3 +- code/modules/research/rdconsole.dm | 3 +- .../research/xenobiology/xenobio_camera.dm | 1 - code/modules/spells/spell_types/conjure.dm | 5 +- code/modules/spells/spell_types/devil.dm | 2 +- .../modules/spells/spell_types/devil_boons.dm | 2 +- .../spells/spell_types/infinite_guns.dm | 5 +- code/modules/surgery/cavity_implant.dm | 3 +- code/modules/surgery/dental_implant.dm | 3 +- code/modules/surgery/limb_augmentation.dm | 61 +++ code/modules/surgery/organ_manipulation.dm | 2 +- code/modules/surgery/organs/autosurgeon.dm | 3 +- code/modules/surgery/organs/heart.dm | 2 +- code/modules/surgery/organs/organ_internal.dm | 5 +- .../modules/surgery/prosthetic_replacement.dm | 3 +- code/modules/vehicles/pimpin_ride.dm | 3 +- 152 files changed, 1778 insertions(+), 425 deletions(-) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 397e04a4f5..9730aaf552 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -196,7 +196,8 @@ plane = HUD_PLANE /obj/screen/drop/Click() - usr.drop_item_v() + if(usr.stat == CONSCIOUS) + usr.dropItemToGround(usr.get_active_held_item()) /obj/screen/act_intent name = "intent" diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm index 95577fe351..6b84e88dfb 100644 --- a/code/datums/diseases/advance/symptoms/cough.dm +++ b/code/datums/diseases/advance/symptoms/cough.dm @@ -34,6 +34,7 @@ BONUS Stage Speed 6: Increases cough frequency.
\ If Airborne: Coughing will infect bystanders.
\ Stealth 4: The symptom remains hidden until active." +<<<<<<< HEAD /datum/symptom/cough/Start(datum/disease/advance/A) ..() @@ -72,3 +73,43 @@ BONUS if(infective) A.spread(1) +======= + +/datum/symptom/cough/Start(datum/disease/advance/A) + ..() + if(A.properties["stealth"] >= 4) + suppress_warning = TRUE + if(A.spread_flags &= AIRBORNE) //infect bystanders + infective = TRUE + if(A.properties["resistance"] >= 3) //strong enough to drop items + power = 1.5 + if(A.properties["resistance"] >= 10) //strong enough to stun (rarely) + power = 2 + if(A.properties["stage_rate"] >= 6) //cough more often + symptom_delay_max = 10 + +/datum/symptom/cough/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + switch(A.stage) + if(1, 2, 3) + if(prob(base_message_chance) && !suppress_warning) + to_chat(M, "[pick("You swallow excess mucus.", "You lightly cough.")]") + else + M.emote("cough") + if(power >= 1.5) + var/obj/item/I = M.get_active_held_item() + if(I && I.w_class == WEIGHT_CLASS_TINY) + M.dropItemToGround(I) + if(power >= 2 && prob(10)) + to_chat(M, "[pick("You have a coughing fit!", "You can't stop coughing!")]") + M.Stun(20) + M.emote("cough") + addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 6) + addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 12) + addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 18) + if(infective) + A.spread(1) + +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm index d740a4213c..8974c388b1 100644 --- a/code/datums/martial/cqc.dm +++ b/code/datums/martial/cqc.dm @@ -85,7 +85,7 @@ "[A] strikes your abdomen, neck and back consecutively!") playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1) var/obj/item/I = D.get_active_held_item() - if(I && D.drop_item()) + if(I && D.temporarilyRemoveItemFromInventory(I)) A.put_in_hands(I) D.adjustStaminaLoss(50) D.apply_damage(25, BRUTE) @@ -145,7 +145,7 @@ D.visible_message("[A] strikes [D]'s jaw with their hand!", \ "[A] strikes your jaw, disorienting you!") playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1) - if(I && D.drop_item()) + if(I && D.temporarilyRemoveItemFromInventory(I)) A.put_in_hands(I) D.Jitter(2) D.apply_damage(5, BRUTE) @@ -193,7 +193,6 @@ to_chat(user, "You remember the basics of CQC.") var/datum/martial_art/cqc/D = new(null) D.teach(user) - user.drop_item() visible_message("[src] beeps ominously, and a moment later it bursts up in flames.") - new /obj/effect/decal/cleanable/ash(get_turf(src)) qdel(src) + new /obj/effect/decal/cleanable/ash(user.drop_location()) diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index 84f0f00e45..a898c1866b 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -150,7 +150,7 @@ if(prob(60)) I = D.get_active_held_item() if(I) - if(D.drop_item()) + if(D.temporarilyRemoveItemFromInventory(I)) A.put_in_hands(I) D.visible_message("[A] has disarmed [D]!", \ "[A] has disarmed [D]!") diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index ac5083cc17..8fe8fcd366 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -41,7 +41,7 @@ "[A] grabs your wrist and violently wrenches it to the side!") playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) D.emote("scream") - D.drop_item() + D.dropItemToGround(D.get_active_held_item()) D.apply_damage(5, BRUTE, pick("l_arm", "r_arm")) D.Stun(60) return 1 @@ -79,7 +79,7 @@ D.visible_message("[A] kicks [D] in the head!", \ "[A] kicks you in the jaw!") D.apply_damage(20, BRUTE, "head") - D.drop_item() + D.drop_all_held_items() playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) D.Stun(80) return 1 @@ -168,10 +168,9 @@ to_chat(user, message) var/datum/martial_art/the_sleeping_carp/theSleepingCarp = new(null) theSleepingCarp.teach(user) - user.drop_item() - visible_message("[src] lights up in fire and quickly burns to ash.") - new /obj/effect/decal/cleanable/ash(get_turf(src)) qdel(src) + visible_message("[src] lights up in fire and quickly burns to ash.") + new /obj/effect/decal/cleanable/ash(user.drop_location()) /obj/item/twohanded/bostaff name = "bo staff" diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index 4e8ae4e73a..dea7a7308a 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -270,7 +270,7 @@ GLOBAL_LIST_EMPTY(mutations_list) /datum/mutation/human/cough/on_life(mob/living/carbon/human/owner) if(prob(5) && owner.stat == CONSCIOUS) - owner.drop_item() + owner.drop_all_held_items() owner.emote("cough") /datum/mutation/human/dwarfism diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index ae938f18ce..c508907bf4 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -250,9 +250,10 @@ if(istype(I, /obj/item/device/assembly)) var/obj/item/device/assembly/A = I if(A.attachable) - if(!L.drop_item()) + if(!L.temporarilyRemoveItemFromInventory(A)) return - attach_assembly(target_wire, A) + if(!attach_assembly(target_wire, A)) + A.forceMove(L.drop_location()) . = TRUE else to_chat(L, "You need an attachable assembly!") diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 3b5b862559..c529ab546d 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -90,7 +90,7 @@ if("healing") M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null)) M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null)) - M.put_in_hands_or_del(new /obj/item/gun/magic/staff/healing(M)) + M.put_in_hands(new /obj/item/gun/magic/staff/healing(M), TRUE) to_chat(M, "Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.") if("robeless") M.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null)) diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index addca91629..467d23e726 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -37,8 +37,9 @@ return 1 /obj/effect/proc_holder/changeling/weapon/sting_action(mob/living/user) - if(!user.drop_item()) - to_chat(user, "The [user.get_active_held_item()] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!") + var/obj/item/held = user.get_active_held_item() + if(held && !user.dropItemToGround(held)) + to_chat(user, "[held] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!") return var/limb_regen = 0 if(user.active_hand_index % 2 == 0) //we regen the arm before changing it into the weapon @@ -338,7 +339,7 @@ if(INTENT_DISARM) var/obj/item/I = C.get_active_held_item() if(I) - if(C.drop_item()) + if(C.dropItemToGround(I)) C.visible_message("[I] is yanked off [C]'s hand by [src]!","A tentacle pulls [I] away from you!") on_hit(I) //grab the item as if you had hit it directly with the tentacle return 1 diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm index 1732e98630..e98898f37c 100644 --- a/code/game/gamemodes/changeling/powers/tiny_prick.dm +++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm @@ -127,8 +127,9 @@ /obj/effect/proc_holder/changeling/sting/false_armblade/sting_action(mob/user, mob/target) add_logs(user, target, "stung", object="falso armblade sting") - if(!target.drop_item()) - to_chat(user, "The [target.get_active_held_item()] is stuck to their hand, you cannot grow a false armblade over it!") + var/obj/item/held = target.get_active_held_item() + if(held && !target.dropItemToGround(held)) + to_chat(user, "[held] is stuck to their hand, you cannot grow a false armblade over it!") return if(ismonkey(target)) diff --git a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm index 9b1ef66c9e..8f8a4bfcbf 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm @@ -88,7 +88,7 @@ if(istype(I, /obj/item/clockwork/slab)) to_chat(user, "\"I don't think you want to drop your slab into that.\"\n\"If you really want to, try throwing it.\"") return TRUE - if(user.drop_item() && uses) + if(uses && user.dropItemToGround(I)) user.visible_message("[user] drops [I] into [src]!", "You drop [I] into [src]!") pass_through_gateway(I, TRUE) return TRUE diff --git a/code/game/gamemodes/clock_cult/clock_items/clock_components.dm b/code/game/gamemodes/clock_cult/clock_items/clock_components.dm index b1409aae18..65c4f9f0af 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clock_components.dm +++ b/code/game/gamemodes/clock_cult/clock_items/clock_components.dm @@ -20,7 +20,6 @@ "You crush [src], capturing its escaping energy for use as power.") playsound(user, 'sound/effects/pop_expl.ogg', 50, TRUE) adjust_clockwork_power(POWER_WALL_TOTAL) - user.drop_item() qdel(src) /obj/item/clockwork/component/pickup(mob/living/user) diff --git a/code/game/gamemodes/clock_cult/clock_items/clock_weapons/_call_weapon.dm b/code/game/gamemodes/clock_cult/clock_items/clock_weapons/_call_weapon.dm index afe6aca217..a87767c05e 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clock_weapons/_call_weapon.dm +++ b/code/game/gamemodes/clock_cult/clock_items/clock_weapons/_call_weapon.dm @@ -28,7 +28,6 @@ if(weapon.loc == owner) owner.visible_message("[owner]'s [weapon.name] flickers and disappears!") to_chat(owner, "You dismiss [weapon].") - owner.drop_item() QDEL_NULL(weapon) weapon_reset(RATVARIAN_SPEAR_COOLDOWN * 0.5) return diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm index a9c241b2c3..563e83e9cd 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm +++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm @@ -136,7 +136,7 @@ to_chat(user, "\"You reek of blood. You've got a lot of nerve to even look at that slab.\"") user.visible_message("A sizzling sound comes from [user]'s hands!", "[src] suddenly grows extremely hot in your hands!") playsound(get_turf(user), 'sound/weapons/sear.ogg', 50, 1) - user.drop_item() + user.dropItemToGround(src) user.emote("scream") user.apply_damage(5, BURN, "l_arm") user.apply_damage(5, BURN, "r_arm") diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 2a5f64915b..115f931975 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -21,7 +21,6 @@ if(invoke(user)) uses-- if(uses <= 0) - user.drop_item() qdel(src) /obj/item/paper/talisman/proc/invoke(mob/living/user, successfuluse = 1) @@ -182,7 +181,6 @@ C.Jitter(15) if(is_servant_of_ratvar(target)) target.adjustBruteLoss(15) - user.drop_item() qdel(src) return ..() @@ -204,13 +202,13 @@ user.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit) user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult/alt(user), slot_shoes) user.equip_to_slot_or_del(new /obj/item/storage/backpack/cultpack(user), slot_back) - user.drop_item() + user.dropItemToGround(src) user.put_in_hands(new /obj/item/melee/cultblade(user)) user.put_in_hands(new /obj/item/restraints/legcuffs/bola/cult(user)) /obj/item/paper/talisman/armor/attack(mob/living/target, mob/living/user) if(iscultist(user) && iscultist(target)) - user.drop_item() + user.temporarilyRemoveItemFromInventory(src) invoke(target) qdel(src) return @@ -335,7 +333,6 @@ else to_chat(user, "[C] is already bound.") if(uses <= 0) - user.drop_item() qdel(src) /obj/item/restraints/handcuffs/energy/cult //For the talisman of shackling diff --git a/code/game/gamemodes/devil/true_devil/_true_devil.dm b/code/game/gamemodes/devil/true_devil/_true_devil.dm index 5b85cbd811..9b24d096c4 100644 --- a/code/game/gamemodes/devil/true_devil/_true_devil.dm +++ b/code/game/gamemodes/devil/true_devil/_true_devil.dm @@ -184,7 +184,7 @@ "[M] has pushed down [src]!") else if (prob(25)) - drop_item() + dropItemToGround(get_active_held_item()) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) visible_message("[M] has disarmed [src]!", \ "[M] has disarmed [src]!") diff --git a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm index 879f68e960..5b5bafdd21 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm @@ -49,7 +49,7 @@ /datum/surgery_step/gland_insert/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] inserts [tool] into [target].", "You insert [tool] into [target].") - user.drop_item() + user.temporarilyRemoveItemFromInventory(tool, TRUE) var/obj/item/organ/heart/gland/gland = tool gland.Insert(target, 2) return 1 diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 5e1d80e175..e72babc5b0 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -353,7 +353,7 @@ return ..() user.visible_message("[user] scatters [src] in all directions.", \ "You scatter [src] across the area. The particles slowly fade away.") - user.drop_item() + user.dropItemToGround(src) scatter() /obj/item/ectoplasm/revenant/throw_impact(atom/hit_atom) diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index 7aba0adf26..b9a07093d3 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -97,7 +97,7 @@ return user.visible_message("[user]'s eyes flare a deep crimson!", \ "You feel a strange power seep into your body... you have absorbed the demon's blood-travelling powers!") - user.drop_item() + user.temporarilyRemoveItemFromInventory(src, TRUE) src.Insert(user) //Consuming the heart literally replaces your heart with a demon heart. H A R D C O R E /obj/item/organ/heart/demon/Insert(mob/living/carbon/M, special = 0) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 2179177fc1..a24efbe3f5 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -91,7 +91,7 @@ to_chat(synd_mind.current, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge - synd_mind.current.put_in_hands_or_del(challenge) + synd_mind.current.put_in_hands(challenge, TRUE) var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/card/id) if(foundIDs.len) @@ -110,8 +110,7 @@ P.info = "The nuclear authorization code is: [nuke_code]" P.name = "nuclear bomb code" var/mob/living/carbon/human/H = synd_mind.current - P.forceMove(H.drop_location()) - H.put_in_hands_or_del(P) + H.put_in_hands(P, TRUE) H.update_icons() else nuke_code = "code will be provided later" diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 8870399f24..8cae25eb38 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -105,9 +105,8 @@ /obj/machinery/nuclearbomb/attackby(obj/item/I, mob/user, params) if (istype(I, /obj/item/disk/nuclear)) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - I.forceMove(src) auth = I add_fingerprint(user) return @@ -309,10 +308,8 @@ . = TRUE if("insert_disk") if(!auth) - var/obj/item/I = usr.get_active_held_item() - if(istype(I, /obj/item/disk/nuclear)) - usr.drop_item() - I.forceMove(src) + var/obj/item/I = usr.is_holding_item_of_type(/obj/item/disk/nuclear) + if(I && usr.transferItemToLoc(I, src)) auth = I . = TRUE if("keypad") diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 42d676c29b..ced6ebbd35 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -193,8 +193,8 @@ H.equip_to_slot_or_del(new hat(H), slot_head) H.equip_to_slot_or_del(new /obj/item/clothing/under/roman(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(H), slot_shoes) - H.put_in_hands_or_del(new /obj/item/shield/riot/roman(H)) - H.put_in_hands_or_del(new /obj/item/claymore(H)) + H.put_in_hands(new /obj/item/shield/riot/roman(H), TRUE) + H.put_in_hands(new /obj/item/claymore(H), TRUE) H.equip_to_slot_or_del(new /obj/item/twohanded/spear(H), slot_back) diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index dee9ab4a3d..fb9fb31fff 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -159,7 +159,7 @@ wizard_mob.equip_to_slot_or_del(new /obj/item/teleportation_scroll(wizard_mob), slot_r_store) var/obj/item/spellbook/spellbook = new /obj/item/spellbook(wizard_mob) spellbook.owner = wizard_mob - wizard_mob.put_in_hands_or_del(spellbook) + wizard_mob.put_in_hands(spellbook, TRUE) to_chat(wizard_mob, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.") to_chat(wizard_mob, "The spellbook is bound to you, and others cannot use it.") diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index bd84e7a464..9721fb6ee1 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -46,6 +46,7 @@ /obj/machinery/pdapainter/Destroy() QDEL_NULL(storedpda) +<<<<<<< HEAD return ..() /obj/machinery/pdapainter/on_deconstruction() @@ -103,6 +104,61 @@ return ..() /obj/machinery/pdapainter/deconstruct(disassembled = TRUE) +======= + return ..() + +/obj/machinery/pdapainter/on_deconstruction() + if(storedpda) + storedpda.forceMove(loc) + storedpda = null + +/obj/machinery/pdapainter/contents_explosion(severity, target) + if(storedpda) + storedpda.ex_act(severity, target) + +/obj/machinery/pdapainter/handle_atom_del(atom/A) + if(A == storedpda) + storedpda = null + update_icon() + +/obj/machinery/pdapainter/attackby(obj/item/O, mob/user, params) + if(default_unfasten_wrench(user, O)) + power_change() + return + + else if(istype(O, /obj/item/device/pda)) + if(storedpda) + to_chat(user, "There is already a PDA inside!") + return + else if(!user.transferItemToLoc(O, src)) + return + storedpda = O + O.add_fingerprint(user) + update_icon() + + else if(istype(O, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) + var/obj/item/weldingtool/WT = O + if(stat & BROKEN) + if(WT.remove_fuel(0,user)) + user.visible_message("[user] is repairing [src].", \ + "You begin repairing [src]...", \ + "You hear welding.") + playsound(loc, WT.usesound, 40, 1) + if(do_after(user,40*WT.toolspeed, 1, target = src)) + if(!WT.isOn() || !(stat & BROKEN)) + return + to_chat(user, "You repair [src].") + playsound(loc, 'sound/items/welder2.ogg', 50, 1) + stat &= ~BROKEN + obj_integrity = max_integrity + update_icon() + else + to_chat(user, "[src] does not need repairs.") + else + return ..() + +/obj/machinery/pdapainter/deconstruct(disassembled = TRUE) +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) if(!(flags_1 & NODECONSTRUCT_1)) if(!(stat & BROKEN)) stat |= BROKEN diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 7d3c40a0d9..80d50cfb17 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -149,10 +149,10 @@ else if(istype(W, /obj/item/device/analyzer)) if(!isXRay()) - if(!user.drop_item(W)) + if(!user.temporarilyRemoveItemFromInventory(W)) return - upgradeXRay() qdel(W) + upgradeXRay() to_chat(user, "[msg]") else to_chat(user, "[msg2]") diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 1e6fe4c532..5b828af820 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -109,11 +109,10 @@ // Upgrades! if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already. - if(!user.drop_item(W)) + if(!user.transferItemToLoc(W, src)) return to_chat(user, "You attach \the [W] into the assembly inner circuits.") upgrades += W - W.forceMove(src) return // Taking out upgrades diff --git a/code/game/machinery/computer/gulag_teleporter.dm b/code/game/machinery/computer/gulag_teleporter.dm index d80dc73f15..b1d56f2b2e 100644 --- a/code/game/machinery/computer/gulag_teleporter.dm +++ b/code/game/machinery/computer/gulag_teleporter.dm @@ -92,18 +92,13 @@ beacon = findbeacon() if("handle_id") if(id) - if(!usr.get_active_held_item()) - usr.put_in_hands(id) - id = null - else - id.forceMove(get_turf(src)) - id = null + usr.put_in_hands(id) + id = null else - var/obj/item/I = usr.get_active_held_item() - if(istype(I, /obj/item/card/id/prisoner)) - if(!usr.drop_item()) + var/obj/item/I = usr.is_holding_item_of_type(/obj/item/card/id/prisoner) + if(I) + if(!usr.transferItemToLoc(I, src)) return - I.forceMove(src) id = I if("set_goal") var/new_goal = input("Set the amount of points:", "Points", id.goal) as num|null diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 6ec144d257..f13cfe8c00 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -27,9 +27,8 @@ /obj/machinery/computer/med_data/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/card/id) && !scan) - if(!user.drop_item()) + if(!user.transferItemToLoc(O, src)) return - O.loc = src scan = O to_chat(user, "You insert [O].") else @@ -215,17 +214,13 @@ src.temp = null if(href_list["scan"]) if(src.scan) - if(ishuman(usr) && !usr.get_active_held_item()) - usr.put_in_hands(scan) - else - scan.loc = get_turf(src) - src.scan = null + usr.put_in_hands(scan) + scan = null else - var/obj/item/I = usr.get_active_held_item() - if(istype(I, /obj/item/card/id)) - if(!usr.drop_item()) + var/obj/item/I = usr.is_holding_item_of_type(/obj/item/card/id) + if(I) + if(!usr.transferItemToLoc(I, src)) return - I.loc = src src.scan = I else if(href_list["logout"]) src.authenticated = null diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index a7626258ae..c983bc319f 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -90,11 +90,10 @@ if(href_list["id"]) if(href_list["id"] =="insert" && !inserted_id) - var/obj/item/card/id/prisoner/I = usr.get_active_held_item() - if(istype(I)) - if(!usr.drop_item()) + var/obj/item/card/id/prisoner/I = usr.is_holding_item_of_type(/obj/item/card/id/prisoner) + if(I) + if(!usr.transferItemToLoc(I, src)) return - I.loc = src inserted_id = I else to_chat(usr, "No valid ID.") else if(inserted_id) diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 1a74c44c30..7fadcac2f2 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -37,9 +37,8 @@ /obj/machinery/computer/secure_data/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/card/id)) if(!scan) - if(!user.drop_item()) + if(!user.transferItemToLoc(O, src)) return - O.loc = src scan = O to_chat(user, "You insert [O].") else @@ -303,17 +302,13 @@ What a mess.*/ if("Confirm Identity") if(scan) - if(ishuman(usr) && !usr.get_active_held_item()) - usr.put_in_hands(scan) - else - scan.loc = get_turf(src) + usr.put_in_hands(scan) scan = null else - var/obj/item/I = usr.get_active_held_item() - if(istype(I, /obj/item/card/id)) - if(!usr.drop_item()) + var/obj/item/I = usr.is_holding_item_of_type(/obj/item/card/id) + if(I) + if(!usr.transferItemToLoc(I, src)) return - I.loc = src scan = I if("Log Out") diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 52de3830df..eb6c2902e8 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -29,21 +29,19 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E ID = rand(1,999) name = "[name] [ID]" -/obj/machinery/computer/telecrystals/uplinker/attackby(obj/item/O, mob/user, params) +/obj/machinery/computer/telecrystals/uplinker/attackby(obj/item/I, mob/user, params) if(uplinkholder) to_chat(user, "The [src] already has an uplink in it.") return - if(O.hidden_uplink) - var/obj/item/I = user.get_active_held_item() - if(!user.drop_item()) + if(I.hidden_uplink) + if(!user.transferItemToLoc(I, src)) return uplinkholder = I - I.loc = src I.add_fingerprint(user) update_icon() updateUsrDialog() else - to_chat(user, "The [O] doesn't appear to be an uplink...") + to_chat(user, "[I] doesn't appear to be an uplink...") /obj/machinery/computer/telecrystals/uplinker/update_icon() ..() diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 04c2ad6e29..bca494e8e0 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -15,6 +15,7 @@ /obj/structure/frame/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) +<<<<<<< HEAD new /obj/item/stack/sheet/metal(loc, 5) if(circuit) circuit.forceMove(loc) @@ -253,6 +254,244 @@ /obj/structure/frame/machine/deconstruct(disassembled = TRUE) +======= + new /obj/item/stack/sheet/metal(loc, 5) + if(circuit) + circuit.forceMove(loc) + circuit = null + qdel(src) + + +/obj/structure/frame/machine + name = "machine frame" + var/list/components = null + var/list/req_components = null + var/list/req_component_names = null // user-friendly names of components + +/obj/structure/frame/machine/examine(user) + ..() + if(state == 3 && req_components && req_component_names) + var/hasContent = 0 + var/requires = "It requires" + + for(var/i = 1 to req_components.len) + var/tname = req_components[i] + var/amt = req_components[tname] + if(amt == 0) + continue + var/use_and = i == req_components.len + requires += "[(hasContent ? (use_and ? ", and" : ",") : "")] [amt] [amt == 1 ? req_component_names[tname] : "[req_component_names[tname]]\s"]" + hasContent = 1 + + if(hasContent) + to_chat(user, requires + ".") + else + to_chat(user, "It does not require any more components.") + +/obj/structure/frame/machine/proc/update_namelist() + if(!req_components) + return + + req_component_names = new() + for(var/tname in req_components) + if(ispath(tname, /obj/item/stack)) + var/obj/item/stack/S = tname + var/singular_name = initial(S.singular_name) + if(singular_name) + req_component_names[tname] = singular_name + else + req_component_names[tname] = initial(S.name) + else + var/obj/O = tname + req_component_names[tname] = initial(O.name) + +/obj/structure/frame/machine/proc/get_req_components_amt() + var/amt = 0 + for(var/path in req_components) + amt += req_components[path] + return amt + +/obj/structure/frame/machine/attackby(obj/item/P, mob/user, params) + switch(state) + if(1) + if(istype(P, /obj/item/circuitboard/machine)) + to_chat(user, "The frame needs wiring first!") + return + else if(istype(P, /obj/item/circuitboard)) + to_chat(user, "This frame does not accept circuit boards of this type!") + return + if(istype(P, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = P + if(C.get_amount() >= 5) + playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) + to_chat(user, "You start to add cables to the frame...") + if(do_after(user, 20*P.toolspeed, target = src)) + if(C.get_amount() >= 5 && state == 1) + C.use(5) + to_chat(user, "You add cables to the frame.") + state = 2 + icon_state = "box_1" + else + to_chat(user, "You need five length of cable to wire the frame!") + return + if(istype(P, /obj/item/screwdriver) && !anchored) + playsound(src.loc, P.usesound, 50, 1) + user.visible_message("[user] disassembles the frame.", \ + "You start to disassemble the frame...", "You hear banging and clanking.") + if(do_after(user, 40*P.toolspeed, target = src)) + if(state == 1) + to_chat(user, "You disassemble the frame.") + var/obj/item/stack/sheet/metal/M = new (loc, 5) + M.add_fingerprint(user) + qdel(src) + return + if(istype(P, /obj/item/wrench)) + to_chat(user, "You start [anchored ? "un" : ""]securing [name]...") + playsound(src.loc, P.usesound, 75, 1) + if(do_after(user, 40*P.toolspeed, target = src)) + if(state == 1) + to_chat(user, "You [anchored ? "un" : ""]secure [name].") + anchored = !anchored + return + + if(2) + if(istype(P, /obj/item/wrench)) + to_chat(user, "You start [anchored ? "un" : ""]securing [name]...") + playsound(src.loc, P.usesound, 75, 1) + if(do_after(user, 40*P.toolspeed, target = src)) + to_chat(user, "You [anchored ? "un" : ""]secure [name].") + anchored = !anchored + return + + if(istype(P, /obj/item/circuitboard/machine)) + if(!anchored) + to_chat(user, "The frame needs to be secured first!") + return + var/obj/item/circuitboard/machine/B = P + if(!user.transferItemToLoc(B, src)) + return + playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) + to_chat(user, "You add the circuit board to the frame.") + circuit = B + icon_state = "box_2" + state = 3 + components = list() + req_components = B.req_components.Copy() + update_namelist() + return + + else if(istype(P, /obj/item/circuitboard)) + to_chat(user, "This frame does not accept circuit boards of this type!") + return + + if(istype(P, /obj/item/wirecutters)) + playsound(src.loc, P.usesound, 50, 1) + to_chat(user, "You remove the cables.") + state = 1 + icon_state = "box_0" + var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( src.loc ) + A.amount = 5 + return + + if(3) + if(istype(P, /obj/item/crowbar)) + playsound(src.loc, P.usesound, 50, 1) + state = 2 + circuit.loc = src.loc + components.Remove(circuit) + circuit = null + if(components.len == 0) + to_chat(user, "You remove the circuit board.") + else + to_chat(user, "You remove the circuit board and other components.") + for(var/atom/movable/A in components) + A.loc = src.loc + desc = initial(desc) + req_components = null + components = null + icon_state = "box_1" + return + + if(istype(P, /obj/item/screwdriver)) + var/component_check = 1 + for(var/R in req_components) + if(req_components[R] > 0) + component_check = 0 + break + if(component_check) + playsound(src.loc, P.usesound, 50, 1) + var/obj/machinery/new_machine = new src.circuit.build_path(src.loc, 1) + new_machine.on_construction() + for(var/obj/O in new_machine.component_parts) + qdel(O) + new_machine.component_parts = list() + for(var/obj/O in src) + O.loc = null + new_machine.component_parts += O + circuit.loc = null + new_machine.RefreshParts() + qdel(src) + return + + if(istype(P, /obj/item/storage/part_replacer) && P.contents.len && get_req_components_amt()) + var/obj/item/storage/part_replacer/replacer = P + var/list/added_components = list() + var/list/part_list = list() + + //Assemble a list of current parts, then sort them by their rating! + for(var/obj/item/stock_parts/co in replacer) + part_list += co + //Sort the parts. This ensures that higher tier items are applied first. + part_list = sortTim(part_list, /proc/cmp_rped_sort) + + for(var/path in req_components) + while(req_components[path] > 0 && (locate(path) in part_list)) + var/obj/item/part = (locate(path) in part_list) + added_components[part] = path + replacer.remove_from_storage(part, src) + req_components[path]-- + part_list -= part + + for(var/obj/item/stock_parts/part in added_components) + components += part + to_chat(user, "[part.name] applied.") + if(added_components.len) + replacer.play_rped_sound() + return + + if(isitem(P) && get_req_components_amt()) + for(var/I in req_components) + if(istype(P, I) && (req_components[I] > 0)) + if(istype(P, /obj/item/stack)) + var/obj/item/stack/S = P + var/used_amt = min(round(S.get_amount()), req_components[I]) + + if(used_amt && S.use(used_amt)) + var/obj/item/stack/NS = locate(S.merge_type) in components + + if(!NS) + NS = new S.merge_type(src, used_amt) + components += NS + else + NS.add(used_amt) + + req_components[I] -= used_amt + to_chat(user, "You add [P] to [src].") + return + if(!user.transferItemToLoc(P, src)) + break + to_chat(user, "You add [P] to [src].") + components += P + req_components[I]-- + return 1 + to_chat(user, "You cannot add that to the machine!") + return 0 + if(user.a_intent == INTENT_HARM) + return ..() + + +/obj/structure/frame/machine/deconstruct(disassembled = TRUE) +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) if(!(flags_1 & NODECONSTRUCT_1)) if(state >= 2) new /obj/item/stack/cable_coil(loc , 5) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index e7fa7447b5..e00f1c9b9e 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1170,10 +1170,9 @@ to_chat(user, "The maintenance panel is destroyed!") return to_chat(user, "You apply [C]. Next time someone opens the door, it will explode.") - user.drop_item() panel_open = FALSE update_icon() - C.forceMove(src) + user.transferItemToLoc(C, src, TRUE) charge = C else if(istype(C, /obj/item/paper) || istype(C, /obj/item/photo)) if(note) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 95adf12875..542989fa15 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -426,7 +426,6 @@ return if(constructionStep != CONSTRUCTION_NOCIRCUIT) return - user.drop_item() qdel(C) user.visible_message("[user] adds a circuit to [src].", \ "You insert and secure [C].") diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index f8186a8a51..9bf40542a7 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -63,10 +63,9 @@ else if (istype(W, /obj/item/device/assembly/flash/handheld)) if (!bulb) - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return user.visible_message("[user] installs [W] into [src].", "You install [W] into [src].") - W.forceMove(src) bulb = W power_change() else diff --git a/code/game/machinery/gulag_item_reclaimer.dm b/code/game/machinery/gulag_item_reclaimer.dm index ffa903c3e9..571899d860 100644 --- a/code/game/machinery/gulag_item_reclaimer.dm +++ b/code/game/machinery/gulag_item_reclaimer.dm @@ -33,9 +33,8 @@ /obj/machinery/gulag_item_reclaimer/attackby(obj/item/I, mob/user) if(istype(I, /obj/item/card/id/prisoner)) if(!inserted_id) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - I.forceMove(src) inserted_id = I to_chat(user, "You insert [I].") return @@ -82,18 +81,13 @@ switch(action) if("handle_id") if(inserted_id) - if(!usr.get_active_held_item()) - usr.put_in_hands(inserted_id) - inserted_id = null - else - inserted_id.forceMove(get_turf(src)) - inserted_id = null + usr.put_in_hands(inserted_id) + inserted_id = null else - var/obj/item/I = usr.get_active_held_item() - if(istype(I, /obj/item/card/id/prisoner)) - if(!usr.drop_item()) + var/obj/item/I = usr.is_holding_item_of_type(/obj/item/card/id/prisoner) + if(I) + if(!usr.transferItemToLoc(I, src)) return - I.forceMove(src) inserted_id = I if("release_items") var/mob/M = locate(params["mobref"]) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index c5c0200493..23048caf67 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -95,10 +95,8 @@ if(beaker) to_chat(user, "There is already a reagent container loaded!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return - - W.forceMove(src) beaker = W to_chat(user, "You attach [W] to [src].") update_icon() diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 204ae83c9d..863eb3286b 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -786,11 +786,9 @@ GLOBAL_LIST_EMPTY(allCasters) else qdel(photo) photo = null - if(istype(user.get_active_held_item(), /obj/item/photo)) - photo = user.get_active_held_item() - if(!user.drop_item()) - return - photo.loc = src + photo = user.is_holding_item_of_type(/obj/item/photo) + if(photo && !user.transferItemToLoc(photo, src)) + photo = null if(issilicon(user)) var/list/nametemp = list() var/find diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index cedb94b7b3..26559c5ef9 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -71,8 +71,6 @@ add_fingerprint(user) if (istype(W, /obj/item/pipe) || istype(W, /obj/item/pipe_meter)) to_chat(usr, "You put [W] back into [src].") - if(!user.drop_item()) - return qdel(W) return else if (istype(W, /obj/item/wrench)) diff --git a/code/game/machinery/porta_turret/portable_turret_construct.dm b/code/game/machinery/porta_turret/portable_turret_construct.dm index 7eace08636..ab16ee67ed 100644 --- a/code/game/machinery/porta_turret/portable_turret_construct.dm +++ b/code/game/machinery/porta_turret/portable_turret_construct.dm @@ -84,9 +84,8 @@ if(PTURRET_INTERNAL_ARMOUR_ON) if(istype(I, /obj/item/gun/energy)) //the gun installation part var/obj/item/gun/energy/E = I - if(!user.drop_item()) + if(!user.transferItemToLoc(E, src)) return - E.forceMove(src) installed_gun = E to_chat(user, "You add [I] to the turret.") build_step = PTURRET_GUN_EQUIPPED @@ -101,7 +100,7 @@ if(PTURRET_GUN_EQUIPPED) if(isprox(I)) build_step = PTURRET_SENSORS_ON - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(I)) return to_chat(user, "You add the proximity sensor to the turret.") qdel(I) diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 4a72fa90c6..d373e1267a 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -50,9 +50,8 @@ to_chat(user, "Your gun has no external power connector.") return 1 - if(!user.drop_item()) + if(!user.transferItemToLoc(G, src)) return 1 - G.loc = src charging = G use_power = ACTIVE_POWER_USE update_icon(scan = TRUE) diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index 957f533a29..a9162b85f8 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -83,16 +83,15 @@ if(istype(I, /obj/item/coin)) var/obj/item/coin/C = I if(prob(2)) - if(!user.drop_item()) + if(!user.transferItemToLoc(C, drop_location())) return - C.loc = loc C.throw_at(user, 3, 10) if(prob(10)) balance = max(balance - SPIN_PRICE, 0) to_chat(user, "[src] spits your coin back out!") else - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(C)) return to_chat(user, "You insert a [C.cmineral] coin into [src]'s slot!") balance += C.value diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 886798156e..b45b393ab2 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -140,18 +140,13 @@ if(cell) to_chat(user, "There is already a power cell inside!") return - else - // insert cell - var/obj/item/stock_parts/cell/C = usr.get_active_held_item() - if(istype(C)) - if(!user.drop_item()) - return - cell = C - C.loc = src - C.add_fingerprint(usr) + else if(!user.transferItemToLoc(I, src)) + return + cell = I + I.add_fingerprint(usr) - user.visible_message("\The [user] inserts a power cell into \the [src].", "You insert the power cell into \the [src].") - SStgui.update_uis(src) + user.visible_message("\The [user] inserts a power cell into \the [src].", "You insert the power cell into \the [src].") + SStgui.update_uis(src) else to_chat(user, "The hatch must be open to insert a power cell!") return diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 7c51c383fa..0854e63e5b 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -298,32 +298,31 @@ if(suit) to_chat(user, "The unit already contains a suit!.") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return suit = I else if(istype(I, /obj/item/clothing/head/helmet)) if(helmet) to_chat(user, "The unit already contains a helmet!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return helmet = I else if(istype(I, /obj/item/clothing/mask)) if(mask) to_chat(user, "The unit already contains a mask!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return mask = I else if(storage) to_chat(user, "The auxiliary storage compartment is full!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return storage = I - I.loc = src visible_message("[user] inserts [I] into [src]", "You load [I] into [src].") update_icon() return diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index efb872b766..d279f2849f 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -150,11 +150,10 @@ to_chat(user, "The cover is screwed on, it won't pry off!") else if(istype(I, /obj/item/bombcore)) if(!payload) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return payload = I to_chat(user, "You place [payload] into [src].") - payload.loc = src else to_chat(user, "[payload] is already loaded into [src]! You'll have to remove it first.") else if(istype(I, /obj/item/weldingtool)) @@ -463,11 +462,10 @@ return else if(istype(I, /obj/item/reagent_containers/glass/beaker) || istype(I, /obj/item/reagent_containers/glass/bottle)) if(beakers.len < max_beakers) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return beakers += I to_chat(user, "You load [src] with [I].") - I.loc = src else to_chat(user, "The [I] wont fit! The [src] can only hold up to [max_beakers] containers.") return diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index d4a06d0580..bf08e98992 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -189,9 +189,8 @@ var/obj/item/reagent_containers/food/snacks/S = W if(!S.junkiness) if(!iscompartmentfull(user)) - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return - W.loc = src food_load(W) to_chat(user, "You insert [W] into [src]'s chef compartment.") else @@ -279,9 +278,8 @@ if(!premium.len) to_chat(user, "[src] doesn't have a coin slot.") return - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return - W.loc = src coin = W to_chat(user, "You insert [W] into [src].") return diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index 7091bfd72a..a75294c28f 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -161,7 +161,7 @@ var/obj/item/mecha_parts/mecha_equipment/E = W spawn() if(E.can_attach(src)) - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(W)) return E.attach(src) user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src].") @@ -226,11 +226,10 @@ else if(istype(W, /obj/item/stock_parts/cell)) if(state==4) if(!cell) - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return var/obj/item/stock_parts/cell/C = W to_chat(user, "You install the powercell.") - C.forceMove(src) cell = C log_message("Powercell installed") else diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index 3f32b18178..41ba67d616 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -128,7 +128,7 @@ /obj/effect/particle_effect/smoke/bad/smoke_mob(mob/living/carbon/M) if(..()) - M.drop_item() + M.drop_all_held_items() M.adjustOxyLoss(1) M.emote("cough") return 1 @@ -205,7 +205,6 @@ /obj/effect/particle_effect/smoke/sleeping/smoke_mob(mob/living/carbon/M) if(..()) - M.drop_item() M.Sleeping(200) M.emote("cough") return 1 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 362148c801..76e1468751 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -531,7 +531,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) to_chat(M, "You become nearsighted!") if(prob(50)) if(M.stat != DEAD) - if(M.drop_item()) + if(M.drop_all_held_items()) to_chat(M, "You drop what you're holding and clutch at your eyes!") M.adjust_blurriness(10) M.Unconscious(20) diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index 50b0f4e7e6..e7dfc96ab5 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/item/restraints breakouttime = 600 @@ -369,4 +370,378 @@ var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(hit_atom)) B.Crossed(hit_atom) qdel(src) - ..() \ No newline at end of file + ..() +======= +/obj/item/restraints + breakouttime = 600 + +//Handcuffs + +/obj/item/restraints/handcuffs + name = "handcuffs" + desc = "Use this to keep prisoners in line." + gender = PLURAL + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "handcuff" + lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + throwforce = 0 + w_class = WEIGHT_CLASS_SMALL + throw_speed = 3 + throw_range = 5 + materials = list(MAT_METAL=500) + origin_tech = "engineering=3;combat=3" + breakouttime = 600 //Deciseconds = 60s = 1 minute + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) + var/cuffsound = 'sound/weapons/handcuffs.ogg' + var/trashtype = null //for disposable cuffs + +/obj/item/restraints/handcuffs/attack(mob/living/carbon/C, mob/living/carbon/human/user) + if(!istype(C)) + return + if(user.disabilities & CLUMSY && prob(50)) + to_chat(user, "Uh... how do those things work?!") + apply_cuffs(user,user) + return + + // chance of monkey retaliation + if(ismonkey(C) && prob(MONKEY_CUFF_RETALIATION_PROB)) + var/mob/living/carbon/monkey/M + M = C + M.retaliate(user) + + if(!C.handcuffed) + if(C.get_num_arms() >= 2 || C.get_arm_ignore()) + C.visible_message("[user] is trying to put [src.name] on [C]!", \ + "[user] is trying to put [src.name] on [C]!") + + playsound(loc, cuffsound, 30, 1, -2) + if(do_mob(user, C, 30) && (C.get_num_arms() >= 2 || C.get_arm_ignore())) + apply_cuffs(C,user) + to_chat(user, "You handcuff [C].") + SSblackbox.add_details("handcuffs","[type]") + + add_logs(user, C, "handcuffed") + else + to_chat(user, "You fail to handcuff [C]!") + else + to_chat(user, "[C] doesn't have two hands...") + +/obj/item/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user, var/dispense = 0) + if(target.handcuffed) + return + + if(!user.temporarilyRemoveItemFromInventory(src) && !dispense) + return + + var/obj/item/restraints/handcuffs/cuffs = src + if(trashtype) + cuffs = new trashtype() + else if(dispense) + cuffs = new type() + + cuffs.forceMove(target) + target.handcuffed = cuffs + + target.update_handcuffed() + if(trashtype && !dispense) + qdel(src) + return + +/obj/item/restraints/handcuffs/sinew + name = "sinew restraints" + desc = "A pair of restraints fashioned from long strands of flesh." + icon = 'icons/obj/mining.dmi' + icon_state = "sinewcuff" + item_state = "sinewcuff" + breakouttime = 300 //Deciseconds = 30s + cuffsound = 'sound/weapons/cablecuff.ogg' + +/obj/item/restraints/handcuffs/cable + name = "cable restraints" + desc = "Looks like some cables tied together. Could be used to tie something up." + icon_state = "cuff_red" + item_state = "coil_red" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + materials = list(MAT_METAL=150, MAT_GLASS=75) + origin_tech = "engineering=2" + breakouttime = 300 //Deciseconds = 30s + cuffsound = 'sound/weapons/cablecuff.ogg' + var/datum/robot_energy_storage/wirestorage = null + +/obj/item/restraints/handcuffs/cable/attack(mob/living/carbon/C, mob/living/carbon/human/user) + if(!istype(C)) + return + if(wirestorage && wirestorage.energy < 15) + to_chat(user, "You need at least 15 wire to restrain [C]!") + return + return ..() + +/obj/item/restraints/handcuffs/cable/apply_cuffs(mob/living/carbon/target, mob/user, var/dispense = 0) + if(wirestorage) + if(!wirestorage.use_charge(15)) + to_chat(user, "You need at least 15 wire to restrain [target]!") + return + return ..(target, user, 1) + + return ..() + +/obj/item/restraints/handcuffs/cable/red + icon_state = "cuff_red" + item_state = "coil_red" + +/obj/item/restraints/handcuffs/cable/yellow + icon_state = "cuff_yellow" + item_state = "coil_yellow" + +/obj/item/restraints/handcuffs/cable/blue + icon_state = "cuff_blue" + item_state = "coil_blue" + +/obj/item/restraints/handcuffs/cable/green + icon_state = "cuff_green" + item_state = "coil_green" + +/obj/item/restraints/handcuffs/cable/pink + icon_state = "cuff_pink" + item_state = "coil_pink" + +/obj/item/restraints/handcuffs/cable/orange + icon_state = "cuff_orange" + item_state = "coil_orange" + +/obj/item/restraints/handcuffs/cable/cyan + icon_state = "cuff_cyan" + item_state = "coil_cyan" + +/obj/item/restraints/handcuffs/cable/white + icon_state = "cuff_white" + item_state = "coil_white" + +/obj/item/restraints/handcuffs/alien + icon_state = "handcuffAlien" + +/obj/item/restraints/handcuffs/fake + name = "fake handcuffs" + desc = "Fake handcuffs meant for gag purposes." + breakouttime = 10 //Deciseconds = 1s + +/obj/item/restraints/handcuffs/fake/kinky + name = "kinky handcuffs" + desc = "Fake handcuffs meant for erotic roleplay." + icon_state = "handcuffGag" + +/obj/item/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params) + ..() + if(istype(I, /obj/item/stack/rods)) + var/obj/item/stack/rods/R = I + if (R.use(1)) + var/obj/item/wirerod/W = new /obj/item/wirerod + remove_item_from_storage(user) + user.put_in_hands(W) + to_chat(user, "You wrap the cable restraint around the top of the rod.") + qdel(src) + else + to_chat(user, "You need one rod to make a wired rod!") + return + else if(istype(I, /obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/M = I + if(M.get_amount() < 6) + to_chat(user, "You need at least six metal sheets to make good enough weights!") + return + to_chat(user, "You begin to apply [I] to [src]...") + if(do_after(user, 35, target = src)) + if(M.get_amount() < 6 || !M) + return + var/obj/item/restraints/legcuffs/bola/S = new /obj/item/restraints/legcuffs/bola + M.use(6) + user.put_in_hands(S) + to_chat(user, "You make some weights out of [I] and tie them to [src].") + remove_item_from_storage(user) + qdel(src) + else + return ..() + +/obj/item/restraints/handcuffs/cable/zipties/cyborg/attack(mob/living/carbon/C, mob/user) + if(iscyborg(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/restraints/handcuffs/cable/zipties/used(C) + C.update_handcuffed() + to_chat(user, "You handcuff [C].") + add_logs(user, C, "handcuffed") + else + to_chat(user, "You fail to handcuff [C]!") + +/obj/item/restraints/handcuffs/cable/zipties + name = "zipties" + desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use." + icon_state = "cuff_white" + lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' + materials = list() + breakouttime = 450 //Deciseconds = 45s + trashtype = /obj/item/restraints/handcuffs/cable/zipties/used + +/obj/item/restraints/handcuffs/cable/zipties/used + desc = "A pair of broken zipties." + icon_state = "cuff_white_used" + item_state = "cuff_white" + +/obj/item/restraints/handcuffs/cable/zipties/used/attack() + return + + +//Legcuffs + +/obj/item/restraints/legcuffs + name = "leg cuffs" + desc = "Use this to keep prisoners in line." + gender = PLURAL + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "handcuff" + lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' + flags_1 = CONDUCT_1 + throwforce = 0 + w_class = WEIGHT_CLASS_NORMAL + origin_tech = "engineering=3;combat=3" + slowdown = 7 + breakouttime = 300 //Deciseconds = 30s = 0.5 minute + +/obj/item/restraints/legcuffs/beartrap + name = "bear trap" + throw_speed = 1 + throw_range = 1 + icon_state = "beartrap" + desc = "A trap used to catch bears and other legged creatures." + origin_tech = "engineering=4" + var/armed = 0 + var/trap_damage = 20 + +/obj/item/restraints/legcuffs/beartrap/Initialize() + . = ..() + icon_state = "[initial(icon_state)][armed]" + +/obj/item/restraints/legcuffs/beartrap/suicide_act(mob/user) + user.visible_message("[user] is sticking [user.p_their()] head in the [src.name]! It looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/restraints/legcuffs/beartrap/attack_self(mob/user) + ..() + if(ishuman(user) && !user.stat && !user.restrained()) + armed = !armed + icon_state = "[initial(icon_state)][armed]" + to_chat(user, "[src] is now [armed ? "armed" : "disarmed"]") + +/obj/item/restraints/legcuffs/beartrap/Crossed(AM as mob|obj) + if(armed && isturf(src.loc)) + if(isliving(AM)) + var/mob/living/L = AM + var/snap = 0 + var/def_zone = "chest" + if(iscarbon(L)) + var/mob/living/carbon/C = L + snap = 1 + if(!C.lying) + def_zone = pick("l_leg", "r_leg") + if(!C.legcuffed && C.get_num_legs() >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs. + C.legcuffed = src + src.loc = C + C.update_inv_legcuffed() + SSblackbox.add_details("handcuffs","[type]") + else if(isanimal(L)) + var/mob/living/simple_animal/SA = L + if(SA.mob_size > MOB_SIZE_TINY) + snap = 1 + if(L.movement_type & FLYING) + snap = 0 + if(snap) + armed = 0 + icon_state = "[initial(icon_state)][armed]" + playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) + L.visible_message("[L] triggers \the [src].", \ + "You trigger \the [src]!") + L.apply_damage(trap_damage,BRUTE, def_zone) + ..() + +/obj/item/restraints/legcuffs/beartrap/energy + name = "energy snare" + armed = 1 + icon_state = "e_snare" + trap_damage = 0 + flags_1 = DROPDEL_1 + +/obj/item/restraints/legcuffs/beartrap/energy/New() + ..() + addtimer(CALLBACK(src, .proc/dissipate), 100) + +/obj/item/restraints/legcuffs/beartrap/energy/proc/dissipate() + if(!ismob(loc)) + do_sparks(1, TRUE, src) + qdel(src) + +/obj/item/restraints/legcuffs/beartrap/energy/attack_hand(mob/user) + Crossed(user) //honk + +/obj/item/restraints/legcuffs/beartrap/energy/cyborg + breakouttime = 20 // Cyborgs shouldn't have a strong restraint + +/obj/item/restraints/legcuffs/bola + name = "bola" + desc = "A restraining device designed to be thrown at the target. Upon connecting with said target, it will wrap around their legs, making it difficult for them to move quickly." + icon_state = "bola" + breakouttime = 35//easy to apply, easy to break out of + gender = NEUTER + origin_tech = "engineering=3;combat=1" + var/knockdown = 0 + +/obj/item/restraints/legcuffs/bola/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) + if(!..()) + return + playsound(src.loc,'sound/weapons/bolathrow.ogg', 75, 1) + +/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom) + if(..() || !iscarbon(hit_atom))//if it gets caught or the target can't be cuffed, + return//abort + var/mob/living/carbon/C = hit_atom + if(!C.legcuffed && C.get_num_legs() >= 2) + visible_message("\The [src] ensnares [C]!") + C.legcuffed = src + src.loc = C + C.update_inv_legcuffed() + SSblackbox.add_details("handcuffs","[type]") + to_chat(C, "\The [src] ensnares you!") + C.Knockdown(knockdown) + +/obj/item/restraints/legcuffs/bola/tactical//traitor variant + name = "reinforced bola" + desc = "A strong bola, made with a long steel chain. It looks heavy, enough so that it could trip somebody." + icon_state = "bola_r" + breakouttime = 70 + origin_tech = "engineering=4;combat=3" + knockdown = 20 + +/obj/item/restraints/legcuffs/bola/energy //For Security + name = "energy bola" + desc = "A specialized hard-light bola designed to ensnare fleeing criminals and aid in arrests." + icon_state = "ebola" + hitsound = 'sound/weapons/taserhit.ogg' + w_class = WEIGHT_CLASS_SMALL + breakouttime = 60 + +/obj/item/restraints/legcuffs/bola/energy/throw_impact(atom/hit_atom) + if(iscarbon(hit_atom)) + var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(hit_atom)) + B.Crossed(hit_atom) + qdel(src) + ..() +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index d727c517bd..cff958926d 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -233,7 +233,7 @@ /obj/item/melee/supermatter_sword/afterattack(target, mob/user, proximity_flag) if(user && target == user) - user.drop_item() + user.dropItemToGround(src) if(proximity_flag) consume_everything(target) ..() @@ -243,7 +243,7 @@ if(ismob(target)) var/mob/M if(src.loc == M) - M.drop_item() + M.dropItemToGround(src) consume_everything(target) /obj/item/melee/supermatter_sword/pickup(user) @@ -267,7 +267,7 @@ /obj/item/melee/supermatter_sword/suicide_act(mob/user) user.visible_message("[user] touches [src]'s blade. It looks like [user.p_theyre()] tired of waiting for the radiation to kill [user.p_them()]!") - user.drop_item() + user.dropItemToGround(src, TRUE) shard.CollidedWith(user) /obj/item/melee/supermatter_sword/proc/consume_everything(target) diff --git a/code/game/objects/items/paiwire.dm b/code/game/objects/items/paiwire.dm index e0900ba50d..6b6b3101c6 100644 --- a/code/game/objects/items/paiwire.dm +++ b/code/game/objects/items/paiwire.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/item/pai_cable desc = "A flexible coated cable with a universal jack on one end." name = "data cable" @@ -11,4 +12,18 @@ return user.visible_message("[user] inserts [src] into a data port on [M].", "You insert [src] into a data port on [M].", "You hear the satisfying click of a wire jack fastening into place.") src.loc = M +======= +/obj/item/pai_cable + desc = "A flexible coated cable with a universal jack on one end." + name = "data cable" + icon = 'icons/obj/power.dmi' + icon_state = "wire1" + flags_1 = NOBLUDGEON_1 + var/obj/machinery/machine + +/obj/item/pai_cable/proc/plugin(obj/machinery/M, mob/living/user) + if(!user.transferItemToLoc(src, M)) + return + user.visible_message("[user] inserts [src] into a data port on [M].", "You insert [src] into a data port on [M].", "You hear the satisfying click of a wire jack fastening into place.") +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) machine = M \ No newline at end of file diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index 6cb26b3144..9400303b84 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -122,7 +122,7 @@ return if(user.disabilities & CLUMSY && prob(75) && clumsyCheck) user.visible_message("[user] loses their grip on [src], causing it to go off!", "[src] slips out of your hands and goes off!") - user.drop_item() + user.dropItemToGround(src, TRUE) if(prob(10)) target = get_turf(user) else diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 3d7b4a9603..f47c5d30eb 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -254,7 +254,7 @@ if(!isturf(loc)) to_chat(user, "You cannot install[M], the frame has to be standing on the ground to be perfectly precise!") return - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(M)) to_chat(user, "[M] is stuck to your hand!") return qdel(M) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 3e9231f562..2428524383 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -48,7 +48,7 @@ /obj/item/storage/backpack/holding/suicide_act(mob/living/user) user.visible_message("[user] is jumping into [src]! It looks like [user.p_theyre()] trying to commit suicide.") - user.drop_item() + user.dropItemToGround(src, TRUE) user.Stun(100, ignore_canstun = TRUE) sleep(20) playsound(src, "rustle", 50, 1, -5) diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index 489f1c6bf0..313988b7d4 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -57,11 +57,9 @@ close_all() to_chat(user, "You fold [src] flat.") - var/obj/item/I = new foldable(get_turf(src)) - user.drop_item() - user.put_in_hands(I) - user.update_inv_hands() + var/obj/item/I = new foldable qdel(src) + user.put_in_hands(I) /obj/item/storage/box/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/stack/packageWrap)) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index a683902a6c..85f5de7526 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1022,8 +1022,8 @@ throwforce = 12 //pelt your enemies to death with lumps of snow /obj/item/toy/snowball/afterattack(atom/target as mob|obj|turf|area, mob/user) - user.drop_item() - src.throw_at(target, throw_range, throw_speed) + if(user.dropItemToGround(src)) + throw_at(target, throw_range, throw_speed) /obj/item/toy/snowball/throw_impact(atom/hit_atom) if(!..()) @@ -1041,8 +1041,8 @@ w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets /obj/item/toy/beach_ball/afterattack(atom/target as mob|obj|turf|area, mob/user) - user.drop_item() - src.throw_at(target, throw_range, throw_speed) + if(user.dropItemToGround(src)) + throw_at(target, throw_range, throw_speed) /* * Xenomorph action figure diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index b1103ac1da..5504c1a8fc 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -20,6 +20,7 @@ /obj/structure/Destroy() GLOB.cameranet.updateVisibility(src) +<<<<<<< HEAD if(smooth) queue_smooth_neighbors(src) return ..() @@ -61,6 +62,49 @@ /obj/structure/proc/do_climb(atom/movable/A) if(climbable) +======= + if(smooth) + queue_smooth_neighbors(src) + return ..() + +/obj/structure/attack_hand(mob/user) + . = ..() + add_fingerprint(user) + if(structureclimber && structureclimber != user) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) + structureclimber.Knockdown(40) + structureclimber.visible_message("[structureclimber.name] has been knocked off the [src]", "You're knocked off the [src]!", "You see [structureclimber.name] get knocked off the [src]") + interact(user) + +/obj/structure/interact(mob/user) + ui_interact(user) + +/obj/structure/ui_act(action, params) + ..() + add_fingerprint(usr) + +/obj/structure/MouseDrop_T(atom/movable/O, mob/user) + . = ..() + if(!climbable) + return + if(user == O && iscarbon(O)) + if(user.canmove) + climb_structure(user) + return + if ((!( istype(O, /obj/item) ) || user.get_active_held_item() != O)) + return + if(iscyborg(user)) + return + if(!user.drop_all_held_items()) + return + if (O.loc != src.loc) + step(O, get_dir(O, src)) + return + +/obj/structure/proc/do_climb(atom/movable/A) + if(climbable) +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) density = FALSE . = step(A,get_dir(A,src.loc)) density = TRUE diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 9d6985c620..606b10da0a 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -58,14 +58,14 @@ playsound(src.loc, W.usesound, 50, 1) deconstruct() else if(istype(W, /obj/item/assembly/shock_kit)) - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(W)) return var/obj/item/assembly/shock_kit/SK = W var/obj/structure/chair/e_chair/E = new /obj/structure/chair/e_chair(src.loc) playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) E.setDir(dir) E.part = SK - SK.loc = E + SK.forceMove(E) SK.master = E qdel(src) else diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 68de701967..f6e2023943 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -27,7 +27,8 @@ LINEN BINS ..() /obj/item/bedsheet/attack_self(mob/user) - user.drop_item() + if(!user.dropItemToGround(src)) + return if(layer == initial(layer)) layer = ABOVE_MOB_LAYER to_chat(user, "You cover yourself with [src].") @@ -275,18 +276,16 @@ LINEN BINS /obj/structure/bedsheetbin/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/bedsheet)) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - I.loc = src sheets.Add(I) amount++ to_chat(user, "You put [I] in [src].") update_icon() else if(amount && !hidden && I.w_class < WEIGHT_CLASS_BULKY) //make sure there's sheets to hide it among, make sure nothing else is hidden in there. - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) to_chat(user, "\The [I] is stuck to your hand, you cannot hide it among the sheets!") return - I.loc = src hidden = I to_chat(user, "You hide [I] among the sheets.") diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 3d77be1bb5..4e3056f39a 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -229,8 +229,7 @@ "You cut \the [src] apart with \the [W].") deconstruct(TRUE) return 0 - if(user.drop_item()) // so we put in unlit welder too - W.forceMove(loc) + if(user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too return 1 else if(istype(W, /obj/item/weldingtool) && can_weld_shut) var/obj/item/weldingtool/WT = W diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index a5173a5f80..448b358c1a 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -602,10 +602,9 @@ if(do_after(user, 40, target = src)) if( src.state != 1 ) return - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return - W.loc = src to_chat(user, "You install the airlock electronics.") src.state = 2 src.name = "near finished airlock assembly" diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index e61e1a1870..0a3574b1a6 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -54,9 +54,8 @@ return if(istype(I, /obj/item/extinguisher)) if(!stored_extinguisher && opened) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - contents += I stored_extinguisher = I to_chat(user, "You place [I] in [src].") update_icon() diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm index 803c4d4627..afcd855caf 100644 --- a/code/game/objects/structures/fireaxe.dm +++ b/code/game/objects/structures/fireaxe.dm @@ -53,10 +53,9 @@ if(F.wielded) to_chat(user, "Unwield the [F.name] first.") return - if(!user.drop_item()) + if(!user.transferItemToLoc(F, src)) return fireaxe = F - F.forceMove(src) to_chat(user, "You place the [F.name] back in the [name].") update_icon() return diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 3d7e9be21a..b3b6022834 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -259,9 +259,8 @@ else if(istype(W, /obj/item/pipe)) var/obj/item/pipe/P = W if (P.pipe_type in list(0, 1, 5)) //simple pipes, simple bends, and simple manifolds. - if(!user.drop_item()) + if(!user.transferItemToLoc(P, drop_location())) return - P.loc = src.loc to_chat(user, "You fit the pipe into \the [src].") else return ..() diff --git a/code/game/objects/structures/guncase.dm b/code/game/objects/structures/guncase.dm index 24a6bd4ceb..ac6a69ed93 100644 --- a/code/game/objects/structures/guncase.dm +++ b/code/game/objects/structures/guncase.dm @@ -39,9 +39,8 @@ return if(istype(I, gun_category) && open) if(LAZYLEN(contents) < capacity) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - I.forceMove(src) to_chat(user, "You place [I] in [src].") update_icon() else diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 58db777abe..747e0b3317 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -32,9 +32,8 @@ return 1 /obj/structure/janitorialcart/proc/put_in_cart(obj/item/I, mob/user) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - I.loc = src updateUsrDialog() to_chat(user, "You put [I] into [src].") return diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index dc4ffe37b6..0ba290ac31 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -159,10 +159,9 @@ FLOOR SAFES . = 1 //no afterattack if(I.w_class + space <= maxspace) space += I.w_class - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) to_chat(user, "\The [I] is stuck to your hand, you cannot put it in the safe!") return - I.forceMove(src) to_chat(user, "You put [I] in [src].") updateUsrDialog() return diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index afa74cbb5e..fb46dd45de 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -104,7 +104,6 @@ "You attach the sign to [T].") playsound(T, 'sound/items/deconstruct.ogg', 50, 1) new sign_path(T) - user.drop_item() qdel(src) else return ..() diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index c54661066a..a3dfe2b669 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -131,8 +131,7 @@ // If the tray IS empty, continue on (tray will be placed on the table like other items) if(user.a_intent != INTENT_HARM && !(I.flags_1 & ABSTRACT_1)) - if(user.drop_item()) - I.Move(loc) + if(user.transferItemToLoc(I, drop_location())) var/list/click_params = params2list(params) //Center the icon where the user clicked. if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) @@ -439,7 +438,7 @@ /obj/structure/rack/MouseDrop_T(obj/O, mob/user) if ((!( istype(O, /obj/item) ) || user.get_active_held_item() != O)) return - if(!user.drop_item()) + if(!user.dropItemToGround(O)) return if(O.loc != src.loc) step(O, get_dir(O, src)) @@ -452,8 +451,7 @@ return if(user.a_intent == INTENT_HARM) return ..() - if(user.drop_item()) - W.Move(loc) + if(user.transferItemToLoc(W, drop_location())) return 1 /obj/structure/rack/attack_paw(mob/living/user) @@ -516,7 +514,7 @@ building = TRUE to_chat(user, "You start constructing a rack...") if(do_after(user, 50, target = user, progress=TRUE)) - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(src)) return var/obj/structure/rack/R = new /obj/structure/rack(user.loc) user.visible_message("[user] assembles \a [R].\ diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 1699010309..076f39b85f 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -62,9 +62,8 @@ to_chat(user, "[src] can't hold any more of [I].") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - I.loc = src to_chat(user, "You put [I] in [src].") update_icon() diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index dc6d350c91..b70326b893 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -5,6 +5,7 @@ icon_state = "target_stake" density = TRUE flags_1 = CONDUCT_1 +<<<<<<< HEAD var/obj/item/target/pinned_target /obj/structure/target_stake/Destroy() @@ -52,4 +53,52 @@ if(pinned_target) pinned_target.bullet_act(P) else +======= + var/obj/item/target/pinned_target + +/obj/structure/target_stake/Destroy() + if(pinned_target) + pinned_target.nullPinnedLoc() + return ..() + +/obj/structure/target_stake/proc/nullPinnedTarget() + pinned_target = null + +/obj/structure/target_stake/Move() + ..() + if(pinned_target) + pinned_target.loc = loc + +/obj/structure/target_stake/attackby(obj/item/target/T, mob/user) + if(pinned_target) + return + if(istype(T) && user.transferItemToLoc(T, drop_location())) + pinned_target = T + T.pinnedLoc = src + T.density = TRUE + T.layer = OBJ_LAYER + 0.01 + to_chat(user, "You slide the target into the stake.") + +/obj/structure/target_stake/attack_hand(mob/user) + if(pinned_target) + removeTarget(user) + +/obj/structure/target_stake/proc/removeTarget(mob/user) + pinned_target.layer = OBJ_LAYER + pinned_target.loc = user.loc + pinned_target.nullPinnedLoc() + nullPinnedTarget() + if(ishuman(user)) + if(!user.get_active_held_item()) + user.put_in_hands(pinned_target) + to_chat(user, "You take the target out of the stake.") + else + pinned_target.loc = get_turf(user) + to_chat(user, "You take the target out of the stake.") + +/obj/structure/target_stake/bullet_act(obj/item/projectile/P) + if(pinned_target) + pinned_target.bullet_act(P) + else +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) ..() \ No newline at end of file diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index a475bb7069..18d8b8f7f0 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -88,10 +88,9 @@ if(w_items + I.w_class > WEIGHT_CLASS_HUGE) to_chat(user, "The cistern is full!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) to_chat(user, "\The [I] is stuck to your hand, you cannot put it in the cistern!") return - I.loc = src w_items += I.w_class to_chat(user, "You carefully place [I] into the cistern.") @@ -173,10 +172,9 @@ if(I.w_class > 1) to_chat(user, "[I] is too large for the drain enclosure.") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) to_chat(user, "\[I] is stuck to your hand, you cannot put it in the drain enclosure!") return - I.forceMove(src) hiddenitem = I to_chat(user, "You place [I] into the drain enclosure.") diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index c4a0d48dde..cb22c2a8c1 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -208,11 +208,10 @@ //Adding airlock electronics for access. Step 6 complete. else if(istype(W, /obj/item/electronics/airlock)) - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return playsound(loc, W.usesound, 100, 1) user.visible_message("[user] installs the electronics into the airlock assembly.", "You start to install electronics into the airlock assembly...") - W.loc = src if(do_after(user, 40, target = src)) if(!src || electronics) diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm index 0dd3673f6a..f0fb7c4448 100644 --- a/code/game/turfs/simulated/floor/light_floor.dm +++ b/code/game/turfs/simulated/floor/light_floor.dm @@ -72,7 +72,7 @@ if(..()) return if(istype(C, /obj/item/light/bulb)) //only for light tiles - if(state && user.drop_item()) + if(state && user.temporarilyRemoveItemFromInventory(C)) qdel(C) state = 0 //fixing it by bashing it with a light bulb, fun eh? update_icon() diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index 0dcd676213..ebd2214aba 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -89,22 +89,20 @@ var/mob/M = user if(isigniter(S.a_left) == isigniter(S.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it return - if(!M.drop_item()) //Remove the assembly from your hands + if(!M.temporarilyRemoveItemFromInventory(src)) //Remove the assembly from your hands return - var/obj/item/device/onetankbomb/R = new /obj/item/device/onetankbomb(loc) + var/obj/item/device/onetankbomb/R = new - M.temporarilyRemoveItemFromInventory(src, TRUE) //Remove the tank from your character,in case you were holding it - if(!M.put_in_hands(R)) //Equips the bomb if possible, or puts it on the floor. - forceMove(get_turf(M)) + M.put_in_hands(R) //Equips the bomb if possible, or puts it on the floor. R.bombassembly = S //Tell the bomb about its assembly part S.master = R //Tell the assembly about its new owner - S.loc = R //Move the assembly out of the fucking way + S.forceMove(R) //Move the assembly out of the fucking way R.bombtank = src //Same for tank master = R - loc = R + forceMove(R) R.update_icon() return diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index e368fdde92..efc6a8e899 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -276,10 +276,9 @@ if(beaker) to_chat(user, "A beaker is already loaded into [src]!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return beaker = I - I.loc = src user.visible_message("[user] places [I] in [src].", \ "You place [I] in [src].") var/reagentlist = pretty_string_from_reagent_list(I.reagents.reagent_list) diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm index 9a2ecb6fea..96a5b8e489 100644 --- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm +++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm @@ -80,9 +80,8 @@ if(istype(W, /obj/item/tank)) if(!(stat & BROKEN)) var/obj/item/tank/T = W - if(holding || !user.drop_item()) + if(holding || !user.transferItemToLoc(T, src)) return - T.loc = src holding = T update_icon() else if(istype(W, /obj/item/wrench)) diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm index 1bc43cc293..87583ebea1 100644 --- a/code/modules/awaymissions/mission_code/Academy.dm +++ b/code/modules/awaymissions/mission_code/Academy.dm @@ -174,7 +174,7 @@ /obj/item/dice/d20/fate/equipped(mob/user, slot) if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards)) to_chat(user, "You feel the magic of the dice is restricted to ordinary humans! You should leave it alone.") - user.drop_item() + user.dropItemToGround(src) /obj/item/dice/d20/fate/proc/effect(var/mob/living/carbon/human/user,roll) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 237714eb8e..ed81aa0fbf 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -592,7 +592,7 @@ BLIND // can't see anything to_chat(user, "[src] already has an accessory.") return else - if(user && !user.drop_item()) + if(user && !user.temporarilyRemoveItemFromInventory(I)) return if(!A.attach(src, user)) return diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 67fd017153..63ff85ac17 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -22,13 +22,10 @@ /obj/item/reagent_containers/food/drinks/bottle/proc/smash(mob/living/target, mob/living/user, ranged = 0) //Creates a shattering noise and replaces the bottle with a broken_bottle - var/new_location = get_turf(loc) + var/new_location = get_turf(src) var/obj/item/broken_bottle/B = new /obj/item/broken_bottle(new_location) - if(ranged) - B.loc = new_location - else - user.drop_item() - user.put_in_active_hand(B) + if(!ranged) + user.put_in_hands(B) B.icon_state = src.icon_state var/icon/I = new('icons/obj/drinks.dmi', src.icon_state) diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index 0f27265b4b..df323a99ff 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -58,10 +58,9 @@ insert ascii eagle on american flag background here else if(is_type_in_typecache(I, deepfry_blacklisted_items)) . = ..() - else if(user.drop_item() && !frying) + else if(!frying && user.transferItemToLoc(I, src)) to_chat(user, "You put [I] into [src].") frying = I - frying.forceMove(src) icon_state = "fryer_on" /obj/machinery/deepfryer/process() diff --git a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm index ee29690027..d6037af55b 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm @@ -68,8 +68,6 @@ if(istype(O, /obj/item/reagent_containers/food/drinks/drinkingglass)) var/obj/item/reagent_containers/food/drinks/drinkingglass/DG = O if(!DG.reagents.total_volume) //glass is empty - if(!user.drop_item()) - return qdel(DG) glasses++ to_chat(user, "The [src] accepts the drinking glass, sterilizing it.") @@ -78,9 +76,8 @@ to_chat(user, "The [src] is at full capacity.") else var/obj/item/reagent_containers/food/snacks/S = O - if(!user.drop_item()) + if(!user.transferItemToLoc(S, src)) return - S.loc = src if(stored_food[sanitize(S.name)]) stored_food[sanitize(S.name)]++ else diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index e25b29f721..fd2471b96e 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -142,11 +142,10 @@ to_chat(user, "[src] is full, you can't put anything in!") return 1 else - if(!user.drop_item()) + if(!user.transferItemToLoc(O, src)) to_chat(user, "\the [O] is stuck to your hand, you cannot put it in \the [src]!") return 0 - O.loc = src user.visible_message( \ "[user] has added \the [O] to \the [src].", \ "You add \the [O] to \the [src].") diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index 6e245bd386..fb871f2c3a 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -195,8 +195,7 @@ if(P) user.visible_message("[user] put [O] into [src].", \ "You put [O] into [src].") - user.drop_item() - O.loc = src + user.transferItemToLoc(O, src, TRUE) return 1 else if(user.a_intent != INTENT_HARM) diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index 82fcc8c538..6788d1fc92 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -178,20 +178,18 @@ if(pizza) to_chat(user, "[src] already has \a [pizza.name]!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return pizza = I - I.loc = src to_chat(user, "You put [I] in [src].") update_icon() return else if(istype(I, /obj/item/bombcore/pizza)) if(open && !bomb) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return wires = new /datum/wires/explosive/pizza(src) bomb = I - I.loc = src to_chat(user, "You put [I] in [src]. Sneeki breeki...") update_icon() return diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index 86481b4c14..a735a48ff4 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -104,7 +104,7 @@ /obj/structure/holohoop/attackby(obj/item/W as obj, mob/user as mob, params) if(get_dist(src,user)<2) - if(user.drop_item(src)) + if(user.transferItemToLoc(W, drop_location())) visible_message(" [user] dunks [W] into \the [src]!") /obj/structure/holohoop/attack_hand(mob/user) @@ -211,9 +211,7 @@ /obj/machinery/conveyor/holodeck /obj/machinery/conveyor/holodeck/attackby(obj/item/I, mob/user, params) - if(user.drop_item()) - I.loc = src.loc - else + if(!user.transferItemToLoc(I, drop_location())) return ..() /obj/item/paper/fluff/holodeck/trek_diploma diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 5c9b0dac5e..1535173f8d 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -95,9 +95,8 @@ if(beaker) to_chat(user, "A container is already loaded into the machine.") else - if(!user.drop_item()) + if(!user.transferItemToLoc(O, src)) return - O.loc = src beaker = O to_chat(user, "You add the container to the machine.") update_icon() diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index 9439346bba..de881a0611 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -80,7 +80,7 @@ if(seed) to_chat(user, "A sample is already loaded into the machine!") else - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory()) return insert_seed(I) to_chat(user, "You add [I] to the machine.") @@ -90,10 +90,9 @@ if(disk) to_chat(user, "A data disk is already loaded into the machine!") else - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return disk = I - disk.loc = src to_chat(user, "You add [I] to the machine.") interact(user) else @@ -269,7 +268,7 @@ else var/obj/item/I = usr.get_active_held_item() if (istype(I, /obj/item/seeds)) - if(!usr.drop_item()) + if(!usr.temporarilyRemoveItemFromInventory(I)) return insert_seed(I) to_chat(usr, "You add [I] to the machine.") @@ -283,10 +282,9 @@ else var/obj/item/I = usr.get_active_held_item() if(istype(I, /obj/item/disk/plantgene)) - if(!usr.drop_item()) + if(!usr.transferItemToLoc(I, src)) return disk = I - disk.loc = src to_chat(usr, "You add [I] to the machine.") else if(href_list["op"] == "insert" && disk && disk.gene && seed) if(!operation) // Wait for confirmation diff --git a/code/modules/hydroponics/grown/cereals.dm b/code/modules/hydroponics/grown/cereals.dm index 5e32701526..7834ed15e8 100644 --- a/code/modules/hydroponics/grown/cereals.dm +++ b/code/modules/hydroponics/grown/cereals.dm @@ -87,8 +87,7 @@ /obj/item/reagent_containers/food/snacks/grown/meatwheat/attack_self(mob/living/user) user.visible_message("[user] crushes [src] into meat.", "You crush [src] into something that resembles meat.") playsound(user, 'sound/effects/blobattack.ogg', 50, 1) - var/obj/item/reagent_containers/food/snacks/meat/slab/meatwheat/M = new(get_turf(user)) - user.drop_item() + var/obj/item/reagent_containers/food/snacks/meat/slab/meatwheat/M = new qdel(src) user.put_in_hands(M) return 1 diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index ba56219062..6f54ea5e9b 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -114,4 +114,4 @@ if(prob(20)) M.Unconscious(force / 0.3) M.Knockdown(force / 0.75) - M.drop_item() + M.drop_all_held_items() diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index 5d609a9e69..3cc45bf9be 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /proc/seedify(obj/item/O, t_max, obj/machinery/seed_extractor/extractor, mob/living/user) var/t_amount = 0 if(t_max == -1) @@ -42,6 +43,52 @@ desc = "Extracts and bags seeds from produce." icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "sextractor" +======= +/proc/seedify(obj/item/O, t_max, obj/machinery/seed_extractor/extractor, mob/living/user) + var/t_amount = 0 + if(t_max == -1) + if(extractor) + t_max = rand(1,4) * extractor.seed_multiplier + else + t_max = rand(1,4) + + var/seedloc = O.loc + if(extractor) + seedloc = extractor.loc + + if(istype(O, /obj/item/reagent_containers/food/snacks/grown/)) + var/obj/item/reagent_containers/food/snacks/grown/F = O + if(F.seed) + if(user && !user.temporarilyRemoveItemFromInventory(O)) //couldn't drop the item + return + while(t_amount < t_max) + var/obj/item/seeds/t_prod = F.seed.Copy() + t_prod.loc = seedloc + t_amount++ + qdel(O) + return 1 + + else if(istype(O, /obj/item/grown)) + var/obj/item/grown/F = O + if(F.seed) + if(user && !user.temporarilyRemoveItemFromInventory(O)) + return + while(t_amount < t_max) + var/obj/item/seeds/t_prod = F.seed.Copy() + t_prod.loc = seedloc + t_amount++ + qdel(O) + return 1 + + return 0 + + +/obj/machinery/seed_extractor + name = "seed extractor" + desc = "Extracts and bags seeds from produce." + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "sextractor" +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) density = TRUE anchored = TRUE circuit = /obj/item/circuitboard/machine/seed_extractor @@ -90,6 +137,7 @@ to_chat(user, "You extract some seeds.") return else if (istype(O, /obj/item/seeds)) +<<<<<<< HEAD if(add_seed(O)) to_chat(user, "You add [O] to [src.name].") updateUsrDialog() @@ -196,3 +244,110 @@ piles += new /datum/seed_pile(O.plantname, O.lifespan, O.endurance, O.maturation, O.production, O.yield, O.potency) return +======= + if(add_seed(O)) + to_chat(user, "You add [O] to [src.name].") + updateUsrDialog() + return + else if(user.a_intent != INTENT_HARM) + to_chat(user, "You can't extract any seeds from \the [O.name]!") + else + return ..() + +/datum/seed_pile + var/name = "" + var/lifespan = 0 //Saved stats + var/endurance = 0 + var/maturation = 0 + var/production = 0 + var/yield = 0 + var/potency = 0 + var/amount = 0 + +/datum/seed_pile/New(var/name, var/life, var/endur, var/matur, var/prod, var/yie, var/poten, var/am = 1) + src.name = name + src.lifespan = life + src.endurance = endur + src.maturation = matur + src.production = prod + src.yield = yie + src.potency = poten + src.amount = am + +/obj/machinery/seed_extractor/attack_hand(mob/user) + user.set_machine(src) + interact(user) + +/obj/machinery/seed_extractor/interact(mob/user) + if (stat) + return 0 + + var/dat = "Stored seeds:
" + + if (contents.len == 0) + dat += "No seeds" + else + dat += "" + for (var/datum/seed_pile/O in piles) + dat += "" + dat += "" + dat += "
NameLifespanEnduranceMaturationProductionYieldPotencyStock
[O.name][O.lifespan][O.endurance][O.maturation][O.production][O.yield][O.potency]" + dat += "Vend ([O.amount] left)
" + var/datum/browser/popup = new(user, "seed_ext", name, 700, 400) + popup.set_content(dat) + popup.open() + return + +/obj/machinery/seed_extractor/Topic(var/href, var/list/href_list) + if(..()) + return + usr.set_machine(src) + + href_list["li"] = text2num(href_list["li"]) + href_list["en"] = text2num(href_list["en"]) + href_list["ma"] = text2num(href_list["ma"]) + href_list["pr"] = text2num(href_list["pr"]) + href_list["yi"] = text2num(href_list["yi"]) + href_list["pot"] = text2num(href_list["pot"]) + + for (var/datum/seed_pile/N in piles)//Find the pile we need to reduce... + if (href_list["name"] == N.name && href_list["li"] == N.lifespan && href_list["en"] == N.endurance && href_list["ma"] == N.maturation && href_list["pr"] == N.production && href_list["yi"] == N.yield && href_list["pot"] == N.potency) + if(N.amount <= 0) + return + N.amount = max(N.amount - 1, 0) + if (N.amount <= 0) + piles -= N + qdel(N) + break + + for (var/obj/T in contents)//Now we find the seed we need to vend + var/obj/item/seeds/O = T + if (O.plantname == href_list["name"] && O.lifespan == href_list["li"] && O.endurance == href_list["en"] && O.maturation == href_list["ma"] && O.production == href_list["pr"] && O.yield == href_list["yi"] && O.potency == href_list["pot"]) + O.loc = src.loc + break + + src.updateUsrDialog() + return + +/obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/O) + if(contents.len >= 999) + to_chat(usr, "\The [src] is full.") + return 0 + + if(ismob(O.loc)) + var/mob/M = O.loc + if(!M.transferItemToLoc(O, src)) + return 0 + else if(istype(O.loc, /obj/item/storage)) + var/obj/item/storage/S = O.loc + S.remove_from_storage(O,src) + + . = 1 + for (var/datum/seed_pile/N in piles) + if (O.plantname == N.name && O.lifespan == N.lifespan && O.endurance == N.endurance && O.maturation == N.maturation && O.production == N.production && O.yield == N.yield && O.potency == N.potency) + ++N.amount + return + + piles += new /datum/seed_pile(O.plantname, O.lifespan, O.endurance, O.maturation, O.production, O.yield, O.potency) + return +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 33f02bc759..711ac4f33a 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -84,9 +84,8 @@ if(2) if(is_type_in_list(I, allowed_books)) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - I.loc = src update_icon() else if(istype(I, /obj/item/storage/bag/books)) var/obj/item/storage/bag/books/B = I diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index dc48bbae2d..081ecdcdaa 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -507,9 +507,8 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums /obj/machinery/libraryscanner/attackby(obj/O, mob/user, params) if(istype(O, /obj/item/book)) - if(!user.drop_item()) + if(!user.transferItemToLoc(O, src)) return - O.loc = src else return ..() @@ -576,9 +575,8 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums if(busy) to_chat(user, "The book binder is busy. Please wait for completion of previous operation.") return - if(!user.drop_item()) + if(!user.transferItemToLoc(P, src)) return - P.loc = src user.visible_message("[user] loads some paper into [src].", "You load some paper into [src].") audible_message("[src] begins to hum as it warms up its printing drums.") busy = TRUE diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index d419ce7e38..d76278a410 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -67,8 +67,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) B.handle_item_insertion(src) uses_left-- if(uses_left <= 0) - user.drop_item(src) - loc = A + user.transferItemToLoc(src, A, TRUE) var/mutable_appearance/balloon var/mutable_appearance/balloon2 var/mutable_appearance/balloon3 diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 9ada4c768e..2bcccdb164 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -20,6 +20,7 @@ Radio = new/obj/item/device/radio(src) Radio.listening = FALSE locate_stacking_machine() +<<<<<<< HEAD /obj/machinery/mineral/labor_claim_console/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/card/id/prisoner)) @@ -122,6 +123,108 @@ /obj/machinery/mineral/labor_claim_console/emag_act(mob/user) if(!emagged) +======= + +/obj/machinery/mineral/labor_claim_console/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/card/id/prisoner)) + if(!inserted_id) + if(!user.transferItemToLoc(I, src)) + return + inserted_id = I + to_chat(user, "You insert [I].") + return + else + to_chat(user, "There's an ID inserted already.") + return ..() + +/obj/machinery/mineral/labor_claim_console/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "labor_claim_console", name, 450, 475, master_ui, state) + ui.open() + +/obj/machinery/mineral/labor_claim_console/ui_data(mob/user) + var/list/data = list() + var/can_go_home = FALSE + + data["emagged"] = emagged + if(inserted_id) + data["id"] = inserted_id + data["id_name"] = inserted_id.registered_name + data["points"] = inserted_id.points + data["goal"] = inserted_id.goal + if(check_auth()) + can_go_home = TRUE + + var/list/ores = list() + if(stacking_machine) + data["unclaimed_points"] = stacking_machine.points + for(var/ore in stacking_machine.ore_values) + var/list/O = list() + O["ore"] = ore + O["value"] = stacking_machine.ore_values[ore] + ores += list(O) + + data["ores"] = ores + data["can_go_home"] = can_go_home + + return data + +/obj/machinery/mineral/labor_claim_console/ui_act(action, params) + if(..()) + return + switch(action) + if("handle_id") + if(inserted_id) + if(!usr.get_active_held_item()) + usr.put_in_hands(inserted_id) + inserted_id = null + else + inserted_id.forceMove(get_turf(src)) + inserted_id = null + else + var/obj/item/I = usr.get_active_held_item() + if(istype(I, /obj/item/card/id/prisoner)) + if(!usr.transferItemToLoc(I, src)) + return + inserted_id = I + if("claim_points") + inserted_id.points += stacking_machine.points + stacking_machine.points = 0 + to_chat(usr, "Points transferred.") + if("move_shuttle") + if(!alone_in_area(get_area(src), usr)) + to_chat(usr, "Prisoners are only allowed to be released while alone.") + else + switch(SSshuttle.moveShuttle("laborcamp","laborcamp_home")) + if(1) + to_chat(usr, "Shuttle not found") + if(2) + to_chat(usr, "Shuttle already at station") + if(3) + to_chat(usr, "No permission to dock could be granted.") + else + if(!emagged) + Radio.set_frequency(GLOB.SEC_FREQ) + Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", GLOB.SEC_FREQ, get_spans(), get_default_language()) + to_chat(usr, "Shuttle received message and will be sent shortly.") + +/obj/machinery/mineral/labor_claim_console/proc/check_auth() + if(emagged) + return 1 //Shuttle is emagged, let any ol' person through + return (istype(inserted_id) && inserted_id.points >= inserted_id.goal) //Otherwise, only let them out if the prisoner's reached his quota. + +/obj/machinery/mineral/labor_claim_console/proc/locate_stacking_machine() + stacking_machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir)) + if(stacking_machine) + stacking_machine.CONSOLE = src + else + qdel(src) + +/obj/machinery/mineral/labor_claim_console/emag_act(mob/user) + if(!emagged) +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) emagged = TRUE to_chat(user, "PZZTTPFFFT") diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 95c4898605..efc46faa31 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -1005,7 +1005,7 @@ if(H == L) continue to_chat(H, "You have an overwhelming desire to kill [L]. [L.p_they(TRUE)] [L.p_have()] been marked red! Go kill [L.p_them()]!") - H.put_in_hands_or_del(new /obj/item/kitchen/knife/butcher(H)) + H.put_in_hands(new /obj/item/kitchen/knife/butcher(H), TRUE) qdel(src) diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 38e02474f4..437073a1fc 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -166,9 +166,8 @@ if(istype(W, /obj/item/card/id)) var/obj/item/card/id/I = user.get_active_held_item() if(istype(I) && !istype(inserted_id)) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - I.forceMove(src) inserted_id = I interact(user) return diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 8ae3632d34..5a228973ce 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -116,9 +116,8 @@ else if(href_list["choice"] == "insert") var/obj/item/card/id/I = usr.get_active_held_item() if(istype(I)) - if(!usr.drop_item()) + if(!usr.transferItemToLoc(I, src)) return - I.loc = src inserted_id = I to_chat(usr, "You insert the ID into [src]'s card slot.") else @@ -155,9 +154,8 @@ if(istype(I, /obj/item/card/id)) var/obj/item/card/id/C = usr.get_active_held_item() if(istype(C) && !istype(inserted_id)) - if(!usr.drop_item()) + if(!usr.transferItemToLoc(C, src)) return - C.loc = src inserted_id = C to_chat(usr, "You insert the ID into [src]'s card slot.") interact(user) diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index 2836bd67f8..17c89b3af9 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -11,9 +11,7 @@ /obj/structure/ore_box/attackby(obj/item/W, mob/user, params) if (istype(W, /obj/item/ore)) - if(!user.drop_item()) - return - W.forceMove(src) + user.transferItemToLoc(W, src) else if (istype(W, /obj/item/storage)) var/obj/item/storage/S = W for(var/obj/item/ore/O in S.contents) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 59e7db1286..486a918c06 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -222,26 +222,10 @@ I.dropped(src) return FALSE - -/mob/proc/put_in_hands_or_del(obj/item/I) - return put_in_hands(I, TRUE) - - -/mob/proc/drop_item_v() //this is dumb. - if(stat == CONSCIOUS && isturf(loc)) - return drop_item() - return FALSE - - /mob/proc/drop_all_held_items() + . = FALSE for(var/obj/item/I in held_items) - dropItemToGround(I) - -//Drops the item in our active hand. -/mob/proc/drop_item() - var/obj/item/held = get_active_held_item() - return dropItemToGround(held) - + . |= dropItemToGround(I) //Here lie drop_from_inventory and before_item_take, already forgotten and not missed. diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index aa15e28e66..6ac5ab1bad 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -115,9 +115,8 @@ //since these people will be dead M != usr if(!C.getorgan(/obj/item/organ/brain)) - if(!C.get_bodypart("head")) + if(!C.get_bodypart("head") || !C.temporarilyRemoveItemFromInventory(src)) return - user.drop_item() var/msg = "[C] has [src] inserted into [C.p_their()] head by [user]." if(C == user) msg = "[user] inserts [src] into [user.p_their()] head!" diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm index a09734ff49..36ed5ec884 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm @@ -51,7 +51,7 @@ "[M] has pushed down [src]!") else if (prob(50)) - drop_item() + dropItemToGround(get_active_held_item()) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) visible_message("[M] has disarmed [src]!", \ "[M] has disarmed [src]!", null, COMBAT_MESSAGE_RANGE) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index b4a57ea361..7be010b3ba 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -205,7 +205,7 @@ return 0 if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stunned instead. - if(get_active_held_item() && drop_item()) + if(dropItemToGround(get_active_held_item())) playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) visible_message("[M] disarmed [src]!", \ "[M] disarmed [src]!") @@ -259,7 +259,7 @@ damage_clothes(damage, BRUTE, "melee", affecting.body_zone) if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stun instead. - if(get_active_held_item() && drop_item()) + if(dropItemToGround(get_active_held_item())) playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) visible_message("[M] disarmed [src]!", \ "[M] disarmed [src]!") diff --git a/code/modules/mob/living/carbon/human/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm index 51b65bf44f..35e83a8e04 100644 --- a/code/modules/mob/living/carbon/human/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive.dm @@ -657,7 +657,7 @@ insert_into_backpack() //---------FASHION if(istype(TARGET, /obj/item/clothing)) - drop_item() + temporarilyRemoveItemFromInventory(TARGET, TRUE) dressup(TARGET) update_hands = 1 if(MYPDA in src.loc || MYID in src.loc) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 34d4ae8e51..12131ea94e 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1373,7 +1373,7 @@ target.stop_pulling() else I = target.get_active_held_item() - if(target.drop_item()) + if(target.dropItemToGround(I)) target.visible_message("[user] has disarmed [target]!", \ "[user] has disarmed [target]!", null, COMBAT_MESSAGE_RANGE) else diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm index d95b10a148..96cafa4501 100644 --- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm +++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm @@ -74,11 +74,9 @@ add_logs(M, src, "pushed") visible_message("[M] has pushed down [src]!", \ "[M] has pushed down [src]!", null, COMBAT_MESSAGE_RANGE) - else - if(drop_item()) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - visible_message("[M] has disarmed [src]!", \ - "[M] has disarmed [src]!", null, COMBAT_MESSAGE_RANGE) + else if(dropItemToGround(get_active_held_item())) + playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + visible_message("[M] has disarmed [src]!", "[M] has disarmed [src]!", null, COMBAT_MESSAGE_RANGE) /mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M) if(..()) //if harm or disarm intent. @@ -119,12 +117,10 @@ "[M] has tackled down [name]!", null, COMBAT_MESSAGE_RANGE) else I = get_active_held_item() - if(drop_item()) - visible_message("[M] has disarmed [name]!", \ - "[M] has disarmed [name]!", null, COMBAT_MESSAGE_RANGE) + if(dropItemToGround(I)) + visible_message("[M] has disarmed [name]!", "[M] has disarmed [name]!", null, COMBAT_MESSAGE_RANGE) else - I = null//did not manage to actually disarm the item, gross but no time to refactor - + I = null add_logs(M, src, "disarmed", "[I ? " removing \the [I]" : ""]") updatehealth() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index f8e4c4d752..5f995956be 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -427,9 +427,8 @@ else if(cell) to_chat(user, "There is a power cell already installed!") else - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return - W.loc = src cell = W to_chat(user, "You insert the power cell.") update_icons() @@ -518,7 +517,7 @@ else if(U.locked) to_chat(user, "The upgrade is locked and cannot be used yet!") else - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(U)) return if(U.action(src)) to_chat(user, "You apply the upgrade to [src].") @@ -529,12 +528,13 @@ upgrades += U else to_chat(user, "Upgrade error.") + U.forceMove(drop_location()) else if(istype(W, /obj/item/device/toner)) if(toner >= tonermax) to_chat(user, "The toner level of [src] is at its highest level possible!") else - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(W)) return toner = tonermax qdel(W) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 562b51945b..c15c287f7c 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /mob/living/silicon gender = NEUTER voice_name = "synthesized voice" @@ -384,3 +385,388 @@ /mob/living/silicon/is_literate() return 1 +======= +/mob/living/silicon + gender = NEUTER + voice_name = "synthesized voice" + has_unlimited_silicon_privilege = 1 + verb_say = "states" + verb_ask = "queries" + verb_exclaim = "declares" + verb_yell = "alarms" + initial_language_holder = /datum/language_holder/synthetic + see_in_dark = 8 + bubble_icon = "machine" + weather_immunities = list("ash") + possible_a_intents = list(INTENT_HELP, INTENT_HARM) + + var/syndicate = 0 + var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS + var/last_lawchange_announce = 0 + var/list/alarms_to_show = list() + var/list/alarms_to_clear = list() + var/designation = "" + var/radiomod = "" //Radio character used before state laws/arrivals announce to allow department transmissions, default, or none at all. + var/obj/item/device/camera/siliconcam/aicamera = null //photography + hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_TRACK_HUD) + + var/obj/item/device/radio/borg/radio = null //AIs dont use this but this is at the silicon level to advoid copypasta in say() + + var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0) + var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0) + + var/lawcheck[1] + var/ioncheck[1] + var/devillawcheck[5] + + var/med_hud = DATA_HUD_MEDICAL_ADVANCED //Determines the med hud to use + var/sec_hud = DATA_HUD_SECURITY_ADVANCED //Determines the sec hud to use + var/d_hud = DATA_HUD_DIAGNOSTIC //There is only one kind of diag hud + + var/law_change_counter = 0 + var/obj/machinery/camera/builtInCamera = null + var/updating = FALSE //portable camera camerachunk update + +/mob/living/silicon/Initialize() + . = ..() + GLOB.silicon_mobs += src + var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC] + diag_hud.add_to_hud(src) + diag_hud_set_status() + diag_hud_set_health() + +/mob/living/silicon/med_hud_set_health() + return //we use a different hud + +/mob/living/silicon/med_hud_set_status() + return //we use a different hud + +/mob/living/silicon/Destroy() + radio = null + aicamera = null + QDEL_NULL(builtInCamera) + GLOB.silicon_mobs -= src + return ..() + +/mob/living/silicon/contents_explosion(severity, target) + return + +/mob/living/silicon/proc/cancelAlarm() + return + +/mob/living/silicon/proc/triggerAlarm() + return + +/mob/living/silicon/proc/queueAlarm(message, type, incoming = 1) + var/in_cooldown = (alarms_to_show.len > 0 || alarms_to_clear.len > 0) + if(incoming) + alarms_to_show += message + alarm_types_show[type] += 1 + else + alarms_to_clear += message + alarm_types_clear[type] += 1 + + if(!in_cooldown) + spawn(3 * 10) // 3 seconds + + if(alarms_to_show.len < 5) + for(var/msg in alarms_to_show) + to_chat(src, msg) + else if(alarms_to_show.len) + + var/msg = "--- " + + if(alarm_types_show["Burglar"]) + msg += "BURGLAR: [alarm_types_show["Burglar"]] alarms detected. - " + + if(alarm_types_show["Motion"]) + msg += "MOTION: [alarm_types_show["Motion"]] alarms detected. - " + + if(alarm_types_show["Fire"]) + msg += "FIRE: [alarm_types_show["Fire"]] alarms detected. - " + + if(alarm_types_show["Atmosphere"]) + msg += "ATMOSPHERE: [alarm_types_show["Atmosphere"]] alarms detected. - " + + if(alarm_types_show["Power"]) + msg += "POWER: [alarm_types_show["Power"]] alarms detected. - " + + if(alarm_types_show["Camera"]) + msg += "CAMERA: [alarm_types_show["Camera"]] alarms detected. - " + + msg += "\[Show Alerts\]" + to_chat(src, msg) + + if(alarms_to_clear.len < 3) + for(var/msg in alarms_to_clear) + to_chat(src, msg) + + else if(alarms_to_clear.len) + var/msg = "--- " + + if(alarm_types_clear["Motion"]) + msg += "MOTION: [alarm_types_clear["Motion"]] alarms cleared. - " + + if(alarm_types_clear["Fire"]) + msg += "FIRE: [alarm_types_clear["Fire"]] alarms cleared. - " + + if(alarm_types_clear["Atmosphere"]) + msg += "ATMOSPHERE: [alarm_types_clear["Atmosphere"]] alarms cleared. - " + + if(alarm_types_clear["Power"]) + msg += "POWER: [alarm_types_clear["Power"]] alarms cleared. - " + + if(alarm_types_show["Camera"]) + msg += "CAMERA: [alarm_types_clear["Camera"]] alarms cleared. - " + + msg += "\[Show Alerts\]" + to_chat(src, msg) + + + alarms_to_show = list() + alarms_to_clear = list() + for(var/key in alarm_types_show) + alarm_types_show[key] = 0 + for(var/key in alarm_types_clear) + alarm_types_clear[key] = 0 + +/mob/living/silicon/can_inject(mob/user, error_msg) + if(error_msg) + to_chat(user, "Their outer shell is too tough.") + return 0 + +/mob/living/silicon/IsAdvancedToolUser() + return 1 + +/proc/islinked(mob/living/silicon/robot/bot, mob/living/silicon/ai/ai) + if(!istype(bot) || !istype(ai)) + return 0 + if (bot.connected_ai == ai) + return 1 + return 0 + +/mob/living/silicon/Topic(href, href_list) + if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite + var/L = text2num(href_list["lawc"]) + switch(lawcheck[L+1]) + if ("Yes") + lawcheck[L+1] = "No" + if ("No") + lawcheck[L+1] = "Yes" + checklaws() + + if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite + var/L = text2num(href_list["lawi"]) + switch(ioncheck[L]) + if ("Yes") + ioncheck[L] = "No" + if ("No") + ioncheck[L] = "Yes" + checklaws() + + if (href_list["lawdevil"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite + var/L = text2num(href_list["lawdevil"]) + switch(devillawcheck[L]) + if ("Yes") + devillawcheck[L] = "No" + if ("No") + devillawcheck[L] = "Yes" + checklaws() + + + if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite + statelaws() + + return + + +/mob/living/silicon/proc/statelaws(force = 0) + + //"radiomod" is inserted before a hardcoded message to change if and how it is handled by an internal radio. + src.say("[radiomod] Current Active Laws:") + //src.laws_sanity_check() + //src.laws.show_laws(world) + var/number = 1 + sleep(10) + + if (src.laws.devillaws && src.laws.devillaws.len) + for(var/index = 1, index <= src.laws.devillaws.len, index++) + if (force || src.devillawcheck[index] == "Yes") + src.say("[radiomod] 666. [src.laws.devillaws[index]]") + sleep(10) + + + if (src.laws.zeroth) + if (force || src.lawcheck[1] == "Yes") + src.say("[radiomod] 0. [src.laws.zeroth]") + sleep(10) + + for (var/index = 1, index <= src.laws.ion.len, index++) + var/law = src.laws.ion[index] + var/num = ionnum() + if (length(law) > 0) + if (force || src.ioncheck[index] == "Yes") + src.say("[radiomod] [num]. [law]") + sleep(10) + + for (var/index = 1, index <= src.laws.inherent.len, index++) + var/law = src.laws.inherent[index] + + if (length(law) > 0) + if (force || src.lawcheck[index+1] == "Yes") + src.say("[radiomod] [number]. [law]") + number++ + sleep(10) + + for (var/index = 1, index <= src.laws.supplied.len, index++) + var/law = src.laws.supplied[index] + + if (length(law) > 0) + if(src.lawcheck.len >= number+1) + if (force || src.lawcheck[number+1] == "Yes") + src.say("[radiomod] [number]. [law]") + number++ + sleep(10) + + +/mob/living/silicon/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite + + var/list = "Which laws do you want to include when stating them for the crew?

" + + if (src.laws.devillaws && src.laws.devillaws.len) + for(var/index = 1, index <= src.laws.devillaws.len, index++) + if (!src.devillawcheck[index]) + src.devillawcheck[index] = "No" + list += {"[src.devillawcheck[index]] 666: [src.laws.devillaws[index]]
"} + + if (src.laws.zeroth) + if (!src.lawcheck[1]) + src.lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite + list += {"[src.lawcheck[1]] 0: [src.laws.zeroth]
"} + + for (var/index = 1, index <= src.laws.ion.len, index++) + var/law = src.laws.ion[index] + + if (length(law) > 0) + if (!src.ioncheck[index]) + src.ioncheck[index] = "Yes" + list += {"[src.ioncheck[index]] [ionnum()]: [law]
"} + src.ioncheck.len += 1 + + var/number = 1 + for (var/index = 1, index <= src.laws.inherent.len, index++) + var/law = src.laws.inherent[index] + + if (length(law) > 0) + src.lawcheck.len += 1 + + if (!src.lawcheck[number+1]) + src.lawcheck[number+1] = "Yes" + list += {"[src.lawcheck[number+1]] [number]: [law]
"} + number++ + + for (var/index = 1, index <= src.laws.supplied.len, index++) + var/law = src.laws.supplied[index] + if (length(law) > 0) + src.lawcheck.len += 1 + if (!src.lawcheck[number+1]) + src.lawcheck[number+1] = "Yes" + list += {"[src.lawcheck[number+1]] [number]: [law]
"} + number++ + list += {"

State Laws"} + + usr << browse(list, "window=laws") + +/mob/living/silicon/proc/set_autosay() //For allowing the AI and borgs to set the radio behavior of auto announcements (state laws, arrivals). + if(!radio) + to_chat(src, "Radio not detected.") + return + + //Ask the user to pick a channel from what it has available. + var/Autochan = input("Select a channel:") as null|anything in list("Default","None") + radio.channels + + if(!Autochan) + return + if(Autochan == "Default") //Autospeak on whatever frequency to which the radio is set, usually Common. + radiomod = ";" + Autochan += " ([radio.frequency])" + else if(Autochan == "None") //Prevents use of the radio for automatic annoucements. + radiomod = "" + else //For department channels, if any, given by the internal radio. + for(var/key in GLOB.department_radio_keys) + if(GLOB.department_radio_keys[key] == Autochan) + radiomod = ":" + key + break + + to_chat(src, "Automatic announcements [Autochan == "None" ? "will not use the radio." : "set to [Autochan]."]") + +/mob/living/silicon/put_in_hand_check() // This check is for borgs being able to receive items, not put them in others' hands. + return 0 + +// The src mob is trying to place an item on someone +// But the src mob is a silicon!! Disable. +/mob/living/silicon/stripPanelEquip(obj/item/what, mob/who, slot) + return 0 + + +/mob/living/silicon/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) //Secbots won't hunt silicon units + return -10 + +/mob/living/silicon/proc/remove_med_sec_hud() + var/datum/atom_hud/secsensor = GLOB.huds[sec_hud] + var/datum/atom_hud/medsensor = GLOB.huds[med_hud] + var/datum/atom_hud/diagsensor = GLOB.huds[d_hud] + secsensor.remove_hud_from(src) + medsensor.remove_hud_from(src) + diagsensor.remove_hud_from(src) + +/mob/living/silicon/proc/add_sec_hud() + var/datum/atom_hud/secsensor = GLOB.huds[sec_hud] + secsensor.add_hud_to(src) + +/mob/living/silicon/proc/add_med_hud() + var/datum/atom_hud/medsensor = GLOB.huds[med_hud] + medsensor.add_hud_to(src) + +/mob/living/silicon/proc/add_diag_hud() + var/datum/atom_hud/diagsensor = GLOB.huds[d_hud] + diagsensor.add_hud_to(src) + +/mob/living/silicon/proc/sensor_mode() + if(incapacitated()) + return + var/sensor_type = input("Please select sensor type.", "Sensor Integration", null) in list("Security", "Medical","Diagnostic","Disable") + remove_med_sec_hud() + switch(sensor_type) + if ("Security") + add_sec_hud() + to_chat(src, "Security records overlay enabled.") + if ("Medical") + add_med_hud() + to_chat(src, "Life signs monitor overlay enabled.") + if ("Diagnostic") + add_diag_hud() + to_chat(src, "Robotics diagnostic overlay enabled.") + if ("Disable") + to_chat(src, "Sensor augmentations disabled.") + + +/mob/living/silicon/proc/GetPhoto() + if (aicamera) + return aicamera.selectpicture(aicamera) + +/mob/living/silicon/update_transform() + var/matrix/ntransform = matrix(transform) //aka transform.Copy() + var/changed = 0 + if(resize != RESIZE_DEFAULT_SIZE) + changed++ + ntransform.Scale(resize) + resize = RESIZE_DEFAULT_SIZE + + if(changed) + animate(src, transform = ntransform, time = 2,easing = EASE_IN|EASE_OUT) + return ..() + +/mob/living/silicon/is_literate() + return 1 +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 1afcdaaed4..98b1b46ed8 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -846,9 +846,8 @@ Pass a positive integer as an argument to override a bot's default speed. else if(allow_pai && !key) if(!locked && !open) if(card.pai && card.pai.mind) - if(!user.drop_item()) + if(!user.transferItemToLoc(card, src)) return - card.forceMove(src) paicard = card user.visible_message("[user] inserts [card] into [src]!","You insert [card] into [src].") paicard.pai.mind.transfer_to(src) diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index bbbe4e310c..3a46e46beb 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -223,10 +223,9 @@ if(!isnull(reagent_glass)) to_chat(user, "There is already a beaker loaded!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return - W.loc = src reagent_glass = W to_chat(user, "You insert [W].") show_controls(user) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index e6a4b978ca..6130d92aff 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -84,11 +84,9 @@ if(open) on = FALSE else if(istype(I, /obj/item/stock_parts/cell) && open && !cell) - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - var/obj/item/stock_parts/cell/C = I - C.loc = src - cell = C + cell = I visible_message("[user] inserts a cell into [src].", "You insert the new cell into [src].") else if(istype(I, /obj/item/crowbar) && open && cell) diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 6467990776..35b4b37445 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -174,7 +174,7 @@ usr.visible_message("[usr] pets [src].","You rest your hand on [src]'s back for a moment.") return - if(!usr.drop_item()) + if(!usr.temporarilyRemoveItemFromInventory(item_to_add)) to_chat(usr, "\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s back!") return @@ -189,7 +189,7 @@ if(!allowed) to_chat(usr, "You set [item_to_add] on [src]'s back, but it falls off!") - item_to_add.loc = loc + item_to_add.forceMove(drop_location()) if(prob(25)) step_rand(item_to_add) for(var/i in list(1,2,4,8,4,8,4,dir)) @@ -197,8 +197,7 @@ sleep(1) return - usr.drop_item() - item_to_add.loc = src + item_to_add.forceMove(src) src.inventory_back = item_to_add update_corgi_fluff() regenerate_icons() @@ -226,7 +225,7 @@ user.visible_message("[user] pets [src].","You rest your hand on [src]'s head for a moment.") return - if(user && !user.drop_item()) + if(user && !user.temporarilyRemoveItemFromInventory(item_to_add)) to_chat(user, "\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s head!") return 0 @@ -243,13 +242,13 @@ user.visible_message("[user] puts [item_to_add] on [real_name]'s head. [src] looks at [user] and barks once.", "You put [item_to_add] on [real_name]'s head. [src] gives you a peculiar look, then wags [p_their()] tail once and barks.", "You hear a friendly-sounding bark.") - item_to_add.loc = src + item_to_add.forceMove(src) src.inventory_head = item_to_add update_corgi_fluff() regenerate_icons() else to_chat(user, "You set [item_to_add] on [src]'s head, but it falls off!") - item_to_add.loc = loc + item_to_add.forceMove(drop_location()) if(prob(25)) step_rand(item_to_add) for(var/i in list(1,2,4,8,4,8,4,dir)) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index c29236c2fc..6fb1c500b2 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -275,7 +275,6 @@ if(!stat && eggsleft < 8) var/feedmsg = "[user] feeds [O] to [name]! [pick(feedMessages)]" user.visible_message(feedmsg) - user.drop_item() qdel(O) eggsleft += rand(1, 4) else diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 09d9f66f61..7ceffa198b 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -246,8 +246,8 @@ var/obj/item/device/radio/headset/headset_to_add = item_to_add - usr.drop_item() - headset_to_add.loc = src + if(!usr.transferItemToLoc(headset_to_add, src)) + return src.ears = headset_to_add to_chat(usr, "You fit the headset onto [src].") @@ -340,7 +340,6 @@ drop_held_item(0) else if(istype(O, /obj/item/reagent_containers/food/snacks/cracker)) //Poly wants a cracker. qdel(O) - user.drop_item() if(health < maxHealth) adjustBruteLoss(-10) speak_chance *= 1.27 // 20 crackers to go from 1% to 100% diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 4da630bb31..a66b45d4a2 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -53,10 +53,11 @@ /client/Northwest() - if(!usr.get_active_held_item()) + var/obj/item/I = usr.get_active_held_item() + if(!I) to_chat(usr, "You have nothing to drop in your hand!") return - usr.drop_item() + usr.dropItemToGround(I) //This gets called when you press the delete button. /client/verb/delete_key_pressed() @@ -85,8 +86,8 @@ /client/verb/drop_item() set hidden = 1 - if(!iscyborg(mob)) - mob.drop_item_v() + if(!iscyborg(mob) && mob.stat == CONSCIOUS) + mob.dropItemToGround(mob.get_active_held_item()) return diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm index ead6a35eea..0562bf700d 100644 --- a/code/modules/modular_computers/file_system/programs/card.dm +++ b/code/modules/modular_computers/file_system/programs/card.dm @@ -175,9 +175,8 @@ else var/obj/item/I = usr.get_active_held_item() if (istype(I, /obj/item/card/id)) - if(!usr.drop_item()) + if(!usr.transferItemToLoc(I, computer)) return - I.forceMove(computer) card_slot.stored_card = I if("auth") if(auth_card) @@ -191,9 +190,8 @@ else var/obj/item/I = usr.get_active_held_item() if (istype(I, /obj/item/card/id)) - if(!usr.drop_item()) + if(!usr.transferItemToLoc(I, computer)) return - I.forceMove(computer) card_slot.stored_card2 = I if("PRG_terminate") if(computer && ((id_card.assignment in head_subordinates) || id_card.assignment == "Assistant")) diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm index adec1aa19d..99eb6f1a23 100644 --- a/code/modules/modular_computers/laptop_vendor.dm +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -244,7 +244,7 @@ if(istype(I, /obj/item/stack/spacecash)) var/obj/item/stack/spacecash/c = I - if(!user.drop_item(c)) + if(!user.temporarilyRemoveItemFromInventory(c)) return credits += c.value visible_message("[usr] inserts [c.value] credits into the [src].") diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index f8c4cf1f73..8b4be79e99 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -47,10 +47,9 @@ /obj/structure/filingcabinet/attackby(obj/item/P, mob/user, params) if(istype(P, /obj/item/paper) || istype(P, /obj/item/folder) || istype(P, /obj/item/photo) || istype(P, /obj/item/documents)) - if(!user.drop_item()) + if(!user.transferItemToLoc(P, src)) return to_chat(user, "You put [P] in [src].") - P.loc = src icon_state = "[initial(icon_state)]-open" sleep(5) icon_state = initial(icon_state) diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index 2c704b8568..4a85d03df7 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -44,16 +44,15 @@ /obj/item/papercutter/attackby(obj/item/P, mob/user, params) if(istype(P, /obj/item/paper) && !storedpaper) - if(!user.drop_item()) + if(!user.transferItemToLoc(P, src)) return playsound(loc, "pageturn", 60, 1) to_chat(user, "You place [P] in [src].") - P.loc = src storedpaper = P update_icon() return if(istype(P, /obj/item/hatchet/cutterblade) && !storedcutter) - if(!user.drop_item()) + if(!user.transferItemToLoc(P, src)) return to_chat(user, "You replace [src]'s [P].") P.loc = src diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 0dcd5d09a0..d4e78c4ef3 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -240,7 +240,7 @@ updateUsrDialog() /obj/machinery/photocopier/proc/do_insertion(obj/item/O, mob/user) - O.loc = src + O.forceMove(src) to_chat(user, "You insert [O] into [src].") flick("photocopier1", src) updateUsrDialog() @@ -261,7 +261,7 @@ resistance_flags |= FLAMMABLE fire_act() else - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(O)) return copy = O do_insertion(O, user) @@ -270,7 +270,7 @@ else if(istype(O, /obj/item/photo)) if(copier_empty()) - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(O)) return photocopy = O do_insertion(O, user) @@ -279,7 +279,7 @@ else if(istype(O, /obj/item/documents)) if(copier_empty()) - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(O)) return doccopy = O do_insertion(O, user) @@ -288,7 +288,7 @@ else if(istype(O, /obj/item/device/toner)) if(toner <= 0) - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(O)) return qdel(O) toner = 40 diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 8e20925f9b..ad3e2c9d33 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -449,9 +449,8 @@ if (stat & MAINT) to_chat(user, "There is no connector for your power cell!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return - W.forceMove(src) cell = W user.visible_message(\ "[user.name] has inserted the power cell to [src.name]!",\ diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 096c050fcc..8634e5af5b 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -315,7 +315,7 @@ src.add_fingerprint(user) var/obj/item/light/L = W if(istype(L, light_type)) - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory()) return src.add_fingerprint(user) diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 8399f73e79..9b5592af3b 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -87,10 +87,9 @@ GLOBAL_LIST_EMPTY(rad_collectors) if(loaded_tank) to_chat(user, "There's already a plasma tank loaded!") return TRUE - if(!user.drop_item()) - return TRUE + if(!user.transferItemToLoc(W, src)) + return loaded_tank = W - W.forceMove(src) update_icons() else if(istype(W, /obj/item/crowbar)) if(loaded_tank) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index dcc8c0a200..fb530f128f 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -240,7 +240,7 @@ if(!tracker) if(istype(W, /obj/item/electronics/tracker)) - if(!user.drop_item()) + if(!user.temporarilyRemoveItemFromInventory(W)) return tracker = 1 qdel(W) diff --git a/code/modules/projectiles/box_magazine.dm b/code/modules/projectiles/box_magazine.dm index 29e27d18ba..324470ede4 100644 --- a/code/modules/projectiles/box_magazine.dm +++ b/code/modules/projectiles/box_magazine.dm @@ -81,8 +81,7 @@ if(istype(A, /obj/item/ammo_casing)) var/obj/item/ammo_casing/AC = A if(give_round(AC, replace_spent)) - user.drop_item() - AC.forceMove(src) + user.transferItemToLoc(AC, src, TRUE) num_loaded++ if(num_loaded) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index e5767e48ba..564bcd04d8 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -164,7 +164,7 @@ to_chat(user, "You shoot yourself in the foot with [src]!") var/shot_leg = pick("l_leg", "r_leg") process_fire(user,user,0,params, zone_override = shot_leg) - user.drop_item() + user.dropItemToGround(src, TRUE) return if(weapon_weight == WEAPON_HEAVY && user.get_inactive_held_item()) diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 44bada2771..7c0ec28a44 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -358,5 +358,5 @@ if(process_fire(user, user, 0, zone_override = "head")) user.visible_message("[user] somehow manages to shoot [user.p_them()]self in the face!", "You somehow shoot yourself in the face! How the hell?!") user.emote("scream") - user.drop_item() + user.drop_all_held_items() user.Knockdown(80) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index bbaf20689c..6cd603c8d1 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -172,11 +172,11 @@ if(guns_left) var/obj/item/gun/ballistic/shotgun/boltaction/enchanted/GUN = new gun_type GUN.guns_left = guns_left - 1 - user.drop_item() + user.dropItemToGround(src, TRUE) user.swap_hand() user.put_in_hands(GUN) else - user.drop_item() + user.dropItemToGround(src, TRUE) discard_gun(user) // Automatic Shotguns// diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm index 5ee2ecec05..8772ae05c0 100644 --- a/code/modules/projectiles/guns/misc/blastcannon.dm +++ b/code/modules/projectiles/guns/misc/blastcannon.dm @@ -49,12 +49,11 @@ if(!T.tank_one || !T.tank_two) to_chat(user, "What good would an incomplete bomb do?") return FALSE - if(!user.drop_item(O)) + if(!user.transferItemToLoc(O, src)) to_chat(user, "The [O] seems to be stuck to your hand!") return FALSE user.visible_message("[user] attaches the [O] to the [src]!") bomb = O - O.forceMove(src) update_icon() return TRUE return ..() diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index 8fdb973ef6..a6f6782d30 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -189,9 +189,7 @@ M.emote("laugh") if(prob(33)) M.visible_message("[M]'s hands flip out and flail everywhere!") - var/obj/item/I = M.get_active_held_item() - if(I) - M.drop_item() + M.drop_all_held_items() ..() M.adjustToxLoss(1, 0) M.adjustBrainLoss(pick(0.5, 0.6, 0.7, 0.8, 0.9, 1)) @@ -268,9 +266,7 @@ if(prob(20)) M.emote(pick("twitch","drool","moan")) if(prob(33)) - var/obj/item/I = M.get_active_held_item() - if(I) - M.drop_item() + M.drop_all_held_items() ..() /datum/reagent/drug/bath_salts/addiction_act_stage1(mob/living/M) diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 72001d5ca9..f1b076ca68 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -256,7 +256,6 @@ victim.confused = max(M.confused, 3) victim.damageoverlaytemp = 60 victim.Knockdown(60) - victim.drop_item() return else if ( eyes_covered ) // Eye cover is better than mouth cover victim.blur_eyes(3) @@ -270,7 +269,6 @@ victim.confused = max(M.confused, 6) victim.damageoverlaytemp = 75 victim.Knockdown(100) - victim.drop_item() victim.update_damage_hud() /datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/M) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index ab9d95582b..01d50fb606 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -626,27 +626,20 @@ /datum/reagent/medicine/morphine/overdose_process(mob/living/M) if(prob(33)) - var/obj/item/I = M.get_active_held_item() - if(I) - M.drop_item() + M.drop_all_held_items() M.Dizzy(2) M.Jitter(2) ..() /datum/reagent/medicine/morphine/addiction_act_stage1(mob/living/M) if(prob(33)) - var/obj/item/I = M.get_active_held_item() - if(I) - M.drop_item() - M.Dizzy(2) + M.drop_all_held_items() M.Jitter(2) ..() /datum/reagent/medicine/morphine/addiction_act_stage2(mob/living/M) if(prob(33)) - var/obj/item/I = M.get_active_held_item() - if(I) - M.drop_item() + M.drop_all_held_items() M.adjustToxLoss(1*REM, 0) . = 1 M.Dizzy(3) @@ -655,9 +648,7 @@ /datum/reagent/medicine/morphine/addiction_act_stage3(mob/living/M) if(prob(33)) - var/obj/item/I = M.get_active_held_item() - if(I) - M.drop_item() + M.drop_all_held_items() M.adjustToxLoss(2*REM, 0) . = 1 M.Dizzy(4) @@ -666,9 +657,7 @@ /datum/reagent/medicine/morphine/addiction_act_stage4(mob/living/M) if(prob(33)) - var/obj/item/I = M.get_active_held_item() - if(I) - M.drop_item() + M.drop_all_held_items() M.adjustToxLoss(3*REM, 0) . = 1 M.Dizzy(5) diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index 49e375b723..2a194ee95c 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -141,8 +141,7 @@ to_chat(user, "You reverse [src]'s direction.") else if(user.a_intent != INTENT_HARM) - if(user.drop_item()) - I.loc = src.loc + user.transferItemToLoc(I, drop_location()) else return ..() diff --git a/code/modules/recycling/disposal-unit.dm b/code/modules/recycling/disposal-unit.dm index 517b4aa195..9fdc62c8d2 100644 --- a/code/modules/recycling/disposal-unit.dm +++ b/code/modules/recycling/disposal-unit.dm @@ -96,7 +96,7 @@ return if(user.a_intent != INTENT_HARM) - if(!user.drop_item() || (I.flags_1 & ABSTRACT_1)) + if((I.flags_1 & ABSTRACT_1) || !user.temporarilyRemoveItemFromInventory(I)) return place_item_in_disposal(I, user) update_icon() diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 5d3cde7aac..790cba0889 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -43,12 +43,11 @@ Note: Must be placed within 3 tiles of the R&D Console if (temp_tech.len == 0) to_chat(user, "You cannot deconstruct this item!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(O, src)) to_chat(user, "\The [O] is stuck to your hand, you cannot put it in the [src.name]!") return busy = TRUE loaded_item = O - O.forceMove(src) to_chat(user, "You add the [O.name] to the [src.name]!") flick("d_analyzer_la", src) addtimer(CALLBACK(src, .proc/finish_loading), 10) diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 4d8938b1b8..3a2b1f6b7f 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -122,10 +122,9 @@ if (temp_tech.len == 0) to_chat(user, "You cannot experiment on this item!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(O, src)) return loaded_item = O - O.loc = src to_chat(user, "You add the [O.name] to the machine.") flick("h_lathe_load", src) diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 70e4bf7f62..efb64c6623 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -127,9 +127,8 @@ won't update every console in existence) but it's more of a hassle to do. Also, else to_chat(user, "Machine cannot accept disks in that format.") return - if(!user.drop_item()) + if(!user.transferItemToLoc(D, src)) return - D.loc = src to_chat(user, "You add the disk to the machine!") else if(!(linked_destroy && linked_destroy.busy) && !(linked_lathe && linked_lathe.busy) && !(linked_imprinter && linked_imprinter.busy)) . = ..() diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 1be515f177..02180b273f 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -70,7 +70,6 @@ if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube)) monkeys++ to_chat(user, "You feed [O] to [src]. It now has [monkeys] monkey cubes stored.") - user.drop_item() qdel(O) return else if(istype(O, /obj/item/storage/bag)) diff --git a/code/modules/spells/spell_types/conjure.dm b/code/modules/spells/spell_types/conjure.dm index 08837c956d..c73c5de58a 100644 --- a/code/modules/spells/spell_types/conjure.dm +++ b/code/modules/spells/spell_types/conjure.dm @@ -75,9 +75,8 @@ item = null else for(var/mob/living/carbon/C in targets) - if(C.drop_item()) - item = make_item() - C.put_in_hands(item) + if(C.dropItemToGround(C.get_active_held_item())) + C.put_in_hands(make_item(), TRUE) /obj/effect/proc_holder/spell/targeted/conjure_item/Destroy() if(item) diff --git a/code/modules/spells/spell_types/devil.dm b/code/modules/spells/spell_types/devil.dm index 9d1afdcebc..b1867413a3 100644 --- a/code/modules/spells/spell_types/devil.dm +++ b/code/modules/spells/spell_types/devil.dm @@ -49,7 +49,7 @@ for(var/mob/living/carbon/C in targets) if(C.mind && user.mind) if(C.stat == DEAD) - if(user.drop_item()) + if(user.dropItemToGround(user.get_active_held_item())) var/obj/item/paper/contract/infernal/revive/contract = new(user.loc, C.mind, user.mind) user.put_in_hands(contract) else diff --git a/code/modules/spells/spell_types/devil_boons.dm b/code/modules/spells/spell_types/devil_boons.dm index a0be169d85..5d335745d2 100644 --- a/code/modules/spells/spell_types/devil_boons.dm +++ b/code/modules/spells/spell_types/devil_boons.dm @@ -14,7 +14,7 @@ /obj/effect/proc_holder/spell/targeted/summon_wealth/cast(list/targets, mob/user = usr) for(var/mob/living/carbon/C in targets) - if(user.drop_item()) + if(user.dropItemToGround(user.get_active_held_item())) var/obj/item = pick( new /obj/item/coin/gold(user.loc), new /obj/item/coin/diamond(user.loc), diff --git a/code/modules/spells/spell_types/infinite_guns.dm b/code/modules/spells/spell_types/infinite_guns.dm index 6036d1a70b..feb6eeddb6 100644 --- a/code/modules/spells/spell_types/infinite_guns.dm +++ b/code/modules/spells/spell_types/infinite_guns.dm @@ -14,12 +14,9 @@ /obj/effect/proc_holder/spell/targeted/infinite_guns/cast(list/targets, mob/user = usr) for(var/mob/living/carbon/C in targets) - C.drop_item() - C.swap_hand() - C.drop_item() + C.drop_all_held_items() var/GUN = new summon_path C.put_in_hands(GUN) - C.swap_hand(C.get_held_index_of_item(GUN)) /obj/effect/proc_holder/spell/targeted/infinite_guns/gun diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index a37502a96b..8bad429102 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -29,9 +29,8 @@ return 0 else user.visible_message("[user] stuffs [tool] into [target]'s [target_zone]!", "You stuff [tool] into [target]'s [target_zone].") - user.drop_item() + user.transferItemToLoc(tool, target, TRUE) CH.cavity_item = tool - tool.loc = target return 1 else if(IC) diff --git a/code/modules/surgery/dental_implant.dm b/code/modules/surgery/dental_implant.dm index db3771ad21..0073c59f8d 100644 --- a/code/modules/surgery/dental_implant.dm +++ b/code/modules/surgery/dental_implant.dm @@ -15,8 +15,7 @@ if(!istype(tool)) return 0 - user.drop_item() - tool.loc = target + user.transferItemToLoc(tool, target, TRUE) var/datum/action/item_action/hands_free/activate_pill/P = new(tool) P.button.name = "Activate [tool.name]" diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index 6272039201..4df1d847be 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /////AUGMENTATION SURGERIES////// @@ -57,6 +58,66 @@ qdel(tool) target.update_body_parts() target.updatehealth() +======= + +/////AUGMENTATION SURGERIES////// + + +//SURGERY STEPS + +/datum/surgery_step/replace + name = "sever muscles" + implements = list(/obj/item/scalpel = 100, /obj/item/wirecutters = 55) + time = 32 + + +/datum/surgery_step/replace/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] begins to sever the muscles on [target]'s [parse_zone(user.zone_selected)].", "You begin to sever the muscles on [target]'s [parse_zone(user.zone_selected)]...") + + +/datum/surgery_step/add_limb + name = "replace limb" + implements = list(/obj/item/bodypart = 100) + time = 32 + var/obj/item/bodypart/L = null // L because "limb" + + +/datum/surgery_step/add_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/obj/item/bodypart/aug = tool + if(aug.status != BODYPART_ROBOTIC) + to_chat(user, "that's not an augment silly!") + return -1 + if(aug.body_zone != target_zone) + to_chat(user, "[tool] isn't the right type for [parse_zone(target_zone)].") + return -1 + L = surgery.operated_bodypart + if(L) + user.visible_message("[user] begins to augment [target]'s [parse_zone(user.zone_selected)].", "You begin to augment [target]'s [parse_zone(user.zone_selected)]...") + else + user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") + + +//ACTUAL SURGERIES + +/datum/surgery/augmentation + name = "augmentation" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/replace, /datum/surgery_step/saw, /datum/surgery_step/add_limb) + species = list(/mob/living/carbon/human) + possible_locs = list("r_arm","l_arm","r_leg","l_leg","chest","head") + requires_real_bodypart = TRUE + +//SURGERY STEP SUCCESSES + +/datum/surgery_step/add_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/bodypart/tool, datum/surgery/surgery) + if(L) + user.visible_message("[user] successfully augments [target]'s [parse_zone(target_zone)]!", "You successfully augment [target]'s [parse_zone(target_zone)].") + L.change_bodypart_status(BODYPART_ROBOTIC, TRUE) + L.icon = tool.icon + L.max_damage = tool.max_damage + qdel(tool) + target.update_body_parts() + target.updatehealth() +>>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) target.update_hair() add_logs(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]") else diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index 4ba9faaf41..f30d45e422 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -127,7 +127,7 @@ tool = I else I = tool - user.drop_item() + user.temporarilyRemoveItemFromInventory(I, TRUE) I.Insert(target) user.visible_message("[user] inserts [tool] into [target]'s [parse_zone(target_zone)]!", "You insert [tool] into [target]'s [parse_zone(target_zone)].") diff --git a/code/modules/surgery/organs/autosurgeon.dm b/code/modules/surgery/organs/autosurgeon.dm index caa6cc7a97..0de1683fbd 100644 --- a/code/modules/surgery/organs/autosurgeon.dm +++ b/code/modules/surgery/organs/autosurgeon.dm @@ -49,9 +49,8 @@ else if(!uses) to_chat(user, "[src] has already been used up.") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - I.forceMove(src) storedorgan = I to_chat(user, "You insert the [I] into [src].") else if(istype(I, /obj/item/screwdriver)) diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index d1699cb257..9308154c48 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -89,7 +89,7 @@ /obj/item/organ/heart/cursed/attack(mob/living/carbon/human/H, mob/living/carbon/human/user, obj/target) if(H == user && istype(H)) playsound(user,'sound/effects/singlebeat.ogg',40,1) - user.drop_item() + user.temporarilyRemoveItemFromInventory(src, TRUE) Insert(user) else return ..() diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 4fdda7a7bc..681dcb21cf 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -92,10 +92,9 @@ if(status == ORGAN_ORGANIC) var/obj/item/reagent_containers/food/snacks/S = prepare_eat() if(S) - H.drop_item() - H.put_in_active_hand(S) - S.attack(H, H) qdel(src) + if(H.put_in_active_hand(S)) + S.attack(H, H) else ..() diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm index e817416d7e..2dddb95872 100644 --- a/code/modules/surgery/prosthetic_replacement.dm +++ b/code/modules/surgery/prosthetic_replacement.dm @@ -63,9 +63,8 @@ tool.desc = "A container for holding body parts." tool.cut_overlays() tool = tool.contents[1] - if(istype(tool, /obj/item/bodypart)) + if(istype(tool, /obj/item/bodypart) && user.temporarilyRemoveItemFromInventory(tool)) var/obj/item/bodypart/L = tool - user.drop_item() L.attach_limb(target) if(organ_rejection_dam) target.adjustToxLoss(organ_rejection_dam) diff --git a/code/modules/vehicles/pimpin_ride.dm b/code/modules/vehicles/pimpin_ride.dm index 7be42b6e4d..0d97cb63c1 100644 --- a/code/modules/vehicles/pimpin_ride.dm +++ b/code/modules/vehicles/pimpin_ride.dm @@ -47,10 +47,9 @@ if(mybag) to_chat(user, "[src] already has a trashbag hooked!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return to_chat(user, "You hook the trashbag onto [src].") - I.loc = src mybag = I update_icon() else if(istype(I, /obj/item/janiupgrade)) From 988dd758503c66aeaed6c596e89a6b83bf720ae3 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Sat, 7 Oct 2017 10:37:27 -0700 Subject: [PATCH 03/60] Allows editing config.allow_admin_ooccolor --- .../configuration/entries/config.dm | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/code/controllers/configuration/entries/config.dm b/code/controllers/configuration/entries/config.dm index ec96e88553..9da8e0105c 100644 --- a/code/controllers/configuration/entries/config.dm +++ b/code/controllers/configuration/entries/config.dm @@ -56,7 +56,6 @@ CONFIG_DEF(flag/log_twitter) // log certain expliotable parrots and other such f CONFIG_DEF(flag/log_world_topic) // log all world.Topic() calls CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour - protection = CONFIG_ENTRY_LOCKED CONFIG_DEF(flag/allow_vote_restart) // allow votes to restart @@ -351,4 +350,30 @@ CONFIG_DEF(number/error_msg_delay) // How long to wait between messaging admins CONFIG_DEF(flag/irc_announce_new_game) -CONFIG_DEF(flag/debug_admin_hrefs) \ No newline at end of file +<<<<<<< HEAD +CONFIG_DEF(flag/debug_admin_hrefs) +======= +CONFIG_DEF(flag/debug_admin_hrefs) + +CONFIG_DEF(number/mc_tick_rate/base_mc_tick_rate) + integer = FALSE + value = 1 + +CONFIG_DEF(number/mc_tick_rate/high_pop_mc_tick_rate) + integer = FALSE + value = 1.1 + +CONFIG_DEF(number/mc_tick_rate/high_pop_mc_mode_amount) + value = 65 + +CONFIG_DEF(number/mc_tick_rate/disable_high_pop_mc_mode_amount) + value = 60 + +CONFIG_TWEAK(number/mc_tick_rate) + abstract_type = /datum/config_entry/number/mc_tick_rate + +CONFIG_TWEAK(number/mc_tick_rate/ValidateAndSet(str_val)) + . = ..() + if (.) + Master.UpdateTickRate() +>>>>>>> 119f3fa... Allows editing config.allow_admin_ooccolor (#31371) From 4f32b7a0d4d8a27b4d26cbbed5212651e7fe9dba Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 7 Oct 2017 14:36:28 -0400 Subject: [PATCH 04/60] Moves assert_gas() into a define it should always have been, speeding up atmos slightly --- code/__DEFINES/atmospherics.dm | 10 +- .../game/mecha/equipment/tools/other_tools.dm | 2 +- .../effects/effect_system/effects_smoke.dm | 2 +- code/game/objects/items/tanks/jetpack.dm | 214 ++++++++++++++++++ code/game/objects/items/tanks/tank_types.dm | 17 +- code/game/turfs/turf.dm | 2 +- code/modules/admin/verbs/debug.dm | 2 +- .../atmospherics/gasmixtures/gas_mixture.dm | 43 ++-- .../gasmixtures/immutable_mixtures.dm | 2 +- .../atmospherics/gasmixtures/reactions.dm | 8 +- .../components/trinary_devices/filter.dm | 3 +- .../unary_devices/oxygen_generator.dm | 2 +- .../components/unary_devices/tank.dm | 2 +- .../components/unary_devices/vent_scrubber.dm | 14 +- .../atmospherics/machinery/other/miner.dm | 2 +- .../machinery/portable/canister.dm | 2 +- .../machinery/portable/scrubber.dm | 2 +- 17 files changed, 266 insertions(+), 63 deletions(-) diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index c6ca2cf0ec..c38f4d932e 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -175,4 +175,12 @@ #define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland #define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300" -#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity()) \ No newline at end of file +#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity()) + +#define ADD_GAS(gas_id, out_list)\ + var/list/tmp_gaslist = GLOB.gaslist_cache[gas_id];\ + out_list[gas_id] = tmp_gaslist.Copy(); + +//ASSERT_GAS(gas_id, gas_mixture) - used to guarantee that the gas list for this id exists in gas_mixture.gases. +//Must be used before adding to a gas. May be used before reading from a gas. +#define ASSERT_GAS(gas_id, gas_mixture) if (!gas_mixture.gases[gas_id]) { ADD_GAS(gas_id, gas_mixture.gases) }; diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index e22db80bb7..3eaddc14d2 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -426,7 +426,7 @@ if(!istype(T)) return var/datum/gas_mixture/GM = new - GM.assert_gas("plasma") + ASSERT_GAS("plasma", GM) if(prob(10)) GM.gases["plasma"][MOLES] += 100 GM.temperature = 1500+T0C //should be enough to start a fire diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index 3f32b18178..538ea3bd84 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -169,7 +169,7 @@ qdel(H) var/list/G_gases = G.gases if(G_gases["plasma"]) - G.assert_gas("n2") + ASSERT_GAS("n2", G) G_gases["n2"][MOLES] += (G_gases["plasma"][MOLES]) G_gases["plasma"][MOLES] = 0 G.garbage_collect() diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 650da88240..65e37ed906 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/item/tank/jetpack name = "jetpack (empty)" desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution." @@ -209,3 +210,216 @@ var/obj/item/clothing/suit/space/hardsuit/C = wear_suit J = C.jetpack return J +======= +/obj/item/tank/jetpack + name = "jetpack (empty)" + desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution." + icon_state = "jetpack" + item_state = "jetpack" + lefthand_file = 'icons/mob/inhands/equipment/jetpacks_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/jetpacks_righthand.dmi' + w_class = WEIGHT_CLASS_BULKY + distribute_pressure = ONE_ATMOSPHERE * O2STANDARD + actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) + var/gas_type = "o2" + var/on = FALSE + var/stabilizers = FALSE + var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not + var/datum/effect_system/trail_follow/ion/ion_trail + +/obj/item/tank/jetpack/New() + ..() + if(gas_type) + ASSERT_GAS(gas_type,air_contents) + air_contents.gases[gas_type][MOLES] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) + + ion_trail = new + ion_trail.set_up(src) + +/obj/item/tank/jetpack/ui_action_click(mob/user, action) + if(istype(action, /datum/action/item_action/toggle_jetpack)) + cycle(user) + else if(istype(action, /datum/action/item_action/jetpack_stabilization)) + if(on) + stabilizers = !stabilizers + to_chat(user, "You turn the jetpack stabilization [stabilizers ? "on" : "off"].") + else + toggle_internals(user) + + +/obj/item/tank/jetpack/proc/cycle(mob/user) + if(user.incapacitated()) + return + + if(!on) + turn_on() + to_chat(user, "You turn the jetpack on.") + else + turn_off() + to_chat(user, "You turn the jetpack off.") + for(var/X in actions) + var/datum/action/A = X + A.UpdateButtonIcon() + + +/obj/item/tank/jetpack/proc/turn_on() + on = TRUE + icon_state = "[initial(icon_state)]-on" + ion_trail.start() + +/obj/item/tank/jetpack/proc/turn_off() + on = FALSE + stabilizers = FALSE + icon_state = initial(icon_state) + ion_trail.stop() + +/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user) + if(!on) + return + if((num < 0.005 || air_contents.total_moles() < num)) + turn_off() + return + + var/datum/gas_mixture/removed = air_contents.remove(num) + if(removed.total_moles() < 0.005) + turn_off() + return + + var/turf/T = get_turf(user) + T.assume_air(removed) + + return 1 + +/obj/item/tank/jetpack/suicide_act(mob/user) + if (istype(user, /mob/living/carbon/human/)) + var/mob/living/carbon/human/H = user + H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?") + H.visible_message("[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!") + return (OXYLOSS) + else + ..() + +/obj/item/tank/jetpack/void + name = "void jetpack (oxygen)" + desc = "It works well in a void." + icon_state = "jetpack-void" + item_state = "jetpack-void" + +/obj/item/tank/jetpack/oxygen + name = "jetpack (oxygen)" + desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution." + icon_state = "jetpack" + item_state = "jetpack" + +/obj/item/tank/jetpack/oxygen/harness + name = "jet harness (oxygen)" + desc = "A lightweight tactical harness, used by those who don't want to be weighed down by traditional jetpacks." + icon_state = "jetpack-mini" + item_state = "jetpack-mini" + volume = 40 + throw_range = 7 + w_class = WEIGHT_CLASS_NORMAL + +/obj/item/tank/jetpack/oxygen/captain + name = "\improper Captain's jetpack" + desc = "A compact, lightweight jetpack containing a high amount of compressed oxygen." + icon_state = "jetpack-captain" + item_state = "jetpack-captain" + w_class = WEIGHT_CLASS_NORMAL + volume = 90 + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //steal objective items are hard to destroy. + +/obj/item/tank/jetpack/oxygen/security + name = "security jetpack (oxygen)" + desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas by security forces." + icon_state = "jetpack-sec" + item_state = "jetpack-sec" + +/obj/item/tank/jetpack/carbondioxide + name = "jetpack (carbon dioxide)" + desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals." + icon_state = "jetpack-black" + item_state = "jetpack-black" + distribute_pressure = 0 + gas_type = "co2" + + +/obj/item/tank/jetpack/suit + name = "hardsuit jetpack upgrade" + desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment." + origin_tech = "materials=4;magnets=4;engineering=5" + icon_state = "jetpack-mining" + item_state = "jetpack-black" + w_class = WEIGHT_CLASS_NORMAL + actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) + volume = 1 + slot_flags = null + gas_type = null + full_speed = FALSE + var/datum/gas_mixture/temp_air_contents + var/obj/item/tank/internals/tank = null + +/obj/item/tank/jetpack/suit/New() + ..() + STOP_PROCESSING(SSobj, src) + temp_air_contents = air_contents + +/obj/item/tank/jetpack/suit/attack_self() + return + +/obj/item/tank/jetpack/suit/cycle(mob/user) + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit)) + to_chat(user, "\The [src] must be connected to a hardsuit!") + return + + var/mob/living/carbon/human/H = user + if(!istype(H.s_store, /obj/item/tank/internals)) + to_chat(user, "You need a tank in your suit storage!") + return + ..() + +/obj/item/tank/jetpack/suit/turn_on() + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) + return + var/mob/living/carbon/human/H = loc.loc + tank = H.s_store + air_contents = tank.air_contents + START_PROCESSING(SSobj, src) + ..() + +/obj/item/tank/jetpack/suit/turn_off() + tank = null + air_contents = temp_air_contents + STOP_PROCESSING(SSobj, src) + ..() + +/obj/item/tank/jetpack/suit/process() + if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) + turn_off() + return + var/mob/living/carbon/human/H = loc.loc + if(!tank || tank != H.s_store) + turn_off() + return + ..() + + +//Return a jetpack that the mob can use +//Back worn jetpacks, hardsuit internal packs, and so on. +//Used in Process_Spacemove() and wherever you want to check for/get a jetpack + +/mob/proc/get_jetpack() + return + +/mob/living/carbon/get_jetpack() + var/obj/item/tank/jetpack/J = back + if(istype(J)) + return J + +/mob/living/carbon/human/get_jetpack() + var/obj/item/tank/jetpack/J = ..() + if(!istype(J) && istype(wear_suit, /obj/item/clothing/suit/space/hardsuit)) + var/obj/item/clothing/suit/space/hardsuit/C = wear_suit + J = C.jetpack + return J +>>>>>>> 6b9832d... Merge pull request #31388 from vuonojenmustaturska/atmoscherrypicking diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm index 9892c35445..146693dd05 100644 --- a/code/game/objects/items/tanks/tank_types.dm +++ b/code/game/objects/items/tanks/tank_types.dm @@ -21,7 +21,7 @@ /obj/item/tank/internals/oxygen/New() ..() - air_contents.assert_gas("o2") + ASSERT_GAS("o2", air_contents) air_contents.gases["o2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -87,7 +87,7 @@ /obj/item/tank/internals/plasma/New() ..() - air_contents.assert_gas("plasma") + ASSERT_GAS("plasma", air_contents) air_contents.gases["plasma"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -105,8 +105,7 @@ return ..() /obj/item/tank/internals/plasma/full/New() - ..() - air_contents.assert_gas("plasma") + ..() // Plasma asserted in parent air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -125,13 +124,12 @@ /obj/item/tank/internals/plasmaman/New() ..() - air_contents.assert_gas("plasma") + ASSERT_GAS("plasma", air_contents) air_contents.gases["plasma"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return /obj/item/tank/internals/plasmaman/full/New() - ..() - air_contents.assert_gas("plasma") + ..() // Plasma asserted in parent air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -145,8 +143,7 @@ w_class = WEIGHT_CLASS_SMALL //thanks i forgot this /obj/item/tank/internals/plasmaman/belt/full/New() - ..() - air_contents.assert_gas("plasma") + ..() // Plasma asserted in parent air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -169,7 +166,7 @@ /obj/item/tank/internals/emergency_oxygen/New() ..() - air_contents.assert_gas("o2") + ASSERT_GAS("o2", air_contents) air_contents.gases["o2"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index b02444281c..66406b88be 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -289,7 +289,7 @@ continue var/list/S_gases = S.air.gases for(var/id in S_gases) - total.assert_gas(id) + ASSERT_GAS(id, total) total_gases[id][MOLES] += S_gases[id][MOLES] total.temperature += S.air.temperature diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index cff80e6117..7fc6bc2e9f 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -715,7 +715,7 @@ GLOBAL_PROTECT(LastAdminCalledProc) if(Rad.anchored) if(!Rad.loaded_tank) var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad) - Plasma.air_contents.assert_gas("plasma") + ASSERT_GAS("plasma", Plasma.air_contents) Plasma.air_contents.gases["plasma"][MOLES] = 70 Rad.drainratio = 0 Rad.loaded_tank = Plasma diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index ac8349f5f7..b9cba55ae6 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -21,10 +21,6 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) cached_gas[ARCHIVE] = 0 cached_gas[GAS_META] = GLOB.meta_gas_info[id] -#define GASLIST(id, out_list)\ - var/list/tmp_gaslist = GLOB.gaslist_cache[id];\ - out_list = tmp_gaslist.Copy(); - /datum/gas_mixture var/list/gases var/temperature //kelvins @@ -43,30 +39,18 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) //listmos procs - //assert_gas(gas_id) - used to guarantee that the gas list for this id exists. - //Must be used before adding to a gas. May be used before reading from a gas. -/datum/gas_mixture/proc/assert_gas(gas_id) - var/cached_gases = gases - if(cached_gases[gas_id]) - return - GASLIST(gas_id, cached_gases[gas_id]) +// The following procs used to live here: thermal_energy(), assert_gas() and add_gas(). They have been moved into defines in code/__DEFINES/atmospherics.dm - //assert_gases(args) - shorthand for calling assert_gas() once for each gas type. + //assert_gases(args) - shorthand for calling ASSERT_GAS() once for each gas type. /datum/gas_mixture/proc/assert_gases() for(var/id in args) - assert_gas(id) - - //add_gas(gas_id) - similar to assert_gas(), but does not check for an existing - //gas list for this id. This can clobber existing gases. - //Used instead of assert_gas() when you know the gas does not exist. Faster than assert_gas(). -/datum/gas_mixture/proc/add_gas(gas_id) - GASLIST(gas_id, gases[gas_id]) + ASSERT_GAS(id, src) //add_gases(args) - shorthand for calling add_gas() once for each gas_type. /datum/gas_mixture/proc/add_gases() var/cached_gases = gases for(var/id in args) - GASLIST(id, cached_gases[id]) + ADD_GAS(id, cached_gases) //garbage_collect() - removes any gas list which is empty. //If called with a list as an argument, only removes gas lists with IDs from that list. @@ -80,6 +64,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) cached_gases -= id //PV = nRT + /datum/gas_mixture/proc/heat_capacity() //joules per kelvin var/list/cached_gases = gases . = 0 @@ -195,7 +180,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) var/list/giver_gases = giver.gases //gas transfer for(var/giver_id in giver_gases) - assert_gas(giver_id) + ASSERT_GAS(giver_id, src) cached_gases[giver_id][MOLES] += giver_gases[giver_id][MOLES] return 1 @@ -212,7 +197,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) removed.temperature = temperature for(var/id in cached_gases) - removed.add_gas(id) + ADD_GAS(id, removed.gases) removed_gases[id][MOLES] = QUANTIZE((cached_gases[id][MOLES] / sum) * amount) cached_gases[id][MOLES] -= removed_gases[id][MOLES] garbage_collect() @@ -230,7 +215,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) removed.temperature = temperature for(var/id in cached_gases) - removed.add_gas(id) + ADD_GAS(id, removed.gases) removed_gases[id][MOLES] = QUANTIZE(cached_gases[id][MOLES] * ratio) cached_gases[id][MOLES] -= removed_gases[id][MOLES] @@ -245,18 +230,19 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) copy.temperature = temperature for(var/id in cached_gases) - copy.add_gas(id) + ADD_GAS(id, copy.gases) copy_gases[id][MOLES] = cached_gases[id][MOLES] return copy + /datum/gas_mixture/copy_from(datum/gas_mixture/sample) var/list/cached_gases = gases //accessing datum vars is slower than proc vars var/list/sample_gases = sample.gases temperature = sample.temperature for(var/id in sample_gases) - assert_gas(id) + ASSERT_GAS(id,src) cached_gases[id][MOLES] = sample_gases[id][MOLES] //remove all gases not in the sample @@ -282,7 +268,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) gas -= "TEMP" gases.Cut() for(var/id in gas) - add_gas(id) + ADD_GAS(id, gases) gases[id][MOLES] = text2num(gas[id]) return 1 @@ -310,10 +296,9 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) //GAS TRANSFER for(var/id in sharer_gases - cached_gases) // create gases not in our cache - add_gas(id) + ADD_GAS(id, gases) for(var/id in cached_gases) // transfer gases - if(!sharer_gases[id]) //checking here prevents an uneeded proc call if the check fails. - sharer.add_gas(id) + ASSERT_GAS(id, sharer) var/gas = cached_gases[id] var/sharergas = sharer_gases[id] diff --git a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm index 086e21daca..50e1b38e52 100644 --- a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm +++ b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm @@ -69,7 +69,7 @@ /datum/gas_mixture/immutable/cloner/garbage_collect() ..() - add_gas("n2") + ADD_GAS("n2", gases) gases["n2"][MOLES] = MOLES_O2STANDARD + MOLES_N2STANDARD /datum/gas_mixture/immutable/cloner/heat_capacity() diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index abbfcf8924..c466213409 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -57,7 +57,7 @@ cached_gases["co2"][MOLES] -= reaction_rate cached_gases["agent_b"][MOLES] -= reaction_rate*0.05 - air.assert_gas("o2") //only need to assert oxygen, as this reaction doesn't occur without the other gases existing + ASSERT_GAS("o2", air) //only need to assert oxygen, as this reaction doesn't occur without the other gases existing cached_gases["o2"][MOLES] += reaction_rate air.temperature -= (reaction_rate*20000)/air.heat_capacity() @@ -126,7 +126,7 @@ if(burned_fuel) energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel - air.assert_gas("co2") + ASSERT_GAS("co2", air) cached_gases["co2"][MOLES] += burned_fuel cached_results[id] += burned_fuel @@ -142,14 +142,14 @@ else temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE) if(temperature_scale > 0) - air.assert_gas("o2") + ASSERT_GAS("o2", air) oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale if(cached_gases["o2"][MOLES] > cached_gases["plasma"][MOLES]*PLASMA_OXYGEN_FULLBURN) plasma_burn_rate = (cached_gases["plasma"][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA else plasma_burn_rate = (temperature_scale*(cached_gases["o2"][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY) - air.assert_gas("co2") + ASSERT_GAS("co2", air) cached_gases["plasma"][MOLES] = QUANTIZE(cached_gases["plasma"][MOLES] - plasma_burn_rate) cached_gases["o2"][MOLES] = QUANTIZE(cached_gases["o2"][MOLES] - (plasma_burn_rate * oxygen_burn_rate)) cached_gases["co2"][MOLES] += plasma_burn_rate diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 2b5a94ef64..4e3ef0f3cc 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -96,7 +96,7 @@ var/datum/gas_mixture/filtered_out = new filtered_out.temperature = removed.temperature - filtered_out.assert_gas(filter_type) + ASSERT_GAS(filter_type, filtered_out) filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES] removed.gases[filter_type][MOLES] = 0 @@ -166,4 +166,3 @@ if(. && on && is_operational()) to_chat(user, "You cannot unwrench [src], turn it off first!") return FALSE - diff --git a/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm b/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm index e31d1efa96..0be10fecf0 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm @@ -47,7 +47,7 @@ var/added_oxygen = oxygen_content - total_moles air_contents.temperature = (current_heat_capacity*air_contents.temperature + 20*added_oxygen*T0C)/(current_heat_capacity+20*added_oxygen) - air_contents.assert_gas("o2") + ASSERT_GAS("o2", air_contents) air_contents.gases["o2"][MOLES] += added_oxygen update_parents() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm index 4b2b1843fe..3b0055edab 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm @@ -16,7 +16,7 @@ air_contents.volume = volume air_contents.temperature = T20C if(gas_type) - air_contents.assert_gas(gas_type) + ASSERT_GAS(gas_type, air_contents) air_contents.gases[gas_type][MOLES] = AIR_CONTENTS name = "[name] ([air_contents.gases[gas_type][GAS_META][META_GAS_NAME]])" diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index d92b061cec..1abf84df10 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -196,37 +196,37 @@ filtered_out.temperature = removed.temperature if(scrub_Toxins && removed_gases["plasma"]) - filtered_out.add_gas("plasma") + ADD_GAS("plasma", filtered_out.gases) filtered_gases["plasma"][MOLES] = removed_gases["plasma"][MOLES] removed.gases["plasma"][MOLES] = 0 if(scrub_CO2 && removed_gases["co2"]) - filtered_out.add_gas("co2") + ADD_GAS("co2", filtered_out.gases) filtered_gases["co2"][MOLES] = removed_gases["co2"][MOLES] removed_gases["co2"][MOLES] = 0 if(removed_gases["agent_b"]) - filtered_out.add_gas("agent_b") + ADD_GAS("agent_b", filtered_out.gases) filtered_gases["agent_b"][MOLES] = removed_gases["agent_b"][MOLES] removed_gases["agent_b"][MOLES] = 0 if(scrub_N2O && removed_gases["n2o"]) - filtered_out.add_gas("n2o") + ADD_GAS("n2o", filtered_out.gases) filtered_gases["n2o"][MOLES] = removed_gases["n2o"][MOLES] removed_gases["n2o"][MOLES] = 0 if(scrub_BZ && removed_gases["bz"]) - filtered_out.add_gas("bz") + ADD_GAS("bz", filtered_out.gases) filtered_gases["bz"][MOLES] = removed_gases["bz"][MOLES] removed_gases["bz"][MOLES] = 0 if(scrub_Freon && removed_gases["freon"]) - filtered_out.add_gas("freon") + ADD_GAS("freon", filtered_out.gases) filtered_gases["freon"][MOLES] = removed_gases["freon"][MOLES] removed_gases["freon"][MOLES] = 0 if(scrub_WaterVapor && removed_gases["water_vapor"]) - filtered_out.add_gas("water_vapor") + ADD_GAS("water_vapor", filtered_out.gases) filtered_gases["water_vapor"][MOLES] = removed_gases["water_vapor"][MOLES] removed_gases["water_vapor"][MOLES] = 0 diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm index 20439e5c2b..1db4c5edd3 100644 --- a/code/modules/atmospherics/machinery/other/miner.dm +++ b/code/modules/atmospherics/machinery/other/miner.dm @@ -132,7 +132,7 @@ if(!isopenturf(O)) return FALSE var/datum/gas_mixture/merger = new - merger.assert_gas(spawn_id) + ASSERT_GAS(spawn_id, merger) merger.gases[spawn_id][MOLES] = (spawn_mol) merger.temperature = spawn_temp O.assume_air(merger) diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 024330ed7e..c08ef25b61 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -174,7 +174,7 @@ /obj/machinery/portable_atmospherics/canister/proc/create_gas() if(gas_type) - air_contents.add_gas(gas_type) + ADD_GAS(gas_type, air_contents.gases) if(starter_temp) air_contents.temperature = starter_temp air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index 93475a00a7..7a76405a90 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -45,7 +45,7 @@ filtered.temperature = filtering.temperature for(var/gas in filtering.gases & scrubbing) - filtered.add_gas(gas) + ADD_GAS(gas, filtered.gases) filtered.gases[gas][MOLES] = filtering.gases[gas][MOLES] // Shuffle the "bad" gasses to the filtered mixture. filtering.gases[gas][MOLES] = 0 filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture. From 98a34c22115468b0b9f81f7d92a5a3896792e7dd Mon Sep 17 00:00:00 2001 From: Robustin Date: Sat, 7 Oct 2017 19:01:30 -0400 Subject: [PATCH 05/60] Virus Neuter Fix (#31392) --- code/datums/diseases/advance/advance.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 26f42fa059..2f39f99ca0 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -290,9 +290,10 @@ if(!id) var/list/L = list() for(var/datum/symptom/S in symptoms) - L += S.id if(S.neutered) - L += "N" + L += "[S.id]N" + else + L += S.id L = sortList(L) // Sort the list so it doesn't matter which order the symptoms are in. var/result = jointext(L, ":") id = result From 0ad78d0c4463daffe6a2fc2fd87f92ff9bb17069 Mon Sep 17 00:00:00 2001 From: bawhoppen Date: Sat, 7 Oct 2017 19:11:17 -0500 Subject: [PATCH 07/60] frown emoji (#31393) --- code/game/objects/items/stacks/wrap.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/objects/items/stacks/wrap.dm b/code/game/objects/items/stacks/wrap.dm index 8d42b97e95..baa462e907 100644 --- a/code/game/objects/items/stacks/wrap.dm +++ b/code/game/objects/items/stacks/wrap.dm @@ -7,7 +7,7 @@ /obj/item/stack/wrapping_paper name = "wrapping paper" desc = "Wrap packages with this festive paper to make gifts." - icon = 'icons/obj/items_and_weapons.dmi' + icon = 'icons/obj/stack_objects.dmi' icon_state = "wrap_paper" flags_1 = NOBLUDGEON_1 amount = 25 @@ -28,7 +28,7 @@ /obj/item/stack/packageWrap name = "package wrapper" desc = "You can use this to wrap items in." - icon = 'icons/obj/items_and_weapons.dmi' + icon = 'icons/obj/stack_objects.dmi' icon_state = "deliveryPaper" flags_1 = NOBLUDGEON_1 amount = 25 @@ -109,7 +109,7 @@ /obj/item/c_tube name = "cardboard tube" desc = "A tube... of cardboard." - icon = 'icons/obj/items_and_weapons.dmi' + icon = 'icons/obj/stack_objects.dmi' icon_state = "c_tube" throwforce = 0 w_class = WEIGHT_CLASS_TINY From 92ec5c11ab79402d12561c143861fecc13776132 Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Sat, 7 Oct 2017 20:12:53 -0400 Subject: [PATCH 09/60] Fixes being able to sell camera mobs to CentCom (#31306) * Fixes being able to sell camera mobs to CENTCOM * Did it Ninja's way. --- code/__DEFINES/is_helpers.dm | 2 ++ code/__HELPERS/unsorted.dm | 2 +- code/modules/holodeck/area_copy.dm | 2 +- code/modules/shuttle/supply.dm | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 1de917d5e1..c3da908ee1 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -133,6 +133,8 @@ #define isovermind(A) (istype(A, /mob/camera/blob)) +#define iscameramob(A) (istype(A, /mob/camera)) + //Objects #define isobj(A) istype(A, /obj) //override the byond proc because it returns true on children of /atom/movable that aren't objs diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 5e190ab709..6c7bb0cda6 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -289,7 +289,7 @@ Turf and target are separate in case you want to teleport some distance from a t var/list/pois = list() for(var/mob/M in mobs) if(skip_mindless && (!M.mind && !M.ckey)) - if(!isbot(M) && !istype(M, /mob/camera) && !ismegafauna(M)) + if(!isbot(M) && !iscameramob(M) && !ismegafauna(M)) continue if(M.client && M.client.holder && M.client.holder.fakekey) //stealthmins continue diff --git a/code/modules/holodeck/area_copy.dm b/code/modules/holodeck/area_copy.dm index 9da772eaee..295441b04e 100644 --- a/code/modules/holodeck/area_copy.dm +++ b/code/modules/holodeck/area_copy.dm @@ -103,7 +103,7 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars,list("tag","area","type","loc","locs", copiedobjs += O2.GetAllContents() for(var/mob/M in T) - if(istype(M, /mob/camera)) + if(iscameramob(M)) continue // If we need to check for more mobs, I'll add a variable var/mob/SM = DuplicateObject(M , perfectcopy=TRUE, newloc = B, holoitem=TRUE) copiedobjs += SM.GetAllContents() diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 56c7b85410..7e1dee155d 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -120,7 +120,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( for(var/place in shuttle_areas) var/area/shuttle/shuttle_area = place for(var/atom/movable/AM in shuttle_area) - if(AM.anchored) + if(AM.anchored || iscameramob(AM)) continue sold_atoms += export_item_and_contents(AM, contraband, emagged, dry_run = FALSE) From 661c2d293b69e4399476fe115a873d1c8a9d96eb Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:45:04 -0500 Subject: [PATCH 11/60] Update client_procs.dm --- code/modules/client/client_procs.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 8e8361194d..e755ff28ac 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -351,11 +351,8 @@ GLOBAL_LIST(external_rsc_urls) if (menuitem) menuitem.Load_checked(src) -<<<<<<< HEAD hook_vr("client_new",list(src)) -======= Master.UpdateTickRate() ->>>>>>> bc4d4e7... Merge pull request #31374 from MrStonedOne/highpopmode ////////////// //DISCONNECT// From 12506ade241109b675b2164ddd00376830ea7971 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:48:23 -0500 Subject: [PATCH 12/60] Update cough.dm --- .../datums/diseases/advance/symptoms/cough.dm | 101 ++++++------------ 1 file changed, 30 insertions(+), 71 deletions(-) diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm index 6b84e88dfb..f0178576bf 100644 --- a/code/datums/diseases/advance/symptoms/cough.dm +++ b/code/datums/diseases/advance/symptoms/cough.dm @@ -1,79 +1,39 @@ -/* -////////////////////////////////////// - -Coughing - - Noticable. - Little Resistance. - Doesn't increase stage speed much. - Transmittable. - Low Level. - -BONUS - Will force the affected mob to drop small items! - -////////////////////////////////////// -*/ - -/datum/symptom/cough - - name = "Cough" +/* +////////////////////////////////////// + +Coughing + + Noticable. + Little Resistance. + Doesn't increase stage speed much. + Transmittable. + Low Level. + +BONUS + Will force the affected mob to drop small items! + +////////////////////////////////////// +*/ + +/datum/symptom/cough + + name = "Cough" desc = "The virus irritates the throat of the host, causing occasional coughing." - stealth = -1 - resistance = 3 - stage_speed = 1 - transmittable = 2 - level = 1 - severity = 1 - base_message_chance = 15 - symptom_delay_min = 2 - symptom_delay_max = 15 - var/infective = FALSE + stealth = -1 + resistance = 3 + stage_speed = 1 + transmittable = 2 + level = 1 + severity = 1 + base_message_chance = 15 + symptom_delay_min = 2 + symptom_delay_max = 15 + var/infective = FALSE threshold_desc = "Resistance 3: Host will drop small items when coughing.
\ Resistance 10: Occasionally causes coughing fits that stun the host.
\ Stage Speed 6: Increases cough frequency.
\ If Airborne: Coughing will infect bystanders.
\ Stealth 4: The symptom remains hidden until active." -<<<<<<< HEAD - -/datum/symptom/cough/Start(datum/disease/advance/A) - ..() - if(A.properties["stealth"] >= 4) - suppress_warning = TRUE - if(A.spread_flags &= AIRBORNE) //infect bystanders - infective = TRUE - if(A.properties["resistance"] >= 3) //strong enough to drop items - power = 1.5 - if(A.properties["resistance"] >= 10) //strong enough to stun (rarely) - power = 2 - if(A.properties["stage_rate"] >= 6) //cough more often - symptom_delay_max = 10 - -/datum/symptom/cough/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(1, 2, 3) - if(prob(base_message_chance) && !suppress_warning) - to_chat(M, "[pick("You swallow excess mucus.", "You lightly cough.")]") - else - M.emote("cough") - if(power >= 1.5) - var/obj/item/I = M.get_active_held_item() - if(I && I.w_class == WEIGHT_CLASS_TINY) - M.drop_item() - if(power >= 2 && prob(10)) - to_chat(M, "[pick("You have a coughing fit!", "You can't stop coughing!")]") - M.Stun(20) - M.emote("cough") - addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 6) - addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 12) - addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 18) - if(infective) - A.spread(1) - -======= /datum/symptom/cough/Start(datum/disease/advance/A) ..() @@ -112,4 +72,3 @@ BONUS if(infective) A.spread(1) ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) From 68fa18f489df3a94a532ffefd80e204d09d6c389 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:48:55 -0500 Subject: [PATCH 13/60] Update PDApainter.dm --- code/game/machinery/PDApainter.dm | 218 +++++++++++------------------- 1 file changed, 79 insertions(+), 139 deletions(-) diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index 9721fb6ee1..00289ee84b 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -1,32 +1,32 @@ -/obj/machinery/pdapainter - name = "\improper PDA painter" - desc = "A PDA painting machine. To use, simply insert your PDA and choose the desired preset paint scheme." - icon = 'icons/obj/pda.dmi' - icon_state = "pdapainter" +/obj/machinery/pdapainter + name = "\improper PDA painter" + desc = "A PDA painting machine. To use, simply insert your PDA and choose the desired preset paint scheme." + icon = 'icons/obj/pda.dmi' + icon_state = "pdapainter" density = TRUE anchored = TRUE - var/obj/item/device/pda/storedpda = null - var/list/colorlist = list() - max_integrity = 200 - - -/obj/machinery/pdapainter/update_icon() - cut_overlays() - - if(stat & BROKEN) - icon_state = "[initial(icon_state)]-broken" - return - - if(storedpda) - add_overlay("[initial(icon_state)]-closed") - - if(powered()) - icon_state = initial(icon_state) - else - icon_state = "[initial(icon_state)]-off" - - return - + var/obj/item/device/pda/storedpda = null + var/list/colorlist = list() + max_integrity = 200 + + +/obj/machinery/pdapainter/update_icon() + cut_overlays() + + if(stat & BROKEN) + icon_state = "[initial(icon_state)]-broken" + return + + if(storedpda) + add_overlay("[initial(icon_state)]-closed") + + if(powered()) + icon_state = initial(icon_state) + else + icon_state = "[initial(icon_state)]-off" + + return + /obj/machinery/pdapainter/Initialize() . = ..() var/list/blocked = list( @@ -37,74 +37,15 @@ /obj/item/device/pda/syndicate) for(var/P in typesof(/obj/item/device/pda) - blocked) - var/obj/item/device/pda/D = new P - - //D.name = "PDA Style [colorlist.len+1]" //Gotta set the name, otherwise it all comes up as "PDA" - D.name = D.icon_state //PDAs don't have unique names, but using the sprite names works. - - src.colorlist += D - -/obj/machinery/pdapainter/Destroy() + var/obj/item/device/pda/D = new P + + //D.name = "PDA Style [colorlist.len+1]" //Gotta set the name, otherwise it all comes up as "PDA" + D.name = D.icon_state //PDAs don't have unique names, but using the sprite names works. + + src.colorlist += D + +/obj/machinery/pdapainter/Destroy() QDEL_NULL(storedpda) -<<<<<<< HEAD - return ..() - -/obj/machinery/pdapainter/on_deconstruction() - if(storedpda) - storedpda.forceMove(loc) - storedpda = null - -/obj/machinery/pdapainter/contents_explosion(severity, target) - if(storedpda) - storedpda.ex_act(severity, target) - -/obj/machinery/pdapainter/handle_atom_del(atom/A) - if(A == storedpda) - storedpda = null - update_icon() - -/obj/machinery/pdapainter/attackby(obj/item/O, mob/user, params) - if(default_unfasten_wrench(user, O)) - power_change() - return - - else if(istype(O, /obj/item/device/pda)) - if(storedpda) - to_chat(user, "There is already a PDA inside!") - return - else - var/obj/item/device/pda/P = user.get_active_held_item() - if(istype(P)) - if(!user.drop_item()) - return - storedpda = P - P.loc = src - P.add_fingerprint(user) - update_icon() - - else if(istype(O, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) - var/obj/item/weldingtool/WT = O - if(stat & BROKEN) - if(WT.remove_fuel(0,user)) - user.visible_message("[user] is repairing [src].", \ - "You begin repairing [src]...", \ - "You hear welding.") - playsound(loc, WT.usesound, 40, 1) - if(do_after(user,40*WT.toolspeed, 1, target = src)) - if(!WT.isOn() || !(stat & BROKEN)) - return - to_chat(user, "You repair [src].") - playsound(loc, 'sound/items/welder2.ogg', 50, 1) - stat &= ~BROKEN - obj_integrity = max_integrity - update_icon() - else - to_chat(user, "[src] does not need repairs.") - else - return ..() - -/obj/machinery/pdapainter/deconstruct(disassembled = TRUE) -======= return ..() /obj/machinery/pdapainter/on_deconstruction() @@ -158,49 +99,48 @@ return ..() /obj/machinery/pdapainter/deconstruct(disassembled = TRUE) ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) if(!(flags_1 & NODECONSTRUCT_1)) - if(!(stat & BROKEN)) - stat |= BROKEN - update_icon() - -/obj/machinery/pdapainter/attack_hand(mob/user) - if(!..()) - add_fingerprint(user) - - if(storedpda) - var/obj/item/device/pda/P - P = input(user, "Select your color!", "PDA Painting") as null|anything in colorlist - if(!P) - return - if(!in_range(src, user)) - return - if(!storedpda)//is the pda still there? - return - storedpda.icon_state = P.icon_state - storedpda.desc = P.desc - ejectpda() - - else - to_chat(user, "\The [src] is empty.") - - -/obj/machinery/pdapainter/verb/ejectpda() - set name = "Eject PDA" - set category = "Object" - set src in oview(1) - - if(usr.stat || usr.restrained() || !usr.canmove) - return - - if(storedpda) - storedpda.loc = get_turf(src.loc) - storedpda = null - update_icon() - else - to_chat(usr, "The [src] is empty.") - - -/obj/machinery/pdapainter/power_change() - ..() - update_icon() + if(!(stat & BROKEN)) + stat |= BROKEN + update_icon() + +/obj/machinery/pdapainter/attack_hand(mob/user) + if(!..()) + add_fingerprint(user) + + if(storedpda) + var/obj/item/device/pda/P + P = input(user, "Select your color!", "PDA Painting") as null|anything in colorlist + if(!P) + return + if(!in_range(src, user)) + return + if(!storedpda)//is the pda still there? + return + storedpda.icon_state = P.icon_state + storedpda.desc = P.desc + ejectpda() + + else + to_chat(user, "\The [src] is empty.") + + +/obj/machinery/pdapainter/verb/ejectpda() + set name = "Eject PDA" + set category = "Object" + set src in oview(1) + + if(usr.stat || usr.restrained() || !usr.canmove) + return + + if(storedpda) + storedpda.loc = get_turf(src.loc) + storedpda = null + update_icon() + else + to_chat(usr, "The [src] is empty.") + + +/obj/machinery/pdapainter/power_change() + ..() + update_icon() From eabe7f67f51cc7a0c03ed909f087e170de270f85 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:49:19 -0500 Subject: [PATCH 14/60] Update constructable_frame.dm --- code/game/machinery/constructable_frame.dm | 283 ++------------------- 1 file changed, 21 insertions(+), 262 deletions(-) diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index bca494e8e0..99cbded13a 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -1,260 +1,20 @@ -/obj/structure/frame - name = "frame" - icon = 'icons/obj/stock_parts.dmi' - icon_state = "box_0" +/obj/structure/frame + name = "frame" + icon = 'icons/obj/stock_parts.dmi' + icon_state = "box_0" density = TRUE - max_integrity = 250 - var/obj/item/circuitboard/circuit = null - var/state = 1 - -/obj/structure/frame/examine(user) - ..() - if(circuit) - to_chat(user, "It has \a [circuit] installed.") - - -/obj/structure/frame/deconstruct(disassembled = TRUE) + max_integrity = 250 + var/obj/item/circuitboard/circuit = null + var/state = 1 + +/obj/structure/frame/examine(user) + ..() + if(circuit) + to_chat(user, "It has \a [circuit] installed.") + + +/obj/structure/frame/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) -<<<<<<< HEAD - new /obj/item/stack/sheet/metal(loc, 5) - if(circuit) - circuit.forceMove(loc) - circuit = null - qdel(src) - - -/obj/structure/frame/machine - name = "machine frame" - var/list/components = null - var/list/req_components = null - var/list/req_component_names = null // user-friendly names of components - -/obj/structure/frame/machine/examine(user) - ..() - if(state == 3 && req_components && req_component_names) - var/hasContent = 0 - var/requires = "It requires" - - for(var/i = 1 to req_components.len) - var/tname = req_components[i] - var/amt = req_components[tname] - if(amt == 0) - continue - var/use_and = i == req_components.len - requires += "[(hasContent ? (use_and ? ", and" : ",") : "")] [amt] [amt == 1 ? req_component_names[tname] : "[req_component_names[tname]]\s"]" - hasContent = 1 - - if(hasContent) - to_chat(user, requires + ".") - else - to_chat(user, "It does not require any more components.") - -/obj/structure/frame/machine/proc/update_namelist() - if(!req_components) - return - - req_component_names = new() - for(var/tname in req_components) - if(ispath(tname, /obj/item/stack)) - var/obj/item/stack/S = tname - var/singular_name = initial(S.singular_name) - if(singular_name) - req_component_names[tname] = singular_name - else - req_component_names[tname] = initial(S.name) - else - var/obj/O = tname - req_component_names[tname] = initial(O.name) - -/obj/structure/frame/machine/proc/get_req_components_amt() - var/amt = 0 - for(var/path in req_components) - amt += req_components[path] - return amt - -/obj/structure/frame/machine/attackby(obj/item/P, mob/user, params) - switch(state) - if(1) - if(istype(P, /obj/item/circuitboard/machine)) - to_chat(user, "The frame needs wiring first!") - return - else if(istype(P, /obj/item/circuitboard)) - to_chat(user, "This frame does not accept circuit boards of this type!") - return - if(istype(P, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = P - if(C.get_amount() >= 5) - playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) - to_chat(user, "You start to add cables to the frame...") - if(do_after(user, 20*P.toolspeed, target = src)) - if(C.get_amount() >= 5 && state == 1) - C.use(5) - to_chat(user, "You add cables to the frame.") - state = 2 - icon_state = "box_1" - else - to_chat(user, "You need five length of cable to wire the frame!") - return - if(istype(P, /obj/item/screwdriver) && !anchored) - playsound(src.loc, P.usesound, 50, 1) - user.visible_message("[user] disassembles the frame.", \ - "You start to disassemble the frame...", "You hear banging and clanking.") - if(do_after(user, 40*P.toolspeed, target = src)) - if(state == 1) - to_chat(user, "You disassemble the frame.") - var/obj/item/stack/sheet/metal/M = new (loc, 5) - M.add_fingerprint(user) - qdel(src) - return - if(istype(P, /obj/item/wrench)) - to_chat(user, "You start [anchored ? "un" : ""]securing [name]...") - playsound(src.loc, P.usesound, 75, 1) - if(do_after(user, 40*P.toolspeed, target = src)) - if(state == 1) - to_chat(user, "You [anchored ? "un" : ""]secure [name].") - anchored = !anchored - return - - if(2) - if(istype(P, /obj/item/wrench)) - to_chat(user, "You start [anchored ? "un" : ""]securing [name]...") - playsound(src.loc, P.usesound, 75, 1) - if(do_after(user, 40*P.toolspeed, target = src)) - to_chat(user, "You [anchored ? "un" : ""]secure [name].") - anchored = !anchored - return - - if(istype(P, /obj/item/circuitboard/machine)) - if(!anchored) - to_chat(user, "The frame needs to be secured first!") - return - var/obj/item/circuitboard/machine/B = P - if(!user.drop_item()) - return - playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) - to_chat(user, "You add the circuit board to the frame.") - circuit = B - B.loc = src - icon_state = "box_2" - state = 3 - components = list() - req_components = B.req_components.Copy() - update_namelist() - return - - else if(istype(P, /obj/item/circuitboard)) - to_chat(user, "This frame does not accept circuit boards of this type!") - return - - if(istype(P, /obj/item/wirecutters)) - playsound(src.loc, P.usesound, 50, 1) - to_chat(user, "You remove the cables.") - state = 1 - icon_state = "box_0" - var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( src.loc ) - A.amount = 5 - return - - if(3) - if(istype(P, /obj/item/crowbar)) - playsound(src.loc, P.usesound, 50, 1) - state = 2 - circuit.loc = src.loc - components.Remove(circuit) - circuit = null - if(components.len == 0) - to_chat(user, "You remove the circuit board.") - else - to_chat(user, "You remove the circuit board and other components.") - for(var/atom/movable/A in components) - A.loc = src.loc - desc = initial(desc) - req_components = null - components = null - icon_state = "box_1" - return - - if(istype(P, /obj/item/screwdriver)) - var/component_check = 1 - for(var/R in req_components) - if(req_components[R] > 0) - component_check = 0 - break - if(component_check) - playsound(src.loc, P.usesound, 50, 1) - var/obj/machinery/new_machine = new src.circuit.build_path(src.loc, 1) - new_machine.on_construction() - for(var/obj/O in new_machine.component_parts) - qdel(O) - new_machine.component_parts = list() - for(var/obj/O in src) - O.loc = null - new_machine.component_parts += O - circuit.loc = null - new_machine.RefreshParts() - qdel(src) - return - - if(istype(P, /obj/item/storage/part_replacer) && P.contents.len && get_req_components_amt()) - var/obj/item/storage/part_replacer/replacer = P - var/list/added_components = list() - var/list/part_list = list() - - //Assemble a list of current parts, then sort them by their rating! - for(var/obj/item/stock_parts/co in replacer) - part_list += co - //Sort the parts. This ensures that higher tier items are applied first. - part_list = sortTim(part_list, /proc/cmp_rped_sort) - - for(var/path in req_components) - while(req_components[path] > 0 && (locate(path) in part_list)) - var/obj/item/part = (locate(path) in part_list) - added_components[part] = path - replacer.remove_from_storage(part, src) - req_components[path]-- - part_list -= part - - for(var/obj/item/stock_parts/part in added_components) - components += part - to_chat(user, "[part.name] applied.") - if(added_components.len) - replacer.play_rped_sound() - return - - if(isitem(P) && get_req_components_amt()) - for(var/I in req_components) - if(istype(P, I) && (req_components[I] > 0)) - if(istype(P, /obj/item/stack)) - var/obj/item/stack/S = P - var/used_amt = min(round(S.get_amount()), req_components[I]) - - if(used_amt && S.use(used_amt)) - var/obj/item/stack/NS = locate(S.merge_type) in components - - if(!NS) - NS = new S.merge_type(src, used_amt) - components += NS - else - NS.add(used_amt) - - req_components[I] -= used_amt - to_chat(user, "You add [P] to [src].") - return - if(!user.drop_item()) - break - to_chat(user, "You add [P] to [src].") - P.forceMove(src) - components += P - req_components[I]-- - return 1 - to_chat(user, "You cannot add that to the machine!") - return 0 - if(user.a_intent == INTENT_HARM) - return ..() - - -/obj/structure/frame/machine/deconstruct(disassembled = TRUE) -======= new /obj/item/stack/sheet/metal(loc, 5) if(circuit) circuit.forceMove(loc) @@ -491,11 +251,10 @@ /obj/structure/frame/machine/deconstruct(disassembled = TRUE) ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) if(!(flags_1 & NODECONSTRUCT_1)) - if(state >= 2) - new /obj/item/stack/cable_coil(loc , 5) - for(var/X in components) - var/obj/item/I = X - I.forceMove(loc) - ..() \ No newline at end of file + if(state >= 2) + new /obj/item/stack/cable_coil(loc , 5) + for(var/X in components) + var/obj/item/I = X + I.forceMove(loc) + ..() From 62d2b26c7a85516f392eacbb69417b9bc8f4e935 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:49:52 -0500 Subject: [PATCH 15/60] Update handcuffs.dm --- code/game/objects/items/handcuffs.dm | 376 +-------------------------- 1 file changed, 1 insertion(+), 375 deletions(-) diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index e7dfc96ab5..6fb85e5ad5 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -1,377 +1,3 @@ -<<<<<<< HEAD -/obj/item/restraints - breakouttime = 600 - -//Handcuffs - -/obj/item/restraints/handcuffs - name = "handcuffs" - desc = "Use this to keep prisoners in line." - gender = PLURAL - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "handcuff" - lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 3 - throw_range = 5 - materials = list(MAT_METAL=500) - origin_tech = "engineering=3;combat=3" - breakouttime = 600 //Deciseconds = 60s = 1 minute - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) - var/cuffsound = 'sound/weapons/handcuffs.ogg' - var/trashtype = null //for disposable cuffs - -/obj/item/restraints/handcuffs/attack(mob/living/carbon/C, mob/living/carbon/human/user) - if(!istype(C)) - return - if(user.disabilities & CLUMSY && prob(50)) - to_chat(user, "Uh... how do those things work?!") - apply_cuffs(user,user) - return - - // chance of monkey retaliation - if(ismonkey(C) && prob(MONKEY_CUFF_RETALIATION_PROB)) - var/mob/living/carbon/monkey/M - M = C - M.retaliate(user) - - if(!C.handcuffed) - if(C.get_num_arms() >= 2 || C.get_arm_ignore()) - C.visible_message("[user] is trying to put [src.name] on [C]!", \ - "[user] is trying to put [src.name] on [C]!") - - playsound(loc, cuffsound, 30, 1, -2) - if(do_mob(user, C, 30) && (C.get_num_arms() >= 2 || C.get_arm_ignore())) - apply_cuffs(C,user) - to_chat(user, "You handcuff [C].") - SSblackbox.add_details("handcuffs","[type]") - - add_logs(user, C, "handcuffed") - else - to_chat(user, "You fail to handcuff [C]!") - else - to_chat(user, "[C] doesn't have two hands...") - -/obj/item/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user, var/dispense = 0) - if(target.handcuffed) - return - - if(!user.drop_item() && !dispense) - return - - var/obj/item/restraints/handcuffs/cuffs = src - if(trashtype) - cuffs = new trashtype() - else if(dispense) - cuffs = new type() - - cuffs.loc = target - target.handcuffed = cuffs - - target.update_handcuffed() - if(trashtype && !dispense) - qdel(src) - return - -/obj/item/restraints/handcuffs/sinew - name = "sinew restraints" - desc = "A pair of restraints fashioned from long strands of flesh." - icon = 'icons/obj/mining.dmi' - icon_state = "sinewcuff" - item_state = "sinewcuff" - breakouttime = 300 //Deciseconds = 30s - cuffsound = 'sound/weapons/cablecuff.ogg' - -/obj/item/restraints/handcuffs/cable - name = "cable restraints" - desc = "Looks like some cables tied together. Could be used to tie something up." - icon_state = "cuff_red" - item_state = "coil_red" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150, MAT_GLASS=75) - origin_tech = "engineering=2" - breakouttime = 300 //Deciseconds = 30s - cuffsound = 'sound/weapons/cablecuff.ogg' - var/datum/robot_energy_storage/wirestorage = null - -/obj/item/restraints/handcuffs/cable/attack(mob/living/carbon/C, mob/living/carbon/human/user) - if(!istype(C)) - return - if(wirestorage && wirestorage.energy < 15) - to_chat(user, "You need at least 15 wire to restrain [C]!") - return - return ..() - -/obj/item/restraints/handcuffs/cable/apply_cuffs(mob/living/carbon/target, mob/user, var/dispense = 0) - if(wirestorage) - if(!wirestorage.use_charge(15)) - to_chat(user, "You need at least 15 wire to restrain [target]!") - return - return ..(target, user, 1) - - return ..() - -/obj/item/restraints/handcuffs/cable/red - icon_state = "cuff_red" - item_state = "coil_red" - -/obj/item/restraints/handcuffs/cable/yellow - icon_state = "cuff_yellow" - item_state = "coil_yellow" - -/obj/item/restraints/handcuffs/cable/blue - icon_state = "cuff_blue" - item_state = "coil_blue" - -/obj/item/restraints/handcuffs/cable/green - icon_state = "cuff_green" - item_state = "coil_green" - -/obj/item/restraints/handcuffs/cable/pink - icon_state = "cuff_pink" - item_state = "coil_pink" - -/obj/item/restraints/handcuffs/cable/orange - icon_state = "cuff_orange" - item_state = "coil_orange" - -/obj/item/restraints/handcuffs/cable/cyan - icon_state = "cuff_cyan" - item_state = "coil_cyan" - -/obj/item/restraints/handcuffs/cable/white - icon_state = "cuff_white" - item_state = "coil_white" - -/obj/item/restraints/handcuffs/alien - icon_state = "handcuffAlien" - -/obj/item/restraints/handcuffs/fake - name = "fake handcuffs" - desc = "Fake handcuffs meant for gag purposes." - breakouttime = 10 //Deciseconds = 1s - -/obj/item/restraints/handcuffs/fake/kinky - name = "kinky handcuffs" - desc = "Fake handcuffs meant for erotic roleplay." - icon_state = "handcuffGag" - -/obj/item/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params) - ..() - if(istype(I, /obj/item/stack/rods)) - var/obj/item/stack/rods/R = I - if (R.use(1)) - var/obj/item/wirerod/W = new /obj/item/wirerod - remove_item_from_storage(user) - user.put_in_hands(W) - to_chat(user, "You wrap the cable restraint around the top of the rod.") - qdel(src) - else - to_chat(user, "You need one rod to make a wired rod!") - return - else if(istype(I, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/metal/M = I - if(M.get_amount() < 6) - to_chat(user, "You need at least six metal sheets to make good enough weights!") - return - to_chat(user, "You begin to apply [I] to [src]...") - if(do_after(user, 35, target = src)) - if(M.get_amount() < 6 || !M) - return - var/obj/item/restraints/legcuffs/bola/S = new /obj/item/restraints/legcuffs/bola - M.use(6) - user.put_in_hands(S) - to_chat(user, "You make some weights out of [I] and tie them to [src].") - remove_item_from_storage(user) - qdel(src) - else - return ..() - -/obj/item/restraints/handcuffs/cable/zipties/cyborg/attack(mob/living/carbon/C, mob/user) - if(iscyborg(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/restraints/handcuffs/cable/zipties/used(C) - C.update_handcuffed() - to_chat(user, "You handcuff [C].") - add_logs(user, C, "handcuffed") - else - to_chat(user, "You fail to handcuff [C]!") - -/obj/item/restraints/handcuffs/cable/zipties - name = "zipties" - desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use." - icon_state = "cuff_white" - lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' - materials = list() - breakouttime = 450 //Deciseconds = 45s - trashtype = /obj/item/restraints/handcuffs/cable/zipties/used - -/obj/item/restraints/handcuffs/cable/zipties/used - desc = "A pair of broken zipties." - icon_state = "cuff_white_used" - item_state = "cuff_white" - -/obj/item/restraints/handcuffs/cable/zipties/used/attack() - return - - -//Legcuffs - -/obj/item/restraints/legcuffs - name = "leg cuffs" - desc = "Use this to keep prisoners in line." - gender = PLURAL - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "handcuff" - lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' - flags_1 = CONDUCT_1 - throwforce = 0 - w_class = WEIGHT_CLASS_NORMAL - origin_tech = "engineering=3;combat=3" - slowdown = 7 - breakouttime = 300 //Deciseconds = 30s = 0.5 minute - -/obj/item/restraints/legcuffs/beartrap - name = "bear trap" - throw_speed = 1 - throw_range = 1 - icon_state = "beartrap" - desc = "A trap used to catch bears and other legged creatures." - origin_tech = "engineering=4" - var/armed = 0 - var/trap_damage = 20 - -/obj/item/restraints/legcuffs/beartrap/Initialize() - . = ..() - icon_state = "[initial(icon_state)][armed]" - -/obj/item/restraints/legcuffs/beartrap/suicide_act(mob/user) - user.visible_message("[user] is sticking [user.p_their()] head in the [src.name]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/restraints/legcuffs/beartrap/attack_self(mob/user) - ..() - if(ishuman(user) && !user.stat && !user.restrained()) - armed = !armed - icon_state = "[initial(icon_state)][armed]" - to_chat(user, "[src] is now [armed ? "armed" : "disarmed"]") - -/obj/item/restraints/legcuffs/beartrap/Crossed(AM as mob|obj) - if(armed && isturf(src.loc)) - if(isliving(AM)) - var/mob/living/L = AM - var/snap = 0 - var/def_zone = "chest" - if(iscarbon(L)) - var/mob/living/carbon/C = L - snap = 1 - if(!C.lying) - def_zone = pick("l_leg", "r_leg") - if(!C.legcuffed && C.get_num_legs() >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs. - C.legcuffed = src - src.loc = C - C.update_inv_legcuffed() - SSblackbox.add_details("handcuffs","[type]") - else if(isanimal(L)) - var/mob/living/simple_animal/SA = L - if(SA.mob_size > MOB_SIZE_TINY) - snap = 1 - if(L.movement_type & FLYING) - snap = 0 - if(snap) - armed = 0 - icon_state = "[initial(icon_state)][armed]" - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) - L.visible_message("[L] triggers \the [src].", \ - "You trigger \the [src]!") - L.apply_damage(trap_damage,BRUTE, def_zone) - ..() - -/obj/item/restraints/legcuffs/beartrap/energy - name = "energy snare" - armed = 1 - icon_state = "e_snare" - trap_damage = 0 - flags_1 = DROPDEL_1 - -/obj/item/restraints/legcuffs/beartrap/energy/New() - ..() - addtimer(CALLBACK(src, .proc/dissipate), 100) - -/obj/item/restraints/legcuffs/beartrap/energy/proc/dissipate() - if(!ismob(loc)) - do_sparks(1, TRUE, src) - qdel(src) - -/obj/item/restraints/legcuffs/beartrap/energy/attack_hand(mob/user) - Crossed(user) //honk - -/obj/item/restraints/legcuffs/beartrap/energy/cyborg - breakouttime = 20 // Cyborgs shouldn't have a strong restraint - -/obj/item/restraints/legcuffs/bola - name = "bola" - desc = "A restraining device designed to be thrown at the target. Upon connecting with said target, it will wrap around their legs, making it difficult for them to move quickly." - icon_state = "bola" - breakouttime = 35//easy to apply, easy to break out of - gender = NEUTER - origin_tech = "engineering=3;combat=1" - var/knockdown = 0 - -/obj/item/restraints/legcuffs/bola/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) - if(!..()) - return - playsound(src.loc,'sound/weapons/bolathrow.ogg', 75, 1) - -/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom) - if(..() || !iscarbon(hit_atom))//if it gets caught or the target can't be cuffed, - return//abort - var/mob/living/carbon/C = hit_atom - if(!C.legcuffed && C.get_num_legs() >= 2) - visible_message("\The [src] ensnares [C]!") - C.legcuffed = src - src.loc = C - C.update_inv_legcuffed() - SSblackbox.add_details("handcuffs","[type]") - to_chat(C, "\The [src] ensnares you!") - C.Knockdown(knockdown) - -/obj/item/restraints/legcuffs/bola/tactical//traitor variant - name = "reinforced bola" - desc = "A strong bola, made with a long steel chain. It looks heavy, enough so that it could trip somebody." - icon_state = "bola_r" - breakouttime = 70 - origin_tech = "engineering=4;combat=3" - knockdown = 20 - -/obj/item/restraints/legcuffs/bola/energy //For Security - name = "energy bola" - desc = "A specialized hard-light bola designed to ensnare fleeing criminals and aid in arrests." - icon_state = "ebola" - hitsound = 'sound/weapons/taserhit.ogg' - w_class = WEIGHT_CLASS_SMALL - breakouttime = 60 - -/obj/item/restraints/legcuffs/bola/energy/throw_impact(atom/hit_atom) - if(iscarbon(hit_atom)) - var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(hit_atom)) - B.Crossed(hit_atom) - qdel(src) - ..() -======= /obj/item/restraints breakouttime = 600 @@ -744,4 +370,4 @@ B.Crossed(hit_atom) qdel(src) ..() ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) + From 6332ae6004cc1395566e959eed10c2a1e88755e8 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:50:21 -0500 Subject: [PATCH 16/60] Update paiwire.dm --- code/game/objects/items/paiwire.dm | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/code/game/objects/items/paiwire.dm b/code/game/objects/items/paiwire.dm index 6b6b3101c6..a20f89bc2b 100644 --- a/code/game/objects/items/paiwire.dm +++ b/code/game/objects/items/paiwire.dm @@ -1,18 +1,3 @@ -<<<<<<< HEAD -/obj/item/pai_cable - desc = "A flexible coated cable with a universal jack on one end." - name = "data cable" - icon = 'icons/obj/power.dmi' - icon_state = "wire1" - flags_1 = NOBLUDGEON_1 - var/obj/machinery/machine - -/obj/item/pai_cable/proc/plugin(obj/machinery/M, mob/living/user) - if(!user.drop_item()) - return - user.visible_message("[user] inserts [src] into a data port on [M].", "You insert [src] into a data port on [M].", "You hear the satisfying click of a wire jack fastening into place.") - src.loc = M -======= /obj/item/pai_cable desc = "A flexible coated cable with a universal jack on one end." name = "data cable" @@ -25,5 +10,4 @@ if(!user.transferItemToLoc(src, M)) return user.visible_message("[user] inserts [src] into a data port on [M].", "You insert [src] into a data port on [M].", "You hear the satisfying click of a wire jack fastening into place.") ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) - machine = M \ No newline at end of file + machine = M From a7ac93dd2bd5780c104df1ae35b7d22b97f240e7 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:50:38 -0500 Subject: [PATCH 17/60] Update structures.dm --- code/game/objects/structures.dm | 176 ++++++++++++-------------------- 1 file changed, 66 insertions(+), 110 deletions(-) diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 5504c1a8fc..85d124fefc 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -1,68 +1,25 @@ -/obj/structure - icon = 'icons/obj/structures.dmi' - pressure_resistance = 8 - max_integrity = 300 - var/climb_time = 20 - var/climb_stun = 20 - var/climbable = FALSE - var/mob/living/structureclimber - var/broken = 0 //similar to machinery's stat BROKEN - -/obj/structure/Initialize() - if (!armor) - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) - . = ..() - if(smooth) - queue_smooth(src) - queue_smooth_neighbors(src) - icon_state = "" +/obj/structure + icon = 'icons/obj/structures.dmi' + pressure_resistance = 8 + max_integrity = 300 + var/climb_time = 20 + var/climb_stun = 20 + var/climbable = FALSE + var/mob/living/structureclimber + var/broken = 0 //similar to machinery's stat BROKEN + +/obj/structure/Initialize() + if (!armor) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) + . = ..() + if(smooth) + queue_smooth(src) + queue_smooth_neighbors(src) + icon_state = "" GLOB.cameranet.updateVisibility(src) - -/obj/structure/Destroy() + +/obj/structure/Destroy() GLOB.cameranet.updateVisibility(src) -<<<<<<< HEAD - if(smooth) - queue_smooth_neighbors(src) - return ..() - -/obj/structure/attack_hand(mob/user) - . = ..() - add_fingerprint(user) - if(structureclimber && structureclimber != user) - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) - structureclimber.Knockdown(40) - structureclimber.visible_message("[structureclimber.name] has been knocked off the [src]", "You're knocked off the [src]!", "You see [structureclimber.name] get knocked off the [src]") - interact(user) - -/obj/structure/interact(mob/user) - ui_interact(user) - -/obj/structure/ui_act(action, params) - ..() - add_fingerprint(usr) - -/obj/structure/MouseDrop_T(atom/movable/O, mob/user) - . = ..() - if(!climbable) - return - if(user == O && iscarbon(O)) - if(user.canmove) - climb_structure(user) - return - if ((!( istype(O, /obj/item/weapon) ) || user.get_active_held_item() != O)) - return - if(iscyborg(user)) - return - if(!user.drop_item()) - return - if (O.loc != src.loc) - step(O, get_dir(O, src)) - return - -/obj/structure/proc/do_climb(atom/movable/A) - if(climbable) -======= if(smooth) queue_smooth_neighbors(src) return ..() @@ -104,52 +61,51 @@ /obj/structure/proc/do_climb(atom/movable/A) if(climbable) ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) density = FALSE - . = step(A,get_dir(A,src.loc)) + . = step(A,get_dir(A,src.loc)) density = TRUE - -/obj/structure/proc/climb_structure(mob/living/user) - src.add_fingerprint(user) - user.visible_message("[user] starts climbing onto [src].", \ - "You start climbing onto [src]...") - var/adjusted_climb_time = climb_time - if(user.restrained()) //climbing takes twice as long when restrained. - adjusted_climb_time *= 2 - if(isalien(user)) - adjusted_climb_time *= 0.25 //aliens are terrifyingly fast - structureclimber = user - if(do_mob(user, user, adjusted_climb_time)) - if(src.loc) //Checking if structure has been destroyed - if(do_climb(user)) - user.visible_message("[user] climbs onto [src].", \ - "You climb onto [src].") - add_logs(user, src, "climbed onto") - if(climb_stun) - user.Stun(climb_stun) - . = 1 - else - to_chat(user, "You fail to climb onto [src].") - structureclimber = null - -/obj/structure/examine(mob/user) - ..() - if(!(resistance_flags & INDESTRUCTIBLE)) - if(resistance_flags & ON_FIRE) - to_chat(user, "It's on fire!") - if(broken) - to_chat(user, "It appears to be broken.") - var/examine_status = examine_status(user) - if(examine_status) - to_chat(user, examine_status) - -/obj/structure/proc/examine_status(mob/user) //An overridable proc, mostly for falsewalls. - var/healthpercent = (obj_integrity/max_integrity) * 100 - switch(healthpercent) - if(50 to 99) - return "It looks slightly damaged." - if(25 to 50) - return "It appears heavily damaged." - if(0 to 25) - if(!broken) - return "It's falling apart!" + +/obj/structure/proc/climb_structure(mob/living/user) + src.add_fingerprint(user) + user.visible_message("[user] starts climbing onto [src].", \ + "You start climbing onto [src]...") + var/adjusted_climb_time = climb_time + if(user.restrained()) //climbing takes twice as long when restrained. + adjusted_climb_time *= 2 + if(isalien(user)) + adjusted_climb_time *= 0.25 //aliens are terrifyingly fast + structureclimber = user + if(do_mob(user, user, adjusted_climb_time)) + if(src.loc) //Checking if structure has been destroyed + if(do_climb(user)) + user.visible_message("[user] climbs onto [src].", \ + "You climb onto [src].") + add_logs(user, src, "climbed onto") + if(climb_stun) + user.Stun(climb_stun) + . = 1 + else + to_chat(user, "You fail to climb onto [src].") + structureclimber = null + +/obj/structure/examine(mob/user) + ..() + if(!(resistance_flags & INDESTRUCTIBLE)) + if(resistance_flags & ON_FIRE) + to_chat(user, "It's on fire!") + if(broken) + to_chat(user, "It appears to be broken.") + var/examine_status = examine_status(user) + if(examine_status) + to_chat(user, examine_status) + +/obj/structure/proc/examine_status(mob/user) //An overridable proc, mostly for falsewalls. + var/healthpercent = (obj_integrity/max_integrity) * 100 + switch(healthpercent) + if(50 to 99) + return "It looks slightly damaged." + if(25 to 50) + return "It appears heavily damaged." + if(0 to 25) + if(!broken) + return "It's falling apart!" From bc2b6b01c102f3f3248504a1df69ca80ec77866a Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:50:50 -0500 Subject: [PATCH 18/60] Update target_stake.dm --- code/game/objects/structures/target_stake.dm | 62 ++------------------ 1 file changed, 6 insertions(+), 56 deletions(-) diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index b70326b893..c3496678c2 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -1,59 +1,10 @@ -/obj/structure/target_stake - name = "target stake" - desc = "A thin platform with negatively-magnetized wheels." - icon = 'icons/obj/objects.dmi' - icon_state = "target_stake" +/obj/structure/target_stake + name = "target stake" + desc = "A thin platform with negatively-magnetized wheels." + icon = 'icons/obj/objects.dmi' + icon_state = "target_stake" density = TRUE flags_1 = CONDUCT_1 -<<<<<<< HEAD - var/obj/item/target/pinned_target - -/obj/structure/target_stake/Destroy() - if(pinned_target) - pinned_target.nullPinnedLoc() - return ..() - -/obj/structure/target_stake/proc/nullPinnedTarget() - pinned_target = null - -/obj/structure/target_stake/Move() - ..() - if(pinned_target) - pinned_target.loc = loc - -/obj/structure/target_stake/attackby(obj/item/target/T, mob/user) - if(pinned_target) - return - if(istype(T) && user.drop_item()) - pinned_target = T - T.pinnedLoc = src - T.density = TRUE - T.layer = OBJ_LAYER + 0.01 - T.loc = loc - to_chat(user, "You slide the target into the stake.") - -/obj/structure/target_stake/attack_hand(mob/user) - if(pinned_target) - removeTarget(user) - -/obj/structure/target_stake/proc/removeTarget(mob/user) - pinned_target.layer = OBJ_LAYER - pinned_target.loc = user.loc - pinned_target.nullPinnedLoc() - nullPinnedTarget() - if(ishuman(user)) - if(!user.get_active_held_item()) - user.put_in_hands(pinned_target) - to_chat(user, "You take the target out of the stake.") - else - pinned_target.loc = get_turf(user) - to_chat(user, "You take the target out of the stake.") - -/obj/structure/target_stake/bullet_act(obj/item/projectile/P) - if(pinned_target) - pinned_target.bullet_act(P) - else -======= var/obj/item/target/pinned_target /obj/structure/target_stake/Destroy() @@ -100,5 +51,4 @@ if(pinned_target) pinned_target.bullet_act(P) else ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) - ..() \ No newline at end of file + ..() From cc3bd63d88bf7c16a36c51efe8e17657eb2a6752 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:51:05 -0500 Subject: [PATCH 19/60] Update seed_extractor.dm --- code/modules/hydroponics/seed_extractor.dm | 343 +++++++++------------ 1 file changed, 148 insertions(+), 195 deletions(-) diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index 3cc45bf9be..a917b6afeb 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -1,49 +1,3 @@ -<<<<<<< HEAD -/proc/seedify(obj/item/O, t_max, obj/machinery/seed_extractor/extractor, mob/living/user) - var/t_amount = 0 - if(t_max == -1) - if(extractor) - t_max = rand(1,4) * extractor.seed_multiplier - else - t_max = rand(1,4) - - var/seedloc = O.loc - if(extractor) - seedloc = extractor.loc - - if(istype(O, /obj/item/reagent_containers/food/snacks/grown/)) - var/obj/item/reagent_containers/food/snacks/grown/F = O - if(F.seed) - if(user && !user.drop_item()) //couldn't drop the item - return - while(t_amount < t_max) - var/obj/item/seeds/t_prod = F.seed.Copy() - t_prod.loc = seedloc - t_amount++ - qdel(O) - return 1 - - else if(istype(O, /obj/item/grown)) - var/obj/item/grown/F = O - if(F.seed) - if(user && !user.drop_item()) - return - while(t_amount < t_max) - var/obj/item/seeds/t_prod = F.seed.Copy() - t_prod.loc = seedloc - t_amount++ - qdel(O) - return 1 - - return 0 - - -/obj/machinery/seed_extractor - name = "seed extractor" - desc = "Extracts and bags seeds from produce." - icon = 'icons/obj/hydroponics/equipment.dmi' - icon_state = "sextractor" -======= /proc/seedify(obj/item/O, t_max, obj/machinery/seed_extractor/extractor, mob/living/user) var/t_amount = 0 if(t_max == -1) @@ -88,162 +42,161 @@ desc = "Extracts and bags seeds from produce." icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "sextractor" ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) density = TRUE anchored = TRUE circuit = /obj/item/circuitboard/machine/seed_extractor - var/piles = list() - var/max_seeds = 1000 - var/seed_multiplier = 1 - -/obj/machinery/seed_extractor/RefreshParts() - for(var/obj/item/stock_parts/matter_bin/B in component_parts) - max_seeds = 1000 * B.rating - for(var/obj/item/stock_parts/manipulator/M in component_parts) - seed_multiplier = M.rating - -/obj/machinery/seed_extractor/attackby(obj/item/O, mob/user, params) - - if(default_deconstruction_screwdriver(user, "sextractor_open", "sextractor", O)) - return - - if(exchange_parts(user, O)) - return - - if(default_pry_open(O)) - return - - if(default_unfasten_wrench(user, O)) - return - - if(default_deconstruction_crowbar(O)) - return - + var/piles = list() + var/max_seeds = 1000 + var/seed_multiplier = 1 + +/obj/machinery/seed_extractor/RefreshParts() + for(var/obj/item/stock_parts/matter_bin/B in component_parts) + max_seeds = 1000 * B.rating + for(var/obj/item/stock_parts/manipulator/M in component_parts) + seed_multiplier = M.rating + +/obj/machinery/seed_extractor/attackby(obj/item/O, mob/user, params) + + if(default_deconstruction_screwdriver(user, "sextractor_open", "sextractor", O)) + return + + if(exchange_parts(user, O)) + return + + if(default_pry_open(O)) + return + + if(default_unfasten_wrench(user, O)) + return + + if(default_deconstruction_crowbar(O)) + return + if (istype(O, /obj/item/storage/bag/plants)) - var/obj/item/storage/P = O - var/loaded = 0 - for(var/obj/item/seeds/G in P.contents) - if(contents.len >= max_seeds) - break - ++loaded - add_seed(G) - if (loaded) - to_chat(user, "You put the seeds from \the [O.name] into [src].") - else - to_chat(user, "There are no seeds in \the [O.name].") - return - - else if(seedify(O,-1, src, user)) - to_chat(user, "You extract some seeds.") - return + var/obj/item/storage/P = O + var/loaded = 0 + for(var/obj/item/seeds/G in P.contents) + if(contents.len >= max_seeds) + break + ++loaded + add_seed(G) + if (loaded) + to_chat(user, "You put the seeds from \the [O.name] into [src].") + else + to_chat(user, "There are no seeds in \the [O.name].") + return + + else if(seedify(O,-1, src, user)) + to_chat(user, "You extract some seeds.") + return else if (istype(O, /obj/item/seeds)) <<<<<<< HEAD - if(add_seed(O)) - to_chat(user, "You add [O] to [src.name].") - updateUsrDialog() - return - else if(user.a_intent != INTENT_HARM) - to_chat(user, "You can't extract any seeds from \the [O.name]!") - else - return ..() - -/datum/seed_pile - var/name = "" - var/lifespan = 0 //Saved stats - var/endurance = 0 - var/maturation = 0 - var/production = 0 - var/yield = 0 - var/potency = 0 - var/amount = 0 - -/datum/seed_pile/New(var/name, var/life, var/endur, var/matur, var/prod, var/yie, var/poten, var/am = 1) - src.name = name - src.lifespan = life - src.endurance = endur - src.maturation = matur - src.production = prod - src.yield = yie - src.potency = poten - src.amount = am - -/obj/machinery/seed_extractor/attack_hand(mob/user) - user.set_machine(src) - interact(user) - -/obj/machinery/seed_extractor/interact(mob/user) - if (stat) - return 0 - - var/dat = "Stored seeds:
" - - if (contents.len == 0) - dat += "No seeds" - else - dat += "" - for (var/datum/seed_pile/O in piles) - dat += "" - dat += "" - dat += "
NameLifespanEnduranceMaturationProductionYieldPotencyStock
[O.name][O.lifespan][O.endurance][O.maturation][O.production][O.yield][O.potency]" - dat += "Vend ([O.amount] left)
" - var/datum/browser/popup = new(user, "seed_ext", name, 700, 400) - popup.set_content(dat) - popup.open() - return - -/obj/machinery/seed_extractor/Topic(var/href, var/list/href_list) - if(..()) - return - usr.set_machine(src) - - href_list["li"] = text2num(href_list["li"]) - href_list["en"] = text2num(href_list["en"]) - href_list["ma"] = text2num(href_list["ma"]) - href_list["pr"] = text2num(href_list["pr"]) - href_list["yi"] = text2num(href_list["yi"]) - href_list["pot"] = text2num(href_list["pot"]) - - for (var/datum/seed_pile/N in piles)//Find the pile we need to reduce... - if (href_list["name"] == N.name && href_list["li"] == N.lifespan && href_list["en"] == N.endurance && href_list["ma"] == N.maturation && href_list["pr"] == N.production && href_list["yi"] == N.yield && href_list["pot"] == N.potency) - if(N.amount <= 0) - return - N.amount = max(N.amount - 1, 0) - if (N.amount <= 0) - piles -= N - qdel(N) - break - - for (var/obj/T in contents)//Now we find the seed we need to vend - var/obj/item/seeds/O = T - if (O.plantname == href_list["name"] && O.lifespan == href_list["li"] && O.endurance == href_list["en"] && O.maturation == href_list["ma"] && O.production == href_list["pr"] && O.yield == href_list["yi"] && O.potency == href_list["pot"]) - O.loc = src.loc - break - - src.updateUsrDialog() - return - -/obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/O) - if(contents.len >= 999) - to_chat(usr, "\The [src] is full.") - return 0 - - if(ismob(O.loc)) - var/mob/M = O.loc - if(!M.drop_item()) - return 0 + if(add_seed(O)) + to_chat(user, "You add [O] to [src.name].") + updateUsrDialog() + return + else if(user.a_intent != INTENT_HARM) + to_chat(user, "You can't extract any seeds from \the [O.name]!") + else + return ..() + +/datum/seed_pile + var/name = "" + var/lifespan = 0 //Saved stats + var/endurance = 0 + var/maturation = 0 + var/production = 0 + var/yield = 0 + var/potency = 0 + var/amount = 0 + +/datum/seed_pile/New(var/name, var/life, var/endur, var/matur, var/prod, var/yie, var/poten, var/am = 1) + src.name = name + src.lifespan = life + src.endurance = endur + src.maturation = matur + src.production = prod + src.yield = yie + src.potency = poten + src.amount = am + +/obj/machinery/seed_extractor/attack_hand(mob/user) + user.set_machine(src) + interact(user) + +/obj/machinery/seed_extractor/interact(mob/user) + if (stat) + return 0 + + var/dat = "Stored seeds:
" + + if (contents.len == 0) + dat += "No seeds" + else + dat += "" + for (var/datum/seed_pile/O in piles) + dat += "" + dat += "" + dat += "
NameLifespanEnduranceMaturationProductionYieldPotencyStock
[O.name][O.lifespan][O.endurance][O.maturation][O.production][O.yield][O.potency]" + dat += "Vend ([O.amount] left)
" + var/datum/browser/popup = new(user, "seed_ext", name, 700, 400) + popup.set_content(dat) + popup.open() + return + +/obj/machinery/seed_extractor/Topic(var/href, var/list/href_list) + if(..()) + return + usr.set_machine(src) + + href_list["li"] = text2num(href_list["li"]) + href_list["en"] = text2num(href_list["en"]) + href_list["ma"] = text2num(href_list["ma"]) + href_list["pr"] = text2num(href_list["pr"]) + href_list["yi"] = text2num(href_list["yi"]) + href_list["pot"] = text2num(href_list["pot"]) + + for (var/datum/seed_pile/N in piles)//Find the pile we need to reduce... + if (href_list["name"] == N.name && href_list["li"] == N.lifespan && href_list["en"] == N.endurance && href_list["ma"] == N.maturation && href_list["pr"] == N.production && href_list["yi"] == N.yield && href_list["pot"] == N.potency) + if(N.amount <= 0) + return + N.amount = max(N.amount - 1, 0) + if (N.amount <= 0) + piles -= N + qdel(N) + break + + for (var/obj/T in contents)//Now we find the seed we need to vend + var/obj/item/seeds/O = T + if (O.plantname == href_list["name"] && O.lifespan == href_list["li"] && O.endurance == href_list["en"] && O.maturation == href_list["ma"] && O.production == href_list["pr"] && O.yield == href_list["yi"] && O.potency == href_list["pot"]) + O.loc = src.loc + break + + src.updateUsrDialog() + return + +/obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/O) + if(contents.len >= 999) + to_chat(usr, "\The [src] is full.") + return 0 + + if(ismob(O.loc)) + var/mob/M = O.loc + if(!M.drop_item()) + return 0 else if(istype(O.loc, /obj/item/storage)) - var/obj/item/storage/S = O.loc - S.remove_from_storage(O,src) - - O.loc = src - . = 1 - for (var/datum/seed_pile/N in piles) - if (O.plantname == N.name && O.lifespan == N.lifespan && O.endurance == N.endurance && O.maturation == N.maturation && O.production == N.production && O.yield == N.yield && O.potency == N.potency) - ++N.amount - return - - piles += new /datum/seed_pile(O.plantname, O.lifespan, O.endurance, O.maturation, O.production, O.yield, O.potency) - return + var/obj/item/storage/S = O.loc + S.remove_from_storage(O,src) + + O.loc = src + . = 1 + for (var/datum/seed_pile/N in piles) + if (O.plantname == N.name && O.lifespan == N.lifespan && O.endurance == N.endurance && O.maturation == N.maturation && O.production == N.production && O.yield == N.yield && O.potency == N.potency) + ++N.amount + return + + piles += new /datum/seed_pile(O.plantname, O.lifespan, O.endurance, O.maturation, O.production, O.yield, O.potency) + return ======= if(add_seed(O)) to_chat(user, "You add [O] to [src.name].") From 5ce923a4d750db7efd0aa56b41dc7cffb08af450 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:51:35 -0500 Subject: [PATCH 20/60] Update laborstacker.dm --- code/modules/mining/laborcamp/laborstacker.dm | 217 +++++------------- 1 file changed, 56 insertions(+), 161 deletions(-) diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 2bcccdb164..12c9bfb30e 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -1,129 +1,25 @@ -/**********************Prisoners' Console**************************/ - -/obj/machinery/mineral/labor_claim_console - name = "point claim console" - desc = "A stacking console with an electromagnetic writer, used to track ore mined by prisoners." - icon = 'icons/obj/machines/mining_machines.dmi' - icon_state = "console" +/**********************Prisoners' Console**************************/ + +/obj/machinery/mineral/labor_claim_console + name = "point claim console" + desc = "A stacking console with an electromagnetic writer, used to track ore mined by prisoners." + icon = 'icons/obj/machines/mining_machines.dmi' + icon_state = "console" density = FALSE anchored = TRUE - var/obj/machinery/mineral/stacking_machine/laborstacker/stacking_machine = null - var/machinedir = SOUTH - var/obj/item/card/id/prisoner/inserted_id - var/obj/machinery/door/airlock/release_door - var/door_tag = "prisonshuttle" - var/obj/item/device/radio/Radio //needed to send messages to sec radio - - + var/obj/machinery/mineral/stacking_machine/laborstacker/stacking_machine = null + var/machinedir = SOUTH + var/obj/item/card/id/prisoner/inserted_id + var/obj/machinery/door/airlock/release_door + var/door_tag = "prisonshuttle" + var/obj/item/device/radio/Radio //needed to send messages to sec radio + + /obj/machinery/mineral/labor_claim_console/Initialize() . = ..() - Radio = new/obj/item/device/radio(src) + Radio = new/obj/item/device/radio(src) Radio.listening = FALSE locate_stacking_machine() -<<<<<<< HEAD - -/obj/machinery/mineral/labor_claim_console/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/card/id/prisoner)) - if(!inserted_id) - if(!user.drop_item()) - return - I.forceMove(src) - inserted_id = I - to_chat(user, "You insert [I].") - return - else - to_chat(user, "There's an ID inserted already.") - return ..() - -/obj/machinery/mineral/labor_claim_console/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "labor_claim_console", name, 450, 475, master_ui, state) - ui.open() - -/obj/machinery/mineral/labor_claim_console/ui_data(mob/user) - var/list/data = list() - var/can_go_home = FALSE - - data["emagged"] = emagged - if(inserted_id) - data["id"] = inserted_id - data["id_name"] = inserted_id.registered_name - data["points"] = inserted_id.points - data["goal"] = inserted_id.goal - if(check_auth()) - can_go_home = TRUE - - var/list/ores = list() - if(stacking_machine) - data["unclaimed_points"] = stacking_machine.points - for(var/ore in stacking_machine.ore_values) - var/list/O = list() - O["ore"] = ore - O["value"] = stacking_machine.ore_values[ore] - ores += list(O) - - data["ores"] = ores - data["can_go_home"] = can_go_home - - return data - -/obj/machinery/mineral/labor_claim_console/ui_act(action, params) - if(..()) - return - switch(action) - if("handle_id") - if(inserted_id) - if(!usr.get_active_held_item()) - usr.put_in_hands(inserted_id) - inserted_id = null - else - inserted_id.forceMove(get_turf(src)) - inserted_id = null - else - var/obj/item/I = usr.get_active_held_item() - if(istype(I, /obj/item/card/id/prisoner)) - if(!usr.drop_item()) - return - I.forceMove(src) - inserted_id = I - if("claim_points") - inserted_id.points += stacking_machine.points - stacking_machine.points = 0 - to_chat(usr, "Points transferred.") - if("move_shuttle") - if(!alone_in_area(get_area(src), usr)) - to_chat(usr, "Prisoners are only allowed to be released while alone.") - else - switch(SSshuttle.moveShuttle("laborcamp","laborcamp_home")) - if(1) - to_chat(usr, "Shuttle not found") - if(2) - to_chat(usr, "Shuttle already at station") - if(3) - to_chat(usr, "No permission to dock could be granted.") - else - if(!emagged) - Radio.set_frequency(GLOB.SEC_FREQ) - Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", GLOB.SEC_FREQ, get_spans(), get_default_language()) - to_chat(usr, "Shuttle received message and will be sent shortly.") - -/obj/machinery/mineral/labor_claim_console/proc/check_auth() - if(emagged) - return 1 //Shuttle is emagged, let any ol' person through - return (istype(inserted_id) && inserted_id.points >= inserted_id.goal) //Otherwise, only let them out if the prisoner's reached his quota. - -/obj/machinery/mineral/labor_claim_console/proc/locate_stacking_machine() - stacking_machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir)) - if(stacking_machine) - stacking_machine.CONSOLE = src - else - qdel(src) - -/obj/machinery/mineral/labor_claim_console/emag_act(mob/user) - if(!emagged) -======= /obj/machinery/mineral/labor_claim_console/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/card/id/prisoner)) @@ -224,48 +120,47 @@ /obj/machinery/mineral/labor_claim_console/emag_act(mob/user) if(!emagged) ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) emagged = TRUE - to_chat(user, "PZZTTPFFFT") - - -/**********************Prisoner Collection Unit**************************/ - - -/obj/machinery/mineral/stacking_machine/laborstacker - var/points = 0 //The unclaimed value of ore stacked. Value for each ore loosely relative to its rarity. + to_chat(user, "PZZTTPFFFT") + + +/**********************Prisoner Collection Unit**************************/ + + +/obj/machinery/mineral/stacking_machine/laborstacker + var/points = 0 //The unclaimed value of ore stacked. Value for each ore loosely relative to its rarity. var/list/ore_values = list("glass" = 1, "metal" = 2, "reinforced glass" = 4, "gold" = 20, "silver" = 20, "uranium" = 20, "titanium" = 20, "solid plasma" = 20, "plasteel" = 23, "plasma glass" = 23, "diamond" = 25, "bluespace polycrystal" = 30, "plastitanium" = 45, "bananium" = 50) - -/obj/machinery/mineral/stacking_machine/laborstacker/process_sheet(obj/item/stack/sheet/inp) - if(istype(inp)) - var/n = inp.name - var/a = inp.amount - if(n in ore_values) - points += ore_values[n] * a - ..() - - -/**********************Point Lookup Console**************************/ -/obj/machinery/mineral/labor_points_checker - name = "points checking console" - desc = "A console used by prisoners to check the progress on their quotas. Simply swipe a prisoner ID." - icon = 'icons/obj/machines/mining_machines.dmi' - icon_state = "console" + +/obj/machinery/mineral/stacking_machine/laborstacker/process_sheet(obj/item/stack/sheet/inp) + if(istype(inp)) + var/n = inp.name + var/a = inp.amount + if(n in ore_values) + points += ore_values[n] * a + ..() + + +/**********************Point Lookup Console**************************/ +/obj/machinery/mineral/labor_points_checker + name = "points checking console" + desc = "A console used by prisoners to check the progress on their quotas. Simply swipe a prisoner ID." + icon = 'icons/obj/machines/mining_machines.dmi' + icon_state = "console" density = FALSE anchored = TRUE - -/obj/machinery/mineral/labor_points_checker/attack_hand(mob/user) - user.examinate(src) - -/obj/machinery/mineral/labor_points_checker/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/card/id)) - if(istype(I, /obj/item/card/id/prisoner)) - var/obj/item/card/id/prisoner/prisoner_id = I - to_chat(user, "ID: [prisoner_id.registered_name]") - to_chat(user, "Points Collected:[prisoner_id.points]") - to_chat(user, "Point Quota: [prisoner_id.goal]") - to_chat(user, "Collect points by bringing smelted minerals to the Labor Shuttle stacking machine. Reach your quota to earn your release.") - else - to_chat(user, "Error: Invalid ID") - else - return ..() + +/obj/machinery/mineral/labor_points_checker/attack_hand(mob/user) + user.examinate(src) + +/obj/machinery/mineral/labor_points_checker/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/card/id)) + if(istype(I, /obj/item/card/id/prisoner)) + var/obj/item/card/id/prisoner/prisoner_id = I + to_chat(user, "ID: [prisoner_id.registered_name]") + to_chat(user, "Points Collected:[prisoner_id.points]") + to_chat(user, "Point Quota: [prisoner_id.goal]") + to_chat(user, "Collect points by bringing smelted minerals to the Labor Shuttle stacking machine. Reach your quota to earn your release.") + else + to_chat(user, "Error: Invalid ID") + else + return ..() From 641ffe003b96ccb076de4214a97e55e20a2deb1e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:51:58 -0500 Subject: [PATCH 21/60] Update silicon.dm --- code/modules/mob/living/silicon/silicon.dm | 389 --------------------- 1 file changed, 389 deletions(-) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index c15c287f7c..46a62a1d50 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -1,391 +1,3 @@ -<<<<<<< HEAD -/mob/living/silicon - gender = NEUTER - voice_name = "synthesized voice" - has_unlimited_silicon_privilege = 1 - verb_say = "states" - verb_ask = "queries" - verb_exclaim = "declares" - verb_yell = "alarms" - initial_language_holder = /datum/language_holder/synthetic - see_in_dark = 8 - bubble_icon = "machine" - weather_immunities = list("ash") - possible_a_intents = list(INTENT_HELP, INTENT_HARM) - - var/syndicate = 0 - var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS - var/last_lawchange_announce = 0 - var/list/alarms_to_show = list() - var/list/alarms_to_clear = list() - var/designation = "" - var/radiomod = "" //Radio character used before state laws/arrivals announce to allow department transmissions, default, or none at all. - var/obj/item/device/camera/siliconcam/aicamera = null //photography - hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_TRACK_HUD) - - var/obj/item/device/radio/borg/radio = null //AIs dont use this but this is at the silicon level to advoid copypasta in say() - - var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0) - var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0) - - var/lawcheck[1] - var/ioncheck[1] - var/devillawcheck[5] - - var/med_hud = DATA_HUD_MEDICAL_ADVANCED //Determines the med hud to use - var/sec_hud = DATA_HUD_SECURITY_ADVANCED //Determines the sec hud to use - var/d_hud = DATA_HUD_DIAGNOSTIC //There is only one kind of diag hud - - var/law_change_counter = 0 - var/obj/machinery/camera/builtInCamera = null - var/updating = FALSE //portable camera camerachunk update - -/mob/living/silicon/Initialize() - . = ..() - GLOB.silicon_mobs += src - var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC] - diag_hud.add_to_hud(src) - diag_hud_set_status() - diag_hud_set_health() - -/mob/living/silicon/med_hud_set_health() - return //we use a different hud - -/mob/living/silicon/med_hud_set_status() - return //we use a different hud - -/mob/living/silicon/Destroy() - radio = null - aicamera = null - QDEL_NULL(builtInCamera) - GLOB.silicon_mobs -= src - return ..() - -/mob/living/silicon/contents_explosion(severity, target) - return - -/mob/living/silicon/proc/cancelAlarm() - return - -/mob/living/silicon/proc/triggerAlarm() - return - -/mob/living/silicon/proc/queueAlarm(message, type, incoming = 1) - var/in_cooldown = (alarms_to_show.len > 0 || alarms_to_clear.len > 0) - if(incoming) - alarms_to_show += message - alarm_types_show[type] += 1 - else - alarms_to_clear += message - alarm_types_clear[type] += 1 - - if(!in_cooldown) - spawn(3 * 10) // 3 seconds - - if(alarms_to_show.len < 5) - for(var/msg in alarms_to_show) - to_chat(src, msg) - else if(alarms_to_show.len) - - var/msg = "--- " - - if(alarm_types_show["Burglar"]) - msg += "BURGLAR: [alarm_types_show["Burglar"]] alarms detected. - " - - if(alarm_types_show["Motion"]) - msg += "MOTION: [alarm_types_show["Motion"]] alarms detected. - " - - if(alarm_types_show["Fire"]) - msg += "FIRE: [alarm_types_show["Fire"]] alarms detected. - " - - if(alarm_types_show["Atmosphere"]) - msg += "ATMOSPHERE: [alarm_types_show["Atmosphere"]] alarms detected. - " - - if(alarm_types_show["Power"]) - msg += "POWER: [alarm_types_show["Power"]] alarms detected. - " - - if(alarm_types_show["Camera"]) - msg += "CAMERA: [alarm_types_show["Camera"]] alarms detected. - " - - msg += "\[Show Alerts\]" - to_chat(src, msg) - - if(alarms_to_clear.len < 3) - for(var/msg in alarms_to_clear) - to_chat(src, msg) - - else if(alarms_to_clear.len) - var/msg = "--- " - - if(alarm_types_clear["Motion"]) - msg += "MOTION: [alarm_types_clear["Motion"]] alarms cleared. - " - - if(alarm_types_clear["Fire"]) - msg += "FIRE: [alarm_types_clear["Fire"]] alarms cleared. - " - - if(alarm_types_clear["Atmosphere"]) - msg += "ATMOSPHERE: [alarm_types_clear["Atmosphere"]] alarms cleared. - " - - if(alarm_types_clear["Power"]) - msg += "POWER: [alarm_types_clear["Power"]] alarms cleared. - " - - if(alarm_types_show["Camera"]) - msg += "CAMERA: [alarm_types_clear["Camera"]] alarms cleared. - " - - msg += "\[Show Alerts\]" - to_chat(src, msg) - - - alarms_to_show = list() - alarms_to_clear = list() - for(var/key in alarm_types_show) - alarm_types_show[key] = 0 - for(var/key in alarm_types_clear) - alarm_types_clear[key] = 0 - -/mob/living/silicon/drop_item() - return - -/mob/living/silicon/can_inject(mob/user, error_msg) - if(error_msg) - to_chat(user, "Their outer shell is too tough.") - return 0 - -/mob/living/silicon/IsAdvancedToolUser() - return 1 - -/proc/islinked(mob/living/silicon/robot/bot, mob/living/silicon/ai/ai) - if(!istype(bot) || !istype(ai)) - return 0 - if (bot.connected_ai == ai) - return 1 - return 0 - -/mob/living/silicon/Topic(href, href_list) - if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite - var/L = text2num(href_list["lawc"]) - switch(lawcheck[L+1]) - if ("Yes") - lawcheck[L+1] = "No" - if ("No") - lawcheck[L+1] = "Yes" - checklaws() - - if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite - var/L = text2num(href_list["lawi"]) - switch(ioncheck[L]) - if ("Yes") - ioncheck[L] = "No" - if ("No") - ioncheck[L] = "Yes" - checklaws() - - if (href_list["lawdevil"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite - var/L = text2num(href_list["lawdevil"]) - switch(devillawcheck[L]) - if ("Yes") - devillawcheck[L] = "No" - if ("No") - devillawcheck[L] = "Yes" - checklaws() - - - if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite - statelaws() - - return - - -/mob/living/silicon/proc/statelaws(force = 0) - - //"radiomod" is inserted before a hardcoded message to change if and how it is handled by an internal radio. - src.say("[radiomod] Current Active Laws:") - //src.laws_sanity_check() - //src.laws.show_laws(world) - var/number = 1 - sleep(10) - - if (src.laws.devillaws && src.laws.devillaws.len) - for(var/index = 1, index <= src.laws.devillaws.len, index++) - if (force || src.devillawcheck[index] == "Yes") - src.say("[radiomod] 666. [src.laws.devillaws[index]]") - sleep(10) - - - if (src.laws.zeroth) - if (force || src.lawcheck[1] == "Yes") - src.say("[radiomod] 0. [src.laws.zeroth]") - sleep(10) - - for (var/index = 1, index <= src.laws.ion.len, index++) - var/law = src.laws.ion[index] - var/num = ionnum() - if (length(law) > 0) - if (force || src.ioncheck[index] == "Yes") - src.say("[radiomod] [num]. [law]") - sleep(10) - - for (var/index = 1, index <= src.laws.inherent.len, index++) - var/law = src.laws.inherent[index] - - if (length(law) > 0) - if (force || src.lawcheck[index+1] == "Yes") - src.say("[radiomod] [number]. [law]") - number++ - sleep(10) - - for (var/index = 1, index <= src.laws.supplied.len, index++) - var/law = src.laws.supplied[index] - - if (length(law) > 0) - if(src.lawcheck.len >= number+1) - if (force || src.lawcheck[number+1] == "Yes") - src.say("[radiomod] [number]. [law]") - number++ - sleep(10) - - -/mob/living/silicon/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite - - var/list = "Which laws do you want to include when stating them for the crew?

" - - if (src.laws.devillaws && src.laws.devillaws.len) - for(var/index = 1, index <= src.laws.devillaws.len, index++) - if (!src.devillawcheck[index]) - src.devillawcheck[index] = "No" - list += {"[src.devillawcheck[index]] 666: [src.laws.devillaws[index]]
"} - - if (src.laws.zeroth) - if (!src.lawcheck[1]) - src.lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite - list += {"[src.lawcheck[1]] 0: [src.laws.zeroth]
"} - - for (var/index = 1, index <= src.laws.ion.len, index++) - var/law = src.laws.ion[index] - - if (length(law) > 0) - if (!src.ioncheck[index]) - src.ioncheck[index] = "Yes" - list += {"[src.ioncheck[index]] [ionnum()]: [law]
"} - src.ioncheck.len += 1 - - var/number = 1 - for (var/index = 1, index <= src.laws.inherent.len, index++) - var/law = src.laws.inherent[index] - - if (length(law) > 0) - src.lawcheck.len += 1 - - if (!src.lawcheck[number+1]) - src.lawcheck[number+1] = "Yes" - list += {"[src.lawcheck[number+1]] [number]: [law]
"} - number++ - - for (var/index = 1, index <= src.laws.supplied.len, index++) - var/law = src.laws.supplied[index] - if (length(law) > 0) - src.lawcheck.len += 1 - if (!src.lawcheck[number+1]) - src.lawcheck[number+1] = "Yes" - list += {"[src.lawcheck[number+1]] [number]: [law]
"} - number++ - list += {"

State Laws"} - - usr << browse(list, "window=laws") - -/mob/living/silicon/proc/set_autosay() //For allowing the AI and borgs to set the radio behavior of auto announcements (state laws, arrivals). - if(!radio) - to_chat(src, "Radio not detected.") - return - - //Ask the user to pick a channel from what it has available. - var/Autochan = input("Select a channel:") as null|anything in list("Default","None") + radio.channels - - if(!Autochan) - return - if(Autochan == "Default") //Autospeak on whatever frequency to which the radio is set, usually Common. - radiomod = ";" - Autochan += " ([radio.frequency])" - else if(Autochan == "None") //Prevents use of the radio for automatic annoucements. - radiomod = "" - else //For department channels, if any, given by the internal radio. - for(var/key in GLOB.department_radio_keys) - if(GLOB.department_radio_keys[key] == Autochan) - radiomod = ":" + key - break - - to_chat(src, "Automatic announcements [Autochan == "None" ? "will not use the radio." : "set to [Autochan]."]") - -/mob/living/silicon/put_in_hand_check() // This check is for borgs being able to receive items, not put them in others' hands. - return 0 - -// The src mob is trying to place an item on someone -// But the src mob is a silicon!! Disable. -/mob/living/silicon/stripPanelEquip(obj/item/what, mob/who, slot) - return 0 - - -/mob/living/silicon/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) //Secbots won't hunt silicon units - return -10 - -/mob/living/silicon/proc/remove_med_sec_hud() - var/datum/atom_hud/secsensor = GLOB.huds[sec_hud] - var/datum/atom_hud/medsensor = GLOB.huds[med_hud] - var/datum/atom_hud/diagsensor = GLOB.huds[d_hud] - secsensor.remove_hud_from(src) - medsensor.remove_hud_from(src) - diagsensor.remove_hud_from(src) - -/mob/living/silicon/proc/add_sec_hud() - var/datum/atom_hud/secsensor = GLOB.huds[sec_hud] - secsensor.add_hud_to(src) - -/mob/living/silicon/proc/add_med_hud() - var/datum/atom_hud/medsensor = GLOB.huds[med_hud] - medsensor.add_hud_to(src) - -/mob/living/silicon/proc/add_diag_hud() - var/datum/atom_hud/diagsensor = GLOB.huds[d_hud] - diagsensor.add_hud_to(src) - -/mob/living/silicon/proc/sensor_mode() - if(incapacitated()) - return - var/sensor_type = input("Please select sensor type.", "Sensor Integration", null) in list("Security", "Medical","Diagnostic","Disable") - remove_med_sec_hud() - switch(sensor_type) - if ("Security") - add_sec_hud() - to_chat(src, "Security records overlay enabled.") - if ("Medical") - add_med_hud() - to_chat(src, "Life signs monitor overlay enabled.") - if ("Diagnostic") - add_diag_hud() - to_chat(src, "Robotics diagnostic overlay enabled.") - if ("Disable") - to_chat(src, "Sensor augmentations disabled.") - - -/mob/living/silicon/proc/GetPhoto() - if (aicamera) - return aicamera.selectpicture(aicamera) - -/mob/living/silicon/update_transform() - var/matrix/ntransform = matrix(transform) //aka transform.Copy() - var/changed = 0 - if(resize != RESIZE_DEFAULT_SIZE) - changed++ - ntransform.Scale(resize) - resize = RESIZE_DEFAULT_SIZE - - if(changed) - animate(src, transform = ntransform, time = 2,easing = EASE_IN|EASE_OUT) - return ..() - -/mob/living/silicon/is_literate() - return 1 -======= /mob/living/silicon gender = NEUTER voice_name = "synthesized voice" @@ -769,4 +381,3 @@ /mob/living/silicon/is_literate() return 1 ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) From 2606143343824cca4f4f1efeec27c7d6139ade1d Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 22:52:12 -0500 Subject: [PATCH 22/60] Update limb_augmentation.dm --- code/modules/surgery/limb_augmentation.dm | 71 ++--------------------- 1 file changed, 4 insertions(+), 67 deletions(-) diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index 4df1d847be..b5081370f0 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -1,65 +1,3 @@ -<<<<<<< HEAD - -/////AUGMENTATION SURGERIES////// - - -//SURGERY STEPS - -/datum/surgery_step/replace - name = "sever muscles" - implements = list(/obj/item/scalpel = 100, /obj/item/wirecutters = 55) - time = 32 - - -/datum/surgery_step/replace/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - user.visible_message("[user] begins to sever the muscles on [target]'s [parse_zone(user.zone_selected)].", "You begin to sever the muscles on [target]'s [parse_zone(user.zone_selected)]...") - - -/datum/surgery_step/add_limb - name = "replace limb" - implements = list(/obj/item/bodypart = 100) - time = 32 - var/obj/item/bodypart/L = null // L because "limb" - - -/datum/surgery_step/add_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - var/obj/item/bodypart/aug = tool - if(aug.status != BODYPART_ROBOTIC) - to_chat(user, "that's not an augment silly!") - return -1 - if(aug.body_zone != target_zone) - to_chat(user, "[tool] isn't the right type for [parse_zone(target_zone)].") - return -1 - L = surgery.operated_bodypart - if(L) - user.visible_message("[user] begins to augment [target]'s [parse_zone(user.zone_selected)].", "You begin to augment [target]'s [parse_zone(user.zone_selected)]...") - else - user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "You look for [target]'s [parse_zone(user.zone_selected)]...") - - -//ACTUAL SURGERIES - -/datum/surgery/augmentation - name = "augmentation" - steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/replace, /datum/surgery_step/saw, /datum/surgery_step/add_limb) - species = list(/mob/living/carbon/human) - possible_locs = list("r_arm","l_arm","r_leg","l_leg","chest","head") - requires_real_bodypart = TRUE - -//SURGERY STEP SUCCESSES - -/datum/surgery_step/add_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/bodypart/tool, datum/surgery/surgery) - if(L) - user.visible_message("[user] successfully augments [target]'s [parse_zone(target_zone)]!", "You successfully augment [target]'s [parse_zone(target_zone)].") - L.change_bodypart_status(BODYPART_ROBOTIC, TRUE) - L.icon = tool.icon - L.max_damage = tool.max_damage - user.drop_item() - qdel(tool) - target.update_body_parts() - target.updatehealth() -======= - /////AUGMENTATION SURGERIES////// @@ -117,9 +55,8 @@ qdel(tool) target.update_body_parts() target.updatehealth() ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) target.update_hair() - add_logs(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]") - else - to_chat(user, "[target] has no organic [parse_zone(target_zone)] there!") - return 1 + add_logs(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]") + else + to_chat(user, "[target] has no organic [parse_zone(target_zone)] there!") + return 1 From 4a2d9f82a10c6a67d6d9fca914cc60c85b7d994c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 23:06:35 -0500 Subject: [PATCH 23/60] Update config.dm --- code/controllers/configuration/entries/config.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/controllers/configuration/entries/config.dm b/code/controllers/configuration/entries/config.dm index 9da8e0105c..729370c18b 100644 --- a/code/controllers/configuration/entries/config.dm +++ b/code/controllers/configuration/entries/config.dm @@ -350,9 +350,6 @@ CONFIG_DEF(number/error_msg_delay) // How long to wait between messaging admins CONFIG_DEF(flag/irc_announce_new_game) -<<<<<<< HEAD -CONFIG_DEF(flag/debug_admin_hrefs) -======= CONFIG_DEF(flag/debug_admin_hrefs) CONFIG_DEF(number/mc_tick_rate/base_mc_tick_rate) @@ -376,4 +373,3 @@ CONFIG_TWEAK(number/mc_tick_rate/ValidateAndSet(str_val)) . = ..() if (.) Master.UpdateTickRate() ->>>>>>> 119f3fa... Allows editing config.allow_admin_ooccolor (#31371) From cc0e5a1280fdc5dee006e1746f8e6a20c297ef00 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 7 Oct 2017 23:07:25 -0500 Subject: [PATCH 24/60] Update jetpack.dm --- code/game/objects/items/tanks/jetpack.dm | 214 ----------------------- 1 file changed, 214 deletions(-) diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 65e37ed906..63e9e0bb55 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -1,216 +1,3 @@ -<<<<<<< HEAD -/obj/item/tank/jetpack - name = "jetpack (empty)" - desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution." - icon_state = "jetpack" - item_state = "jetpack" - lefthand_file = 'icons/mob/inhands/equipment/jetpacks_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/jetpacks_righthand.dmi' - w_class = WEIGHT_CLASS_BULKY - distribute_pressure = ONE_ATMOSPHERE * O2STANDARD - actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) - var/gas_type = "o2" - var/on = FALSE - var/stabilizers = FALSE - var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not - var/datum/effect_system/trail_follow/ion/ion_trail - -/obj/item/tank/jetpack/New() - ..() - if(gas_type) - air_contents.assert_gas(gas_type) - air_contents.gases[gas_type][MOLES] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) - - ion_trail = new - ion_trail.set_up(src) - -/obj/item/tank/jetpack/ui_action_click(mob/user, action) - if(istype(action, /datum/action/item_action/toggle_jetpack)) - cycle(user) - else if(istype(action, /datum/action/item_action/jetpack_stabilization)) - if(on) - stabilizers = !stabilizers - to_chat(user, "You turn the jetpack stabilization [stabilizers ? "on" : "off"].") - else - toggle_internals(user) - - -/obj/item/tank/jetpack/proc/cycle(mob/user) - if(user.incapacitated()) - return - - if(!on) - turn_on() - to_chat(user, "You turn the jetpack on.") - else - turn_off() - to_chat(user, "You turn the jetpack off.") - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - - -/obj/item/tank/jetpack/proc/turn_on() - on = TRUE - icon_state = "[initial(icon_state)]-on" - ion_trail.start() - -/obj/item/tank/jetpack/proc/turn_off() - on = FALSE - stabilizers = FALSE - icon_state = initial(icon_state) - ion_trail.stop() - -/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user) - if(!on) - return - if((num < 0.005 || air_contents.total_moles() < num)) - turn_off() - return - - var/datum/gas_mixture/removed = air_contents.remove(num) - if(removed.total_moles() < 0.005) - turn_off() - return - - var/turf/T = get_turf(user) - T.assume_air(removed) - - return 1 - -/obj/item/tank/jetpack/suicide_act(mob/user) - if (istype(user, /mob/living/carbon/human/)) - var/mob/living/carbon/human/H = user - H.forcesay("WHAT THE FUCK IS CARBON DIOXIDE?") - H.visible_message("[user] is suffocating [user.p_them()]self with [src]! It looks like [user.p_they()] didn't read what that jetpack says!") - return (OXYLOSS) - else - ..() - -/obj/item/tank/jetpack/void - name = "void jetpack (oxygen)" - desc = "It works well in a void." - icon_state = "jetpack-void" - item_state = "jetpack-void" - -/obj/item/tank/jetpack/oxygen - name = "jetpack (oxygen)" - desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution." - icon_state = "jetpack" - item_state = "jetpack" - -/obj/item/tank/jetpack/oxygen/harness - name = "jet harness (oxygen)" - desc = "A lightweight tactical harness, used by those who don't want to be weighed down by traditional jetpacks." - icon_state = "jetpack-mini" - item_state = "jetpack-mini" - volume = 40 - throw_range = 7 - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/tank/jetpack/oxygen/captain - name = "\improper Captain's jetpack" - desc = "A compact, lightweight jetpack containing a high amount of compressed oxygen." - icon_state = "jetpack-captain" - item_state = "jetpack-captain" - w_class = WEIGHT_CLASS_NORMAL - volume = 90 - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //steal objective items are hard to destroy. - -/obj/item/tank/jetpack/oxygen/security - name = "security jetpack (oxygen)" - desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas by security forces." - icon_state = "jetpack-sec" - item_state = "jetpack-sec" - -/obj/item/tank/jetpack/carbondioxide - name = "jetpack (carbon dioxide)" - desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals." - icon_state = "jetpack-black" - item_state = "jetpack-black" - distribute_pressure = 0 - gas_type = "co2" - - -/obj/item/tank/jetpack/suit - name = "hardsuit jetpack upgrade" - desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment." - origin_tech = "materials=4;magnets=4;engineering=5" - icon_state = "jetpack-mining" - item_state = "jetpack-black" - w_class = WEIGHT_CLASS_NORMAL - actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) - volume = 1 - slot_flags = null - gas_type = null - full_speed = FALSE - var/datum/gas_mixture/temp_air_contents - var/obj/item/tank/internals/tank = null - -/obj/item/tank/jetpack/suit/New() - ..() - STOP_PROCESSING(SSobj, src) - temp_air_contents = air_contents - -/obj/item/tank/jetpack/suit/attack_self() - return - -/obj/item/tank/jetpack/suit/cycle(mob/user) - if(!istype(loc, /obj/item/clothing/suit/space/hardsuit)) - to_chat(user, "\The [src] must be connected to a hardsuit!") - return - - var/mob/living/carbon/human/H = user - if(!istype(H.s_store, /obj/item/tank/internals)) - to_chat(user, "You need a tank in your suit storage!") - return - ..() - -/obj/item/tank/jetpack/suit/turn_on() - if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) - return - var/mob/living/carbon/human/H = loc.loc - tank = H.s_store - air_contents = tank.air_contents - START_PROCESSING(SSobj, src) - ..() - -/obj/item/tank/jetpack/suit/turn_off() - tank = null - air_contents = temp_air_contents - STOP_PROCESSING(SSobj, src) - ..() - -/obj/item/tank/jetpack/suit/process() - if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc)) - turn_off() - return - var/mob/living/carbon/human/H = loc.loc - if(!tank || tank != H.s_store) - turn_off() - return - ..() - - -//Return a jetpack that the mob can use -//Back worn jetpacks, hardsuit internal packs, and so on. -//Used in Process_Spacemove() and wherever you want to check for/get a jetpack - -/mob/proc/get_jetpack() - return - -/mob/living/carbon/get_jetpack() - var/obj/item/tank/jetpack/J = back - if(istype(J)) - return J - -/mob/living/carbon/human/get_jetpack() - var/obj/item/tank/jetpack/J = ..() - if(!istype(J) && istype(wear_suit, /obj/item/clothing/suit/space/hardsuit)) - var/obj/item/clothing/suit/space/hardsuit/C = wear_suit - J = C.jetpack - return J -======= /obj/item/tank/jetpack name = "jetpack (empty)" desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution." @@ -422,4 +209,3 @@ var/obj/item/clothing/suit/space/hardsuit/C = wear_suit J = C.jetpack return J ->>>>>>> 6b9832d... Merge pull request #31388 from vuonojenmustaturska/atmoscherrypicking From ad39e816f4efdbac9eb97d96ee4523f8120478cb Mon Sep 17 00:00:00 2001 From: oranges Date: Sun, 8 Oct 2017 19:03:31 +1300 Subject: [PATCH 25/60] Settles the sabre/rapier debate once and for all --- icons/mob/belt.dmi | Bin 16627 -> 17697 bytes icons/mob/inhands/weapons/swords_lefthand.dmi | Bin 21208 -> 21978 bytes .../mob/inhands/weapons/swords_righthand.dmi | Bin 24474 -> 25442 bytes icons/obj/clothing/belts.dmi | Bin 11442 -> 12369 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index 1ae0b0a2b59233ef6f333e6c093bc4894b3e15f1..5b5ee40cfa977678628954a73d2b21de5d7198d9 100644 GIT binary patch literal 17697 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 hS;N3y`~tUyh(S&Dkq!uS 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 V%xvZ80Rqk-HD%35#SdP*{V#=b)=B^X diff --git a/icons/mob/inhands/weapons/swords_lefthand.dmi b/icons/mob/inhands/weapons/swords_lefthand.dmi index 802b9b85f196ffba6e95ec373eceb071ae67a20e..ae7cc0336cee41a519b17343cc4b3921cfa4d768 100644 GIT binary patch literal 21978 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 literal 21208 zcmb?@2UHVXw>HR&ph!~z1*sNP1XKj1OBF?m(rZBJk)rexq5{&CDuN(HK%^6-*F-@C zq_;$Aks2UCgb*Nw3}2S%YG2(kp^Rin3$LcL(Q!GbzJ-&JofPQ_wey%VhVm+X!bd=;PMf* z4oe+5bg}38f{p0j(gJgCIi$(S`}$+ooN`QFBQY!m7t9Ru)|kbI!ggx**DQAk`{>Oy zVfDmKz8d9M^SBb|TeP&aW&2s!iA>W{oF}-IM#3?Oye5xdJsS|eLyI<^y0L-MO}iw|@wOk5%k;&- zT7B~%o9i-|Rg>bWCtr@y4%Gy|GBMXTwrML#k>NQo($kP&cSuJjxDZY-VVxkOQv6*= zM?z`MFB?2O;$wzm?iCZ<%6duTre|mI2fc>-Wyd*HoGSgzFnbG&19L0GQEcB09y~)x zkV5vE`>ZEDXV)Mvb;T|lC$ep=oaVnE5Waq(_j{rwB}EZ@ZRzu)Y0TFC&u1JnaQn~% zNB=_pTx^u2w)FkM&P4p2xF(&B&RiONU-PybiY!nld7}G5sO|#&)>(kIzE&&19 zeaJA6-q4|Ew~Qb4a&f-UE;6ZVxuaEfoX7jeqieNyE+!JnyK>nl_8gB2Khx0q3*~r> zN7L~BmxBV%yz-6r-F!_bF`HdcUv6f94Po!USFSLkJE_%m^}{2H^Au9Ss##9h>f5kE zIG(hDZ^Bzzuu&|g!**#KwgKuywIc5Xz~cT#A0;p79T&<2NIuwQ3qgAb{7 zfw=0L2~1cYK3=&`3Kq;17ZX?hXUhf_EE?kNlXiER*MgISSNiZtsj*>O4wRc!th;u1_r04w z;_$&Lp5YJ4DP}i)fWc18@B5hx``bP@x6bCVia&@}4m%tS*?Jz6tgZJNXg^}K6{23e z2ihT!t%J!52h$aHqD+o+a`p^zze)IX+>u>Mc@WhHn%X`(LjK+DQ)(n&_tys=ZL8ss zdKa3+`YLPQ1tI=9fwGuyE+&W1N2POed>#Z%9W3P0viecQgM{G(?H`?drFGcJg++gv zAh3A~aZXYa3>j$_9Xu;qXJZTN>FMzlce>(y{o-KBw>E4FyVDXDqy=8W#}Y}FhYsEC z_BDqYn1>CXKG|MAi0pe%>q473{3bKAc(Df;`u3c>bpnDv6||8NaS8bbf)KZJ(JhjV-ktT+*13 zzf2#ld`e0RFa)GD7K0Q-Na>nrTh+Wa6vUB@f+Fk zuZMrzsDgo+xw(xmQ!XE${X@xrwX+$xIm6DVABvIn1}kdlX`5ULFA#rw$AUR6EYCH!g#VB;ezUpje~id)IW zu|{|9WM1;We?Q-b>0@h+oX+A5!RiR$AR5mEanpO$vcGtGRa836*42{EM_I#=c;#^S z(jXiG?k}A&4*oP(eim~EM{F9?!K2XV(0{e@ql5+!sG|HDu9Qn^pL4E8PYTyTy@_v{ z&!jJ_1)U;@wqX;67D-{UBSZpa!-t2Xj`X*YLuYJU zocsTUw9<-F7i;41E*=eacYmnc*8aBOl+z-iKWLdo>*nU;_nkcd7-z%J{Ucd?clqv` z+yAQ<{6A=mZ3bndZjNGQCsJt#Z!!F0qFTKs-vG?R8vmmc2@ccJEB%e+(zqJH>*@_T zVrtGu36FQn`2e7Ap<#^hecj!(D}bal?IwiJUP>t$A51gR{$3ti$!i@eo?}F3QxWDh zx31X>5&7ol=?JiZGsJ(E=amv274_oyn>Ot5YvORUjPeNbpzuof{UE1ZMSVTssQUm{ zxb$mrydi*qv0ifTc2xoY06eyG(!bn}dLhLYG`b+y6^OWvzdyctLZmYYIuiK!IYiYt zU>o(E7>5Qe&5M^6H2g&0e4x>jK??2$oM(X;ho`+?UpPYfz4;5+4ELIR&zbwIT<$un zVEexj!1I`&+IsN-83g{{B=JdGuN3I_hfMGy?9@MK>uPIn5wc51Sp}Y6_`+l1pX>Do z8Jq3!%odiPC;lZlrBhc{yux^RD49x4ZeqXlG`cD<8h%csMbD)}iyBc0_U{C^;sS#! z@&-X)yi5+Ci%M6^eBEj_eLO=`A}aZw!lf^Gfr}ZM7m|6Fq{9u3jGDRi<9HO5lsr7y z0pCj3(mH{cp$z*`o&HVy^W(-7?_SRkV%1_uBmvGt3E~}h zLyXKf)RJ`AYpz2zR6q&m&YhdW8%aN}ii2Cg#SjpUne8_aAxhC!A9~XR$#h(q=&C)MKrTU~2$#(Z?J2<~M(js zJtGqtLk^dTO?PT6?YIq%ybN8^h#wU0`VSX-+n{{u(i6O(odyz5JNVHg8!wnicSnDs z-u%NVdl3=;Em8cB4)6uAepvdk4g@`G^F#fn3xuh5vOIPmez|ILqWB@K!UhJgjp24` zAcJm37s(G(PM4N8d!^MYI|EIiQR?|oeX?HNG)w>`7Li@LI_AKMXmA<{9V{@!6>zMV zXCmttndENR;F~tksl+#Y!|t5!+Z?HYjxrA*3q+8o2u|)1KN=uNqZI z%q2t^p(RD`OdP$M3Q)ucV%!1!t9P8IXU>_2KI|pCuQ{e-cN9uS9tfc%MQ+SFN#K5O zf&Xpm7;f}GG0@u&u`~RWy*R zb3ecU*f0U;B+|oQ!!khrvr96&`1@C!9GjG;%3(gh_A_}b{^18DJvsHt<~0QLqN- zjP-vw!T#T#Q4&DlcFI%-*H)`nu2zj;#QI>Qq&bF|8V=jIzJ!^>)~o)-;F!<ePolld%?wkxP(C;+?b#}X_MX|lMYmNbNxES1MowO73| zo!S(wdXjmDQa-{P=myKM4UK5FYKXmjT5!M?Mn-twwxa+HXxB`(av)Gj-mT{X#of z(oA@Be1z=GI@AiHdn6r;&u>$y{NU)$e$Dy)<6#5Ge{r8$Vh_QvZe#j@)T;8ks8)4d z9A^bm(~c2*EO46FA23jR_}8~;C-G)bH{d%r7*g!t97$K7?ad{buquSQIXvtTDeK+2 zO41=0$R2rjtYcx}y#?2yuN}ItZ9)f6@0?;NG?eG#$M?#f|Am{C0B#@43*`b61THjC zj%^tkzb%7>Yumu~0%SvG^u&o3g4g=M&*FD-30ER*V727<@O=u>yR`Lc8`}H+{dOwX zODTXP@&QLWhYtR`!;pyZO3TWD3S(3Ye4GQ)$1J&c zYyYCykQ$ZT2VA+XUidpCnUim%9bBLYO^NY)66{$BqU(a08vmVh{M-KI4Hvk5kXd&U z_rG=jbK^#b8Or0>F7xH7q20RcfOCX?4G_veFqtnJcpE&HoiVLO)=N#`iz~P%WTi}M z)!d8AO`8^9Mw2i3iGD9^n7XI>B%_ggtB3gYK6mSU%~9bf6=9_=uUp)o_?=N>i`OHK>G#bZLIl|4o$oLS@R**M!4`K49p_2vC; zI`=5u&C^kGm6OH!`FX-oX#u6TL82+e8sjwas1diURzQ7yC4OGMYh4uDD_t74Q(S3# z@{|8yZgf(^8Fw8rS>`(^onmvGm`eWGDUw}Ta%l6ULI}t}{d7KzcbG$_@f|z~_{fC|f-;;AJOT3z}g9M(~!@z=qK0e4enYxt|&TVO$JO zt0Sa42TEQNsh$Hs*V~HPT%=lLoDhL5qr@{mWt}r%M&exhLQc9ogmGb?i{06BDmEkL0nwJd;6; zsa6OHLZm+XeyAowx%8WnJ!%DI(l}Fi#0kQP*el95y2`%YR70U0lYx-^wx;;WYg#L9 zo|urRDutea^Mn(qusfzVF(FnC*>Z!brU@J2XFG%12UH1nO!q6U3oo|hnw^E48>mdL z=BpN+awrlQA>X-kXY8J>eUfRzIb3z~!AM}+?6COVA@+*hQV5o}eL@FkvUsI@H}gXx zf>70};FcTWI-3K35Bvt79QFp!}E=7w!hLhVH|YJaLf(DdC-GGt@+h# z^@-XMk$AE6c~Mn+MtTm9Wq{R+4-ZUU&_>h}bD})FW79e&UH-)Tb;4jf?mja?v;v#x z$CuU4{s6()<rWR2g% z-4fsB)&g{KY&S-=35HjasE!y#h=Q6o^W5TMsXyF|>BG6}U??icuu@kIIr~yz{~8|R zP3Z=yb&QZ-+`jIc*F8}O$-!c==25~`U(W_b^80wZe2R^M7Y#-rP7#BWULA5w>guqa zM7bY-8?-I>atU!dMakMYP6xN>caz0d*Uq#4_#&0KW~Y2>xMGJaWJFgm^# z*>G$87hec@4QsFruJxLfRESsr+ak8Mjgv^@^U$rH47~hjTDRWyT|oYCwMNWt{w(K2@5o%YxHFFauOXY+lK8z z?v1*Mp4Dh2LliN4&i)jNH)6A=U?Ikmz9#@BuW8U=$ZZjrJW9F@D{-mPSg7MEhk4M) ziQ0i4U>1%{3D3sS4c_VYErAs$zEs+`D1$J~b$GwY`zB%@wx5dS!sB9Fi7F~Zlhu0G zPv1*3pRTO@#diqua^?}y4YPAhX;T+T>!Z-9UG!GU#6lO8I@ki=C%Vn-Vl`5ZfwmLN zG$;z9@+dDW;4#?26rx!KR+Xc_KMyeC07-D#v+%Q)X3I8;$%l8^`+jC6qwHIBbQaLI zzAtTZZ`=!V-(1P+1lO-_oZgoIc1(YjOB&I*cDh!6VrQ27)P6J_&#Fj+`{ZoCo>>9x zVVwou>@|c%&IW1hKhNQA+e2mKkUxpSDD6IW5k0Rl(skek)8X8Nsz!CMHj9$O0^p;o z%5KrJDF*{TJzoz$TjwEp$;bUfZSQ;y?dn{cH#G>HTPh_M-Fob`;`4$39BvZ*VtMHH#ypC;updc5i6-kGD(2`V$Y zD3~AUQGiRBj08d*PZE_2g9lS64)`$0M3uIwq^0JCF99OQ5jv;vm-&8>ZXbq7miHwZ zPC&HwE@*6!2}VQ0P>N5^y3urNbHlvk)^-zYe}e{#L%EX+>6d)y+0d&^MlJ_#xwoi3 z8m8K#g+Zsm1SGYB?lmr#7*7AR3#*%bL$3d;>T^vzr$Q0wtaGEf}UHekLVud-0N>X}cLAx+!X-5J!?!4dX9x=|;Aq=R8Dr63Ht zH9DWGvJnQE%lp~rwqL$R!JF10WHcfMMd}cQ(JwOQSHsn|5FVx=dWzF*?;8ehCWLQ<-TYqjO(u zOzKnwv;fDAEmn>(x+|^ah327B)L! z*`U=*w?pArMBuZ_a!jyVKid$V==&4VvWD};<(z;oN{*kWs0D zkNSEbb2b1)B8B9=)mK7NO%>pFa7TyLMAMwql^aV!B$f%_nb)X;0fgM9~++1C$(Xts&FTA?!O6nYT zwLneZ7B2YO-V7rkpp7dz_;AY-#Z$ryKm%u*5**_fUxX=c0 zrXb~JH}n5ZivQ*Igkwa60|X81*Gn6PzMAmt?lH|6pI~OXvGMs~b(3_O_g-cWN>DHHiStur`NZ zxQatSZicp3?BeMYDvekzk#GpBmc-O`zIj96=~BPuOY6x|?&S~bd5g?*NF`YE8a}W7 z>UryRja33Xv@{l-yLN#V5BjhHr{iK-lg8&>OLiUikSrQWGAs6HC0QA^-Wzt z3je|U!F^O&S7(sVW;2qw`p6o%gV@*}pD)9T4!kK4%1%#7kf;?o6F-{xhL8lCOHdEG z!W5DX{aVuU4vQz5d7`-PO{`Qc`*pS0<3aSz=B}3McS}%5Z|{`{kwz*@URnY)j9=kt zjNdRZEcDMTLY6I5BMw#*_%b1f|^w`s}-62Y3->XWdr$`gW*V z|LU|0XAic#mL;cNJDqUDogqBQM0m()f~YU2Ra~l{(21y1s?bUj_u(9tN=-j` zDBs;%O4?Je;dJF^CJxpFQGZU0dnkGL$|aw`U>DM1r-VVFO++Q|3<|*QbGG%m8?yHX zje`sF*RqP%pF|^6_}U_>xuPVz!}<>2i!^FE*I{y6V9;&t$;&TP`}I$p?Dw!Uu+7$l zUBE{=rrT?UtA>J#MwVpbGHQE8YMza~8?BUT_kH@)!eU6f{tQ30Z|zw+=UuN*SlI_& zJBkadc*;_xrqq_Yox@B`S-ZR=3b3g+yR)97l;o2sC!=%(TMkxqQ+(z3bL~%^@pS%q z+#PmRGk(aNb5=gPP7$KZa`joVexy&2$%68=nYx*iU>~yQ=Wf|g#bP|ylH}R$m+#ly z1mNj^<0EF;6~tU4AxNiO$OXs$Mx)w~lC@tR($UDbb0p$Pcvp~gfX4%4_h{+I@9{W# z$K$tXv|DTLInPa6XK@@;J#-VP{;VBX@VHgdX{l!ZMccAk(zMNej%jMs&h|H4bv`!k zA<05n+z|uT!@k@6&Htzc-~(Ms8G2@*>R&-U==dQ6Sby}PWjw?OS4jWH(fdtB3sn3h zEh={J(EUG4A8YY8cBpyCiPEg=OtP=WJR0i@fAPsm?%2o+*d5eA*yC*cI`q~6^n&Of z`{9dOZ_LYCGo0?fEMM+1k#$`{o9 z{Qf<2DuS}^>d@+;;4@Rs#x3$nSS9ch#$8GOT;Pp-BsmjWog3^SK8OiRzLV?v;;n?R zDM6IS&PEQZJ!{~+$ffVkv`r+!`0TWDk$AB;s{JQORj1G&uh9XxJ4Wz%|Cvu5JWP8v znU9CgPgnN!_lGEPz9~Oj>b5>nCn0eT$x|S!`UlURHZ>I{g=nN_srDbg#leyQn-t!a zqu1K#@UI^7p!u-@>lBbKDKL!%!5sWAIJYGx1ROn#bs*F|`VDk&(nPQc0qME*X{0M0 zAMDbv5fLwYlvNBwNQ&tUKH(=%Pt+%Kna{8UT-*Ej@rqLLub=T_6F6e6kKzaX4;3jR zdA&NT?}fKog4+P{LqI669ZmsQI2sC{Z{IEN(hnQ(ZYTqzEA7c)rUEmTZ;*APP9Y09 zNSxsFeq?g3aOqpN)d{R9u%MT5ZgGw{MPQ73(bX+ae=gGszX}Bxb!@rMqoEVP97eqY z1~p1McRTksZFFAadQ|AG0)!xow}H0Trg4QbuG`K4@l=QHZWJa}*wo$T5>~F2s0(bd ze~JJ4MgEa;UjWZaU<*Wcrm3mP2#y{VRtb`sws2;<2xgP{jgl8tWn5zN740!p0Lqg% zE`=BNWYGtNdkM1BZVzRKRXt(Qt#-l}0&&`6_di9^cw_aCTgOd){0orMv%6$s600F! zu}Aw0Hb|1jEoWh}5w_EWpa6UGw>XSvpB!CNfFNrZnO?1ZU3~`0`h7i6-e#e@)V$1j zFjq}GThO2Ldlkjv%6aytVA?+*^oxVP68tl;YhrJ&F?In&m^vzu+XaJHk|_6VdA?l$ z)1oUse``D_y-eb6KG>J{RI~dt0h>jCH>C7a@R}vT*dbU1ickpONApH)eFLZfTvc7E z$q_<}tYnrl_cw}smYjecl%qQ@_f0VyArses;CA}eB=5@pqIQS-B&JLbvF}P zCfo?zIEI`>!`eS;Gx^dkZxygiVSTc&`{osRX!YI_q;X&;X87yJ&4Us4Rrj?7TeCn0)~H8 z?I+NQyvJR2{S9ybfxu=41fEr*Ct@f5T>C@V$QS0u`6fiL8UkFBu$Y@l0I4&5FRh6M z))E`MMhZ0^O)8Xp?Revpb-6BR)_6YpA#_dKG;9?7W}>Y5e$ha6r$fF*PwpjR>RV*I z`_{Xus2`nJ!!ljnYfYwZKOUBE)B^kN12se(nrFc@_0^L5LsSTwzu`W0m>zOLZv^~X z3{O~YJI9ug&`yM+2X&WfqX6ZVHp69A1Bvdqw^7KeS!5|+dPe>U>MZG_fQCJCUT+N zeN~hfPk?)6djXdU{q<9mm-k1556n(J#Bt>T@O1C5Kq=SvGwTY*gW_e$Q=OwOm{4LP zfX(tq&Nq)%H*Db|8FgTEd~EmM^zflxKaHS4+*l-0)YG$wFQL$HUc)QZo8IVNYK_tK z%b*s`e)^}WDFAR`xBIi8zlA5HU!&r6ajpp#zhCp@^ibX^L}!Db)pWOL33Dcr_|b~0O0EW zt0#1>ZsYsM(?kSzMs}-HAczc3@cihTbMIRx4uI<2^~r|qIsI&16a*JcE63g$Kz0*~ z*5en{OaQp{SC-=9x+~3JX?nXQSPf6bHU3h=UD@hGmT=&4xyXPfBuyB7c^iimH(x?t zhb)2epW9$ztvn8AcIB<=0Jtv91Anqmy@l!|z{2m_1a3_IV1RIfxzgElGO9_Z_7hje zI$!XIK74p55I@tl{n5P4q9;!~#$s#~z(Iu2F?2WUY$BB9vX=-jR~WTmQNTWrp<5f> zMF2JknGJDnMwfZfHep}qvl_*w0(bz-PRvos@Rq7(Nv~rO=r7oTLvLa7Jnz%;qT$y< zmO%A`dv8NMF>q$*wMnF*Ad4_?1#yUYFw%PsPB0 zLoXbJbSNMy`8q23=K@g>_Q;W(xXY(t31uW)dts53H{6eAjTUa=0{sErEaVr35Vq(6 zKBwyn8Od0@0Yg5k5=1SuK_|Q&X&j?Icq;gimXb?967LZ+&LgB3E~7aJ+>+s!kUg6# z^mMi-i}1el;hoy(3b-{5Gccnr0bp}y$>&cx8W#Xe%4eiCd6Mlh6dCzM&NX*460)5iW=D|bfG zu6WsF&dh)}Y+AfUXtDGV(Mp9j?l*jhC78K(3NRJzszWC=_1}L655)tAC+)74`f_H5 zXfJ8}61;5SlPOsKLhQ`Q&+JtGCa(TpEvT6DQtWZpc0at=t<;{k$4%eb*yi=sdjW{- z=&()SH;7AZLP$ZoA}qB|8Y z`g*<uO>yvVX5`J~N&QI6bEx+k zLCAgr^r*N*#ItsQEN}|KE&2Q)q8Tr@Jp);<)-^zBpzudsV6V;4aP&QaUNsMf3=e-2 z`*)h*f)af>8F%`8U%dOyEC$ugd5qg$iklu7YAxe@CER0;I24EW_z!`c;7MoRL!mEG zcT?Bspy*~nG{|coenYT8olfs_a#W*ZpoN) zcl`V4r^|jwqNfJIxa@4Hu|6ZgvLDx$$bpd)IlZpbGF=HI z-UFMS9~guInS|XN!kp>>oc!Q*gZV2!c(YjYwV0oy<(h{891AQy3n1Lo^m0jx0ke>F zlC6sH>zf;JXqWtveX@`K-yK5OKj*REWn?7YN*Me*!Vdu~V6xbE$$Sa3qM>MM)G)a& z6#?YKMsY-cY+_EYBL9!4-@ZS^8SXk`2Xb<1u~K(;QWrcLx+P&&O{}LxsQ@3Y&9sHB zJYb{&v}3p`ii;-KJ;N2xRmP1vRYvNgs8GUp0MCIuMEM^)2c3b$tS$$QDbn}6@7TG| zN*SW449q8GtjnoqxQoav0W-cbjT={>?-|cOVgR}|0rSz1M1lTLpZAMfy1PrYd>d$> z3Zm9GV=-S=E~AmmnQk=Qz<1SwKkfRVow6b_@mqQrud`T8kb;c&GMAMm4h=^Gvx|%E ze#+9zmNSKRqz^`JnUyL!X!1 zjgyWX){@E97^DKIuZe!wltpjf7KZK%06V!{A~=ReeVkm^pUCgq#s(xr-0ME9C9x6s z^Ba{ve-P7tXOfu%5_AzDL9sJ)^<4~sjspaG;3q9i&h2dI)?{0+NH1_`5~jUxf>|h< z)H3l@3Q+7bzZH9VVohX7V_51{e8=Jnq`TCP#nqlFz?7;2@j$;DFYKfE)&bq+j7#?0 zM_MdE8ZRN;EMu=mChI>yzv~2_uVz7+v6nKy9I*rfRC{Y1w{o{YuEoN$@D99< zXnr{W)>F1uk2i6>45|p~n#e}vTleH3hJr#a+gb1&_1KU;8E+TkO0vhoHn z$He~!MxV&bM;I^xE3iO1H@f`!TieHDE_H!SOgz^!#OL|%riq{PvA>ulRSe{s7nZJy zMT;OLqAoKrnFy6J_Y_vE9Rm`>H(a9NbHDS!*V-*ZqAp**A~mtwrD*UwArexw1Ih;xv?}ij)hOH|t=3^86`H`>9XRc|14+UM*92+&hUBfY$ZIf`YKJ410CFxu4 z5#oJUn#5IKTHeWPQ0-I#rru*VDaoeZ>o)v%E(UD8Gv+S77CtUpl~a`jS$h!eDNQE5 z9-lVY2aiHCZOMAWIAUvbRV|Ap5cvXG*=(rO! zpYjPv#*P{PmcLfpP3Um1DF%ds2z8r4Hgl7{J_Y2i<6}=j zshb~AYP#E5k3dE7WZHzt0%Nv_pRBUU0XP(2IXDghnVmK)eIjX>Vi2;ge*5gvpQ-%fisAfE#Xh@@40`^Zk48mp<4ljnA+fYSA+ zah6=A^BAvRq1*WbOAx@K$!h7%g0AwF&7a>n6{p?>VIV<;A=8lE>Cg^N#lI8@%Aukk zD(fD>yoEvfqIB0w5?2)!(JREzX1}h1MWKYX8!l^~h#$g$G}C|)kg7f30=mr;p9{y= zI~f1X0aq0i&b0*L9mwB-q`<;Zp0?B~prI!kgpRrG6*aUz?ngd^eQauc3$@`PFB}`K z>(^lD=I04hHA_JHVZ*Aq;vsCaNr&LOMFiEH51tM{+XsyCUrr2p7+Wlx1ckf6lcVPCuKHitRK`vf*MDD&eZebMn!bnILj_w^GN z=|puq*1%7#AXUskKrY<w^_|5{z@p;Dj|r3f(7PxM^`2NRP3fKzNp z;mHb5voII)+S4jykG)rWPV!<+X7z4bCngr+$0b+!%8bWW5caC?Vn{Wko}%bIl0wPDyli z5|s>n6@%Pf9D~O&{uxLC(UT-3u2Npz-m)nfI=(Xfrr~XH{!B>Ul~Rdl{(HLH0}m31 z8{VGqJ}NUACIS?or;}QMH>@hLpxycAPXm_wT9bz;8B&Ae63mxs-(Atq*^jDKU_23H zWytyvP*${OlnK18bYY~WM!1S`YT8!H=`9eA2wId)RQfOkq0ePLSU^&7$ZxWuN)qD0 zn^PBos=;sMDPRgVF0{O;7uQ^Xvf5X~k}!eu$wRZ@4YKcZs?J|NwcGCZ7!t7^lK0n3 z&G;SlJNjS(_ilt?#3BqSDbX1Sol|kjyEqwEkq@Kwu8n;ON-7t19x(&zHhEA*o)8p8 z=zZLTG#pq}et~M^xF#o804$>}g&O9~IilrW5_3A;yY%qQ&EL89>@C6iEovU$fNQXW zOIAwmoB#FZa zKei(;WK&gAv#SNvish(&EbFRB8x*W4=VrV}VpQD1)ovLvgYFrxd@(+qdmSWiW0QUU zOxwOW@nCYA5vVLc!*$w@$i>v;n>8fWezCPIY`1ID``#h(@xx5T0&M@a1O3nUeA3TC z>=8p5whj11DX?nGL%a&v#F^_X)cQHhl+q5ykyY2ZdyTtA0 zpwCwfdMSE&vy$*JB5{0E&w%!9(N7!S$WUY}#6Z}_GN5}(ZhB&!^LE&av zh$L~k9{77}Qd`dk6Y{d1tOJy*=Y5ckXmhw0_zd`JRcRaoeI$P=6iHQKD#{^j{iFz; znF&johU*KV+=c{eXNhXv@6Zv9@@E2Q^Y;D}R=wfAfV+86UBreT3_NXQe5MTF3cM|2 zx;vEzh5XEx3Va#?-1#<~JG`b&Ma>$59j_-gZB?&~se8A0B7E&qMthUr?}ngid{GYls=9VMi=+s(O_4Pz@oJwi89*-qks((JXiZ=V&9PLPk= zM-Dk)B9BAXv5-CUrgNRf9PXgHp~%$=|iT&=XmO4;?W( zBsQ%1)!eJHNqJ8%m2I|J6v<_d5(|a2l=jP8&Z-=3M?<%Tpp55J7(tM&wa?X0M-bvQ z5aT@j`(H7OplSP6MY`71B5w&Q$YHaqL8M(qsZ7ovEw!$m@pk;mbjC`guQ2fLqw!8; zqxzoSCDACH6^p>zeeyeP*Xx|h`=>G2So286VsEsb61`F z1_yCJ++Y=`z)!&LIv_J$H3O7Y#6)m03SVSc^pagFS1*Ql?ibO;LVK)*+ZM_bf3Q57o|OU^@KU%g<5u1`0-dA3 z&Q|jPQYC^9V6WBtSln98pu(iz3mMv@i-(;mVQk|MA($4P1r9tY=U>a>)m5I+`EU!fR38VU| zM-p~wWR2*eA~KY*9(44XH=~eSVAbT7}Os`qH)rIlC*NAo$~+!p;|>2IIfOI zZ2&u1TeICV2jWGw z@V%7;aINsj-@TBdKil9y>gYwh4c!R@w|k z%lP5s+-bVCPPEDh_DS-P`1p+_jeFupPWPKxy?mzs#z)J11Kc^=5d+xHcmz*kJFs%v zatChc&m=tx1xnPbfO!Np=OT&lmwQLj*k<=Iqw1*VBp=9f@=j>m1on8e4_c+%yw>UY zjguc7)?A*M0TxFy9PZS-eiBh0ag5)38QHzkxcq7H{%$uLn$VycmhxD$S(&yy&T0^tG8`;@8}4nw-oW5P_F7{$GIJ33<-q zbH-JkrhDzTL!OyWwhO>#UA(fTd7}0dLM+&O$tN(MCQdgU%c2Gg1*w0$q%54yUzJvr z^9HJ-EBIiQf&x}SOF zKZTbkhi6WF*Rbc+YV!apxfP!TUjG)v%=Em)SV!UEcOISV?1clD^3b5M4SPCH5(owK zc$tr|cNa&qSXySI?pZH?fmu&DMfUtcEs@mrsELCVM*!$31InpIUFG>lv??l(F1nBu0L3?U*p~HoREZ>)UF>ox%{{ozo ziG$s#^Oc&sr+8G``Ys%Oj-@?YrsX!0+KIH?w4=~wg(@0dt;_@H9W~^73=#qF`hfnC zvEV(lBKrn43c5P|Ew}8sY)Uj!{UgG-k=A!PT*M8gjcN3XKdNN)iY%mraZ~uV-I+vu zR{2DgQzUH!L#qgXKYF26Pjtm!*~iR0WW}JZV$%>03B$%oM!c8I-Lv~a|5ctFzACu# zYWXbOmbQ?U7`vPlvBv^I`9;XkRBsMO`0cP3Q7NXhhB9p6Epy@|WT1vG#F4{JVTkkRz}{NZ$P^_&Q?v~zLVj{h(|@gv!1lU!G*l^-z)y-O zTYErXoQBeCyS12(@rG=|TeqxuQ*d&&A`Zz^|IxsBp9^p~bfFV#TJ#n<%E(*>r zek7W4!8(1W8o_JdifcrB!D)Q$dh$=2LRDTU3ff>bf_K@r4Sf)$vZw6)<|Vh`8?<|c zHi&RMnwW!**p`&d{Qk?|f6`KYKi;p)Sbcs)bGPPamXJoCMDHvP7OXT+gdVT1Oi`4O*m?#Eu^fUY<^K*t z^1&fKVF|UYSQ*i4YCF>Y^Q;Ssa~ozRYp(k z9co+MLR*w#3xcK!EbaHXlzy$Vy%uq!F34S@1(gBMtPG8zVu3;BZu>$_q_06{l}g|o z4Pu-|8odo`;EI0V7hv-H_s0L?UJ%{gZ;J{v{9ZFSQ7n+7VZV|ESIw6X-2x#bLDTf4 zE!kbDLUDi=OTKXS=_F{O$vus&Jb9uLc>1mXaPxZjexpAF3Ca$wOkSRYr36mGsDXt{M_FG^(iR#bZF?DET!&FW4cmkVE^Tqi7(^+F{C!I)Hr3r(udrG zi&%*c#X_NVB%XTUj)!(>D}no~Gd?IAx5qhYVEZm*bj59b$DpnP;3Cb0U$Y&dt0hIN zRBE_MJ5Y}pA6F2E5JSxP}x!sy$T2p$V;Nj1H8C%S8l zXca)A76p}T(3@+1@p;_O>3w_>!5+xJo{*~T9)pv}O+scNS<*b)8%j|Kn z6+8<#m~4CX)t8P8c-HDsV*Lrk>I^G~a^?ZwNS=f5suZH(*AE<&M#Fh%)~tY>{i!QZBH1CJq6Uy#qK-gumyDHUFd&8-&9IYlK%W>}yTE_S zdw)8I8WZscp4=sLpH5mP!06O>h#j+q_C1V>1a!UZwdP#FbE|@Jas?{=xK@t%fGE@9 zkcE_+ef#rUNvd114!}Z7(`vODGTv@)jA~yhQ7R#Dj^zz&Lcq%XoTb%cCmkL<&Vh_& z>gmdald}h}SX$cE)+YoUv@Tc-pzRq7oAb(H(ngA7Bd8y^f)6~;l>Q>#l zbdomc^G`bZMc@vHOn=@VCJ^k{+rFwYV8^K#|<{^I~;g<{D&sHmC6KDHg zX89GA3`iS!BV;Ek{^tq%>cz`c|8Vga|G%acwnM=Yx*B9bPT51h>kl4@p@&9cQJPRy&L=VU??`_)+m{ zzO~hMt}{t?eviEB$R^={4(7gz_7BSUix&$o+4j1H2|j_)kG9QjVbj;6CxPcj7+Hs@J^R@68u-|vG{poe1n2f6mZg4r>QL3qXuQl}}47;G=+xDZF^CYjp!5%8` zIhZU5G}hznD8}gEm{PS58ZMORWMRDm(?xrA;v(DC!lVJf3+XbU(rOPcUGccchs>!O z(KrgvLr|khhz6I;(O5$k>-(n0;S*b(1B>F%&$*ZI;&Wg@3T`_yW|J|?S)-&*R}Gp`q<8m23bJM5Sx zgz^q@KHRe)KYh%wf@wBdY4`7~7@FCL%1c$ld{o+h3ec77Zx4r@4kfw~z;5jXsDdfr zYfmILv1%NhvVWJ9cG~VSVULbo z-6Q*<9O*UZ385_=%}oO#CD6rhI+iZxdsU8Cy7#^)lIn#+?YFZWV3yuIa+|i71!5>K zR}d2}`yX`h-*2h&K|CWuz1mdofV|CYZeVY`{thY*$&ca4(uteYI{vyx2`~Plj^&1Cixdrn(YE8;I3Bh)}dif!35+&X1##Ovht*>i{hx z?9japbiz879D#!BthO+x|D8r$=d43kH=ddW0AM8&+iy`Z z5QCjJ>&4rIpit(UQU2_fzSHOQP>k0ioHrDN3iD?J2@+4I8fMeAVDG!*xolpmm){PP zU}7`_qM0m6y^)t5Tcc1?JW?1V%N4vB!+Br81kq_jUYg6R-ZyxaRD6PwA&hBqiw2$D zVQr;2O0HmjeHB=;262I4x6w1~3^nNH+UXanK6$o`o%bP$>|cDmdhJd7t1KTKuwpgw zlE^>Yk?3^Ra{y9xj+;|>Ge=Y%xMMD1T5Y4;8BS}AnRzn_^9d;7fVIHW8Qg#?ygH?VxjMQ7Uk6_-!xu1Ws%hq=DGbO67M z3dZl_bC7<|DzQ`V4zFGw;ri{kw2flZXf9|u>hoKYZO?p~G&I5ob~y9&=>Ej($mdo+ z0X&|`bsy|DxUkkgPLa1Jjkg=ZeEx$NnRVJOEbFX0HK>jeTaA-H1wt_e@_!cJE$uwA z*c|@cDTc$UnL5=a0<^JvMkvCCFd5(V38RQU`r}dtR_1{FRTS56@zSFzbN?=L^MKAw z=5Nb!VX3nP0{#PY0e9_zLw#9KfB=Rw-~_GLGocJ1yV525?qfAYZzPy+_4oV`xciy{ zfC@;fW-Rp3RvLOl8FuohK%&irP@N&>t(JvFwu^?8-t1|V zxT00;FyChzuUGQxs&^SpI-pbTg)3G=AV&BHXR?76U*e*`3{*A}qME020XW^se}ZMG z|6}?VXo}pQl`lsz?>2|GD=4X%t#ykI+2505U4w*GV)`m}O0t$!lzWZ5TQh+}WkCSNUIDaKZa2ORow>S8Cxl zPIwYW$^~D$z%nLYx!CdDzzpQmi}#tmeeT)*;}HJ^-F;$$Iwrmer_d3F(&#T7?!G8Vt6o3n83g&ShG<>G%6X{e3>yWX1*+o`Y=I~?ExR$ zrgQAU>EhxWgl%dEgFs1?rRz|uWr7brn%IswL$6T`=u1efB^si z7%|Vnkpc_=06;U20RsR4(2N2M002NU3NQcw0L=zyJUMG@}3mpw)%1FT8N}=l{A70P-0H7(8!mY|L|S{wC)f{(m7n zuloQXpHYCp^U~?G=@hgxHRqRgy6A!d@Dd6zc;10`52{ou<(W7CR4OG0-aTk!Y`@>H zdLlh9oP4V%(qsAkeiJDHfDsg60JP`|cS+lsw*UQo+nF}i74Gs(Aq>FdM1&wbAKSLp zN;Dc3(|On((P&h*ZLQTl&w>5{X@A(=Fz2`pyBlPne?VJ)0ALE2A_AtZSh2!%3br#b z$KKvvIrr%~)pxyb&g=eM>AGU=+_6*Af2XCszMks@0mxsbKamrJQ=+yeD2YTuOy^-& zBoYa!tqE$K-{6fw2?awUBI?bWHcC05F9P7%(k8F@LU#ii%99 zVVk0&B9)#P*EZgR2M^@*snau^ugK2>bAI(Q^O(Nteb%nfE-7AHETyHTbix4SAJd=8 z3BpNHRbDR1WKvA$k?Tk%lTuY)u5DhiSZt>ARaIGSWxXAypA!m(Bo>R=mNx*HLI(^$ zPJMCqOX>abC)IzW->RytUVn4*_Rt^M{*9qqzsmG;txzx|^?P>7(PJOd2?LNfI1L3b z%TPRSHSXP)SLX#wrBc$kcb^)H$89fQIyyR~C)}+jWpb5LN-d=L%E&x-QYKgRgu7Ko zM`zw_696#2YlI-27}XUOa{vB)F`Y-Q=AvVq_V!Mx+g@keSasX$q<_7=GpBza08Gic z0~QDbWcF=7^U_@B%S&rgSXij8UcH+4^IWK=E$e62=32N*E}g%q#wVVwv1`2XiDzpr zoxiBA%{p1@>>L2VO|m`)Y~=E&3IqZ&64`G@K8`XH**`Vc%cG`KaSSi4$=&Y5vcvaS zy}fU*YWnyS)9EbQ4u9Wcb+`MlY~KA%PIp1BTvo9B$?d~(w)LTk|D{x9FkC9{8ie(#Vi^LaXaM2>GhiBd}6t7c}7nK`@7*s0vFmB}@knvd<(aVsvy5~!N=sRZ9IYvn**VTP0Kk~6U-+Ex2CQprw}0+#wR4@EP=LE_dk~Hd05B!{ z{Sqd3LFpdbM;`m2ytL4ZV*|jVW&Np<4w&=NfEf!bz~FooD!`m5 zzyO#+0Wk)^vnap-n8L-l0RR9rqW}W{0MLvA3;+N?vwr|xsCkT8fU!mZ0000=yzW0yPzkS=8{=47#k9eGGcwEMH!Fij1GfFuy$(C*wcUmf4?~yCP zwunK?nLqG_=p^B7r=OI)H1sOsE=}ZFIz_VOipf*X(8tInA6v5d)B_`WXyt3<5q3%nTfA4U7yd!Uq@_nmAE(g4GdLw&5n@ zn+lt2^XErzTOK99RGnc%L)7a%&x2k)ELiciYSrfbw{I8Q_HKQ48s4?s^w{J+5J8*HKzHyFSGM85Np2cV8eUWNmd@y~VTEgX9**<0eF1=>SIa_|k zi9ud{A;X3BH@~MDy>D<`fA@9ma?{^aZcY}x#?~OBE0f-IcHQ0A{CwBmTt3ER!LX#_ zQNwv2@r&(serwOat=u~SsIv7sTLVwCbH?Jl=TUL@+u!7F$&=W^(NMu8u^Sj<6Asop dG9icCKE~fao-^FJT+hM)1fH&bF6*2UngI6X@mc@? diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index 473f2b8573e23ff69c76669132f53f1479b91fef..73598f1d77c8a2acc3e6760bbfa3a53ed56897fe 100644 GIT binary patch literal 12369 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 From af077de46ce1c4388dee17dac278b23cc86503cf Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Sat, 7 Oct 2017 23:04:47 -0700 Subject: [PATCH 26/60] TTV code cleanup (#31262) * Update transfer_valve.dm * Update transfer_valve.dm * Update transfer_valve.dm * Update transfer_valve.dm * Update transfer_valve.dm --- .../objects/items/devices/transfer_valve.dm | 78 +++++++++---------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 045da484ed..a24f300b18 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -15,7 +15,7 @@ origin_tech = "materials=1;engineering=1" /obj/item/device/transfer_valve/IsAssemblyHolder() - return 1 + return TRUE /obj/item/device/transfer_valve/attackby(obj/item/item, mob/user, params) if(istype(item, /obj/item/tank)) @@ -76,47 +76,46 @@ /obj/item/device/transfer_valve/Topic(href, href_list) ..() - if ( usr.stat || usr.restrained() ) + if(!usr.canUseTopic(src)) return - if (src.loc == usr) - if(tank_one && href_list["tankone"]) - split_gases() - valve_open = FALSE - tank_one.loc = get_turf(src) - tank_one = null + if(tank_one && href_list["tankone"]) + split_gases() + valve_open = FALSE + tank_one.forceMove(drop_location()) + tank_one = null + update_icon() + if((!tank_two || tank_two.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) + w_class = WEIGHT_CLASS_NORMAL + else if(tank_two && href_list["tanktwo"]) + split_gases() + valve_open = FALSE + tank_two.forceMove(drop_location()) + tank_two = null + update_icon() + if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) + w_class = WEIGHT_CLASS_NORMAL + else if(href_list["open"]) + toggle_valve() + else if(attached_device) + if(href_list["rem_device"]) + attached_device.forceMove(drop_location()) + attached_device.holder = null + attached_device = null update_icon() - if((!tank_two || tank_two.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) - w_class = WEIGHT_CLASS_NORMAL - else if(tank_two && href_list["tanktwo"]) - split_gases() - valve_open = FALSE - tank_two.loc = get_turf(src) - tank_two = null - update_icon() - if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) - w_class = WEIGHT_CLASS_NORMAL - else if(href_list["open"]) - toggle_valve() - else if(attached_device) - if(href_list["rem_device"]) - attached_device.forceMove(get_turf(src)) - attached_device.holder = null - attached_device = null - update_icon() - if(href_list["device"]) - attached_device.attack_self(usr) + if(href_list["device"]) + attached_device.attack_self(usr) - src.attack_self(usr) - src.add_fingerprint(usr) - return - return + attack_self(usr) + add_fingerprint(usr) /obj/item/device/transfer_valve/proc/process_activation(obj/item/device/D) if(toggle) - toggle = 0 + toggle = FALSE toggle_valve() - spawn(50) // To stop a signal being spammed from a proxy sensor constantly going off or whatever - toggle = 1 + addtimer(CALLBACK(src, .proc/toggle_off), 5) //To stop a signal being spammed from a proxy sensor constantly going off or whatever + +/obj/item/device/transfer_valve/proc/toggle_off() + toggle = TRUE /obj/item/device/transfer_valve/update_icon() cut_overlays() @@ -196,16 +195,13 @@ message_admins(bomb_message, 0, 1) log_game("[log_str1] [A.name][COORD(bombturf)] [log_str2] [log_str3]") merge_gases() - spawn(20) // In case one tank bursts - for (var/i=0,i<5,i++) - src.update_icon() - sleep(10) - src.update_icon() + for(var/i in 1 to 6) + addtimer(CALLBACK(src, .proc/update_icon), 20 + (i - 1) * 10) else if(valve_open && tank_one && tank_two) split_gases() valve_open = FALSE - src.update_icon() + update_icon() // this doesn't do anything but the timer etc. expects it to be here // eventually maybe have it update icon to show state (timer, prox etc.) like old bombs From e5e8a807a26ac05b5f8f9c49d56b544c790bfc7d Mon Sep 17 00:00:00 2001 From: Emmett Gaines Date: Sun, 8 Oct 2017 02:36:51 -0400 Subject: [PATCH 28/60] fixes directionless ghosts having direction (#31405) --- code/modules/shuttle/shuttle_rotate.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm index 389a2406ed..5368ef0a73 100644 --- a/code/modules/shuttle/shuttle_rotate.dm +++ b/code/modules/shuttle/shuttle_rotate.dm @@ -1,5 +1,7 @@ /* All shuttleRotate procs go here + +If ever any of these procs are useful for non-shuttles, rename it to proc/rotate and move it to be a generic atom proc */ /************************************Base proc************************************/ @@ -34,6 +36,10 @@ All shuttleRotate procs go here /mob/shuttleRotate(rotation) setDir(angle2dir(rotation+dir2angle(dir))) +/mob/dead/observer/shuttleRotate(rotation) + . = ..() + update_icon() + /************************************Structure rotate procs************************************/ /obj/structure/door_assembly/door_assembly_pod/shuttleRotate(rotation) From 8c4e9d6a023b64ae5d8dfcbf0918bdd339f347c0 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sun, 8 Oct 2017 02:48:26 -0400 Subject: [PATCH 30/60] Merge pull request #31409 from ninjanomnom/buckled-mobs Buckled mobs rotation fix --- code/modules/shuttle/shuttle_rotate.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm index 389a2406ed..1979ca1c3b 100644 --- a/code/modules/shuttle/shuttle_rotate.dm +++ b/code/modules/shuttle/shuttle_rotate.dm @@ -32,7 +32,8 @@ All shuttleRotate procs go here //override to avoid rotating pixel_xy on mobs /mob/shuttleRotate(rotation) - setDir(angle2dir(rotation+dir2angle(dir))) + if(!buckled) + setDir(angle2dir(rotation+dir2angle(dir))) /************************************Structure rotate procs************************************/ From 58fd7f20675de493599794e0da3e83931448a0c6 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sun, 8 Oct 2017 10:59:34 -0400 Subject: [PATCH 32/60] Merge pull request #31413 from vuonojenmustaturska/codejanitoring Removes useless commented-out what-if code from the 1970s --- code/__DEFINES/admin.dm | 3 +-- code/__DEFINES/atmospherics.dm | 4 ++-- code/_globalvars/lists/mapping.dm | 7 ------ code/game/atoms.dm | 2 -- code/modules/mining/machine_processing.dm | 23 +------------------ .../mob/living/carbon/human/species.dm | 5 +--- .../reagents/reagent_containers/borghydro.dm | 8 ------- .../research/designs/weapon_designs.dm | 13 ----------- 8 files changed, 5 insertions(+), 60 deletions(-) diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index c5c79b9610..482e42dafb 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -93,7 +93,6 @@ #define BANTYPE_ADMIN_TEMP 8 #define BANTYPE_ANY_JOB 9 //used to remove jobbans -//Please don't edit these values without speaking to Errorage first ~Carn //Admin Permissions #define R_BUILDMODE 1 #define R_ADMIN 2 @@ -113,7 +112,7 @@ #error Remove the flag below , its been long enough #endif //legacy , remove post 512, it was replaced by R_POLL -#define R_REJUVINATE 2 +#define R_REJUVINATE 2 #define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated. diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index c6ca2cf0ec..06800d6ae4 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -118,8 +118,8 @@ #define PRESSURE_DAMAGE_COEFFICIENT 4 //The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE -#define MAX_HIGH_PRESSURE_DAMAGE 4 //This used to be 20... I got this much random rage for some retarded decision by polymorph?! Polymorph now lies in a pool of blood with a katana jammed in his spleen. ~Errorage --PS: The katana did less than 20 damage to him :( -#define LOW_PRESSURE_DAMAGE 2 //The amounb of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value). +#define MAX_HIGH_PRESSURE_DAMAGE 4 +#define LOW_PRESSURE_DAMAGE 2 //The amount of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value). #define COLD_SLOWDOWN_FACTOR 20 //Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm index 03824c4c83..e6b05e033f 100644 --- a/code/_globalvars/lists/mapping.dm +++ b/code/_globalvars/lists/mapping.dm @@ -7,13 +7,6 @@ GLOBAL_LIST_INIT(cardinals, list(NORTH, SOUTH, EAST, WEST)) GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)) GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)) -//This list contains the z-level numbers which can be accessed via space travel and the percentile chances to get there. -//(Exceptions: extended, sandbox and nuke) -Errorage -//Was list("3" = 30, "4" = 70). -//Spacing should be a reliable method of getting rid of a body -- Urist. -//Go away Urist, I'm restoring this to the longer list. ~Errorage -GLOBAL_LIST_INIT(accessable_z_levels, list(1,3,4,5,6,7)) //Keep this to six maps, repeating z-levels is ok if needed - GLOBAL_LIST_INIT(station_z_levels, list(ZLEVEL_STATION_PRIMARY)) GLOBAL_LIST(global_map) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 0774253d47..d1ca8b3890 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -36,8 +36,6 @@ if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New() GLOB._preloader.load(src) - //. = ..() //uncomment if you are dumb enough to add a /datum/New() proc - var/do_initialize = SSatoms.initialized if(do_initialize > INITIALIZATION_INSSATOMS) args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 0927a0ba88..75c0f94ac4 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -143,27 +143,6 @@ if(CONSOLE) CONSOLE.updateUsrDialog() - - //THESE TWO ARE CODED FOR URIST TO USE WHEN HE GETS AROUND TO IT. - //They were coded on 18 Feb 2012. If you're reading this in 2015, then firstly congratulations on the world not ending on 21 Dec 2012 and secondly, Urist is apparently VERY lazy. ~Errorage - //Even in the dark year of 2016, where /tg/ is dead, Urist still hasn't finished this -Bawhoppennn - /*if (selected_glass == 0 && selected_gold == 0 && selected_silver == 0 && selected_diamond == 1 && selected_plasma == 0 && selected_uranium == 1 && selected_iron == 0 && selected_clown == 0) - if (ore_uranium >= 2 && ore_diamond >= 1) - ore_uranium -= 2 - ore_diamond -= 1 - generate_mineral(/obj/item/stack/sheet/mineral/adamantine) - else - on = FALSE - continue - if (selected_glass == 0 && selected_gold == 0 && selected_silver == 1 && selected_diamond == 0 && selected_plasma == 1 && selected_uranium == 0 && selected_iron == 0 && selected_clown == 0) - if (ore_silver >= 1 && ore_plasma >= 3) - ore_silver -= 1 - ore_plasma -= 3 - generate_mineral(/obj/item/stack/sheet/mineral/mythril) - else - on = FALSE - continue*/ - /obj/machinery/mineral/processing_unit/proc/smelt_ore() GET_COMPONENT(materials, /datum/component/material_container) var/datum/material/mat = materials.materials[selected_material] @@ -221,4 +200,4 @@ materials.retrieve_all() ..() -#undef SMELT_AMOUNT \ No newline at end of file +#undef SMELT_AMOUNT diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 34d4ae8e51..e8e2b606fb 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -246,7 +246,7 @@ if(DIGITIGRADE in species_traits) C.Digitigrade_Leg_Swap(FALSE) - regenerate_organs(C,old_species) + regenerate_organs(C,old_species) if(exotic_bloodtype && C.dna.blood_type != exotic_bloodtype) C.dna.blood_type = exotic_bloodtype @@ -1632,9 +1632,6 @@ else H.clear_alert("temp") - // Account for massive pressure differences. Done by Polymorph - // Made it possible to actually have something that can protect against high pressure... Done by Errorage. Polymorph now has an axe sticking from his head for his previous hardcoded nonsense! - var/pressure = environment.return_pressure() var/adjusted_pressure = H.calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob. switch(adjusted_pressure) diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 2493f9628d..a7f8fc9195 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -55,14 +55,6 @@ Borg Hypospray //update_icon() return 1 -// Purely for testing purposes I swear~ //don't lie to me -/* -/obj/item/reagent_containers/borghypo/verb/add_cyanide() - set src in world - add_reagent("cyanide") -*/ - - // Use this to add more chemicals for the borghypo to produce. /obj/item/reagent_containers/borghypo/proc/add_reagent(reagent) reagent_ids |= reagent diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 89adfe8edc..5cd10ca50d 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -124,19 +124,6 @@ build_path = /obj/item/grenade/chem_grenade/pyro category = list("Weapons") -/* // Currently commented out, because it has no worthwhile useage yet. - -/datum/design/cryo_grenade - name = "Cryo Grenade" - desc = "An advanced grenade that rapidly cools its contents upon detonation." - id = "cryo_Grenade" - req_tech = list("combat" = 3, "materials" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_SILVER = 500) - build_path = /obj/item/grenade/chem_grenade/cryo - category = list("Weapons") -*/ - /datum/design/adv_grenade name = "Advanced Release Grenade" desc = "An advanced grenade that can be detonated several times, best used with a repeating igniter." From bf7f4e6e6901d077df73edf15d5d2079fb3f2b6d Mon Sep 17 00:00:00 2001 From: oranges Date: Mon, 9 Oct 2017 04:06:43 +1300 Subject: [PATCH 34/60] Minor refactor to storage items (#31324) They now do not call the on exit storage hook when items are being deleted, as well as do not bother to reset a bunch of values we now cache the see contents list for a very small speed boost the fancy storage specific update icon is moved to the fancy storage equivalent proc --- code/game/objects/items/storage/fancy.dm | 4 ++- code/game/objects/items/storage/storage.dm | 40 +++++++++++++--------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm index 435bc64c41..a37ea9f8cf 100644 --- a/code/game/objects/items/storage/fancy.dm +++ b/code/game/objects/items/storage/fancy.dm @@ -58,7 +58,9 @@ /obj/item/storage/fancy/remove_from_storage(obj/item/W, atom/new_location, burn = 0) fancy_open = TRUE - return ..() + . = ..() + //Recall update icon with the fancy item snowflake arg (ugh) + update_icon(1) /* * Donut Box diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/storage.dm index 9a3769206c..309479dd86 100644 --- a/code/game/objects/items/storage/storage.dm +++ b/code/game/objects/items/storage/storage.dm @@ -359,35 +359,43 @@ return 1 -//Call this proc to handle the removal of an item from the storage item. The item will be moved to the atom sent as new_target +//Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted /obj/item/storage/proc/remove_from_storage(obj/item/W, atom/new_location) if(!istype(W)) return 0 - if(istype(src, /obj/item/storage/fancy)) - var/obj/item/storage/fancy/F = src - F.update_icon(1) - - for(var/mob/M in can_see_contents()) - if(M.client) - M.client.screen -= W + //Cache this as it should be reusable down the bottom, will not apply if anyone adds a sleep to dropped + //or moving objects, things that should never happen + var/list/seeing_mobs = can_see_contents() + for(var/mob/M in seeing_mobs) + M.client.screen -= W if(ismob(loc)) var/mob/M = loc W.dropped(M) - W.layer = initial(W.layer) - W.plane = initial(W.plane) - W.forceMove(new_location) + - for(var/mob/M in can_see_contents()) + if(new_location) + W.forceMove(new_location) + //Reset the items values + W.layer = initial(W.layer) + W.plane = initial(W.plane) + W.mouse_opacity = initial(W.mouse_opacity) + if(W.maptext) + W.maptext = "" + //We don't want to call this if the item is being destroyed + W.on_exit_storage(src) + + else + //Being destroyed, just move to nullspace now (so it's not in contents for the icon update) + W.moveToNullspace() + + + for(var/mob/M in seeing_mobs) orient2hud(M) show_to(M) - if(W.maptext) - W.maptext = "" - W.on_exit_storage(src) update_icon() - W.mouse_opacity = initial(W.mouse_opacity) return 1 /obj/item/storage/deconstruct(disassembled = TRUE) From 04006b2ad2758bd6c8b524e4f0a7c03c4cad626a Mon Sep 17 00:00:00 2001 From: Robustin Date: Sun, 8 Oct 2017 11:08:04 -0400 Subject: [PATCH 36/60] Tweak to abandoned airlock (#31312) --- code/game/machinery/doors/airlock.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index e7fa7447b5..24611ea4fc 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -127,7 +127,6 @@ here.ChangeTurf(T.type) return INITIALIZE_HINT_QDEL here.ChangeTurf(/turf/closed/wall) - return INITIALIZE_HINT_QDEL if(9 to 11) lights = FALSE locked = TRUE From ef57f560ed23543214d5ad189f9349e4af7e6029 Mon Sep 17 00:00:00 2001 From: Ashe Higgs Date: Sun, 8 Oct 2017 11:09:07 -0400 Subject: [PATCH 38/60] Clockwork scripture now uses one progress bar instead of multiple (#31329) * Clockcult scripture now uses one progress bar * why do you code for a server you're banned from * Checks for QDELETED of scripture and slab --- .../gamemodes/clock_cult/clock_scripture.dm | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm index 6edaede8df..8e8cd912e7 100644 --- a/code/game/gamemodes/clock_cult/clock_scripture.dm +++ b/code/game/gamemodes/clock_cult/clock_scripture.dm @@ -12,6 +12,7 @@ Applications: 8 servants, 3 caches, and 100 CV var/name = "scripture" var/desc = "Ancient Ratvarian lore. This piece seems particularly mundane." var/list/invocations = list() //Spoken over time in the ancient language of Ratvar. See clock_unsorted.dm for more details on the language and how to make it. + var/chanting = FALSE //If the invocation's words are being spoken var/channel_time = 10 //In deciseconds, how long a ritual takes to chant var/power_cost = 5 //In watts, how much a scripture takes to invoke var/special_power_text //If the scripture can use additional power to have a unique function, use this; put POWERCOST here to display the special power cost. @@ -145,18 +146,29 @@ Applications: 8 servants, 3 caches, and 100 CV to_chat(invoker, "You [channel_time <= 0 ? "recite" : "begin reciting"] a piece of scripture entitled \"[name]\".") if(!channel_time) return TRUE + chant() + if(!do_after(invoker, channel_time, target = invoker, extra_checks = CALLBACK(src, .proc/check_special_requirements))) + slab.busy = null + chanting = FALSE + scripture_fail() + chanting = FALSE + return + chanting = FALSE + return TRUE + +/datum/clockwork_scripture/proc/chant() + set waitfor = FALSE + chanting = TRUE for(var/invocation in invocations) - if(!do_after(invoker, channel_time / invocations.len, target = invoker, extra_checks = CALLBACK(src, .proc/check_special_requirements))) - slab.busy = null - scripture_fail() - return FALSE + sleep(channel_time / invocations.len) + if(QDELETED(src) || QDELETED(slab) || !chanting) + return if(multiple_invokers_used) for(var/mob/living/L in range(1, get_turf(invoker))) if(can_recite_scripture(L)) clockwork_say(L, text2ratvar(invocation), whispered) else clockwork_say(invoker, text2ratvar(invocation), whispered) - return TRUE /datum/clockwork_scripture/proc/scripture_effects() //The actual effects of the recital after its conclusion From 5d0853e16a494bfcf99c883124c966e87e3df3e2 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Sun, 8 Oct 2017 17:05:40 +0000 Subject: [PATCH 40/60] Crew objective/miscreant system tweaks (#3213) * Loadsa tweaks * adds miscreant pref, other fixes * fixes runtime * fixes compiling errors for REAL now hopefully * HOPEFULLY fixes compiling errors * COMPILE! --- code/__DEFINES/citadel_defines.dm | 2 +- code/__DEFINES/role_preferences.dm | 4 ++- code/citadel/cit_crewobjectives.dm | 5 ++-- code/citadel/cit_miscreants.dm | 7 ++++- .../cit_crewobjectives_civilian.dm | 27 +++---------------- .../cit_crewobjectives_medical.dm | 2 +- code/controllers/subsystem/ticker.dm | 12 ++++----- .../modules/mob/dead/new_player/new_player.dm | 4 +-- 8 files changed, 25 insertions(+), 38 deletions(-) diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm index 51ba9d4c59..4c8243cdc5 100644 --- a/code/__DEFINES/citadel_defines.dm +++ b/code/__DEFINES/citadel_defines.dm @@ -70,4 +70,4 @@ #define ADMIN_MARKREAD(client) "(MARK READ)"//marks an adminhelp as read and under investigation #define ADMIN_IC(client) "(IC)"//marks and adminhelp as an IC issue -#define ADMIN_REJECT(client) "(REJT)"//Rejects an adminhelp for being unclear or otherwise unhelpful. resets their adminhelp timer \ No newline at end of file +#define ADMIN_REJECT(client) "(REJT)"//Rejects an adminhelp for being unclear or otherwise unhelpful. resets their adminhelp timer diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index cea6bc5e36..ab62710652 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -24,6 +24,7 @@ #define ROLE_SERVANT_OF_RATVAR "servant of Ratvar" #define ROLE_BORER "borer" #define ROLE_BROTHER "blood brother" +#define ROLE_MISCREANT "miscreant" //Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR. //The gamemode specific ones are just so the gamemodes can query whether a player is old enough @@ -46,7 +47,8 @@ GLOBAL_LIST_INIT(special_roles, list( ROLE_ABDUCTOR = /datum/game_mode/abduction, ROLE_DEVIL = /datum/game_mode/devil, ROLE_BORER, - ROLE_SERVANT_OF_RATVAR = /datum/game_mode/clockwork_cult + ROLE_SERVANT_OF_RATVAR = /datum/game_mode/clockwork_cult, + ROLE_MISCREANT )) //Job defines for what happens when you fail to qualify for any job during job selection diff --git a/code/citadel/cit_crewobjectives.dm b/code/citadel/cit_crewobjectives.dm index 2d9149f5b1..90a655b622 100644 --- a/code/citadel/cit_crewobjectives.dm +++ b/code/citadel/cit_crewobjectives.dm @@ -1,6 +1,6 @@ /datum/controller/subsystem/ticker/proc/generate_crew_objectives() for(var/datum/mind/crewMind in SSticker.minds) - if(prob(2) && !issilicon(crewMind.current) && !jobban_isbanned(crewMind, "Syndicate") && GLOB.miscreants_allowed) + if(prob(2) && !issilicon(crewMind.current) && !jobban_isbanned(crewMind, "Syndicate") && GLOB.miscreants_allowed && ROLE_MISCREANT in crewMind.current.client.prefs.be_special) generate_miscreant_objectives(crewMind) else if(CONFIG_GET(flag/allow_crew_objectives)) @@ -25,7 +25,8 @@ return newObjective.owner = crewMind crewMind.objectives += newObjective - to_chat(crewMind, "Your objective: [newObjective.explanation_text]") + to_chat(crewMind, "As a part of Nanotrasen's anti-tide efforts, you have been assigned an optional objective. It will be checked at the end of the shift. Performing traitorous acts in pursuit of your objective may result in termination of your employment.") + to_chat(crewMind, "Your optional objective: [newObjective.explanation_text]") /datum/controller/subsystem/ticker/proc/get_valid_crew_objs(var/job = "")//taken from old hippie with adjustments var/list/objpaths = typesof(/datum/objective/crew) diff --git a/code/citadel/cit_miscreants.dm b/code/citadel/cit_miscreants.dm index f828127b55..e658fad097 100644 --- a/code/citadel/cit_miscreants.dm +++ b/code/citadel/cit_miscreants.dm @@ -7,6 +7,8 @@ return if(!crewMind.assigned_role) return + if(ROLE_MISCREANT in crewMind.current.client.prefs.be_special) + return if(jobban_isbanned(crewMind, "Syndicate")) return var/list/objectiveTypes = typesof(/datum/objective/miscreant) - /datum/objective/miscreant @@ -58,4 +60,7 @@ explanation_text = "Act as out of character as you possibly can." /datum/objective/miscreant/racism - explanation_text = "Attempt to establish superiority of your race." + explanation_text = "Attempt to establish superiority of your species." + +/datum/objective/miscreant/cargonia + explanation_text = "Attempt to establish independence of your department." diff --git a/code/citadel/crew_objectives/cit_crewobjectives_civilian.dm b/code/citadel/crew_objectives/cit_crewobjectives_civilian.dm index 81427c7951..9be0e1c028 100644 --- a/code/citadel/crew_objectives/cit_crewobjectives_civilian.dm +++ b/code/citadel/crew_objectives/cit_crewobjectives_civilian.dm @@ -185,29 +185,6 @@ else return FALSE -/datum/objective/crew/departmentclothes - var/obj/item/clothing/under/rank/targetuniform - explanation_text = "Be wearing a (Yo, this objective broke. report this to citadels discord via the development channel) at the end of the shift." - jobs = "assistant" - -/datum/objective/crew/departmentclothes/New() - . = ..() - var/list/blacklist = list(/obj/item/clothing/under/rank, /obj/item/clothing/under/rank/miner, /obj/item/clothing/under/rank/medical/blue, /obj/item/clothing/under/rank/medical/green, /obj/item/clothing/under/rank/medical/purple, /obj/item/clothing/under/rank/security/grey, /obj/item/clothing/under/rank/warden/grey, /obj/item/clothing/under/rank/head_of_security/grey, /obj/item/clothing/under/rank/mailman, /obj/item/clothing/under/rank/psyche, /obj/item/clothing/under/rank/clown/sexy, /obj/item/clothing/under/rank/centcom_officer, /obj/item/clothing/under/rank/centcom_commander, /obj/item/clothing/under/rank/security/navyblue/russian, /obj/item/clothing/under/rank/security/blueshirt) - var/list/validclothes = typesof(/obj/item/clothing/under/rank) - blacklist - targetuniform = pick(validclothes) - update_explanation_text() - -/datum/objective/crew/departmentclothes/update_explanation_text() - . = ..() - explanation_text = "Be wearing a [initial(targetuniform.name)] at the end of the shift." - -/datum/objective/crew/departmentclothes/check_completion() - if(owner && owner.current) - var/mob/living/carbon/human/H = owner.current - if(istype(H.w_uniform, targetuniform)) - return TRUE - return FALSE - /datum/objective/crew/pwrgame //ported from Goon with adjustments var/obj/item/clothing/targettidegarb explanation_text = "Get your grubby hands on a (Dear god something broke. Report this to Citadel's development dicussion channel)." @@ -215,7 +192,9 @@ /datum/objective/crew/pwrgame/New() . = ..() - var/list/muhvalids = list(/obj/item/clothing/mask/gas, /obj/item/clothing/head/welding, /obj/item/clothing/head/ushanka, /obj/item/clothing/gloves/color/yellow, /obj/item/clothing/mask/gas/owl_mask, /obj/item/clothing/suit/space) + var/list/muhvalids = list(/obj/item/clothing/mask/gas, /obj/item/clothing/head/welding, /obj/item/clothing/head/ushanka, /obj/item/clothing/gloves/color/yellow, /obj/item/clothing/mask/gas/owl_mask) + if(prob(10)) + muhvalids += list(/obj/item/clothing/suit/space) targettidegarb = pick(muhvalids) update_explanation_text() diff --git a/code/citadel/crew_objectives/cit_crewobjectives_medical.dm b/code/citadel/crew_objectives/cit_crewobjectives_medical.dm index 43d470f2f3..53a9dc73aa 100644 --- a/code/citadel/crew_objectives/cit_crewobjectives_medical.dm +++ b/code/citadel/crew_objectives/cit_crewobjectives_medical.dm @@ -74,7 +74,7 @@ return FALSE /datum/objective/crew/noinfections - explanation_text = "Ensure no living crew members are infected with harmful viruses at the end of the shift" + explanation_text = "Make sure there are no crew members with harmful diseases at the end of the shift." jobs = "virologist" /datum/objective/crew/noinfections/check_completion() diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index fc53bfa25a..b7c3176067 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -258,7 +258,7 @@ SUBSYSTEM_DEF(ticker) //Deleting Startpoints but we need the ai point to AI-ize people later if(S.name != "AI") qdel(S) - + //assign crew objectives and generate miscreants if(CONFIG_GET(flag/allow_extended_miscreants) && GLOB.master_mode == "extended") GLOB.miscreants_allowed = TRUE @@ -282,7 +282,7 @@ SUBSYSTEM_DEF(ticker) qdel(bomb) if(epi) explosion(epi, 0, 256, 512, 0, TRUE, TRUE, 0, TRUE) - + /datum/controller/subsystem/ticker/proc/create_characters() for(var/mob/dead/new_player/player in GLOB.player_list) if(player.ready == PLAYER_READY_TO_PLAY && player.mind) @@ -472,13 +472,13 @@ SUBSYSTEM_DEF(ticker) if(!crewMind.current || !crewMind.objectives.len) continue for(var/datum/objective/miscreant/MO in crewMind.objectives) - miscreants += "[crewMind.current.real_name] (Played by: [crewMind.key]). Objective: [MO.explanation_text]" + miscreants += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [MO.explanation_text] (Optional)
" for(var/datum/objective/crew/CO in crewMind.objectives) if(CO.check_completion()) - to_chat(crewMind.current, "
Your objective: [CO.explanation_text] Success!") - successfulCrew += "[crewMind.current.real_name] (Played by: [crewMind.key]). Objective: [CO.explanation_text]" + to_chat(crewMind.current, "
Your optional objective: [CO.explanation_text] Success!") + successfulCrew += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [CO.explanation_text] Success! (Optional)
" else - to_chat(crewMind.current, "
Your objective: [CO.explanation_text] Failed.") + to_chat(crewMind.current, "
Your optional objective: [CO.explanation_text] Failed.") if (successfulCrew.len) var/completedObjectives = "The following crew members completed their Crew Objectives:
" diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 9aab9e54f1..b692ab2d32 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -80,7 +80,7 @@ if(SSticker.current_state == GAME_STATE_PREGAME) var/time_remaining = SSticker.GetTimeLeft() if(time_remaining > 0) - stat("Time To Start:", "[round(time_remaining/10)]s") + stat("Time To Start:", "[round(time_remaining/10)]s") else if(time_remaining == -10) stat("Time To Start:", "DELAYED") else @@ -375,7 +375,7 @@ if(GLOB.highlander) to_chat(humanc, "THERE CAN BE ONLY ONE!!!") humanc.make_scottish() - if(prob(2) && !issilicon(humanc) && !jobban_isbanned(humanc.mind, "Syndicate") && GLOB.miscreants_allowed) + if(prob(2) && !issilicon(humanc) && !jobban_isbanned(humanc.mind, "Syndicate") && GLOB.miscreants_allowed && ROLE_MISCREANT in humanc.client.prefs.be_special) SSticker.generate_miscreant_objectives(humanc.mind) else if(CONFIG_GET(flag/allow_crew_objectives)) From c91d54c6a66e353c6ed3ec428fc8809817795993 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 8 Oct 2017 12:05:42 -0500 Subject: [PATCH 41/60] Automatic changelog generation for PR #3213 [ci skip] --- html/changelogs/AutoChangeLog-pr-3213.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3213.yml diff --git a/html/changelogs/AutoChangeLog-pr-3213.yml b/html/changelogs/AutoChangeLog-pr-3213.yml new file mode 100644 index 0000000000..cc1948c676 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3213.yml @@ -0,0 +1,9 @@ +author: "deathride58" +delete-after: True +changes: + - tweak: "Crew objectives are now more clearly stated to be assigned by Nanotrasen." + - tweak: "You can now opt out of being a miscreant in your preferences" + - tweak: "Round end objective display is a lot more readable" + - tweak: "Crew objectives and miscreant objectives now have more emphasis on being optional" + - tweak: "Space suits are a much rarer target for the pwrgame objective" + - rscdel: "Got rid of the departmental clothing objective" From b5981147dd60a789a315e2d527681a61ca2d3061 Mon Sep 17 00:00:00 2001 From: AnturK Date: Sun, 8 Oct 2017 20:15:35 +0200 Subject: [PATCH 42/60] Fixes mob swap on tables. (#31414) --- code/modules/mob/living/living.dm | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f4e85e40fb..2fc6f79ec3 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -152,16 +152,20 @@ M.pass_flags |= PASSMOB pass_flags |= PASSMOB - M.Move(oldloc) - Move(oldMloc) - + var/move_failed = FALSE + if(!M.Move(oldloc) || !Move(oldMloc)) + M.forceMove(oldMloc) + forceMove(oldloc) + move_failed = TRUE if(!src_passmob) pass_flags &= ~PASSMOB if(!M_passmob) M.pass_flags &= ~PASSMOB now_pushing = 0 - return 1 + + if(!move_failed) + return 1 //okay, so we didn't switch. but should we push? //not if he's not CANPUSH of course From 2f41af546e34027fa68c9354eba23e404d6a3284 Mon Sep 17 00:00:00 2001 From: JamieH Date: Sun, 8 Oct 2017 19:16:09 +0100 Subject: [PATCH 44/60] Allows easy hosting of server side lobby music (#31352) * Allows easy hosting of server side lobby music * No images here!!! * Undelete /tg/ sounds... REEE * Add back the old system and use it if this doesn't find any music * Documentation++ * Update round_start_sounds.txt * Allow for rare map specific title music Also don't attempt to play non-valid sounds/non-sounds * Fix bad sound filter, fix common sounds * Update README.txt * Update ticker.dm * Update ticker.dm --- code/controllers/subsystem/ticker.dm | 49 +++++++++++++++++++++++++++- config/title_music/LICENSE.txt | 34 +++++++++++++++++++ config/title_music/README.txt | 39 ++++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 config/title_music/LICENSE.txt create mode 100644 config/title_music/README.txt diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index b7c3176067..02a9808f48 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -68,10 +68,57 @@ SUBSYSTEM_DEF(ticker) /datum/controller/subsystem/ticker/Initialize(timeofday) load_mode() - var/list/music = world.file2list(ROUND_START_MUSIC_LIST, "\n") + + var/list/byond_sound_formats = list( + "mid" = TRUE, + "midi" = TRUE, + "mod" = TRUE, + "it" = TRUE, + "s3m" = TRUE, + "xm" = TRUE, + "oxm" = TRUE, + "wav" = TRUE, + "ogg" = TRUE, + "raw" = TRUE, + "wma" = TRUE, + "aiff" = TRUE + ) + + var/list/provisional_title_music = flist("config/title_music/sounds/") + var/list/music = list() + var/use_rare_music = prob(1) + + for(var/S in provisional_title_music) + var/lower = lowertext(S) + var/list/L = splittext(lower,"+") + switch(L.len) + if(3) //rare+MAP+sound.ogg or MAP+rare.sound.ogg -- Rare Map-specific sounds + if(use_rare_music) + if(L[1] == "rare" && L[2] == SSmapping.config.map_name) + music += S + else if(L[2] == "rare" && L[1] == SSmapping.config.map_name) + music += S + if(2) //rare+sound.ogg or MAP+sound.ogg -- Rare sounds or Map-specific sounds + if((use_rare_music && L[1] == "rare") || (L[1] == SSmapping.config.map_name)) + music += S + if(1) //sound.ogg -- common sound + music += S + var/old_login_music = trim(file2text("data/last_round_lobby_music.txt")) if(music.len > 1) music -= old_login_music + + for(var/S in music) + var/list/L = splittext(S,".") + if(L.len >= 2) + var/ext = lowertext(L[L.len]) //pick the real extension, no 'honk.ogg.exe' nonsense here + if(byond_sound_formats[ext]) + continue + music -= S + + if(isemptylist(music)) + music = world.file2list(ROUND_START_MUSIC_LIST, "\n") + login_music = pick(music) if(!GLOB.syndicate_code_phrase) diff --git a/config/title_music/LICENSE.txt b/config/title_music/LICENSE.txt new file mode 100644 index 0000000000..3f1576d19d --- /dev/null +++ b/config/title_music/LICENSE.txt @@ -0,0 +1,34 @@ +---LICENSE NOTICE--- + +The server operator(s) is responsible for the copyright status of all sounds placed within the /config/title_music/sounds folder unless otherwise noted. + +If a sound requires attribution and/or a specific license it is up to the operator(s) to make this information publicly available on either +a website associated with their server or on the server itself. + +If operators(s) allow these configuration files to be public this file can serve that purpose by keeping it properly updated. + +If in the future new sounds are published to these folders (i.e. in an online code repository) they must explicitly state their +license if said license is not the same as the default licensing found in README.md in the root directory of the project. + +Do not remove this notice. + +---END NOTICE--- + + + + +---EXAMPLES (NOT PART OF ANY LICENSE)--- + +These are examples of properly attrubuted and licensed sounds. +They are not an actual part of any license under any circumstance. + +title5.ogg was created by Mya Quinn on Feburary 28, 2557. It is licensed under a Combative Clowning 3.0 HO-NK license (http://example.com/license/url/). + +Unless otherwise noted all sounds were created by Cuban Pete on July 26, 2555. They are licensed under the RUMBABEAT Public License.(http://example.com/license/url/). + +---END EXAMPLES (NOT PART OF ANY LICENSE)--- + + + + +---ADD LICENSING INFORMATION BELOW--- diff --git a/config/title_music/README.txt b/config/title_music/README.txt new file mode 100644 index 0000000000..6734508a68 --- /dev/null +++ b/config/title_music/README.txt @@ -0,0 +1,39 @@ +The enclosed sounds folder holds the sound files used as the title music for the game. OGG and WAV are supported. + +Using unnecessarily huge sounds can cause client side lag and should be avoided. + +You may add as many title sounds as you like, if there is more than one a random screen is chosen (see name conventions for specifics). + +--- + +Naming Conventions: + +Every title sound you add must have a unique name. It is allowed to name two things the same if they have different file types, but this should be discouraged. +Avoid using the plus sign "+" and the period "." in names, as these are used internally to classify sounds. + + +Common Title Sounds: + +Common sounds are in the rotation to be displayed all the time. Any name that does not include the character "+" is considered a common sound. + +An example of a common sound name is "clown". + + +Map Title Sounds: + +Map sounds are tied to a specific in game map. To make a map title you format the name like this "(name of a map)+(name of your sound)" + +The spelling of the map name is important. It must match exactly the define MAP_NAME found in the relevant .DM file in the /_maps folder in +the root directory. It can also be seen in game in the status menu. Note that there are no spaces between the two names. + +It is absolutely fine to have more than one sound tied to the same map. It's also fine to have a rare map sound. + +An example of a map sound name is "Omegastation+splash". + + +Rare Title Sounds: + +Rare title sounds are a just for fun feature where they will only have a 1% chance of appear in in the title sound pool of a given round. +Add the phrase "rare+" to the beginning of the name. Again note there are no spaces. + +An example of a rare sound name is "rare+explosion" From 3f975a63b7feba699c5c7b2f4084b911f01bd02c Mon Sep 17 00:00:00 2001 From: AnturK Date: Sun, 8 Oct 2017 20:17:35 +0200 Subject: [PATCH 46/60] Dedicated equipment removal proc (#31411) * Dedicated equipment removal proc * department of redundancy department * Whitespace makes me angry --- code/modules/mob/living/carbon/human/dummy.dm | 2 +- code/modules/mob/living/carbon/human/inventory.dm | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index 0492a0b5e6..018f04ab8f 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -14,7 +14,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) return /mob/living/carbon/human/dummy/proc/wipe_state() - QDEL_LIST(contents) + delete_equipment() cut_overlays(TRUE) //Inefficient pooling/caching way. diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 593becfd48..67000ad788 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -260,3 +260,12 @@ return 0 return O.equip(src, visualsOnly) + + +//delete all equipment without dropping anything +/mob/living/carbon/human/proc/delete_equipment() + for(var/slot in get_all_slots())//order matters, dependant slots go first + var/obj/item/I = get_item_by_slot(slot) + qdel(I) + for(var/obj/item/I in held_items) + qdel(I) \ No newline at end of file From 4a9dbd1447f113458fc50502e284efe66671b014 Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Sat, 7 Oct 2017 13:10:54 -0400 Subject: [PATCH 48/60] Makes the noop turf less eyerapey --- code/modules/mapping/reader.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm index 51e3463782..862de852bc 100644 --- a/code/modules/mapping/reader.dm +++ b/code/modules/mapping/reader.dm @@ -467,3 +467,4 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new) /turf/template_noop name = "Turf Passthrough" + icon_state = "noop" From 4a0d3c4d4077f894691fc98d5f97c45bd991ee44 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 8 Oct 2017 14:35:35 -0500 Subject: [PATCH 49/60] Update seed_extractor.dm --- code/modules/hydroponics/seed_extractor.dm | 109 --------------------- 1 file changed, 109 deletions(-) diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index a917b6afeb..54805f3141 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -90,114 +90,6 @@ to_chat(user, "You extract some seeds.") return else if (istype(O, /obj/item/seeds)) -<<<<<<< HEAD - if(add_seed(O)) - to_chat(user, "You add [O] to [src.name].") - updateUsrDialog() - return - else if(user.a_intent != INTENT_HARM) - to_chat(user, "You can't extract any seeds from \the [O.name]!") - else - return ..() - -/datum/seed_pile - var/name = "" - var/lifespan = 0 //Saved stats - var/endurance = 0 - var/maturation = 0 - var/production = 0 - var/yield = 0 - var/potency = 0 - var/amount = 0 - -/datum/seed_pile/New(var/name, var/life, var/endur, var/matur, var/prod, var/yie, var/poten, var/am = 1) - src.name = name - src.lifespan = life - src.endurance = endur - src.maturation = matur - src.production = prod - src.yield = yie - src.potency = poten - src.amount = am - -/obj/machinery/seed_extractor/attack_hand(mob/user) - user.set_machine(src) - interact(user) - -/obj/machinery/seed_extractor/interact(mob/user) - if (stat) - return 0 - - var/dat = "Stored seeds:
" - - if (contents.len == 0) - dat += "No seeds" - else - dat += "" - for (var/datum/seed_pile/O in piles) - dat += "" - dat += "" - dat += "
NameLifespanEnduranceMaturationProductionYieldPotencyStock
[O.name][O.lifespan][O.endurance][O.maturation][O.production][O.yield][O.potency]" - dat += "Vend ([O.amount] left)
" - var/datum/browser/popup = new(user, "seed_ext", name, 700, 400) - popup.set_content(dat) - popup.open() - return - -/obj/machinery/seed_extractor/Topic(var/href, var/list/href_list) - if(..()) - return - usr.set_machine(src) - - href_list["li"] = text2num(href_list["li"]) - href_list["en"] = text2num(href_list["en"]) - href_list["ma"] = text2num(href_list["ma"]) - href_list["pr"] = text2num(href_list["pr"]) - href_list["yi"] = text2num(href_list["yi"]) - href_list["pot"] = text2num(href_list["pot"]) - - for (var/datum/seed_pile/N in piles)//Find the pile we need to reduce... - if (href_list["name"] == N.name && href_list["li"] == N.lifespan && href_list["en"] == N.endurance && href_list["ma"] == N.maturation && href_list["pr"] == N.production && href_list["yi"] == N.yield && href_list["pot"] == N.potency) - if(N.amount <= 0) - return - N.amount = max(N.amount - 1, 0) - if (N.amount <= 0) - piles -= N - qdel(N) - break - - for (var/obj/T in contents)//Now we find the seed we need to vend - var/obj/item/seeds/O = T - if (O.plantname == href_list["name"] && O.lifespan == href_list["li"] && O.endurance == href_list["en"] && O.maturation == href_list["ma"] && O.production == href_list["pr"] && O.yield == href_list["yi"] && O.potency == href_list["pot"]) - O.loc = src.loc - break - - src.updateUsrDialog() - return - -/obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/O) - if(contents.len >= 999) - to_chat(usr, "\The [src] is full.") - return 0 - - if(ismob(O.loc)) - var/mob/M = O.loc - if(!M.drop_item()) - return 0 - else if(istype(O.loc, /obj/item/storage)) - var/obj/item/storage/S = O.loc - S.remove_from_storage(O,src) - - O.loc = src - . = 1 - for (var/datum/seed_pile/N in piles) - if (O.plantname == N.name && O.lifespan == N.lifespan && O.endurance == N.endurance && O.maturation == N.maturation && O.production == N.production && O.yield == N.yield && O.potency == N.potency) - ++N.amount - return - - piles += new /datum/seed_pile(O.plantname, O.lifespan, O.endurance, O.maturation, O.production, O.yield, O.potency) - return -======= if(add_seed(O)) to_chat(user, "You add [O] to [src.name].") updateUsrDialog() @@ -303,4 +195,3 @@ piles += new /datum/seed_pile(O.plantname, O.lifespan, O.endurance, O.maturation, O.production, O.yield, O.potency) return ->>>>>>> b6d349e... Remove drop_item, drop_item_v, put_in_hands_or_del (#31386) From 0f5443140d7e3dc989ff3a98295eefbccd2f58ce Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 8 Oct 2017 14:36:40 -0500 Subject: [PATCH 50/60] Automatic changelog generation for PR #3205 [ci skip] --- html/changelogs/AutoChangeLog-pr-3205.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3205.yml diff --git a/html/changelogs/AutoChangeLog-pr-3205.yml b/html/changelogs/AutoChangeLog-pr-3205.yml new file mode 100644 index 0000000000..7385e023e6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3205.yml @@ -0,0 +1,6 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - tweak: "The MC will now reduce tick rate during high populations to keep it from fighting with byond for processing time. +config: Added config options to control MC tick rate +admin: Admins can no longer manually control the mc's tick rate by editing the MC's processing value, instead you will have to edit the config datum's values for high/low pop tick rates." From 86d9e5955a5af1320a88ef29365a3a7436c5dfec Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 8 Oct 2017 14:51:27 -0500 Subject: [PATCH 51/60] Update autoimplanter.dm --- code/modules/surgery/organs/autoimplanter.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/modules/surgery/organs/autoimplanter.dm b/code/modules/surgery/organs/autoimplanter.dm index f521017dd1..9d2075da12 100644 --- a/code/modules/surgery/organs/autoimplanter.dm +++ b/code/modules/surgery/organs/autoimplanter.dm @@ -39,9 +39,8 @@ else if(!uses) to_chat(user, "[src] has already been used up.") return - if(!user.drop_item()) + if(!user.transferItemToLoc(I, src)) return - I.loc = src storedorgan = I to_chat(user, "You insert the [I] into [src].") else if(istype(I, /obj/item/screwdriver)) @@ -56,7 +55,7 @@ if(uses != INFINITE) uses-- if(!uses) - desc = "[initial(desc)] Looks like it's been used up." +desc = "[initial(desc)] Looks like it's been used up." /obj/item/device/autoimplanter/cmo name = "medical HUD autoimplanter" From 4c408f45415fc50d800a00be0cb7a20e9e0b5551 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 8 Oct 2017 14:55:37 -0500 Subject: [PATCH 52/60] Update give.dm --- code/modules/mob/living/carbon/give.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm index 392b494d00..a712240622 100644 --- a/code/modules/mob/living/carbon/give.dm +++ b/code/modules/mob/living/carbon/give.dm @@ -44,7 +44,7 @@ user << "Your hands are full." user << "Their hands are full." return - if(!user.drop_item(I)) + if(!user.dropItemToGround(I)) src << "[user] can't let go of \the [I]!" user << "You can't seem to let go of \the [I]." return @@ -55,4 +55,4 @@ if("No") src.visible_message("[user] tried to hand \the [I] to [src] but \he didn't want it.") else - user << "[src]'s hands are full." \ No newline at end of file + user << "[src]'s hands are full." From 6cb68e06e34b75916cddea51cb35ac4d95dcfbeb Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 8 Oct 2017 15:07:28 -0500 Subject: [PATCH 53/60] Update autoimplanter.dm --- code/modules/surgery/organs/autoimplanter.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/surgery/organs/autoimplanter.dm b/code/modules/surgery/organs/autoimplanter.dm index 9d2075da12..2caae96184 100644 --- a/code/modules/surgery/organs/autoimplanter.dm +++ b/code/modules/surgery/organs/autoimplanter.dm @@ -55,7 +55,7 @@ if(uses != INFINITE) uses-- if(!uses) -desc = "[initial(desc)] Looks like it's been used up." + desc = "[initial(desc)] Looks like it's been used up." /obj/item/device/autoimplanter/cmo name = "medical HUD autoimplanter" From 63f3bfcb7333c79bf58321965444f282ba641a0a Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 8 Oct 2017 15:18:20 -0500 Subject: [PATCH 54/60] Automatic changelog generation for PR #3208 [ci skip] --- html/changelogs/AutoChangeLog-pr-3208.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3208.yml diff --git a/html/changelogs/AutoChangeLog-pr-3208.yml b/html/changelogs/AutoChangeLog-pr-3208.yml new file mode 100644 index 0000000000..79cc3c460a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3208.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Fixed a rare case where creating a one tank bomb would result in a broken object" + - bugfix: "Fixed many cases where forced item drops could be avoided by not having an item in your active hand" From d5df4650003aacc14d13526c9f3fd3672b758c18 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 8 Oct 2017 15:19:13 -0500 Subject: [PATCH 55/60] Automatic changelog generation for PR #3210 [ci skip] --- html/changelogs/AutoChangeLog-pr-3210.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3210.yml diff --git a/html/changelogs/AutoChangeLog-pr-3210.yml b/html/changelogs/AutoChangeLog-pr-3210.yml new file mode 100644 index 0000000000..b4865f12c7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3210.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - bugfix: "Tweaks to atmos performance" From 70c652bb81050088d1ec387881a901d79db339dc Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 8 Oct 2017 15:19:34 -0500 Subject: [PATCH 56/60] Automatic changelog generation for PR #3215 [ci skip] --- html/changelogs/AutoChangeLog-pr-3215.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3215.yml diff --git a/html/changelogs/AutoChangeLog-pr-3215.yml b/html/changelogs/AutoChangeLog-pr-3215.yml new file mode 100644 index 0000000000..032b493743 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3215.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - bugfix: "Neutering a disease symptom now produces a unique ID that will ensure the PANDEMIC machine copies it properly." From a5fd3e41df9e6b93237ae7647bb25a8fbbbaa5e9 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 8 Oct 2017 15:20:30 -0500 Subject: [PATCH 57/60] Automatic changelog generation for PR #3220 [ci skip] --- html/changelogs/AutoChangeLog-pr-3220.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3220.yml diff --git a/html/changelogs/AutoChangeLog-pr-3220.yml b/html/changelogs/AutoChangeLog-pr-3220.yml new file mode 100644 index 0000000000..0f1045db2e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3220.yml @@ -0,0 +1,4 @@ +author: "spessmenart" +delete-after: True +changes: + - imageadd: "The captains sabre no longer looks like a rapier." From e91192cefce368f8f9c1bf32054e6d0123b48104 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 8 Oct 2017 15:21:08 -0500 Subject: [PATCH 58/60] Automatic changelog generation for PR #3222 [ci skip] --- html/changelogs/AutoChangeLog-pr-3222.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3222.yml diff --git a/html/changelogs/AutoChangeLog-pr-3222.yml b/html/changelogs/AutoChangeLog-pr-3222.yml new file mode 100644 index 0000000000..f341d68170 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3222.yml @@ -0,0 +1,4 @@ +author: "ninjanomnom" +delete-after: True +changes: + - bugfix: "Shuttles no longer rotate ghosts of players who prefer directionless sprites" From 36b1e11612f2f87183dd2d66ddebb272254b245e Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 8 Oct 2017 15:21:25 -0500 Subject: [PATCH 59/60] Automatic changelog generation for PR #3223 [ci skip] --- html/changelogs/AutoChangeLog-pr-3223.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3223.yml diff --git a/html/changelogs/AutoChangeLog-pr-3223.yml b/html/changelogs/AutoChangeLog-pr-3223.yml new file mode 100644 index 0000000000..98d61d2fca --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3223.yml @@ -0,0 +1,4 @@ +author: "ninjanomnom" +delete-after: True +changes: + - bugfix: "Buckled mobs when on a rotating shuttle should now rotate correctly" From c6785f71d3f66e85815b872da77b6a254ff545f3 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 8 Oct 2017 15:22:56 -0500 Subject: [PATCH 60/60] Automatic changelog generation for PR #3227 [ci skip] --- html/changelogs/AutoChangeLog-pr-3227.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3227.yml diff --git a/html/changelogs/AutoChangeLog-pr-3227.yml b/html/changelogs/AutoChangeLog-pr-3227.yml new file mode 100644 index 0000000000..2d82a2137d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3227.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - tweak: "Abandoned Airlocks will no longer be deleted when their turf is changed to a wall."