"
-
- if(sprite)
- body += "
" - - body += "E - Edit, tries to determine the variable type by itself. " - body += "C - Change, asks you for the var type first. " - body += "M - Mass modify: changes this variable for all objects of this type. " - - body += "
" - - body += "
+
+
+ + E - Edit, tries to determine the variable type by itself. + C - Change, asks you for the var type first. + M - Mass modify: changes this variable for all objects of this type. + + +
+
"
- for(var/block=0;block<8;block++)
- html += " "
- for(var/i=0;i<4;i++)
- idx=(block*4)+i
- to_chat(bit=1, idx)
- bv=value & bit
- html += "[bv?1:0]"
- html += ""
- html += " "
- */
- html += "" diff --git a/code/game/gamemodes/cult/cult_datums.dm b/code/game/gamemodes/cult/cult_datums.dm index b08632f0359..a3b9329bf6c 100644 --- a/code/game/gamemodes/cult/cult_datums.dm +++ b/code/game/gamemodes/cult/cult_datums.dm @@ -1,5 +1,3 @@ -//cult datums by FalseIncarnate - /datum/cult_info var/name = "Cult of Nar'Sie" var/theme = "blood" @@ -81,11 +79,13 @@ /datum/cult_info/death name = "Cult of Mortality" theme = "death" + tome_icon = "firetome" entity_name = "The Reaper" entity_title1 = "The Silent One" entity_title2 = "The One Who Beckons" entity_title3 = "The Ferryman of Oblivion" + entity_icon_state = "legion" cult_wall_icon_state = "deathcult" cult_floor_icon_state = "carpet-broken" @@ -93,13 +93,13 @@ artificer_name = "Boneshaper" behemoth_name = "Draugr" - behemoth_icon_state = "horror" + behemoth_icon_state = "Draugr" wraith_name = "Wraith" - wraith_icon_state = "stand" + wraith_icon_state = "Wraith" juggernaut_name = "Wight" - juggernaut_icon_state = "horror" + juggernaut_icon_state = "Draugr" harvester_name = "Psychopomp" diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index abc8aa8952f..a5ea89f504d 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -32,6 +32,10 @@ to_chat(user, "An overwhelming sense of nausea overpowers you!") user.Dizzy(120) + if(HULK in user.mutations) + to_chat(user, "You can't seem to hold the blade properly!") + user.unEquip(src, 1) + /obj/item/weapon/melee/cultblade/dagger name = "sacrificial dagger" desc = "A strange dagger said to be used by sinister groups for \"preparing\" a corpse before sacrificing it to their dark gods." @@ -41,16 +45,13 @@ force = 15 throwforce = 25 embed_chance = 75 - var/cooldown = 0 -/obj/item/weapon/melee/cultblade/dagger/afterattack(atom/target, mob/living/carbon/human/user) +/obj/item/weapon/melee/cultblade/dagger/attack(atom/target, mob/living/carbon/human/user) ..() if(ishuman(target)) var/mob/living/carbon/human/H = target - if(!(cooldown > world.time) && ((H.stat != DEAD) && !(NO_BLOOD in H.species.species_traits))) - user.visible_message("The runes on the blade absorb the blood of [H]!") - H.bleed(5000) - cooldown = world.time + 2400 + if((H.stat != DEAD) && !(NO_BLOOD in H.species.species_traits)) + H.bleed(50) /obj/item/weapon/restraints/legcuffs/bola/cult name = "runed bola" @@ -195,13 +196,15 @@ /obj/item/weapon/whetstone/cult name = "eldritch whetstone" desc = "A block, empowered by dark magic. Sharp weapons will be enhanced when used on the stone." - icon = 'icons/obj/cult.dmi' - icon_state = "cultstone" + icon_state = "cult_sharpener" used = 0 increment = 5 max = 40 prefix = "darkened" +/obj/item/weapon/whetstone/cult/update_icon() + icon_state = "cult_sharpener[used ? "_used" : ""]" + /obj/item/weapon/reagent_containers/food/drinks/bottle/unholywater name = "flask of unholy water" desc = "Toxic to nonbelievers; this water renews and reinvigorates the faithful of a cult." @@ -335,3 +338,19 @@ else to_chat(C, "The veil cannot be torn here!") + + +/obj/item/clothing/suit/space/eva/plasmaman/cultist + name = "plasmaman cultist armor" + icon_state = "plasmaman_cult" + item_state = "plasmaman_cult" + desc = "A bulky suit of armour, menacing with red energy. It looks like it would fit a plasmaman." + slowdown = 1 + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) + +/obj/item/clothing/head/helmet/space/eva/plasmaman/cultist + name = "plasmaman cultist helmet" + icon_state = "plasmamanCult_helmet0" + base_state = "plasmamanCult_helmet" + desc = "A helmet designed by cultists. It glows menacingly with unearthly flames." + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) diff --git a/code/game/gamemodes/cult/cult_objectives.dm b/code/game/gamemodes/cult/cult_objectives.dm index c9e951cf940..69b6de0c73e 100644 --- a/code/game/gamemodes/cult/cult_objectives.dm +++ b/code/game/gamemodes/cult/cult_objectives.dm @@ -109,10 +109,10 @@ if(prob(40))//split the chance of this objectives += "eldergod" - explanation = "Summon [ticker.mode.cultdat.entity_name] on the Station via the use of the Tear Reality rune." + explanation = "Summon [ticker.mode.cultdat.entity_name] on the Station via the use of the Tear Reality rune. The veil is weak enough in [english_list(summon_spots)] for the ritual to begin." else objectives += "slaughter" - explanation = "Bring the Slaughter via the rune 'Bring forth the slaughter'." + explanation = "Bring the Slaughter via the rune 'Bring forth the slaughter'. The veil is weak enough in [english_list(summon_spots)] for the ritual to begin." for(var/datum/mind/cult_mind in cult) to_chat(cult_mind.current, "You and your acolytes have succeeded in preparing the station for the ultimate ritual!") diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index 60b9fcb2c85..182ed68e004 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -54,6 +54,10 @@ to_chat(user, "\The [src] is [anchored ? "":"not "]secured to the floor.") /obj/structure/cult/functional/attackby(obj/I, mob/user, params) + if(HULK in user.mutations) + to_chat(user, "You cannot seem to manipulate this structure with your bulky hands!") + return + if(istype(I, /obj/item/weapon/tome) && iscultist(user)) anchored = !anchored to_chat(user, "You [anchored ? "":"un"]secure \the [src] [anchored ? "to":"from"] the floor.") @@ -65,6 +69,23 @@ else return ..() +/obj/structure/cult/functional/proc/updatehealth() + if(health <= 0) + destroy_structure() + +/obj/structure/cult/functional/proc/take_damage(damage, damage_type = BRUTE) + if(damage_type == BRUTE || damage_type == BURN) + health -= damage + updatehealth() + +/obj/structure/cult/functional/attackby(obj/item/I, mob/living/user) + ..() + take_damage(I.force, I.damtype) + playsound(loc, I.hitsound, 80, 1) + +/obj/structure/cult/functional/bullet_act(var/obj/item/projectile/P) + take_damage(P.damage, P.damage_type) + /obj/structure/cult/functional/attack_hand(mob/living/user) if(!iscultist(user)) to_chat(user, "[heathen_message]") @@ -142,6 +163,8 @@ C.apply_damage(30, BURN, "head") //30 fire damage because it's FUCKING LAVA head.disfigure("burn") //Your face is unrecognizable because it's FUCKING LAVA return 1 + else + ..() var/list/blacklisted_pylon_turfs = typecacheof(list( /turf/simulated/floor/engine/cult, @@ -161,7 +184,7 @@ var/list/blacklisted_pylon_turfs = typecacheof(list( death_message = "The pylon's crystal vibrates and glows fiercely before violently shattering!" death_sound = 'sound/effects/pylon_shatter.ogg' - var/heal_delay = 25 + var/heal_delay = 30 var/last_heal = 0 var/corrupt_delay = 50 var/last_corrupt = 0 diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 36ebc5d3dab..55d2a51de61 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -201,6 +201,7 @@ /obj/item/weapon/tome/proc/finale_runes_ok(mob/living/user, obj/effect/rune/rune_to_scribe) var/datum/game_mode/cult/cult_mode = ticker.mode + var/area/A = get_area(src) if(GAMEMODE_IS_CULT) if(!canbypass)//not an admin-tome, check things if(!cult_mode.narsie_condition_cleared) @@ -215,6 +216,9 @@ if(!((CULT_ELDERGOD in cult_mode.objectives) || (CULT_SLAUGHTER in cult_mode.objectives))) to_chat(user, "[cult_mode.cultdat.entity_name]'s power does not wish to be unleashed!") return 0 + if(!(A in summon_spots)) + to_chat(user, "[cult_mode.cultdat.entity_name] can only be summoned where the veil is weak - in [english_list(summon_spots)]!") + return 0 var/confirm_final = alert(user, "This is the FINAL step to summon your deities power, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for [cult_mode.cultdat.entity_name]!", "No") if(confirm_final == "No" || confirm_final == null) to_chat(user, "You decide to prepare further before scribing the rune.") @@ -236,6 +240,7 @@ var/entered_rune_name var/list/possible_runes = list() var/list/shields = list() + var/area/A = get_area(src) if(locate(/obj/effect/rune) in runeturf) to_chat(user, "There is already a rune here.") return @@ -261,6 +266,7 @@ if(!rune_to_scribe) return runeturf = get_turf(user) //we may have moved. adjust as needed... + A = get_area(src) if(locate(/obj/effect/rune) in runeturf) to_chat(user, "There is already a rune here.") return @@ -268,7 +274,11 @@ return if(ispath(rune_to_scribe, /obj/effect/rune/narsie) || ispath(rune_to_scribe, /obj/effect/rune/slaughter))//may need to change this - Fethas if(finale_runes_ok(user,rune_to_scribe)) - command_announcement.Announce("Figments from an eldritch god are being summoned somwhere on the station from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/AI/spanomalies.ogg') + A = get_area(src) + if(!(A in summon_spots)) // Check again to make sure they didn't move + to_chat(user, "The ritual can only begin where the veil is weak - in [english_list(summon_spots)]!") + return + command_announcement.Announce("Figments from an eldritch god are being summoned somewhere on the station from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/AI/spanomalies.ogg') for(var/B in spiral_range_turfs(1, user, 1)) var/turf/T = B var/obj/machinery/shield/N = new(T) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index c6e64c4665c..892a5e7a204 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -636,17 +636,17 @@ var/list/teleport_runes = list() log_game("Raise Dead rune failed - no catalyst corpse") return mob_to_sacrifice = input(user, "Choose a corpse to sacrifice.", "Corpse to Sacrifice") as null|anything in potential_sacrifice_mobs - if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated() || !mob_to_revive || !mob_to_sacrifice || rune_in_use) + if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated() || !mob_to_sacrifice || rune_in_use) return for(var/mob/living/M in T.contents) if(M.stat == DEAD) potential_revive_mobs.Add(M) if(!potential_revive_mobs.len) to_chat(user, "There is no eligible revival target on the rune!") - log_game("Raise Dead rune failed - no corpse to revived") + log_game("Raise Dead rune failed - no corpse to revive") return mob_to_revive = input(user, "Choose a corpse to revive.", "Corpse to Revive") as null|anything in potential_revive_mobs - if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated() || rune_in_use) + if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated() || rune_in_use || !mob_to_revive) return if(!in_range(mob_to_sacrifice,src)) to_chat(user, "The sacrificial target has been moved!") diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 4bf4bd9f9e7..24b3a2208d2 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -148,8 +148,9 @@ var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to? - if(!actual_selected_rune) + if(!src || qdeleted(src) || !user || user.l_hand != src && user.r_hand != src || user.incapacitated() || !actual_selected_rune) return ..(user, 0) + user.visible_message("Dust flows from [user]'s hand, and they disappear in a flash of red light!", \ "You speak the words of the talisman and find yourself somewhere else!") user.forceMove(get_turf(actual_selected_rune)) @@ -277,7 +278,11 @@ var/mob/living/carbon/human/H = user user.visible_message("Otherworldly armor suddenly appears on [user]!", \ "You speak the words of the talisman, arming yourself!") - H.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), slot_wear_suit) + if(H.get_species() == "Plasmaman") + H.equip_to_slot(new /obj/item/clothing/suit/space/eva/plasmaman/cultist(H), slot_wear_suit) + H.equip_to_slot(new /obj/item/clothing/head/helmet/space/eva/plasmaman/cultist(H), slot_head) + else + H.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes) H.put_in_hands(new /obj/item/weapon/melee/cultblade(user)) diff --git a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm index 4f7ad2ade9a..64b77d3b374 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm @@ -11,7 +11,7 @@ var/obj/item/organ/external/affected = H.get_organ(target_zone) if(!affected) return 0 - if(affected.status & ORGAN_ROBOT) //Maybe add in a machine version, later? + if(affected.status & ORGAN_ROBOT) return 0 var/mob/living/carbon/human/H = user // You must either: Be of the abductor species, or contain an abductor implant @@ -64,3 +64,31 @@ var/obj/item/organ/internal/heart/gland/gland = tool gland.insert(target, 2) return 1 + +//IPC Gland Surgery// + +/datum/surgery/organ_extraction/synth + name = "experimental robotic dissection" + steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/internal/extract_organ/synth,/datum/surgery_step/internal/gland_insert,/datum/surgery_step/robotics/external/close_hatch) + possible_locs = list("chest") + requires_organic_bodypart = 0 + +/datum/surgery/organ_extraction/synth/can_start(mob/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(!ishuman(user)) + return FALSE + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(target_zone) + if(!affected) + return FALSE + if(!(affected.status & ORGAN_ROBOT)) + return FALSE + var/mob/living/carbon/human/H = user + // You must either: Be of the abductor species, or contain an abductor implant + if((H.get_species() == "Abductor" || (locate(/obj/item/weapon/implant/abductor) in H))) + return TRUE + return FALSE + +/datum/surgery_step/internal/extract_organ/synth + name = "remove cell" + organ_types = list(/obj/item/organ/internal/cell) \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 5e25103aeb8..d7fa1b4c9f2 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -40,6 +40,10 @@ if(be_swarmer == "No") return + if(jobban_isbanned(user, "Syndicate")) + to_chat(user, "You are banned from antagonists!") + return + if(crit_fail)//in case it depowers while ghost is looking at yes/no to_chat(user, "This swarmer shell is completely depowered. You cannot activate it.") return diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm index 4825dea6ebb..b6f240b8319 100644 --- a/code/game/gamemodes/miniantags/guardian/guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/guardian.dm @@ -39,40 +39,43 @@ var/bio_fluff_string = "Your scarabs fail to mutate. This shouldn't happen! Submit a bug report!" var/admin_fluff_string = "URK URF!"//the wheels on the bus... var/adminseal = FALSE + var/name_color = "white"//only used with protector shields for the time being /mob/living/simple_animal/hostile/guardian/Life() //Dies if the summoner dies ..() if(summoner) if(summoner.stat == DEAD) to_chat(src, "Your summoner has died!") - visible_message("The [src] dies along with its user!") + visible_message("The [src] dies along with its user!") ghostize() qdel(src) - if(summoner) - if(get_dist(get_turf(summoner),get_turf(src)) <= range) - return - else - to_chat(src, "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]") - visible_message("The [src] jumps back to its user.") - Recall() + snapback() if(summoned && !summoner && !adminseal) to_chat(src, "You somehow lack a summoner! As a result, you dispel!") ghostize() qdel() -/mob/living/simple_animal/hostile/guardian/Move() //Returns to summoner if they move out of range - ..() +/mob/living/simple_animal/hostile/guardian/proc/snapback() if(summoner) if(get_dist(get_turf(summoner),get_turf(src)) <= range) return else - to_chat(src, "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]") - visible_message("The [src] jumps back to its user.") - Recall() + to_chat(src, "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]!") + visible_message("\The [src] jumps back to its user.") + if(istype(summoner.loc, /obj/effect)) + Recall(TRUE) + else + new /obj/effect/overlay/temp/guardian/phase/out(loc) + forceMove(summoner.loc) //move to summoner's tile, don't recall + new /obj/effect/overlay/temp/guardian/phase(loc) + +/mob/living/simple_animal/hostile/guardian/Move() //Returns to summoner if they move out of range + ..() + snapback() /mob/living/simple_animal/hostile/guardian/death(gibbed) ..() - to_chat(summoner, "Your [name] died somehow!") + to_chat(summoner, "Your [name] died somehow!") summoner.death() @@ -93,10 +96,10 @@ return summoner.adjustBruteLoss(damage) if(damage) - to_chat(summoner, "Your [name] is under attack! You take damage!") - summoner.visible_message("Blood sprays from [summoner] as [src] takes damage!") + to_chat(summoner, "Your [name] is under attack! You take damage!") + summoner.visible_message("Blood sprays from [summoner] as [src] takes damage!") if(summoner.stat == UNCONSCIOUS) - to_chat(summoner, "Your body can't take the strain of sustaining [src] in this condition, it begins to fall apart!") + to_chat(summoner, "Your body can't take the strain of sustaining [src] in this condition, it begins to fall apart!") summoner.adjustCloneLoss(damage/2) /mob/living/simple_animal/hostile/guardian/ex_act(severity, target) @@ -112,7 +115,7 @@ /mob/living/simple_animal/hostile/guardian/gib() if(summoner) - to_chat(summoner, "Your [src] was blown up!") + to_chat(summoner, "Your [src] was blown up!") summoner.Weaken(10)// your fermillier has died! ROLL FOR CON LOSS! ghostize() qdel(src) @@ -128,8 +131,8 @@ src.client.eye = loc cooldown = world.time + 30 -/mob/living/simple_animal/hostile/guardian/proc/Recall() - if(cooldown > world.time) +/mob/living/simple_animal/hostile/guardian/proc/Recall(forced = FALSE) + if(cooldown > world.time && !forced) return if(!summoner) return new /obj/effect/overlay/temp/guardian/phase/out(get_turf(src)) @@ -141,7 +144,6 @@ var/input = stripped_input(src, "Please enter a message to tell your summoner.", "Guardian", "") if(!input) return - for(var/mob/M in mob_list) if(M == summoner) to_chat(M, "[src]: [input]") @@ -151,7 +153,7 @@ to_chat(src, "[src]: [input]") /mob/living/simple_animal/hostile/guardian/proc/ToggleMode() - to_chat(src, "You dont have another mode!") + to_chat(src, "You dont have another mode!") /mob/living/proc/guardian_comm() @@ -212,456 +214,6 @@ to_chat(src, "You deactivate your light.") light_on = !light_on -//////////////////////////TYPES OF GUARDIANS - - -//Fire. Low damage, low resistance, sets mobs on fire when bumping - -/mob/living/simple_animal/hostile/guardian/fire - a_intent = INTENT_HELP - melee_damage_lower = 10 - melee_damage_upper = 10 - attack_sound = 'sound/items/Welder.ogg' - attacktext = "sears" - damage_transfer = 0.8 - range = 10 - playstyle_string = "As a Chaos type, you have only light damage resistance, but will ignite any enemy you bump into. In addition, your melee attacks will randomly teleport enemies." - environment_smash = 1 - magic_fluff_string = "..And draw the Wizard, bringer of endless chaos!" - tech_fluff_string = "Boot sequence complete. Crowd control modules activated. Holoparasite swarm online." - bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to sow havoc at random." - var/toggle = FALSE - -/mob/living/simple_animal/hostile/guardian/fire/Life() //Dies if the summoner dies - ..() - if(summoner) - summoner.ExtinguishMob() - summoner.adjust_fire_stacks(-20) - -/mob/living/simple_animal/hostile/guardian/fire/ToggleMode() - if(src.loc == summoner) - if(toggle) - to_chat(src, "You switch to dispersion mode, and will teleport victims away from your master.") - toggle = FALSE - else - to_chat(src, "You switch to deception mode, and will turn your victims against their allies.") - toggle = TRUE - -/mob/living/simple_animal/hostile/guardian/fire/AttackingTarget() - if(..()) - if(toggle) - if(ishuman(target) && !summoner) - spawn(0) - new /obj/effect/hallucination/delusion(target.loc, target, force_kind="custom", duration=200, skip_nearby=0, custom_icon = src.icon_state, custom_icon_file = src.icon) - else - if(prob(45)) - if(istype(target, /atom/movable)) - var/atom/movable/M = target - if(!M.anchored && M != summoner) - new /obj/effect/overlay/temp/guardian/phase/out(get_turf(M)) - do_teleport(M, M, 10) - new /obj/effect/overlay/temp/guardian/phase/out(get_turf(M)) - -/mob/living/simple_animal/hostile/guardian/fire/Crossed(AM as mob|obj) - ..() - collision_ignite(AM) - -/mob/living/simple_animal/hostile/guardian/fire/Bumped(AM as mob|obj) - ..() - collision_ignite(AM) - -/mob/living/simple_animal/hostile/guardian/fire/Bump(AM as mob|obj) - ..() - collision_ignite(AM) - -/mob/living/simple_animal/hostile/guardian/fire/proc/collision_ignite(AM as mob|obj) - if(istype(AM, /mob/living/)) - var/mob/living/M = AM - if(AM != summoner && M.fire_stacks < 7) - M.fire_stacks = 7 - M.IgniteMob() - -/mob/living/simple_animal/hostile/guardian/fire/Bump(AM as mob|obj) - ..() - collision_ignite(AM) -//Standard - -/mob/living/simple_animal/hostile/guardian/punch - melee_damage_lower = 20 - melee_damage_upper = 20 - damage_transfer = 0.5 - playstyle_string = "As a standard type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls." - environment_smash = 2 - magic_fluff_string = "..And draw the Assistant, faceless and generic, but never to be underestimated." - tech_fluff_string = "Boot sequence complete. Standard combat modules loaded. Holoparasite swarm online." - bio_fluff_string = "Your scarab swarm stirs to life, ready to tear apart your enemies." - var/battlecry = "AT" - - -/mob/living/simple_animal/hostile/guardian/punch/sealpunch - name = "Seal Sprit" - real_name = "Seal Sprit" - icon = 'icons/mob/animal.dmi' - icon_living = "seal" - icon_state = "seal" - attacktext = "slaps" - speak_emote = list("barks") - melee_damage_lower = 0 - melee_damage_upper = 0 - melee_damage_type = STAMINA - damage_transfer = 0 - playstyle_string = "As a standard type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls." - environment_smash = 2 - battlecry = "URK" - adminseal = TRUE - -/mob/living/simple_animal/hostile/guardian/punch/verb/Battlecry() - set name = "Set Battlecry" - set category = "Guardian" - set desc = "Choose what you shout as you punch" - var/input = stripped_input(src,"What do you want your battlecry to be? Max length of 5 characters.", ,"", 6) - if(input) - battlecry = input - - - -/mob/living/simple_animal/hostile/guardian/punch/AttackingTarget() - ..() - if(iscarbon(target) && target != summoner) - if(length(battlecry) > 11)//no more then 11 letters in a battle cry. - src.visible_message("[src] punches [target]!") - else - src.say("[src.battlecry][src.battlecry][src.battlecry][src.battlecry][src.battlecry]") - playsound(loc, src.attack_sound, 50, 1, 1) - playsound(loc, src.attack_sound, 50, 1, 1) - playsound(loc, src.attack_sound, 50, 1, 1) - playsound(loc, src.attack_sound, 50, 1, 1) - -//Healer - -/mob/living/simple_animal/hostile/guardian/healer - a_intent = INTENT_HARM - friendly = "heals" - speed = 0 - melee_damage_lower = 15 - melee_damage_upper = 15 - playstyle_string = "As a Support type, you may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent mob will warp them to your bluespace beacon after a short delay." - magic_fluff_string = "..And draw the CMO, a potent force of life...and death." - tech_fluff_string = "Boot sequence complete. Medical modules active. Bluespace modules activated. Holoparasite swarm online." - bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of mending wounds and travelling via bluespace." - var/turf/simulated/floor/beacon - var/beacon_cooldown = 0 - var/toggle = FALSE - var/heal_cooldown = 0 - -/mob/living/simple_animal/hostile/guardian/healer/sealhealer - name = "Seal Sprit" - real_name = "Seal Sprit" - icon = 'icons/mob/animal.dmi' - icon_living = "seal" - icon_state = "seal" - attacktext = "slaps" - speak_emote = list("barks") - a_intent = INTENT_HARM - friendly = "heals" - speed = 0 - melee_damage_lower = 0 - melee_damage_upper = 0 - melee_damage_type = STAMINA - adminseal = TRUE - - -/mob/living/simple_animal/hostile/guardian/healer/New() - ..() - -/mob/living/simple_animal/hostile/guardian/healer/Life() - ..() - var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED] - medsensor.add_hud_to(src) - -/mob/living/simple_animal/hostile/guardian/healer/AttackingTarget() - ..() - if(toggle == TRUE) - if(src.loc == summoner) - to_chat(src, "You must be manifested to heal!") - return - if(iscarbon(target)) - src.changeNext_move(CLICK_CD_MELEE) - if(heal_cooldown <= world.time && !stat) - var/mob/living/carbon/C = target - C.adjustBruteLoss(-5) - C.adjustFireLoss(-5) - C.adjustOxyLoss(-5) - C.adjustToxLoss(-5) - heal_cooldown = world.time + 20 - -/mob/living/simple_animal/hostile/guardian/healer/ToggleMode() - if(src.loc == summoner) - if(toggle) - a_intent = INTENT_HARM - speed = 0 - damage_transfer = 0.7 - if(src.adminseal) - damage_transfer = 0 - melee_damage_lower = 15 - melee_damage_upper = 15 - to_chat(src, "You switch to combat mode.") - toggle = FALSE - else - a_intent = INTENT_HELP - speed = 1 - damage_transfer = 1 - if(src.adminseal) - damage_transfer = 0 - melee_damage_lower = 0 - melee_damage_upper = 0 - to_chat(src, "You switch to healing mode.") - toggle = TRUE - else - to_chat(src, "You have to be recalled to toggle modes!") - - -/mob/living/simple_animal/hostile/guardian/healer/verb/Beacon() - set name = "Place Bluespsace Beacon" - set category = "Guardian" - set desc = "Mark a floor as your beacon point, allowing you to warp targets to it. Your beacon will not work in unfavorable atmospheric conditions." - if(beacon_cooldown Error: permission denied.") + //to_chat(usr, "Error: permission denied.") + return 1 if("incarcerated") active2.fields["criminal"] = "Incarcerated" if("parolled") active2.fields["criminal"] = "Parolled" if("released") active2.fields["criminal"] = "Released" - + var/newstatus = active2.fields["criminal"] + log_admin("[key_name_admin(usr)] set secstatus of [their_rank] [their_name] to [newstatus], comment: [t1]") + active2.fields["comments"] += "Set to [newstatus] by [usr.name] ([rank]) on [current_date_string] [worldtime2text()], comment: [t1]" update_all_mob_security_hud() if("rank") if(active1) @@ -206,6 +224,7 @@ if(check_access(scan)) authenticated = scan.registered_name rank = scan.assignment + authcard_access = scan.access if(authenticated) active1 = null @@ -218,6 +237,7 @@ screen = null active1 = null active2 = null + authcard_access = list() else if(href_list["sort"]) // Reverse the order if clicked twice @@ -458,6 +478,7 @@ buttons[++buttons.len] = list("name" = "None", "icon" = "unlock", "href" = "criminal=none", "status" = (active2.fields["criminal"] == "None" ? "selected" : null)) buttons[++buttons.len] = list("name" = "*Arrest*", "icon" = "lock", "href" = "criminal=arrest", "status" = (active2.fields["criminal"] == "*Arrest*" ? "selected" : null)) buttons[++buttons.len] = list("name" = "Incarcerated", "icon" = "lock", "href" = "criminal=incarcerated", "status" = (active2.fields["criminal"] == "Incarcerated" ? "selected" : null)) + buttons[++buttons.len] = list("name" = "*Execute*", "icon" = "lock", "href" = "criminal=execute", "status" = (active2.fields["criminal"] == "*Execute*" ? "selected" : null)) buttons[++buttons.len] = list("name" = "Parolled", "icon" = "unlock-alt", "href" = "criminal=parolled", "status" = (active2.fields["criminal"] == "Parolled" ? "selected" : null)) buttons[++buttons.len] = list("name" = "Released", "icon" = "unlock", "href" = "criminal=released", "status" = (active2.fields["criminal"] == "Released" ? "selected" : null)) setTemp("Criminal Status", buttons) diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 8e026cfd80a..938011c1fc8 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -126,6 +126,15 @@ on = 0 go_out() playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) + + if(air_contents) + if(occupant) + process_occupant() + + return 1 + +/obj/machinery/atmospherics/unary/cryo_cell/process_atmos() + ..() if(!node) return if(!on) @@ -135,13 +144,9 @@ temperature_archived = air_contents.temperature heat_gas_contents() - if(occupant) - process_occupant() if(abs(temperature_archived-air_contents.temperature) > 1) parent.update = 1 - return 1 - /obj/machinery/atmospherics/unary/cryo_cell/allow_drop() return 0 diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index d3cbc93d4f0..6df9f81f14c 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -24,10 +24,23 @@ var/list/frozen_crew = list() var/list/frozen_items = list() + // Used for containing rare items traitors need to steal, so it's not + // game-over if they get iced + var/list/objective_items = list() + // A cache of theft datums so you don't have to re-create them for + // each item check + var/list/theft_cache = list() + var/storage_type = "crewmembers" var/storage_name = "Cryogenic Oversight Control" var/allow_items = 1 + +/obj/machinery/computer/cryopod/New() + ..() + for(var/T in potential_theft_objectives) + theft_cache += new T + /obj/machinery/computer/cryopod/attack_ai() attack_hand() @@ -101,8 +114,7 @@ visible_message("The console beeps happily as it disgorges \the [I].") - I.forceMove(get_turf(src)) - frozen_items -= I + dispense_item(I) else if(href_list["allitems"]) if(!allowed(user)) @@ -117,12 +129,31 @@ visible_message("The console beeps happily as it disgorges the desired objects.") for(var/obj/item/I in frozen_items) - I.forceMove(get_turf(src)) - frozen_items -= I + dispense_item(I) updateUsrDialog() return +/obj/machinery/computer/cryopod/proc/dispense_item(obj/item/I) + if(!(I in frozen_items)) + return + I.forceMove(get_turf(src)) + objective_items -= I + frozen_items -= I + +/obj/machinery/computer/cryopod/emag_act(mob/user) + user.changeNext_move(CLICK_CD_MELEE) + if(!objective_items.len) + visible_message("The console buzzes in an annoyed manner.") + playsound(src, 'sound/machines/buzz-sigh.ogg', 30, 1) + return + visible_message("The console sparks, and some items fall out!") + var/datum/effect/system/spark_spread/sparks = new + sparks.set_up(5, 1, src) + sparks.start() + for(var/obj/item/I in objective_items) + dispense_item(I) + /obj/item/weapon/circuitboard/cryopodcontrol name = "Circuit board (Cryogenic Oversight Console)" build_path = "/obj/machinery/computer/cryopod" @@ -275,6 +306,19 @@ despawn_occupant() +#define CRYO_DESTROY 0 +#define CRYO_PRESERVE 1 +#define CRYO_OBJECTIVE 2 + +/obj/machinery/cryopod/proc/should_preserve_item(obj/item/I) + for(var/datum/theft_objective/T in control_computer.theft_cache) + if(istype(I, T.typepath) && T.check_special_completion(I)) + return CRYO_OBJECTIVE + for(var/T in preserve_items) + if(istype(I, T) && !(I.type in do_not_preserve_items)) + return CRYO_PRESERVE + return CRYO_DESTROY + // This function can not be undone; do not call this unless you are sure // Also make sure there is a valid control computer /obj/machinery/cryopod/proc/despawn_occupant() @@ -284,12 +328,7 @@ W.forceMove(src) if(W.contents.len) //Make sure we catch anything not handled by qdel() on the items. - var/preserve = null - for(var/T in preserve_items) - if(istype(W,T)) - preserve = 1 - break - if(preserve) // Don't remove the contents of things that need preservation + if(should_preserve_item(W) != CRYO_DESTROY) // Don't remove the contents of things that need preservation continue for(var/obj/item/O in W.contents) if(istype(O,/obj/item/weapon/tank)) //Stop eating pockets, you fuck! @@ -307,26 +346,22 @@ items -= announce // or the autosay radio. for(var/obj/item/W in items) - - var/preserve = null - for(var/T in preserve_items) - if(istype(W,T) && !(W in do_not_preserve_items)) - preserve = 1 - break - if(istype(W,/obj/item/device/pda)) var/obj/item/device/pda/P = W QDEL_NULL(P.id) qdel(P) + continue - if(!preserve) + var/preserve = should_preserve_item(W) + if(preserve == CRYO_DESTROY) qdel(W) + else if(control_computer && control_computer.allow_items) + control_computer.frozen_items += W + if(preserve == CRYO_OBJECTIVE) + control_computer.objective_items += W + W.loc = null else - if(control_computer && control_computer.allow_items) - control_computer.frozen_items += W - W.loc = null - else - W.forceMove(loc) + W.forceMove(loc) // Skip past any cult sacrifice objective using this person if(GAMEMODE_IS_CULT && is_sacrifice_target(occupant.mind)) @@ -422,6 +457,9 @@ QDEL_NULL(occupant) name = initial(name) +#undef CRYO_DESTROY +#undef CRYO_PRESERVE +#undef CRYO_OBJECTIVE /obj/machinery/cryopod/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params) @@ -727,4 +765,4 @@ if(target_cryopod.check_occupant_allowed(person_to_cryo)) target_cryopod.take_occupant(person_to_cryo, 1) return 1 - return 0 \ No newline at end of file + return 0 diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index a0b72ed5074..80a4a36ee44 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -647,13 +647,12 @@ About the new airlock wires panel: src.attack_ai(user) /obj/machinery/door/airlock/CanPass(atom/movable/mover, turf/target, height=0) - if(src.isElectrified()) - if(istype(mover, /obj/item)) - var/obj/item/i = mover - if(i.materials[MAT_METAL]) - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() + if(isElectrified() && density && istype(mover, /obj/item)) + var/obj/item/I = mover + if(I.flags & CONDUCT) + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() return ..() /obj/machinery/door/airlock/attack_hand(mob/user as mob) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 818f251024c..39fa5e04037 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -46,7 +46,7 @@Log generated at: [worldtime2text()] Detainee: [logname] - Duration: [timetoset/10] seconds + Duration: [seconds_to_time(timetoset / 10)] Charge(s): [logcharges] Arresting Officer: [usr.name] This log file was generated automatically upon activation of a cell timer."} @@ -55,7 +55,7 @@ cell_logs += P var/datum/data/record/R = find_security_record("name", logname) - Radio.autosay("Detainee [logname] has been incarcerated for [timetoset/10] seconds for the charges of, '[logcharges]'. \ + Radio.autosay("Detainee [logname] has been incarcerated for [seconds_to_time(timetoset / 10)] for the charges of, '[logcharges]'. \ Arresting Officer: [usr.name].[R ? "" : " Detainee record not found, manual record update required."]", name, "Security", list(z)) if(R) @@ -277,7 +277,7 @@ dat += "Set Timer: [(setminute ? text("[setminute]:") : null)][setsecond] " // Controls - dat += "- - + + " + dat += "Input Time" // Mounted flash controls for(var/obj/machinery/flasher/F in targets) @@ -319,13 +319,9 @@ Radio.autosay("Timer stopped manually by [usr.name].", name, "Security", list(z)) else - if(href_list["tp"]) //adjust timer, close door if not already closed - var/tp = text2num(href_list["tp"]) - var/addtime = (timetoset / 10) - addtime += tp - addtime = min(max(round(addtime), 0), 3600) - - timeset(addtime) + if(href_list["settime"]) + var/time = min(max(round(return_time_input(usr)), 0), 3600) + timeset(time) if(href_list["fc"]) for(var/obj/machinery/flasher/F in targets) @@ -368,6 +364,11 @@ overlays.Cut() overlays += image('icons/obj/status_display.dmi', icon_state=picture_state) +/obj/machinery/door_timer/proc/return_time_input() + var/mins = input(usr, "Minutes", "Enter number of minutes", 0) as num + var/seconds = input(usr, "Seconds", "Enter number of seconds", 0) as num + var/totaltime = (seconds + (mins * 60)) + return totaltime //Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display // Stolen from status_display diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index c3e105a7fee..4f68c721c1c 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -76,8 +76,13 @@ var/mob/living/M = AM if(world.time - M.last_bumped <= 10) return //Can bump-open one airlock per second. This is to prevent shock spam. M.last_bumped = world.time - if(!M.restrained() && M.mob_size > MOB_SIZE_SMALL) - bumpopen(M) + if(!M.restrained()) + if(M.mob_size > MOB_SIZE_SMALL) + bumpopen(M) + else if(ispet(M)) + var/mob/living/simple_animal/A = AM + if(A.collar) + bumpopen(M) return if(istype(AM, /obj/mecha)) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index bda658ef128..0f397a51dbb 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -59,7 +59,9 @@ if(operating) return - if(istype(C, /obj/item/weapon/weldingtool)) + if(iswelder(C)) + if(!density) + return var/obj/item/weapon/weldingtool/W = C if(W.remove_fuel(0, user)) welded = !welded @@ -169,6 +171,8 @@ update_icon() /obj/machinery/door/firedoor/open(auto_close = TRUE) + if(welded) + return . = ..() latetoggle(auto_close) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index c7a41eb7937..2b217b52127 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -297,7 +297,6 @@ var/list/holopads = list() if(eye_area != holo_area) clear_holo(user) - return 1 /obj/machinery/hologram/holopad/proc/activate_holo(mob/living/user, var/force = 0) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 901ea27a7df..b8244771de0 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -166,6 +166,9 @@ Class Procs: /obj/machinery/process() // If you dont use process or power why are you here return PROCESS_KILL +/obj/machinery/proc/process_atmos() //If you dont use process why are you here + return PROCESS_KILL + /obj/machinery/emp_act(severity) if(use_power && stat == 0) use_power(7500/severity) diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index 7775744ba45..543ea80f490 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -47,14 +47,14 @@ if(operation == 1) // Play if(working == 1) return - if(!account || account.money < 10) + if(!account || account.money < 100) return - if(!account.charge(10, transaction_purpose = "Bet", dest_name = name)) + if(!account.charge(100, transaction_purpose = "Bet", dest_name = name)) return plays += 1 working = 1 icon_state = "slots-on" - var/roll = rand(1,1350) + var/roll = rand(1,20000) playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) spawn(25) if(roll == 1) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index caf6840ebc7..5b1211a7394 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -977,7 +977,7 @@ /obj/item/seeds/cabbage = 3, /obj/item/seeds/carrot = 3, /obj/item/seeds/cherry = 3, /obj/item/seeds/chanter = 3, /obj/item/seeds/chili = 3, /obj/item/seeds/cocoapod = 3, /obj/item/seeds/coffee = 3, /obj/item/seeds/comfrey =3, /obj/item/seeds/corn = 3, /obj/item/seeds/nymph =3, /obj/item/seeds/eggplant = 3, /obj/item/seeds/grape = 3, /obj/item/seeds/grass = 3, /obj/item/seeds/lemon = 3, - /obj/item/seeds/lime = 3, /obj/item/seeds/onion = 3, /obj/item/seeds/orange = 3, /obj/item/seeds/peanuts = 3, /obj/item/seeds/potato = 3, /obj/item/seeds/poppy = 3, + /obj/item/seeds/lime = 3, /obj/item/seeds/onion = 3, /obj/item/seeds/orange = 3, /obj/item/seeds/peanuts = 3, /obj/item/seeds/pineapple = 3, /obj/item/seeds/potato = 3, /obj/item/seeds/poppy = 3, /obj/item/seeds/pumpkin = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/wheat/rice = 3, /obj/item/seeds/soya = 3, /obj/item/seeds/sunflower = 3, /obj/item/seeds/tea = 3, /obj/item/seeds/tobacco = 3, /obj/item/seeds/tomato = 3, /obj/item/seeds/tower = 3, /obj/item/seeds/watermelon = 3, /obj/item/seeds/wheat = 3, /obj/item/seeds/whitebeet = 3) diff --git a/code/game/magic/Uristrunes.dm b/code/game/magic/Uristrunes.dm index ed881c71fb1..b645aa819f5 100644 --- a/code/game/magic/Uristrunes.dm +++ b/code/game/magic/Uristrunes.dm @@ -22,6 +22,9 @@ var/runetype = "rune" runetype = "rune" else if(ticker.mode.cultdat.theme == "fire") runetype = "fire-rune" + else if(ticker.mode.cultdat.theme == "death") + runetype = "death-rune" + if(lookup in rune_cache) return rune_cache[lookup] diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index ef4330800ed..aebd54401a6 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -9,6 +9,8 @@ var/variance = 0 var/randomspread = 0 //use random spread for machineguns, instead of shotgun scatter var/projectile_delay = 0 + var/projectiles + var/projectile_energy_cost /obj/item/mecha_parts/mecha_equipment/weapon/can_attach(var/obj/mecha/combat/M as obj) if(..()) @@ -50,6 +52,7 @@ A.preparePixelProjectile(target, targloc, chassis.occupant, params, spread) chassis.use_power(energy_drain) + projectiles-- A.fire() playsound(chassis, fire_sound, 50, 1) @@ -243,8 +246,6 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic name = "General Ballisic Weapon" - var/projectiles - var/projectile_energy_cost size = 2 /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action_checks(atom/target) if(..()) @@ -482,6 +483,7 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/bola name = "PCMK-6 Bola Launcher" icon_state = "mecha_bola" + origin_tech = "combat=4;engineering=4" projectile = /obj/item/weapon/restraints/legcuffs/bola fire_sound = 'sound/weapons/whip.ogg' projectiles = 10 diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index d386fe07d0b..106c60dc650 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -58,6 +58,10 @@ /obj/effect/mine/dnascramble/mineEffect(mob/living/victim) victim.apply_effect(radiation_amount, IRRADIATE, 0) + if(ishuman(victim)) + var/mob/living/carbon/human/V = victim + if(NO_DNA in V.species.species_traits) + return randmutb(victim) domutcheck(victim ,null) diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 2dd8502d662..96f52929da6 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -277,4 +277,11 @@ /obj/effect/overlay/temp/cult/turf/open/floor icon_state = "floorglow" - duration = 5 \ No newline at end of file + duration = 5 + +/obj/effect/overlay/temp/shieldflash + icon_state = "shield-flash" + duration = 3 + +/obj/effect/overlay/temp/shieldflash/New(var/flash_color) + diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index a1a68ff5cf7..d40baf16877 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -202,7 +202,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d to_chat(user, msg) -/obj/item/attack_hand(mob/user as mob) +/obj/item/attack_hand(mob/user as mob, pickupfireoverride = FALSE) if(!user) return 0 if(hasorgans(user)) var/mob/living/carbon/human/H = user @@ -216,7 +216,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d to_chat(user, "You try to move your [temp.name], but cannot!") return 0 - if(burn_state == ON_FIRE) + if(burn_state == ON_FIRE && !pickupfireoverride) var/mob/living/carbon/human/H = user if(istype(H)) if(H.gloves && (H.gloves.max_heat_protection_temperature > 360)) diff --git a/code/game/objects/items/devices/instruments.dm b/code/game/objects/items/devices/instruments.dm index 3643b197d4c..450dad3d869 100644 --- a/code/game/objects/items/devices/instruments.dm +++ b/code/game/objects/items/devices/instruments.dm @@ -2,14 +2,15 @@ /obj/item/device/instrument name = "generic instrument" icon = 'icons/obj/musician.dmi' + lefthand_file = 'icons/mob/inhands/equipment/instruments_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/instruments_righthand.dmi' burn_state = FLAMMABLE var/datum/song/handheld/song var/instrumentId = "generic" - var/instrumentExt = "ogg" + var/instrumentExt = "mid" /obj/item/device/instrument/New() - song = new(instrumentId, src) - song.instrumentExt = instrumentExt + song = new(instrumentId, src, instrumentExt) ..() /obj/item/device/instrument/Destroy() @@ -44,6 +45,7 @@ desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\"" icon_state = "violin" item_state = "violin" + instrumentExt = "ogg" force = 10 hitsound = "swing_hit" instrumentId = "violin" @@ -55,11 +57,26 @@ item_state = "golden_violin" burn_state = LAVA_PROOF +/obj/item/device/instrument/piano_synth + name = "synthesizer" + desc = "An advanced electronic synthesizer that can be used as various instruments." + icon_state = "synth" + item_state = "synth" + instrumentId = "piano" + instrumentExt = "ogg" + var/static/list/insTypes = list("accordion" = "mid", "glockenspiel" = "mid", "guitar" = "ogg", "eguitar" = "ogg", "harmonica" = "mid", "piano" = "ogg", "recorder" = "mid", "saxophone" = "mid", "trombone" = "mid", "violin" = "ogg", "xylophone" = "mid") + actions_types = list(/datum/action/item_action/synthswitch) + +/obj/item/device/instrument/piano_synth/proc/changeInstrument(name = "piano") + song.instrumentDir = name + song.instrumentExt = insTypes[name] + /obj/item/device/instrument/guitar name = "guitar" desc = "It's made of wood and has bronze strings." icon_state = "guitar" item_state = "guitar" + instrumentExt = "ogg" force = 10 attack_verb = list("played metal on", "serenaded", "crashed", "smashed") hitsound = 'sound/effects/guitarsmash.ogg' @@ -70,11 +87,79 @@ desc = "Makes all your shredding needs possible." icon_state = "eguitar" item_state = "eguitar" + instrumentExt = "ogg" force = 12 attack_verb = list("played metal on", "shredded", "crashed", "smashed") hitsound = 'sound/weapons/stringsmash.ogg' instrumentId = "eguitar" +/obj/item/device/instrument/glockenspiel + name = "glockenspiel" + desc = "Smooth metal bars perfect for any marching band." + icon_state = "glockenspiel" + item_state = "glockenspiel" + instrumentId = "glockenspiel" + +/obj/item/device/instrument/accordion + name = "accordion" + desc = "Pun-Pun not included." + icon_state = "accordion" + item_state = "accordion" + instrumentId = "accordion" + +/obj/item/device/instrument/saxophone + name = "saxophone" + desc = "This soothing sound will be sure to leave your audience in tears." + icon_state = "saxophone" + item_state = "saxophone" + instrumentId = "saxophone" + +/obj/item/device/instrument/trombone + name = "trombone" + desc = "How can any pool table ever hope to compete?" + icon_state = "trombone" + item_state = "trombone" + instrumentId = "trombone" + +/obj/item/device/instrument/recorder + name = "recorder" + desc = "Just like in school, playing ability and all." + icon_state = "recorder" + item_state = "recorder" + instrumentId = "recorder" + +/obj/item/device/instrument/harmonica + name = "harmonica" + desc = "For when you get a bad case of the space blues." + icon_state = "harmonica" + item_state = "harmonica" + instrumentId = "harmonica" + force = 5 + w_class = WEIGHT_CLASS_SMALL + +/obj/item/device/instrument/xylophone + name = "xylophone" + desc = "a percussion instrument with a bright tone." + icon_state = "xylophone" + item_state = "xylophone" + instrumentId = "xylophone" + +/obj/item/device/instrument/bikehorn + name = "gilded bike horn" + desc = "An exquisitely decorated bike horn, capable of honking in a variety of notes." + icon_state = "bike_horn" + item_state = "bike_horn" + lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' + righthand_file = 'icons/mob/inhands/items_righthand.dmi' + attack_verb = list("beautifully honks") + instrumentId = "bikehorn" + instrumentExt = "ogg" + w_class = WEIGHT_CLASS_TINY + force = 0 + throw_speed = 3 + throw_range = 7 + hitsound = 'sound/items/bikehorn.ogg' + /datum/crafting_recipe/violin name = "Violin" result = /obj/item/device/instrument/violin diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index c59e39a2043..20c21ca73d0 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -21,6 +21,11 @@ if(!user.can_speak()) to_chat(user, "You find yourself unable to speak at all.") return + if(ishuman(user)) + var/mob/living/carbon/human/abductor/H = user + if(H && H.mind.abductor) + to_chat(user, "Megaphones can't project psionic communication!") + return if(ishuman(user)) var/mob/living/carbon/human/H = user if(H && H.mind && H.mind.miming) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 3d1f1001b06..67009e3366d 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -675,6 +675,13 @@ var/global/list/default_medbay_channels = list( ..() set_frequency(DTH_FREQ) +/obj/item/device/radio/borg/ert + keyslot = new /obj/item/device/encryptionkey/ert + +/obj/item/device/radio/borg/ert/New() + ..() + set_frequency(ERT_FREQ) + /obj/item/device/radio/borg/attackby(obj/item/weapon/W as obj, mob/user as mob, params) // ..() user.set_machine(src) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 88aa19bfef8..dfec1d1ba09 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -363,7 +363,7 @@ REAGENT SCANNER return /obj/item/device/mass_spectrometer - desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample." + desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample. Inject sample with syringe." name = "mass-spectrometer" icon_state = "spectrometer" item_state = "analyzer" @@ -377,7 +377,7 @@ REAGENT SCANNER origin_tech = "magnets=2;biotech=1;plasmatech=2" var/details = 0 var/datatoprint = "" - var/scanning = 1 + var/scanning = TRUE actions_types = list(/datum/action/item_action/print_report) /obj/item/device/mass_spectrometer/New() @@ -400,8 +400,8 @@ REAGENT SCANNER var/list/blood_traces = list() for(var/datum/reagent/R in reagents.reagent_list) if(R.id != "blood") - reagents.clear_reagents() to_chat(user, "The sample was contaminated! Please insert another sample.") + reagents.clear_reagents() return else blood_traces = params2list(R.data["trace_chem"]) @@ -412,7 +412,9 @@ REAGENT SCANNER dat += "[R] ([blood_traces[R]] units) " else dat += "[R] " - to_chat(user, "[dat]") + to_chat(user, "Analysis completed. Chemicals found: [dat]") + scanning = FALSE + datatoprint = dat reagents.clear_reagents() return @@ -424,6 +426,7 @@ REAGENT SCANNER /obj/item/device/mass_spectrometer/proc/print_report() if(!scanning) + scanning = TRUE usr.visible_message("[src] rattles and prints out a sheet of paper.") playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1) sleep(50) @@ -437,7 +440,6 @@ REAGENT SCANNER M.put_in_hands(P) to_chat(M, "Report printed. Log cleared.") datatoprint = "" - scanning = 1 else to_chat(usr, "[src] has no logs or is already in use.") diff --git a/code/game/objects/items/mountable_frames/apc_frame.dm b/code/game/objects/items/mountable_frames/apc_frame.dm index 11542cdd94c..fbdab5584f1 100644 --- a/code/game/objects/items/mountable_frames/apc_frame.dm +++ b/code/game/objects/items/mountable_frames/apc_frame.dm @@ -10,11 +10,11 @@ var/turf/turf_loc = get_turf(user) var/area/area_loc = turf_loc.loc if(area_loc.get_apc()) - to_chat(user, "This area already has an APC.") + to_chat(user, "This area already has an APC.") return //only one APC per area for(var/obj/machinery/power/terminal/T in turf_loc) if(T.master) - to_chat(user, "There is another network terminal here.") + to_chat(user, "There is another network terminal here.") return else var/obj/item/stack/cable_coil/C = new /obj/item/stack/cable_coil(turf_loc) diff --git a/code/game/objects/items/mountable_frames/frames.dm b/code/game/objects/items/mountable_frames/frames.dm index 0bc5a8f9be6..2bcbea8cbee 100644 --- a/code/game/objects/items/mountable_frames/frames.dm +++ b/code/game/objects/items/mountable_frames/frames.dm @@ -20,11 +20,11 @@ var/turf/turf_loc = get_turf(user) if(src.mount_reqs.Find("simfloor") && !istype(turf_loc, /turf/simulated/floor)) - to_chat(user, "[src] cannot be placed on this spot.") + to_chat(user, "[src] cannot be placed on this spot.") return if(src.mount_reqs.Find("nospace")) var/area/my_area = turf_loc.loc if(!istype(my_area) || (my_area.requires_power == 0 || istype(my_area,/area/space))) - to_chat(user, "[src] cannot be placed in this area.") + to_chat(user, "[src] cannot be placed in this area.") return return 1 diff --git a/code/game/objects/items/mountable_frames/mountables.dm b/code/game/objects/items/mountable_frames/mountables.dm index 1b720712fa9..7120f8c880d 100644 --- a/code/game/objects/items/mountable_frames/mountables.dm +++ b/code/game/objects/items/mountable_frames/mountables.dm @@ -21,11 +21,11 @@ if(proximity_flag != 1) //if we aren't next to the wall return if(!( get_dir(on_wall,user) in cardinal)) - to_chat(user, "You need to be standing next to a wall to place \the [src].") + to_chat(user, "You need to be standing next to a wall to place \the [src].") return if(gotwallitem(get_turf(user), get_dir(on_wall,user))) - to_chat(user, "There's already an item on this wall!") + to_chat(user, "There's already an item on this wall!") return return 1 diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm index 5cc0ab739c0..b5d0066a706 100644 --- a/code/game/objects/items/random_items.dm +++ b/code/game/objects/items/random_items.dm @@ -3,13 +3,14 @@ // ------------------------------------- /obj/item/toy/random name = "Random Toy" - New() - ..() - var/list/types = list(/obj/item/weapon/gun/projectile/shotgun/toy/crossbow, /obj/item/toy/balloon,/obj/item/toy/spinningtoy,/obj/item/weapon/reagent_containers/spray/waterflower) + subtypesof(/obj/item/toy/prize) - var/T = pick(types) - new T(loc) - spawn(1) - qdel(src) + +/obj/item/toy/random/New() + ..() + var/list/types = list(/obj/item/weapon/gun/projectile/shotgun/toy/crossbow, /obj/item/toy/balloon,/obj/item/toy/spinningtoy,/obj/item/weapon/reagent_containers/spray/waterflower) + subtypesof(/obj/item/toy/prize) + var/T = pick(types) + new T(loc) + spawn(1) + qdel(src) // ------------------------------------- // Random cleanables, clearly this makes sense @@ -17,24 +18,26 @@ /obj/effect/decal/cleanable/random name = "Random Mess" - New() - ..() - var/list/list = subtypesof(/obj/effect/decal/cleanable) - list(/obj/effect/decal/cleanable/random,/obj/effect/decal/cleanable/cobweb,/obj/effect/decal/cleanable/cobweb2) - var/T = pick(list) - new T(loc) - spawn(0) - qdel(src) + +/obj/effect/decal/cleanable/random/New() + ..() + var/list/list = subtypesof(/obj/effect/decal/cleanable) - list(/obj/effect/decal/cleanable/random,/obj/effect/decal/cleanable/cobweb,/obj/effect/decal/cleanable/cobweb2) + var/T = pick(list) + new T(loc) + spawn(0) + qdel(src) /obj/item/stack/sheet/animalhide/random name = "random animal hide" - New() - ..() - spawn(1) - var/htype = pick(/obj/item/stack/sheet/animalhide/cat,/obj/item/stack/sheet/animalhide/corgi,/obj/item/stack/sheet/animalhide/human,/obj/item/stack/sheet/animalhide/lizard,/obj/item/stack/sheet/animalhide/monkey) - var/obj/item/stack/S = new htype(loc) - S.amount = amount - qdel(src) + +/obj/item/stack/sheet/animalhide/random/New() + ..() + spawn(1) + var/htype = pick(/obj/item/stack/sheet/animalhide/cat,/obj/item/stack/sheet/animalhide/corgi,/obj/item/stack/sheet/animalhide/human,/obj/item/stack/sheet/animalhide/lizard,/obj/item/stack/sheet/animalhide/monkey) + var/obj/item/stack/S = new htype(loc) + S.amount = amount + qdel(src) // ------------------------------------- // Not yet identified chemical. @@ -43,103 +46,108 @@ /obj/item/weapon/reagent_containers/glass/bottle/random_reagent name = "unlabelled bottle" -// identify_probability = 0 - New() - ..() - var/datum/reagent/R = pick(chemical_reagents_list) - if(rare_chemicals.Find(R)) - reagents.add_reagent(R,10) - else - reagents.add_reagent(R,rand(2,3)*10) - pixel_x = rand(-10,10) - pixel_y = rand(-10,10) + // identify_probability = 0 + +/obj/item/weapon/reagent_containers/glass/bottle/random_reagent/New() + ..() + var/list/possible_chems = chemical_reagents_list.Copy() + possible_chems -= blocked_chems.Copy() + var/datum/reagent/R = pick(possible_chems) + if(rare_chemicals.Find(R)) + reagents.add_reagent(R, 10) + else + reagents.add_reagent(R, rand(2, 3)*10) + pixel_x = rand(-10, 10) + pixel_y = rand(-10, 10) //Cuts out the food and drink reagents /obj/item/weapon/reagent_containers/glass/bottle/random_chem name = "unlabelled chemical bottle" -// identify_probability = 0 - New() - ..() + // identify_probability = 0 - var/datum/reagent/R = pick(standard_chemicals + rare_chemicals) - if(rare_chemicals.Find(R)) - reagents.add_reagent(R,10) - else - reagents.add_reagent(R,rand(2,3)*10) - name = "unlabelled bottle" - pixel_x = rand(-10,10) - pixel_y = rand(-10,10) +/obj/item/weapon/reagent_containers/glass/bottle/random_chem/New() + ..() + var/R = get_random_reagent_id() + if(rare_chemicals.Find(R)) + reagents.add_reagent(R, 10) + else + reagents.add_reagent(R, rand(2, 3)*10) + name = "unlabelled bottle" + pixel_x = rand(-10, 10) + pixel_y = rand(-10, 10) /obj/item/weapon/reagent_containers/glass/bottle/random_base_chem name = "unlabelled chemical bottle" -// identify_probability = 0 - New() - ..() - var/datum/reagent/R = pick(base_chemicals) - reagents.add_reagent(R,rand(2,6)*5) - name = "unlabelled bottle" - pixel_x = rand(-10,10) - pixel_y = rand(-10,10) + // identify_probability = 0 + +/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem/New() + ..() + var/datum/reagent/R = pick(base_chemicals) + reagents.add_reagent(R, rand(2, 6)*5) + name = "unlabelled bottle" + pixel_x = rand(-10, 10) + pixel_y = rand(-10, 10) /obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink name = "unlabelled drink" icon = 'icons/obj/drinks.dmi' - New() - ..() - var/list/additional_drinks = list() - if(prob(50)) - additional_drinks += list("pancuronium","lsd","omnizine","blood") - var/datum/reagent/R = pick(drinks + additional_drinks) - reagents.add_reagent(R,volume) - name = "unlabelled bottle" - icon_state = pick("alco-white","alco-green","alco-blue","alco-clear","alco-red") - pixel_x = rand(-5,5) - pixel_y = rand(-5,5) +/obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink/New() + ..() + var/list/possible_drinks = drinks.Copy() + if(prob(50)) + possible_drinks += list("pancuronium","lsd","omnizine","blood") + + var/datum/reagent/R = pick(possible_drinks) + reagents.add_reagent(R, volume) + name = "unlabelled bottle" + icon_state = pick("alco-white","alco-green","alco-blue","alco-clear","alco-red") + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) /obj/item/weapon/reagent_containers/food/drinks/bottle/random_reagent // Same as the chembottle code except the container name = "unlabelled drink?" icon = 'icons/obj/drinks.dmi' - New() - ..() - var/datum/reagent/R = pick(chemical_reagents_list) - if(rare_chemicals.Find(R)) - reagents.add_reagent(R,10) - else - reagents.add_reagent(R,rand(3,10)*10) - name = "unlabelled bottle" - icon_state = pick("alco-white","alco-green","alco-blue","alco-clear","alco-red") - pixel_x = rand(-5,5) - pixel_y = rand(-5,5) - spawn(0) - qdel(src) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/random_reagent/New() + ..() + + var/R = get_random_reagent_id() + if(rare_chemicals.Find(R)) + reagents.add_reagent(R, 10) + else + reagents.add_reagent(R, rand(3, 10)*10) + name = "unlabelled bottle" + icon_state = pick("alco-white","alco-green","alco-blue","alco-clear","alco-red") + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + spawn(0) + qdel(src) /obj/item/weapon/storage/pill_bottle/random_meds name = "unlabelled pillbottle" desc = "The sheer recklessness of this bottle's existence astounds you." - New() - ..() - var/i = 1 - while(i < storage_slots) +/obj/item/weapon/storage/pill_bottle/random_meds/New() + ..() + var/i = 1 + while(i < storage_slots) + var/list/possible_medicines = standard_medicines.Copy() + if(prob(50)) + possible_medicines += rare_medicines.Copy() + var/datum/reagent/R = pick(possible_medicines) + var/obj/item/weapon/reagent_containers/food/pill/P = new(src) - var/datum/reagent/R - if(prob(50)) - R = pick(standard_medicines + rare_medicines) - else - R = pick(standard_medicines) - var/obj/item/weapon/reagent_containers/food/pill/P = new(src) + if(rare_medicines.Find(R)) + P.reagents.add_reagent(R, 10) + else + P.reagents.add_reagent(R, rand(2, 5)*10) + P.name = "Unlabelled Pill" + P.desc = "Something about this pill entices you to try it, against your better judgement." + i++ + pixel_x = rand(-10, 10) + pixel_y = rand(-10, 10) - if(rare_medicines.Find(R)) - P.reagents.add_reagent(R,10) - else - P.reagents.add_reagent(R,rand(2,5)*10) - P.name = "Unlabelled Pill" - P.desc = "Something about this pill entices you to try it, against your better judgement." - i++ - pixel_x = rand(-10,10) - pixel_y = rand(-10,10) - return // ------------------------------------- // Containers full of unknown crap @@ -150,43 +158,43 @@ desc = "Crate full of chemicals of unknown type and value from a 'trusted' source." req_one_access = list(access_chemistry,access_research,access_qm) // the qm knows a guy, you see. - New() - ..() - new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) - new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) - new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) - new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) - new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) - new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) - new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) - new/obj/item/weapon/reagent_containers/glass/bottle/random_chem(src) - new/obj/item/weapon/reagent_containers/glass/bottle/random_chem(src) - new/obj/item/weapon/reagent_containers/glass/bottle/random_chem(src) - while(prob(50)) - new/obj/item/weapon/reagent_containers/glass/bottle/random_reagent(src) +/obj/structure/closet/crate/secure/unknownchemicals/New() + ..() + new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) + new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) + new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) + new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) + new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) + new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) + new/obj/item/weapon/reagent_containers/glass/bottle/random_base_chem(src) + new/obj/item/weapon/reagent_containers/glass/bottle/random_chem(src) + new/obj/item/weapon/reagent_containers/glass/bottle/random_chem(src) + new/obj/item/weapon/reagent_containers/glass/bottle/random_chem(src) + while(prob(50)) + new/obj/item/weapon/reagent_containers/glass/bottle/random_reagent(src) + new/obj/item/weapon/storage/pill_bottle/random_meds(src) + while(prob(25)) new/obj/item/weapon/storage/pill_bottle/random_meds(src) - while(prob(25)) - new/obj/item/weapon/storage/pill_bottle/random_meds(src) /obj/structure/closet/crate/secure/chemicals - name = "chemical supply kit" - desc = "Full of basic chemistry supplies." - req_one_access = list(access_chemistry,access_research) + name = "chemical supply kit" + desc = "Full of basic chemistry supplies." + req_one_access = list(access_chemistry,access_research) - New() - ..() - for(var/chem in standard_chemicals) - var/obj/item/weapon/reagent_containers/glass/bottle/B = new(src) - B.reagents.add_reagent(chem,B.volume) - if(prob(85)) - var/datum/reagent/r = chemical_reagents_list[chem] - B.name = "[r.name] bottle" -// B.identify_probability = 100 - else - B.name = "unlabelled bottle" - B.desc = "Looks like the label fell off." -// B.identify_probability = 0 +/obj/structure/closet/crate/secure/chemicals/New() + ..() + for(var/chem in standard_chemicals) + var/obj/item/weapon/reagent_containers/glass/bottle/B = new(src) + B.reagents.add_reagent(chem, B.volume) + if(prob(85)) + var/datum/reagent/r = chemical_reagents_list[chem] + B.name = "[r.name] bottle" +// B.identify_probability = 100 + else + B.name = "unlabelled bottle" + B.desc = "Looks like the label fell off." +// B.identify_probability = 0 /* /obj/structure/closet/crate/bin/flowers @@ -235,15 +243,15 @@ icon_broken = "cabinetdetective_broken" icon_off = "cabinetdetective_broken" - New() - ..() - new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink(src) - new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink(src) - new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink(src) - new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink(src) - new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink(src) - while(prob(25)) - new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_reagent(src) +/obj/structure/closet/secure_closet/random_drinks/New() + ..() + new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink(src) + new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink(src) + new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink(src) + new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink(src) + new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_drink(src) + while(prob(25)) + new/obj/item/weapon/reagent_containers/food/drinks/bottle/random_reagent(src) // ------------------------------------- @@ -257,23 +265,23 @@ name = "\improper Mysterious Crate" desc = "What could it be?" - attackby(obj/item/weapon/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/weapon/crowbar)) - var/list/menace = pick( /mob/living/simple_animal/hostile/carp,/mob/living/simple_animal/hostile/faithless,/mob/living/simple_animal/hostile/pirate, - /mob/living/simple_animal/hostile/creature,/mob/living/simple_animal/hostile/pirate/ranged, - /mob/living/simple_animal/hostile/hivebot,/mob/living/simple_animal/hostile/viscerator,/mob/living/simple_animal/hostile/pirate) +/obj/structure/largecrate/evil/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/weapon/crowbar)) + var/list/menace = pick( /mob/living/simple_animal/hostile/carp,/mob/living/simple_animal/hostile/faithless,/mob/living/simple_animal/hostile/pirate, + /mob/living/simple_animal/hostile/creature,/mob/living/simple_animal/hostile/pirate/ranged, + /mob/living/simple_animal/hostile/hivebot,/mob/living/simple_animal/hostile/viscerator,/mob/living/simple_animal/hostile/pirate) - visible_message("Something falls out of the [src]!") - var/obj/item/weapon/grenade/clusterbuster/C = new(src.loc) - C.prime() - spawn(10) - new menace(src.loc) - while(prob(15)) - new menace(get_step_rand(src.loc)) - ..() - return 1 - else - return ..() + visible_message("Something falls out of the [src]!") + var/obj/item/weapon/grenade/clusterbuster/C = new(src.loc) + C.prime() + spawn(10) + new menace(src.loc) + while(prob(15)) + new menace(get_step_rand(src.loc)) + ..() + return 1 + else + return ..() // @@ -288,22 +296,22 @@ name = "Schrodinger's Crate" desc = "What happens if you open it?" - attackby(obj/item/weapon/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/weapon/crowbar)) - var/mob/living/simple_animal/pet/cat/Cat1 = new(loc) - Cat1.apply_damage(250)//,TOX) - Cat1.name = "Schrodinger's Cat" - Cat1.desc = "It seems it's been dead for a while." +/obj/structure/largecrate/schrodinger/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/weapon/crowbar)) + var/mob/living/simple_animal/pet/cat/Cat1 = new(loc) + Cat1.apply_damage(250)//,TOX) + Cat1.name = "Schrodinger's Cat" + Cat1.desc = "It seems it's been dead for a while." - var/mob/living/simple_animal/pet/cat/Cat2 = new(loc) - Cat2.name = "Schrodinger's Cat" - Cat2.desc = "It's was alive the whole time!" - sleep(2) - if(prob(50)) - qdel(Cat1) - else - qdel(Cat2) - return ..() + var/mob/living/simple_animal/pet/cat/Cat2 = new(loc) + Cat2.name = "Schrodinger's Cat" + Cat2.desc = "It's was alive the whole time!" + sleep(2) + if(prob(50)) + qdel(Cat1) + else + qdel(Cat2) + return ..() // -------------------------------------- // Collen's box of wonder and mystery @@ -318,18 +326,18 @@ /obj/item/weapon/grenade/chem_grenade/dirt, /obj/item/weapon/grenade/chem_grenade/lube, /obj/item/weapon/grenade/smokebomb, /obj/item/weapon/grenade/chem_grenade/drugs, /obj/item/weapon/grenade/chem_grenade/ethanol) // holy list batman - New() - ..() - var/nade1 = pick(grenadelist) - var/nade2 = pick(grenadelist) - var/nade3 = pick(grenadelist) - var/nade4 = pick(grenadelist) - var/nade5 = pick(grenadelist) - var/nade6 = pick(grenadelist) +/obj/item/weapon/storage/box/grenades/New() + ..() + var/nade1 = pick(grenadelist) + var/nade2 = pick(grenadelist) + var/nade3 = pick(grenadelist) + var/nade4 = pick(grenadelist) + var/nade5 = pick(grenadelist) + var/nade6 = pick(grenadelist) - new nade1(src) - new nade2(src) - new nade3(src) - new nade4(src) - new nade5(src) - new nade6(src) + new nade1(src) + new nade2(src) + new nade3(src) + new nade4(src) + new nade5(src) + new nade6(src) diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 0e9d9a0ac09..2d790a8df1f 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -1,10 +1,11 @@ /********************************************************************** Cyborg Spec Items ***********************************************************************/ -//Might want to move this into several files later but for now it works here +/obj/item/borg + icon = 'icons/mob/robot_items.dmi' + /obj/item/borg/stun - name = "electrified arm" - icon = 'icons/obj/items.dmi' + name = "electrically-charged arm" icon_state = "elecarm" var/charge_cost = 30 @@ -15,8 +16,9 @@ playsound(M, 'sound/weapons/Genhit.ogg', 50, 1) return 0 - if(!user.cell.use(charge_cost)) - return + if(isrobot(user)) + if(!user.cell.use(charge_cost)) + return user.do_attack_animation(M) M.Weaken(5) @@ -34,3 +36,198 @@ name = "Overdrive" icon = 'icons/obj/decals.dmi' icon_state = "shock" + +#define BORG_HUG 0 +#define BORG_HUG_SUPER 1 +#define BORG_HUG_SHOCK 2 +#define BORG_HUG_CRUSH 3 + +/obj/item/borg/cyborghug + name = "Hugging Module" + icon_state = "hugmodule" + desc = "For when a someone really needs a hug." + var/mode = BORG_HUG //0 = Hugs 1 = "Hug" 2 = Shock 3 = CRUSH + var/ccooldown = 0 + var/scooldown = 0 + var/shockallowed = FALSE//Can it be a stunarm when emagged. Only PK borgs get this by default. + var/boop = FALSE + +/obj/item/borg/cyborghug/attack_self(mob/living/user) + if(isrobot(user)) + var/mob/living/silicon/robot/P = user + if(P.emagged && shockallowed) + if(mode < BORG_HUG_CRUSH) + mode++ + else + mode = BORG_HUG + else if(mode < BORG_HUG_SUPER) + mode++ + else + mode = BORG_HUG + switch(mode) + if(BORG_HUG) + to_chat(user, "Power reset. Hugs!") + if(BORG_HUG_SUPER) + to_chat(user, "Power increased!") + if(BORG_HUG_SHOCK) + to_chat(user, "BZZT. Electrifying arms...") + if(BORG_HUG_CRUSH) + to_chat(user, "ERROR: ARM ACTUATORS OVERLOADED.") + +/obj/item/borg/cyborghug/attack(mob/living/M, mob/living/silicon/robot/user) + if(M == user) + return + switch(mode) + if(BORG_HUG) + if(M.health >= config.health_threshold_crit) + if(user.zone_sel.selecting == "head") + user.visible_message("[user] playfully boops [M] on the head!", \ + "You playfully boop [M] on the head!") + user.do_attack_animation(M) + playsound(loc, 'sound/weapons/tap.ogg', 50, 1, -1) + else if(ishuman(M)) + if(M.lying) + user.visible_message("[user] shakes [M] trying to get \him up!", \ + "You shake [M] trying to get \him up!") + else + user.visible_message("[user] hugs [M] to make \him feel better!", \ + "You hug [M] to make \him feel better!") + if(M.resting) + M.resting = FALSE + M.update_canmove() + else + user.visible_message("[user] pets [M]!", \ + "You pet [M]!") + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + if(BORG_HUG_SUPER) + if(M.health >= config.health_threshold_crit) + if(ishuman(M)) + if(M.lying) + user.visible_message("[user] shakes [M] trying to get \him up!", \ + "You shake [M] trying to get \him up!") + else if(user.zone_sel.selecting == "head") + user.visible_message("[user] bops [M] on the head!", \ + "You bop [M] on the head!") + user.do_attack_animation(M) + else + user.visible_message("[user] hugs [M] in a firm bear-hug! [M] looks uncomfortable...", \ + "You hug [M] firmly to make \him feel better! [M] looks uncomfortable...") + if(M.resting) + M.resting = FALSE + M.update_canmove() + else + user.visible_message("[user] bops [M] on the head!", \ + "You bop [M] on the head!") + playsound(loc, 'sound/weapons/tap.ogg', 50, 1, -1) + if(BORG_HUG_SHOCK) + if(!scooldown) + if(M.health >= config.health_threshold_crit) + if(ishuman(M)) + M.electrocute_act(5, "[user]", safety = 1) + user.visible_message("[user] electrocutes [M] with their touch!", \ + "You electrocute [M] with your touch!") + M.update_canmove() + else + if(!isrobot(M)) + M.adjustFireLoss(10) + user.visible_message("[user] shocks [M]!", \ + "You shock [M]!") + else + user.visible_message("[user] shocks [M]. It does not seem to have an effect", \ + "You shock [M] to no effect.") + playsound(loc, 'sound/effects/sparks2.ogg', 50, 1, -1) + user.cell.charge -= 500 + scooldown = TRUE + spawn(20) + scooldown = FALSE + if(BORG_HUG_CRUSH) + if(!ccooldown) + if(M.health >= config.health_threshold_crit) + if(ishuman(M)) + user.visible_message("[user] crushes [M] in their grip!", \ + "You crush [M] in your grip!") + else + user.visible_message("[user] crushes [M]!", \ + "You crush [M]!") + playsound(loc, 'sound/weapons/smash.ogg', 50, 1, -1) + M.adjustBruteLoss(15) + user.cell.charge -= 300 + ccooldown = TRUE + spawn(10) + ccooldown = FALSE + +#undef BORG_HUG +#undef BORG_HUG_SUPER +#undef BORG_HUG_SHOCK +#undef BORG_HUG_CRUSH + +/obj/item/borg/cyborghug/peacekeeper + shockallowed = TRUE + +/obj/item/device/harmalarm + name = "Sonic Harm Prevention Tool" + desc = "Releases a harmless blast that confuses most organics. For when the harm is JUST TOO MUCH" + icon_state = "megaphone" + var/cooldown = 0 + var/emagged = FALSE + +/obj/item/device/harmalarm/emag_act(mob/user) + emagged = !emagged + if(emagged) + to_chat(user, "You short out the safeties on the [src]!") + else + to_chat(user, "You reset the safeties on the [src]!") + +/obj/item/device/harmalarm/attack_self(mob/user) + var/safety = !emagged + if(cooldown > world.time) + to_chat(user, "The device is still recharging!") + return + + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + if(R.cell.charge < 1200) + to_chat(user, "You don't have enough charge to do this!") + return + R.cell.charge -= 1000 + if(R.emagged) + safety = FALSE + + if(safety) + user.visible_message("[user] blares out a near-deafening siren from its speakers!") + for(var/mob/living/carbon/M in get_mobs_in_view(9, user)) + if(!M.check_ear_prot()) + M.AdjustConfused(6) + to_chat(M, "The siren pierces your hearing!") + audible_message("HUMAN HARM") + playsound(get_turf(src), 'sound/AI/harmalarm.ogg', 70, 3) + cooldown = world.time + 200 + log_game("[key_name(user)] used a Cyborg Harm Alarm in ([user.x],[user.y],[user.z])") + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + if(R.connected_ai) + to_chat(R.connected_ai, " NOTICE - Peacekeeping 'HARM ALARM' used by: [user] ") + + return + + user.audible_message("BZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZT") + for(var/mob/living/carbon/human/H in get_mobs_in_view(9, user)) + if(istype(H.l_ear, /obj/item/clothing/ears/earmuffs) || istype(H.r_ear, /obj/item/clothing/ears/earmuffs) || H.ear_deaf) + continue + var/earsafety = FALSE + if(H.check_ear_prot()) + earsafety = TRUE + + if(earsafety) + H.AdjustConfused(5) + H.AdjustStuttering(10) + H.Jitter(10) + else + H.Weaken(2) + H.AdjustConfused(10) + H.AdjustStuttering(15) + H.Jitter(25) + + playsound(get_turf(src), 'sound/machines/warning-buzzer.ogg', 130, 3) + cooldown = world.time + 600 + log_game("[key_name(user)] used an emagged Cyborg Harm Alarm in ([user.x],[user.y],[user.z])") diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 3be1404a030..3ffdfaaf751 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -207,6 +207,7 @@ to_chat(user, "[H]'s [limb] is already splinted!") if(alert(user, "Would you like to remove the splint from [H]'s [limb]?", "Removing.", "Yes", "No") == "Yes") affecting.status &= ~ORGAN_SPLINTED + H.handle_splints() to_chat(user, "You remove the splint from [H]'s [limb].") return if(M == user) @@ -221,4 +222,7 @@ "You hear something being wrapped.") affecting.status |= ORGAN_SPLINTED + affecting.splinted_count = H.step_count + H.handle_splints() + use(1) diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 029cb8cd4a5..5ce0a786cab 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -258,13 +258,13 @@ var/global/list/datum/stack_recipe/cardboard_recipes = list ( * Runed Metal */ -var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \ - new/datum/stack_recipe("runed door", /obj/machinery/door/airlock/cult, 1, time = 50, one_per_turf = 1, on_floor = 1), - new/datum/stack_recipe("runed girder", /obj/structure/girder/cult, 1, time = 50, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("pylon", /obj/structure/cult/functional/pylon, 3, time = 40, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("forge", /obj/structure/cult/functional/forge, 5, time = 40, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("archives", /obj/structure/cult/functional/tome, 2, time = 40, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("altar", /obj/structure/cult/functional/talisman, 5, time = 40, one_per_turf = 1, on_floor = 1), \ +var/global/list/datum/stack_recipe/cult = list ( \ + new/datum/stack_recipe/cult("runed door", /obj/machinery/door/airlock/cult, 1, time = 50, one_per_turf = 1, on_floor = 1), + new/datum/stack_recipe/cult("runed girder", /obj/structure/girder/cult, 1, time = 50, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe/cult("pylon", /obj/structure/cult/functional/pylon, 3, time = 40, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe/cult("forge", /obj/structure/cult/functional/forge, 5, time = 40, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe/cult("archives", /obj/structure/cult/functional/tome, 2, time = 40, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe/cult("altar", /obj/structure/cult/functional/talisman, 5, time = 40, one_per_turf = 1, on_floor = 1), \ ) /obj/item/stack/sheet/runed_metal @@ -280,13 +280,27 @@ var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \ if(!iscultist(user)) to_chat(user, "Only one with forbidden knowledge could hope to work this metal...") return + if(!is_level_reachable(user.z)) + to_chat(user, "The energies of this place interfere with the metal shaping!") + return + return ..() +/datum/stack_recipe/cult + one_per_turf = 1 + on_floor = 1 + +/datum/stack_recipe/cult/post_build(obj/item/stack/S, obj/result) + if(ishuman(S.loc)) + var/mob/living/carbon/human/H = S.loc + H.bleed(5) + ..() + /obj/item/stack/sheet/runed_metal/fifty amount = 50 /obj/item/stack/sheet/runed_metal/New(var/loc, var/amount=null) - recipes = runed_metal_recipes + recipes = cult return ..() /* diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index b4bacd5326a..9f3f2f4545a 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1397,7 +1397,7 @@ obj/item/toy/cards/deck/syndicate/black is_empty = 1 playsound(src, 'sound/weapons/Gunshot.ogg', 50, 1) user.visible_message("The [src] goes off!") - M.apply_damage(200, BRUTE, "head", sharp =1, used_weapon = "Self-inflicted gunshot would to the head.") + M.apply_damage(200, BRUTE, "head", sharp =1, used_weapon = "Self-inflicted gunshot wound to the head.") M.death() else user.visible_message("[user] lowers the [src] from their head.") diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm index ddeefa002b0..639bd65dd57 100644 --- a/code/game/objects/items/weapons/RSF.dm +++ b/code/game/objects/items/weapons/RSF.dm @@ -232,3 +232,76 @@ RSF to_chat(user, "The RSF now holds [matter]/30 fabrication-units.") desc = "A RSF. It currently holds [matter]/30 fabrication-units." return + +/obj/item/weapon/cookiesynth + name = "\improper Cookie Synthesizer" + desc = "A self-recharging device used to rapidly deploy cookies." + icon = 'icons/obj/tools.dmi' + icon_state = "rcd" + var/matter = 10 + var/toxin = FALSE + var/cooldown = 0 + var/cooldowndelay = 10 + var/emagged = FALSE + w_class = WEIGHT_CLASS_NORMAL + +/obj/item/weapon/cookiesynth/examine(mob/user) + ..() + to_chat(user, "It currently holds [matter]/10 cookie-units.") + +/obj/item/weapon/cookiesynth/attackby() + return + +/obj/item/weapon/cookiesynth/emag_act(mob/user) + emagged = !emagged + if(emagged) + to_chat(user, "You short out [src]'s reagent safety checker!") + else + to_chat(user, "You reset [src]'s reagent safety checker!") + toxin = FALSE + +/obj/item/weapon/cookiesynth/attack_self(mob/user) + var/mob/living/silicon/robot/P = null + if(isrobot(user)) + P = user + if(emagged && !toxin) + toxin = TRUE + to_chat(user, "Cookie Synthesizer Hacked.") + else if(P.emagged && !toxin) + toxin = TRUE + to_chat(user, "Cookie Synthesizer Hacked.") + else + toxin = FALSE + to_chat(user, "Cookie Synthesizer Reset.") + +/obj/item/weapon/cookiesynth/process() + if(matter < 10) + matter++ + +/obj/item/weapon/cookiesynth/afterattack(atom/A, mob/user, proximity) + if(cooldown > world.time) + return + if(!proximity) + return + if(!(istype(A, /obj/structure/table) || isfloorturf(A))) + return + if(matter < 1) + to_chat(user, "[src] doesn't have enough matter left. Wait for it to recharge!") + return + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + if(!R.cell || R.cell.charge < 400) + to_chat(user, "You do not have enough power to use [src].") + return + var/turf/T = get_turf(A) + playsound(loc, 'sound/machines/click.ogg', 10, 1) + to_chat(user, "Fabricating Cookie..") + var/obj/item/weapon/reagent_containers/food/snacks/cookie/S = new /obj/item/weapon/reagent_containers/food/snacks/cookie(T) + if(toxin) + S.reagents.add_reagent("pancuronium", 2.4) + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + R.cell.charge -= 100 + else + matter-- + cooldown = world.time + cooldowndelay \ No newline at end of file diff --git a/code/game/objects/items/weapons/bee_briefcase.dm b/code/game/objects/items/weapons/bee_briefcase.dm index 229a025a18f..098fdc00549 100644 --- a/code/game/objects/items/weapons/bee_briefcase.dm +++ b/code/game/objects/items/weapons/bee_briefcase.dm @@ -62,14 +62,7 @@ else if(world.time >= next_sound) //This cooldown doesn't prevent us from releasing bees, just stops the sound next_sound = world.time + 90 - //Play sound through the station intercomms, so everyone knows the doom you have wrought. - for(var/O in global_intercoms) - var/obj/item/device/radio/intercom/I = O - if(!is_station_level(I.z)) //Only broadcast to the station intercoms - continue - if(!I.on) //Only broadcast to active intercoms (powered, switched on) - continue - playsound(I, sound_file, 35) + playsound(loc, sound_file, 35) //Release up to 5 bees per use. Without using strange reagent, that means two uses. WITH strange reagent, you can get more if you don't release the last bee for(var/bee = min(5, bees_left), bee > 0, bee--) diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 2ac5fb102e1..85e24757517 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -77,6 +77,10 @@ /obj/item/weapon/defibrillator/ui_action_click() toggle_paddles() +/obj/item/weapon/defibrillator/CtrlClick() + if(ishuman(usr) && Adjacent(usr)) + toggle_paddles() + /obj/item/weapon/defibrillator/attackby(obj/item/weapon/W, mob/user, params) if(istype(W, /obj/item/weapon/stock_parts/cell)) var/obj/item/weapon/stock_parts/cell/C = W diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 024783359b5..9601b86beec 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -15,7 +15,6 @@ materials = list(MAT_METAL=500) origin_tech = "combat=1;plasmatech=2;engineering=2" var/status = 0 - var/throw_amount = 100 var/lit = 0 //on or off var/operating = 0//cooldown var/turf/previousturf = null @@ -124,7 +123,7 @@ if(!ptank) to_chat(user, "Attach a plasma tank first!") return - var/dat = text("Flamethrower ([lit ? "Lit" : "Unlit"]) \n Tank Pressure: [ptank.air_contents.return_pressure()] \nAmount to throw: - - - [throw_amount] + + + \nRemove plasmatank - Close") + var/dat = text("Flamethrower ([lit ? "Lit" : "Unlit"]) \n Tank Pressure: [ptank.air_contents.return_pressure()] \nRemove plasmatank - Close") user << browse(dat, "window=flamethrower;size=600x300") onclose(user, "flamethrower") return @@ -143,9 +142,6 @@ lit = !lit if(lit) processing_objects.Add(src) - if(href_list["amount"]) - throw_amount = throw_amount + text2num(href_list["amount"]) - throw_amount = max(50, min(5000, throw_amount)) if(href_list["remove"]) if(!ptank) return usr.put_in_hands(ptank) @@ -191,10 +187,8 @@ /obj/item/weapon/flamethrower/proc/ignite_turf(turf/target, release_amount = 0.05) - //TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this... - //Transfer 5% of current tank air contents to turf var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount) - air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is retarded and I could probably make it work without fucking it up like this, but there you have it. -- TLE + air_transfer.toxins = air_transfer.toxins // This is me not comprehending the air system. I realize this is retarded and I could probably make it work without fucking it up like this, but there you have it. -- TLE target.assume_air(air_transfer) //Burn it based on transfered gas target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) // -- More of my "how do I shot fire?" dickery. -- TLE diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 8c723ed8b72..e60669d4f36 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -22,6 +22,8 @@ var/ignition_temp = 10 // The amount of heat added to the reagents when this grenade goes off. var/threatscale = 1 // Used by advanced grenades to make them slightly more worthy. var/no_splash = FALSE //If the grenade deletes even if it has no reagents to splash with. Used for slime core reactions. + var/contained = "" // For logging + var/cores = "" // Also for logging /obj/item/weapon/grenade/chem_grenade/New() create_reagents(1000) @@ -98,9 +100,9 @@ update_icon() else if(clown_check(user)) // This used to go before the assembly check, but that has absolutely zero to do with priming the damn thing. You could spam the admins with it. - message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP)") - log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])") - bombers += "[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])" + message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP) [contained].") + log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) [contained].") + bombers += "[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])[contained]." to_chat(user, "You prime the [name]! [det_time / 10] second\s!") playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1) active = 1 @@ -136,8 +138,8 @@ playsound(loc, prime_sound, 25, -3) stage = READY update_icon() - var/contained = "" - var/cores = "" + contained = "" + cores = "" // clear them out so no recursive logging by accidentally for(var/obj/O in beakers) if(!O.reagents) continue if(istype(O,/obj/item/slime_extract)) @@ -287,8 +289,8 @@ var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast) var/turf/T = get_turf(src) var/area/A = get_area(T) - message_admins("grenade primed by an assembly, attached by [key_name_admin(M)](?) ([admin_jump_link(M)]) and last touched by [key_name_admin(last)](?) ([admin_jump_link(last)]) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).") - log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])") + message_admins("grenade primed by an assembly, attached by [key_name_admin(M)](?) ([admin_jump_link(M)]) and last touched by [key_name_admin(last)](?) ([admin_jump_link(last)]) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP). [contained]") + log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z]) [contained]") update_mob() diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm index 968aac67272..d721aadfbed 100644 --- a/code/game/objects/items/weapons/holy_weapons.dm +++ b/code/game/objects/items/weapons/holy_weapons.dm @@ -28,7 +28,7 @@ /obj/item/weapon/nullrod/attack_self(mob/user) if(reskinned) return - if(user.mind && (user.mind.assigned_role == "Chaplain")) + if(user.mind && (user.mind.assigned_role == "Chaplain" || user.mind.special_role == SPECIAL_ROLE_ERT)) reskin_holy_weapon(user) /obj/item/weapon/nullrod/proc/reskin_holy_weapon(mob/M) @@ -335,7 +335,7 @@ /obj/item/weapon/nullrod/carp/attack_self(mob/living/user) if(used_blessing) return - if(user.mind && (user.mind.assigned_role != "Chaplain")) + if(user.mind && (user.mind.assigned_role != "Chaplain" && user.mind.special_role != SPECIAL_ROLE_ERT)) return to_chat(user, "You are blessed by Carp-Sie. Wild space carp will no longer attack you.") user.faction |= "carp" @@ -406,7 +406,7 @@ if(!iscarbon(M)) return ..() - if(!user.mind || user.mind.assigned_role != "Chaplain") + if(!user.mind || (user.mind.assigned_role != "Chaplain" && user.mind.special_role != SPECIAL_ROLE_ERT)) to_chat(user, "You are not close enough with [ticker.Bible_deity_name] to use [src].") return @@ -469,7 +469,7 @@ /obj/item/weapon/nullrod/salt/attack_self(mob/user) - if(!user.mind || user.mind.assigned_role != "Chaplain") + if(!user.mind || (user.mind.assigned_role != "Chaplain" && user.mind.special_role != SPECIAL_ROLE_ERT )) to_chat(user, "You are not close enough with [ticker.Bible_deity_name] to use [src].") return @@ -568,7 +568,8 @@ if(!target.mind) //no mind means no conversion, but also means no faith lost. to_chat(missionary, "You halt the conversion as you realize [target] is mindless! Best to save your faith for someone more worthwhile.") return - if(do_after(missionary, 40)) //4 seconds to temporarily convert, roughly 1 second faster than a vampire's enthrall ability + to_chat(target, "Your mind seems foggy. For a moment, all you can think about is serving the greater good... the greater good...") + if(do_after(missionary, 80)) //8 seconds to temporarily convert, roughly 3 seconds slower than a vamp's enthrall, but its a ranged thing if(faith < 100) //to stop people from trying to exploit the do_after system to multi-convert, we check again if you have enough faith when it completes to_chat(missionary, "You don't have enough faith to complete the conversion on [target]!") return @@ -589,14 +590,9 @@ faith -= 25 //same faith cost as losing sight of them mid-conversion, but did you just find someone who can lead you to a fellow traitor? return if(ismindshielded(target)) - if(prob(20)) //loyalty implants typically overpower this, but you CAN get lucky and convert still (20% chance of success) - faith -= 125 //yes, this puts it negative. it's gonna take longer to recharge if you manage to convert a one of these people to balance the new power you gained through them - to_chat(missionary, "Through sheer willpower, you overcome their closed mind and rally [target] to your cause! You may need a bit longer than usual before your faith is fully recharged, and they won't remain loyal to you for long ...") - convert_duration = 3000 //5 min, because the loyalty implant will attempt to counteract the subversion - else //80% chance to fail - faith -= 75 - to_chat(missionary, "Your faith is strong, but their mind remains closed to your ideals. Your resolve helps you retain a bit of faith though.") - return + faith -= 75 + to_chat(missionary, "Your faith is strong, but their mind remains closed to your ideals. Your resolve helps you retain a bit of faith though.") + return else if(target.mind.assigned_role == "Psychiatrist" || target.mind.assigned_role == "Librarian") //fancy book lernin helps counter religion (day 0 job love, what madness!) if(prob(35)) //35% chance to fail to_chat(missionary, "This one is well trained in matters of the mind... They will not be swayed as easily as you thought...") diff --git a/code/game/objects/items/weapons/implants/implant_traitor.dm b/code/game/objects/items/weapons/implants/implant_traitor.dm index 47b993b6007..5d4c88f08c3 100644 --- a/code/game/objects/items/weapons/implants/implant_traitor.dm +++ b/code/game/objects/items/weapons/implants/implant_traitor.dm @@ -76,6 +76,8 @@ log_admin("[ckey(user.key)] has mind-slaved [ckey(H.key)].") activated = 1 + if(jobban_isbanned(M, ROLE_SYNDICATE)) + ticker.mode.replace_jobbanned_player(M, ROLE_SYNDICATE) return 1 return 0 diff --git a/code/game/objects/items/weapons/paint.dm b/code/game/objects/items/weapons/paint.dm index dc5c4d048b5..03eef999c59 100644 --- a/code/game/objects/items/weapons/paint.dm +++ b/code/game/objects/items/weapons/paint.dm @@ -18,6 +18,8 @@ /obj/item/weapon/reagent_containers/glass/paint/afterattack(turf/simulated/target, mob/user, proximity) if(!proximity) return + if(!is_open_container()) + return if(istype(target) && reagents.total_volume >= 5) user.visible_message("[target] has been splashed with something by [user]!") spawn(5) diff --git a/code/game/objects/items/weapons/power_cells.dm b/code/game/objects/items/weapons/power_cells.dm index d291329f354..9758fe3d4f9 100644 --- a/code/game/objects/items/weapons/power_cells.dm +++ b/code/game/objects/items/weapons/power_cells.dm @@ -28,13 +28,14 @@ processing_objects.Remove(src) return ..() -/obj/item/weapon/stock_parts/cell/on_varedit(modified_var) - if(modified_var == "self_recharge") - if(self_recharge) - processing_objects.Add(src) - else - processing_objects.Remove(src) - ..() +/obj/item/weapon/stock_parts/cell/vv_edit_var(var_name, var_value) + switch(var_name) + if("self_recharge") + if(var_value) + processing_objects.Add(src) + else + processing_objects.Remove(src) + . = ..() /obj/item/weapon/stock_parts/cell/suicide_act(mob/user) to_chat(viewers(user), "[user] is licking the electrodes of the [src.name]! It looks like \he's trying to commit suicide.") @@ -170,6 +171,7 @@ icon_state = "yellow slime extract" materials = list() self_recharge = 1 // Infused slime cores self-recharge, over time + chargerate = 500 /obj/item/weapon/stock_parts/cell/pulse //200 pulse shots name = "pulse rifle power cell" diff --git a/code/game/objects/items/weapons/rpd.dm b/code/game/objects/items/weapons/rpd.dm index de5cb54f722..f380ae2d26e 100644 --- a/code/game/objects/items/weapons/rpd.dm +++ b/code/game/objects/items/weapons/rpd.dm @@ -39,7 +39,7 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL = 30000, MAT_GLASS = 5000) + materials = list(MAT_METAL = 75000, MAT_GLASS = 37500) origin_tech = "engineering=4;materials=2" var/datum/effect/system/spark_spread/spark_system var/lastused diff --git a/code/game/objects/items/weapons/scissors.dm b/code/game/objects/items/weapons/scissors.dm index ef49db0e449..862c39b31b4 100644 --- a/code/game/objects/items/weapons/scissors.dm +++ b/code/game/objects/items/weapons/scissors.dm @@ -58,8 +58,8 @@ //handle normal hair var/list/species_hair = list() if(C.species) - for(var/i in hair_styles_list) - var/datum/sprite_accessory/hair/tmp_hair = hair_styles_list[i] + for(var/i in hair_styles_public_list) + var/datum/sprite_accessory/hair/tmp_hair = hair_styles_public_list[i] if(C.species.name in tmp_hair.species_allowed) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human facial hair styles. if(C.species.bodyflags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. if(robohead.is_monitor) @@ -76,7 +76,7 @@ to_chat(user, "You are unable to find anything on [H]'s head worth cutting. How disappointing.") return else - species_hair = hair_styles_list + species_hair = hair_styles_public_list var/h_new_style = input(user, "Select a hair style", "Grooming") as null|anything in species_hair user.visible_message("[user] starts cutting [M]'s hair!", "You start cutting [M]'s hair!") //arguments for this are: 1. what others see 2. what the user sees. --Fixed grammar, (TGameCo) playsound(loc, 'sound/goonstation/misc/Scissor.ogg', 100, 1) diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index 4778a53c28b..a59879c8c50 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -62,8 +62,8 @@ /obj/item/weapon/tank/air name = "air tank" desc = "Mixed anyone?" - icon_state = "oxygen" - + icon_state = "air" + item_state = "air" /obj/item/weapon/tank/air/examine(mob/user) if(..(user, 0)) diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm index 5229a59fe5f..5795b04bfa3 100644 --- a/code/game/objects/items/weapons/tanks/watertank.dm +++ b/code/game/objects/items/weapons/tanks/watertank.dm @@ -277,22 +277,22 @@ if(Adj) return //Safety check so you don't blast yourself trying to refill your tank var/datum/reagents/R = reagents - if(R.total_volume < 100) - to_chat(user, "You need at least 100 units of water to use the nanofrost launcher!") + if(R.total_volume < 50) + to_chat(user, "You need at least 50 units of water to use the nanofrost launcher!") return if(nanofrost_cooldown) to_chat(user, "Nanofrost launcher is still recharging") return nanofrost_cooldown = 1 - R.remove_any(100) + R.remove_any(50) var/obj/effect/nanofrost_container/A = new /obj/effect/nanofrost_container(get_turf(src)) log_game("[user.ckey] ([user.name]) used Nanofrost at [get_area(user)] ([user.x], [user.y], [user.z]).") playsound(src,'sound/items/syringeproj.ogg',40,1) for(var/a=0, a<5, a++) step_towards(A, target) - sleep(2) + sleep(1) A.Smoke() - spawn(100) + spawn(50) if(src) nanofrost_cooldown = 0 return diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 87197426495..4526af7f98d 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -341,6 +341,7 @@ if(G) explosive = G name = "explosive lance" + embed_chance = 0 desc = "A makeshift spear with [G] attached to it. Alt+click on the spear to set your war cry!" update_icon() diff --git a/code/game/objects/items/weapons/whetstone.dm b/code/game/objects/items/weapons/whetstone.dm index c4595f2deb6..d951bca5a17 100644 --- a/code/game/objects/items/weapons/whetstone.dm +++ b/code/game/objects/items/weapons/whetstone.dm @@ -14,28 +14,28 @@ /obj/item/weapon/whetstone/attackby(obj/item/I, mob/user, params) if(used) - to_chat(user, "The whetstone is too worn to use again.") + to_chat(user, "The whetstone is too worn to use again!") return if(I.force >= max || I.throwforce >= max)//no esword sharpening - to_chat(user, "[I] is much too powerful to sharpen further.") + to_chat(user, "[I] is much too powerful to sharpen further!") return if(requires_sharpness && !I.sharp) - to_chat(user, "You can only sharpen items that are already sharp, such as knives.") + to_chat(user, "You can only sharpen items that are already sharp, such as knives!") return if(istype(I, /obj/item/weapon/twohanded))//some twohanded items should still be sharpenable, but handle force differently. therefore i need this stuff var/obj/item/weapon/twohanded/TH = I if(TH.force_wielded >= max) - to_chat(user, "[TH] is much too powerful to sharpen further.") + to_chat(user, "[TH] is much too powerful to sharpen further!") return if(TH.wielded) - to_chat(user, "[TH] must be unwielded before it can be sharpened.") + to_chat(user, "[TH] must be unwielded before it can be sharpened!") return if(TH.force_wielded > initial(TH.force_wielded)) - to_chat(user, "[TH] has already been refined before. It cannot be sharpened further.") + to_chat(user, "[TH] has already been refined before. It cannot be sharpened further!") return TH.force_wielded = Clamp(TH.force_wielded + increment, 0, max)//wieldforce is increased since normal force wont stay if(I.force > initial(I.force)) - to_chat(user, "[I] has already been refined before. It cannot be sharpened further.") + to_chat(user, "[I] has already been refined before. It cannot be sharpened further!") return user.visible_message("[user] sharpens [I] with [src]!", "You sharpen [I], making it much more deadly than before.") if(!requires_sharpness) @@ -47,6 +47,7 @@ name = "worn out [name]" desc = "[desc] At least, it used to." used = 1 + update_icon() /obj/item/weapon/whetstone/attack_self(mob/user as mob) //This is just fluff for now. Species datums are global and not newly created instances, so we can't adjust unarmed damage on a per mob basis. if(ishuman(user)) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 197b742f307..60f9538fde0 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -310,4 +310,8 @@ a { Item.fire_act() //Set them on fire, too /obj/proc/on_mob_move(dir, mob/user) - return \ No newline at end of file + return + +/obj/vv_get_dropdown() + . = ..() + .["Delete all of type"] = "?_src_=vars;delall=[UID()]" diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index d5b966c7d98..e989cea7e85 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -8,6 +8,8 @@ var/icon_opened = "open" var/opened = 0 var/welded = 0 + var/locked = 0 + var/broken = 0 var/wall_mounted = 0 //never solid (You can always pass over it) var/health = 100 var/lastbang diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm index aeb8101fc75..5baef28f262 100644 --- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm +++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm @@ -11,7 +11,7 @@ var/localopened = 0 //Setting this to keep it from behaviouring like a normal closet and obstructing movement in the map. -Agouri opened = 1 var/hitstaken = 0 - var/locked = 1 + locked = 1 var/smashed = 0 attackby(var/obj/item/O as obj, var/mob/living/user as mob) //Marker -Agouri diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm index 20a110f18d0..7a2856eb278 100644 --- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm @@ -141,4 +141,3 @@ new /obj/item/clothing/suit/storage/paramedic(src) new /obj/item/weapon/tank/emergency_oxygen/engi(src) new /obj/item/weapon/tank/emergency_oxygen/engi(src) - new /obj/item/key/ambulance(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/bar.dm b/code/game/objects/structures/crates_lockers/closets/secure/bar.dm index 49006fb7fb5..eb60d578e46 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/bar.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/bar.dm @@ -10,19 +10,18 @@ burn_state = FLAMMABLE burntime = 20 - - New() - ..() - new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) - new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) - new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) - new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) - new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) - new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) - new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) - new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) - new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) - new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) +/obj/structure/closet/secure_closet/bar/New() + ..() + new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) + new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) + new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) + new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) + new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) + new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) + new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) + new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) + new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) + new /obj/item/weapon/reagent_containers/food/drinks/cans/beer( src ) /obj/structure/closet/secure_closet/bar/update_icon() if(broken) @@ -34,4 +33,4 @@ else icon_state = icon_closed else - icon_state = icon_opened \ No newline at end of file + icon_state = icon_opened diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm index 74b811eae24..ee5ea755e04 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm @@ -8,16 +8,17 @@ icon_broken = "securecargobroken" icon_off = "securecargooff" - New() - ..() - new /obj/item/clothing/under/rank/cargotech(src) - new /obj/item/clothing/under/rank/cargotech/skirt(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/device/radio/headset/headset_cargo(src) - new /obj/item/clothing/gloves/fingerless(src) - new /obj/item/clothing/head/soft(src) +/obj/structure/closet/secure_closet/cargotech/New() + ..() + new /obj/item/clothing/under/rank/cargotech(src) + new /obj/item/clothing/under/rank/cargotech/skirt(src) + new /obj/item/clothing/shoes/black(src) + new /obj/item/device/radio/headset/headset_cargo(src) + new /obj/item/clothing/gloves/fingerless(src) + new /obj/item/clothing/head/soft(src) // new /obj/item/weapon/cartridge/quartermaster(src) + /obj/structure/closet/secure_closet/quartermaster name = "quartermaster's locker" req_access = list(access_qm) @@ -28,16 +29,16 @@ icon_broken = "secureqmbroken" icon_off = "secureqmoff" - New() - ..() - new /obj/item/clothing/under/rank/cargo(src) - new /obj/item/clothing/under/rank/cargo/skirt(src) - new /obj/item/clothing/shoes/brown(src) - new /obj/item/device/radio/headset/headset_cargo(src) - new /obj/item/clothing/gloves/fingerless(src) - new /obj/item/clothing/suit/fire/firefighter(src) - new /obj/item/weapon/tank/emergency_oxygen(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/clothing/glasses/meson(src) - new /obj/item/clothing/head/soft(src) - new /obj/item/weapon/door_remote/quartermaster(src) \ No newline at end of file +/obj/structure/closet/secure_closet/quartermaster/New() + ..() + new /obj/item/clothing/under/rank/cargo(src) + new /obj/item/clothing/under/rank/cargo/skirt(src) + new /obj/item/clothing/shoes/brown(src) + new /obj/item/device/radio/headset/headset_cargo(src) + new /obj/item/clothing/gloves/fingerless(src) + new /obj/item/clothing/suit/fire/firefighter(src) + new /obj/item/weapon/tank/emergency_oxygen(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/clothing/glasses/meson(src) + new /obj/item/clothing/head/soft(src) + new /obj/item/weapon/door_remote/quartermaster(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index 1af8b2653b8..d8b4d6906a4 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -8,33 +8,34 @@ icon_broken = "securecebroken" icon_off = "secureceoff" - New() - ..() - if(prob(50)) - new /obj/item/weapon/storage/backpack/industrial(src) - else - new /obj/item/weapon/storage/backpack/satchel_eng(src) - new /obj/item/weapon/storage/backpack/duffel/engineering(src) - new /obj/item/clothing/head/beret/ce(src) - new /obj/item/areaeditor/blueprints(src) - new /obj/item/weapon/storage/box/permits(src) - new /obj/item/clothing/under/rank/chief_engineer(src) - new /obj/item/clothing/under/rank/chief_engineer/skirt(src) - new /obj/item/clothing/head/hardhat/white(src) - new /obj/item/clothing/glasses/welding/superior(src) - new /obj/item/clothing/gloves/color/yellow(src) - new /obj/item/clothing/shoes/brown(src) - new /obj/item/weapon/cartridge/ce(src) - new /obj/item/device/radio/headset/heads/ce(src) - new /obj/item/weapon/storage/toolbox/mechanical(src) - new /obj/item/clothing/suit/storage/hazardvest(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/device/multitool(src) - new /obj/item/device/flash(src) - new /obj/item/taperoll/engineering(src) - new /obj/item/clothing/head/beret/eng(src) - new /obj/item/weapon/door_remote/chief_engineer(src) - new /obj/item/weapon/rpd(src) +/obj/structure/closet/secure_closet/engineering_chief/New() + ..() + if(prob(50)) + new /obj/item/weapon/storage/backpack/industrial(src) + else + new /obj/item/weapon/storage/backpack/satchel_eng(src) + new /obj/item/weapon/storage/backpack/duffel/engineering(src) + new /obj/item/clothing/head/beret/ce(src) + new /obj/item/areaeditor/blueprints(src) + new /obj/item/weapon/storage/box/permits(src) + new /obj/item/clothing/under/rank/chief_engineer(src) + new /obj/item/clothing/under/rank/chief_engineer/skirt(src) + new /obj/item/clothing/head/hardhat/white(src) + new /obj/item/clothing/glasses/welding/superior(src) + new /obj/item/clothing/gloves/color/yellow(src) + new /obj/item/clothing/shoes/brown(src) + new /obj/item/weapon/cartridge/ce(src) + new /obj/item/device/radio/headset/heads/ce(src) + new /obj/item/weapon/storage/toolbox/mechanical(src) + new /obj/item/clothing/suit/storage/hazardvest(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/device/multitool(src) + new /obj/item/device/flash(src) + new /obj/item/taperoll/engineering(src) + new /obj/item/clothing/head/beret/eng(src) + new /obj/item/weapon/door_remote/chief_engineer(src) + new /obj/item/weapon/rpd(src) + /obj/structure/closet/secure_closet/engineering_electrical name = "electrical supplies locker" @@ -46,22 +47,20 @@ icon_broken = "secureengelecbroken" icon_off = "secureengelecoff" - - New() - ..() - new /obj/item/clothing/gloves/color/yellow(src) - new /obj/item/clothing/gloves/color/yellow(src) - new /obj/item/weapon/storage/toolbox/electrical(src) - new /obj/item/weapon/storage/toolbox/electrical(src) - new /obj/item/weapon/storage/toolbox/electrical(src) - new /obj/item/weapon/apc_electronics(src) - new /obj/item/weapon/apc_electronics(src) - new /obj/item/weapon/apc_electronics(src) - new /obj/item/device/multitool(src) - new /obj/item/device/multitool(src) - new /obj/item/device/multitool(src) - new /obj/item/clothing/head/beret/eng - +/obj/structure/closet/secure_closet/engineering_electrical/New() + ..() + new /obj/item/clothing/gloves/color/yellow(src) + new /obj/item/clothing/gloves/color/yellow(src) + new /obj/item/weapon/storage/toolbox/electrical(src) + new /obj/item/weapon/storage/toolbox/electrical(src) + new /obj/item/weapon/storage/toolbox/electrical(src) + new /obj/item/weapon/apc_electronics(src) + new /obj/item/weapon/apc_electronics(src) + new /obj/item/weapon/apc_electronics(src) + new /obj/item/device/multitool(src) + new /obj/item/device/multitool(src) + new /obj/item/device/multitool(src) + new /obj/item/clothing/head/beret/eng /obj/structure/closet/secure_closet/engineering_welding @@ -74,16 +73,14 @@ icon_broken = "secureengweldbroken" icon_off = "secureengweldoff" - - New() - ..() - new /obj/item/clothing/head/welding(src) - new /obj/item/clothing/head/welding(src) - new /obj/item/clothing/head/welding(src) - new /obj/item/weapon/weldingtool/largetank(src) - new /obj/item/weapon/weldingtool/largetank(src) - new /obj/item/weapon/weldingtool/largetank(src) - +/obj/structure/closet/secure_closet/engineering_welding/New() + ..() + new /obj/item/clothing/head/welding(src) + new /obj/item/clothing/head/welding(src) + new /obj/item/clothing/head/welding(src) + new /obj/item/weapon/weldingtool/largetank(src) + new /obj/item/weapon/weldingtool/largetank(src) + new /obj/item/weapon/weldingtool/largetank(src) /obj/structure/closet/secure_closet/engineering_personal @@ -96,24 +93,24 @@ icon_broken = "secureengbroken" icon_off = "secureengoff" +/obj/structure/closet/secure_closet/engineering_personal/New() + ..() + if(prob(50)) + new /obj/item/weapon/storage/backpack/industrial(src) + else + new /obj/item/weapon/storage/backpack/satchel_eng(src) + new /obj/item/weapon/storage/backpack/duffel/engineering(src) + new /obj/item/weapon/storage/toolbox/mechanical(src) + new /obj/item/device/radio/headset/headset_eng(src) + new /obj/item/clothing/under/rank/engineer(src) + new /obj/item/clothing/under/rank/engineer/skirt(src) + new /obj/item/clothing/suit/storage/hazardvest(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/clothing/glasses/meson(src) + new /obj/item/weapon/cartridge/engineering(src) + new /obj/item/taperoll/engineering(src) + new /obj/item/clothing/head/beret/eng(src) - New() - ..() - if(prob(50)) - new /obj/item/weapon/storage/backpack/industrial(src) - else - new /obj/item/weapon/storage/backpack/satchel_eng(src) - new /obj/item/weapon/storage/backpack/duffel/engineering(src) - new /obj/item/weapon/storage/toolbox/mechanical(src) - new /obj/item/device/radio/headset/headset_eng(src) - new /obj/item/clothing/under/rank/engineer(src) - new /obj/item/clothing/under/rank/engineer/skirt(src) - new /obj/item/clothing/suit/storage/hazardvest(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/clothing/glasses/meson(src) - new /obj/item/weapon/cartridge/engineering(src) - new /obj/item/taperoll/engineering(src) - new /obj/item/clothing/head/beret/eng(src) /obj/structure/closet/secure_closet/atmos_personal name = "technician's locker" @@ -125,23 +122,22 @@ icon_broken = "secureatmbroken" icon_off = "secureatmoff" - - New() - ..() - new /obj/item/device/radio/headset/headset_eng(src) - new /obj/item/weapon/cartridge/atmos(src) - new /obj/item/weapon/storage/toolbox/mechanical(src) - new /obj/item/taperoll/engineering(src) - if(prob(50)) - new /obj/item/weapon/storage/backpack/industrial(src) - else - new /obj/item/weapon/storage/backpack/satchel_eng(src) - new /obj/item/weapon/storage/backpack/duffel/atmos(src) - new /obj/item/weapon/extinguisher(src) - new /obj/item/clothing/suit/storage/hazardvest(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/weapon/tank/emergency_oxygen/engi(src) - new /obj/item/weapon/watertank/atmos(src) - new /obj/item/clothing/suit/fire/atmos(src) - new /obj/item/clothing/head/hardhat/atmos(src) - new /obj/item/weapon/rpd(src) +/obj/structure/closet/secure_closet/atmos_personal/New() + ..() + new /obj/item/device/radio/headset/headset_eng(src) + new /obj/item/weapon/cartridge/atmos(src) + new /obj/item/weapon/storage/toolbox/mechanical(src) + new /obj/item/taperoll/engineering(src) + if(prob(50)) + new /obj/item/weapon/storage/backpack/industrial(src) + else + new /obj/item/weapon/storage/backpack/satchel_eng(src) + new /obj/item/weapon/storage/backpack/duffel/atmos(src) + new /obj/item/weapon/extinguisher(src) + new /obj/item/clothing/suit/storage/hazardvest(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/weapon/tank/emergency_oxygen/engi(src) + new /obj/item/weapon/watertank/atmos(src) + new /obj/item/clothing/suit/fire/atmos(src) + new /obj/item/clothing/head/hardhat/atmos(src) + new /obj/item/weapon/rpd(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm index b0e7c0e00cb..36a1241826f 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm @@ -23,6 +23,7 @@ if(!isemptylist(bombs)) // You're fucked. ..(severity) + /obj/structure/closet/secure_closet/freezer/kitchen name = "kitchen cabinet" req_access = list(access_kitchen) @@ -35,12 +36,10 @@ new /obj/item/weapon/reagent_containers/food/condiment/sugar(src) - /obj/structure/closet/secure_closet/freezer/kitchen/mining req_access = list() - /obj/structure/closet/secure_closet/freezer/meat name = "meat fridge" icon_state = "fridge1" @@ -50,12 +49,10 @@ icon_broken = "fridgebroken" icon_off = "fridge1" - - New() - ..() - for(var/i in 1 to 4) - new /obj/item/weapon/reagent_containers/food/snacks/meat/monkey(src) - +/obj/structure/closet/secure_closet/freezer/meat/New() + ..() + for(var/i in 1 to 4) + new /obj/item/weapon/reagent_containers/food/snacks/meat/monkey(src) /obj/structure/closet/secure_closet/freezer/fridge @@ -67,15 +64,13 @@ icon_broken = "fridgebroken" icon_off = "fridge1" - - New() - ..() - for(var/i in 1 to 5) - new /obj/item/weapon/reagent_containers/food/condiment/milk(src) - new /obj/item/weapon/reagent_containers/food/condiment/soymilk(src) - for(var/i in 1 to 2) - new /obj/item/weapon/storage/fancy/egg_box(src) - +/obj/structure/closet/secure_closet/freezer/fridge/New() + ..() + for(var/i in 1 to 5) + new /obj/item/weapon/reagent_containers/food/condiment/milk(src) + new /obj/item/weapon/reagent_containers/food/condiment/soymilk(src) + for(var/i in 1 to 2) + new /obj/item/weapon/storage/fancy/egg_box(src) /obj/structure/closet/secure_closet/freezer/money @@ -96,10 +91,3 @@ new /obj/item/stack/spacecash/c500(src) for(var/i in 1 to 6) new /obj/item/stack/spacecash/c200(src) - - - - - - - diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index c0603396325..9f1783381f5 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -9,20 +9,18 @@ icon_off = "medicaloff" req_access = list(access_medical) - - New() - ..() - new /obj/item/weapon/storage/box/autoinjectors(src) - new /obj/item/weapon/storage/box/syringes(src) - new /obj/item/weapon/reagent_containers/dropper(src) - new /obj/item/weapon/reagent_containers/dropper(src) - new /obj/item/weapon/reagent_containers/glass/beaker(src) - new /obj/item/weapon/reagent_containers/glass/beaker(src) - new /obj/item/weapon/reagent_containers/glass/bottle/epinephrine(src) - new /obj/item/weapon/reagent_containers/glass/bottle/epinephrine(src) - new /obj/item/weapon/reagent_containers/glass/bottle/charcoal(src) - new /obj/item/weapon/reagent_containers/glass/bottle/charcoal(src) - +/obj/structure/closet/secure_closet/medical1/New() + ..() + new /obj/item/weapon/storage/box/autoinjectors(src) + new /obj/item/weapon/storage/box/syringes(src) + new /obj/item/weapon/reagent_containers/dropper(src) + new /obj/item/weapon/reagent_containers/dropper(src) + new /obj/item/weapon/reagent_containers/glass/beaker(src) + new /obj/item/weapon/reagent_containers/glass/beaker(src) + new /obj/item/weapon/reagent_containers/glass/bottle/epinephrine(src) + new /obj/item/weapon/reagent_containers/glass/bottle/epinephrine(src) + new /obj/item/weapon/reagent_containers/glass/bottle/charcoal(src) + new /obj/item/weapon/reagent_containers/glass/bottle/charcoal(src) /obj/structure/closet/secure_closet/medical2 @@ -36,16 +34,14 @@ icon_off = "medicaloff" req_access = list(access_surgery) - - New() - ..() - new /obj/item/weapon/tank/anesthetic(src) - new /obj/item/weapon/tank/anesthetic(src) - new /obj/item/weapon/tank/anesthetic(src) - new /obj/item/clothing/mask/breath/medical(src) - new /obj/item/clothing/mask/breath/medical(src) - new /obj/item/clothing/mask/breath/medical(src) - +/obj/structure/closet/secure_closet/medical2/New() + ..() + new /obj/item/weapon/tank/anesthetic(src) + new /obj/item/weapon/tank/anesthetic(src) + new /obj/item/weapon/tank/anesthetic(src) + new /obj/item/clothing/mask/breath/medical(src) + new /obj/item/clothing/mask/breath/medical(src) + new /obj/item/clothing/mask/breath/medical(src) /obj/structure/closet/secure_closet/medical3 @@ -58,22 +54,23 @@ icon_broken = "securemedbroken" icon_off = "securemedoff" - New() - ..() - if(prob(50)) - new /obj/item/weapon/storage/backpack/medic(src) - else - new /obj/item/weapon/storage/backpack/satchel_med(src) - new /obj/item/weapon/storage/backpack/duffel/medical(src) - new /obj/item/clothing/under/rank/medical(src) - new /obj/item/clothing/suit/storage/labcoat(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/device/radio/headset/headset_med(src) - new /obj/item/clothing/gloves/color/latex/nitrile(src) - new /obj/item/weapon/defibrillator/loaded(src) - new /obj/item/weapon/storage/belt/medical(src) - new /obj/item/clothing/glasses/hud/health(src) - new /obj/item/clothing/shoes/sandal/white(src) +/obj/structure/closet/secure_closet/medical3/New() + ..() + if(prob(50)) + new /obj/item/weapon/storage/backpack/medic(src) + else + new /obj/item/weapon/storage/backpack/satchel_med(src) + new /obj/item/weapon/storage/backpack/duffel/medical(src) + new /obj/item/clothing/under/rank/medical(src) + new /obj/item/clothing/suit/storage/labcoat(src) + new /obj/item/clothing/shoes/white(src) + new /obj/item/device/radio/headset/headset_med(src) + new /obj/item/clothing/gloves/color/latex/nitrile(src) + new /obj/item/weapon/defibrillator/loaded(src) + new /obj/item/weapon/storage/belt/medical(src) + new /obj/item/clothing/glasses/hud/health(src) + new /obj/item/clothing/shoes/sandal/white(src) + //Exam Room /obj/structure/closet/secure_closet/exam @@ -87,23 +84,22 @@ icon_off = "medicaloff" req_access = list(access_medical) - - New() - ..() - new /obj/item/weapon/storage/box/syringes(src) - new /obj/item/weapon/reagent_containers/dropper(src) - new /obj/item/weapon/storage/belt/medical(src) - new /obj/item/clothing/mask/surgical(src) - new /obj/item/clothing/glasses/hud/health(src) - new /obj/item/clothing/gloves/color/latex/nitrile(src) - new /obj/item/clothing/accessory/stethoscope(src) - new /obj/item/device/flashlight/pen(src) - new /obj/item/weapon/storage/firstaid/regular(src) - new /obj/item/weapon/storage/firstaid/adv(src) - new /obj/item/weapon/storage/firstaid/brute(src) - new /obj/item/weapon/storage/firstaid/fire(src) - new /obj/item/weapon/storage/firstaid/o2(src) - new /obj/item/weapon/storage/firstaid/toxin(src) +/obj/structure/closet/secure_closet/exam/New() + ..() + new /obj/item/weapon/storage/box/syringes(src) + new /obj/item/weapon/reagent_containers/dropper(src) + new /obj/item/weapon/storage/belt/medical(src) + new /obj/item/clothing/mask/surgical(src) + new /obj/item/clothing/glasses/hud/health(src) + new /obj/item/clothing/gloves/color/latex/nitrile(src) + new /obj/item/clothing/accessory/stethoscope(src) + new /obj/item/device/flashlight/pen(src) + new /obj/item/weapon/storage/firstaid/regular(src) + new /obj/item/weapon/storage/firstaid/adv(src) + new /obj/item/weapon/storage/firstaid/brute(src) + new /obj/item/weapon/storage/firstaid/fire(src) + new /obj/item/weapon/storage/firstaid/o2(src) + new /obj/item/weapon/storage/firstaid/toxin(src) // Psychiatrist's pill bottle @@ -128,12 +124,13 @@ icon_broken = "securemedbroken" icon_off = "securemedoff" - New() - ..() - new /obj/item/clothing/suit/straight_jacket(src) - new /obj/item/weapon/reagent_containers/syringe(src) - new /obj/item/weapon/reagent_containers/glass/bottle/ether(src) - new /obj/item/weapon/storage/pill_bottle/psychiatrist(src) +/obj/structure/closet/secure_closet/psychiatrist/New() + ..() + new /obj/item/clothing/suit/straight_jacket(src) + new /obj/item/weapon/reagent_containers/syringe(src) + new /obj/item/weapon/reagent_containers/glass/bottle/ether(src) + new /obj/item/weapon/storage/pill_bottle/psychiatrist(src) + /obj/structure/closet/secure_closet/CMO name = "chief medical officer's locker" @@ -145,52 +142,49 @@ icon_broken = "cmosecurebroken" icon_off = "cmosecureoff" - New() - ..() - if(prob(50)) - new /obj/item/weapon/storage/backpack/medic(src) - else - new /obj/item/weapon/storage/backpack/satchel_med(src) - new /obj/item/weapon/storage/backpack/duffel/medical(src) - new /obj/item/clothing/suit/bio_suit/cmo(src) - new /obj/item/clothing/head/bio_hood/cmo(src) - new /obj/item/clothing/shoes/white(src) - switch(pick("blue", "green", "purple")) - if("blue") - new /obj/item/clothing/under/rank/medical/blue(src) - new /obj/item/clothing/head/surgery/blue(src) - if("green") - new /obj/item/clothing/under/rank/medical/green(src) - new /obj/item/clothing/head/surgery/green(src) - if("purple") - new /obj/item/clothing/under/rank/medical/purple(src) - new /obj/item/clothing/head/surgery/purple(src) - new /obj/item/clothing/suit/storage/labcoat/cmo(src) - new /obj/item/clothing/under/rank/chief_medical_officer(src) - new /obj/item/clothing/shoes/brown (src) - new /obj/item/device/radio/headset/heads/cmo(src) - new /obj/item/clothing/gloves/color/latex/nitrile(src) - new /obj/item/weapon/defibrillator/compact/loaded(src) - new /obj/item/weapon/storage/belt/medical(src) - new /obj/item/device/flash(src) - new /obj/item/weapon/reagent_containers/hypospray/CMO(src) - new /obj/item/organ/internal/cyberimp/eyes/hud/medical(src) - new /obj/item/weapon/door_remote/chief_medical_officer(src) - +/obj/structure/closet/secure_closet/CMO/New() + ..() + if(prob(50)) + new /obj/item/weapon/storage/backpack/medic(src) + else + new /obj/item/weapon/storage/backpack/satchel_med(src) + new /obj/item/weapon/storage/backpack/duffel/medical(src) + new /obj/item/clothing/suit/bio_suit/cmo(src) + new /obj/item/clothing/head/bio_hood/cmo(src) + new /obj/item/clothing/shoes/white(src) + switch(pick("blue", "green", "purple")) + if("blue") + new /obj/item/clothing/under/rank/medical/blue(src) + new /obj/item/clothing/head/surgery/blue(src) + if("green") + new /obj/item/clothing/under/rank/medical/green(src) + new /obj/item/clothing/head/surgery/green(src) + if("purple") + new /obj/item/clothing/under/rank/medical/purple(src) + new /obj/item/clothing/head/surgery/purple(src) + new /obj/item/clothing/suit/storage/labcoat/cmo(src) + new /obj/item/clothing/under/rank/chief_medical_officer(src) + new /obj/item/clothing/shoes/brown (src) + new /obj/item/device/radio/headset/heads/cmo(src) + new /obj/item/clothing/gloves/color/latex/nitrile(src) + new /obj/item/weapon/defibrillator/compact/loaded(src) + new /obj/item/weapon/storage/belt/medical(src) + new /obj/item/device/flash(src) + new /obj/item/weapon/reagent_containers/hypospray/CMO(src) + new /obj/item/organ/internal/cyberimp/eyes/hud/medical(src) + new /obj/item/weapon/door_remote/chief_medical_officer(src) /obj/structure/closet/secure_closet/animal name = "animal control locker" req_access = list(access_surgery) - - New() - ..() - new /obj/item/device/assembly/signaler(src) - new /obj/item/device/radio/electropack(src) - new /obj/item/device/radio/electropack(src) - new /obj/item/device/radio/electropack(src) - +/obj/structure/closet/secure_closet/animal/New() + ..() + new /obj/item/device/assembly/signaler(src) + new /obj/item/device/radio/electropack(src) + new /obj/item/device/radio/electropack(src) + new /obj/item/device/radio/electropack(src) /obj/structure/closet/secure_closet/chemical @@ -204,11 +198,11 @@ icon_off = "medicaloff" req_access = list(access_chemistry) +/obj/structure/closet/secure_closet/chemical/New() + ..() + new /obj/item/weapon/storage/box/pillbottles(src) + new /obj/item/weapon/storage/box/pillbottles(src) - New() - ..() - new /obj/item/weapon/storage/box/pillbottles(src) - new /obj/item/weapon/storage/box/pillbottles(src) /obj/structure/closet/secure_closet/medical_wall name = "first aid closet" @@ -247,13 +241,12 @@ icon_off = "medicaloff" req_access = list(access_paramedic) - - New() - ..() - new /obj/item/clothing/suit/space/eva/paramedic(src) - new /obj/item/clothing/head/helmet/space/eva/paramedic(src) - new /obj/item/clothing/head/helmet/space/eva/paramedic(src) - new /obj/item/device/sensor_device(src) +/obj/structure/closet/secure_closet/paramedic/New() + ..() + new /obj/item/clothing/suit/space/eva/paramedic(src) + new /obj/item/clothing/head/helmet/space/eva/paramedic(src) + new /obj/item/device/sensor_device(src) + new /obj/item/key/ambulance(src) /obj/structure/closet/secure_closet/reagents name = "chemical storage closet" @@ -266,12 +259,11 @@ icon_off = "chemicaloff" req_access = list(access_chemistry) - - New() - ..() - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/phenol(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/ammonia(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/oil(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/acetone(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/acid(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/diethylamine(src) +/obj/structure/closet/secure_closet/reagents/New() + ..() + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/phenol(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/ammonia(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/oil(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/acetone(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/acid(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/diethylamine(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index cfecee359d6..7e1b6d83091 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -8,21 +8,42 @@ icon_broken = "secureresbroken" icon_off = "secureresoff" - New() - ..() - new /obj/item/weapon/storage/backpack/science(src) - new /obj/item/weapon/storage/backpack/satchel_tox(src) - new /obj/item/clothing/under/rank/scientist(src) - //new /obj/item/clothing/suit/labcoat/science(src) - new /obj/item/clothing/suit/storage/labcoat/science(src) - new /obj/item/clothing/shoes/white(src) +/obj/structure/closet/secure_closet/scientist/New() + ..() + new /obj/item/weapon/storage/backpack/science(src) + new /obj/item/weapon/storage/backpack/satchel_tox(src) + new /obj/item/clothing/under/rank/scientist(src) + //new /obj/item/clothing/suit/labcoat/science(src) + new /obj/item/clothing/suit/storage/labcoat/science(src) + new /obj/item/clothing/shoes/white(src) // new /obj/item/weapon/cartridge/signal/toxins(src) - new /obj/item/device/radio/headset/headset_sci(src) - new /obj/item/weapon/tank/air(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/clothing/shoes/sandal/white(src) + new /obj/item/device/radio/headset/headset_sci(src) + new /obj/item/weapon/tank/air(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/clothing/shoes/sandal/white(src) +/obj/structure/closet/secure_closet/roboticist + name = "roboticist's locker" + req_access = list(access_robotics) + icon_state = "secureres1" + icon_closed = "secureres" + icon_locked = "secureres1" + icon_opened = "secureresopen" + icon_broken = "secureresbroken" + icon_off = "secureresoff" +/obj/structure/closet/secure_closet/roboticist/New() + ..() + new /obj/item/weapon/storage/backpack(src) + new /obj/item/weapon/storage/backpack(src) + new /obj/item/weapon/storage/backpack/satchel_norm(src) + new /obj/item/weapon/storage/backpack/satchel_norm(src) + new /obj/item/weapon/storage/backpack/duffel(src) + new /obj/item/weapon/storage/backpack/duffel(src) + new /obj/item/clothing/suit/storage/labcoat(src) + new /obj/item/clothing/suit/storage/labcoat(src) + new /obj/item/device/radio/headset/headset_sci(src) + new /obj/item/device/radio/headset/headset_sci(src) /obj/structure/closet/secure_closet/RD name = "research director's locker" @@ -34,22 +55,23 @@ icon_broken = "rdsecurebroken" icon_off = "rdsecureoff" - New() - ..() - new /obj/item/clothing/suit/bio_suit/scientist(src) - new /obj/item/clothing/head/bio_hood/scientist(src) - new /obj/item/clothing/under/rank/research_director(src) - new /obj/item/clothing/suit/storage/labcoat(src) - new /obj/item/weapon/cartridge/rd(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/gloves/color/latex(src) - new /obj/item/device/radio/headset/heads/rd(src) - new /obj/item/weapon/tank/air(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/clothing/suit/armor/reactive/teleport(src) - new /obj/item/device/flash(src) - new /obj/item/device/laser_pointer(src) - new /obj/item/weapon/door_remote/research_director(src) +/obj/structure/closet/secure_closet/RD/New() + ..() + new /obj/item/clothing/suit/bio_suit/scientist(src) + new /obj/item/clothing/head/bio_hood/scientist(src) + new /obj/item/clothing/under/rank/research_director(src) + new /obj/item/clothing/suit/storage/labcoat(src) + new /obj/item/weapon/cartridge/rd(src) + new /obj/item/clothing/shoes/white(src) + new /obj/item/clothing/gloves/color/latex(src) + new /obj/item/device/radio/headset/heads/rd(src) + new /obj/item/weapon/tank/air(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/clothing/suit/armor/reactive/teleport(src) + new /obj/item/device/flash(src) + new /obj/item/device/laser_pointer(src) + new /obj/item/weapon/door_remote/research_director(src) + /obj/structure/closet/secure_closet/research_reagents name = "research chemical storage closet" @@ -62,20 +84,19 @@ icon_off = "rchemicaloff" req_access = list(access_tox_storage) - - New() - ..() - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/morphine(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/morphine(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/morphine(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/morphine(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/insulin(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/insulin(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/insulin(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/insulin(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/phenol(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/ammonia(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/oil(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/acetone(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/acid(src) - new /obj/item/weapon/reagent_containers/glass/bottle/reagent/diethylamine(src) \ No newline at end of file +/obj/structure/closet/secure_closet/research_reagents/New() + ..() + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/morphine(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/morphine(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/morphine(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/morphine(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/insulin(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/insulin(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/insulin(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/insulin(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/phenol(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/ammonia(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/oil(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/acetone(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/acid(src) + new /obj/item/weapon/reagent_containers/glass/bottle/reagent/diethylamine(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index 19dc1622ffe..72ef10a5cde 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -5,8 +5,8 @@ icon_state = "secure1" density = 1 opened = 0 - var/locked = 1 - var/broken = 0 + locked = 1 + broken = 0 var/large = 1 icon_closed = "secure" var/icon_locked = "secure1" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index ed2599e91dd..38a8fe42377 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -8,30 +8,29 @@ icon_broken = "capsecurebroken" icon_off = "capsecureoff" - New() - ..() - if(prob(50)) - new /obj/item/weapon/storage/backpack/captain(src) - else - new /obj/item/weapon/storage/backpack/satchel_cap(src) - new /obj/item/weapon/book/manual/faxes(src) - new /obj/item/weapon/storage/backpack/duffel/captain(src) - new /obj/item/clothing/suit/captunic(src) - new /obj/item/clothing/suit/captunic/capjacket(src) - new /obj/item/clothing/under/captainparade(src) - new /obj/item/clothing/head/caphat/parade(src) - new /obj/item/clothing/under/rank/captain(src) - new /obj/item/clothing/under/dress/dress_cap(src) - new /obj/item/clothing/suit/armor/vest/capcarapace/alt(src) - new /obj/item/weapon/cartridge/captain(src) - new /obj/item/clothing/shoes/brown(src) - new /obj/item/clothing/shoes/laceup(src) - new /obj/item/device/radio/headset/heads/captain/alt(src) - new /obj/item/clothing/gloves/color/captain(src) - new /obj/item/weapon/storage/belt/rapier(src) - new /obj/item/weapon/gun/energy/gun(src) - new /obj/item/weapon/door_remote/captain(src) - +/obj/structure/closet/secure_closet/captains/New() + ..() + if(prob(50)) + new /obj/item/weapon/storage/backpack/captain(src) + else + new /obj/item/weapon/storage/backpack/satchel_cap(src) + new /obj/item/weapon/book/manual/faxes(src) + new /obj/item/weapon/storage/backpack/duffel/captain(src) + new /obj/item/clothing/suit/captunic(src) + new /obj/item/clothing/suit/captunic/capjacket(src) + new /obj/item/clothing/under/captainparade(src) + new /obj/item/clothing/head/caphat/parade(src) + new /obj/item/clothing/under/rank/captain(src) + new /obj/item/clothing/under/dress/dress_cap(src) + new /obj/item/clothing/suit/armor/vest/capcarapace/alt(src) + new /obj/item/weapon/cartridge/captain(src) + new /obj/item/clothing/shoes/brown(src) + new /obj/item/clothing/shoes/laceup(src) + new /obj/item/device/radio/headset/heads/captain/alt(src) + new /obj/item/clothing/gloves/color/captain(src) + new /obj/item/weapon/storage/belt/rapier(src) + new /obj/item/weapon/gun/energy/gun(src) + new /obj/item/weapon/door_remote/captain(src) /obj/structure/closet/secure_closet/hop @@ -44,19 +43,20 @@ icon_broken = "hopsecurebroken" icon_off = "hopsecureoff" - New() - ..() - new /obj/item/clothing/glasses/sunglasses(src) - new /obj/item/clothing/head/hopcap(src) - new /obj/item/weapon/cartridge/hop(src) - new /obj/item/device/radio/headset/heads/hop(src) - new /obj/item/weapon/storage/box/ids(src) - new /obj/item/weapon/storage/box/PDAs(src) - new /obj/item/clothing/suit/armor/vest(src) - new /obj/item/weapon/gun/energy/gun(src) - new /obj/item/device/flash(src) - new /obj/item/clothing/accessory/petcollar(src) - new /obj/item/weapon/door_remote/civillian(src) +/obj/structure/closet/secure_closet/hop/New() + ..() + new /obj/item/clothing/glasses/sunglasses(src) + new /obj/item/clothing/head/hopcap(src) + new /obj/item/weapon/cartridge/hop(src) + new /obj/item/device/radio/headset/heads/hop(src) + new /obj/item/weapon/storage/box/ids(src) + new /obj/item/weapon/storage/box/PDAs(src) + new /obj/item/clothing/suit/armor/vest(src) + new /obj/item/weapon/gun/energy/gun(src) + new /obj/item/device/flash(src) + new /obj/item/clothing/accessory/petcollar(src) + new /obj/item/weapon/door_remote/civillian(src) + /obj/structure/closet/secure_closet/hop2 name = "head of personnel's attire" @@ -68,21 +68,20 @@ icon_broken = "hopsecurebroken" icon_off = "hopsecureoff" - New() - ..() - new /obj/item/clothing/under/rank/head_of_personnel(src) - new /obj/item/clothing/under/dress/dress_hop(src) - new /obj/item/clothing/under/dress/dress_hr(src) - new /obj/item/clothing/under/lawyer/female(src) - new /obj/item/clothing/under/lawyer/black(src) - new /obj/item/clothing/under/lawyer/red(src) - new /obj/item/clothing/under/lawyer/oldman(src) - new /obj/item/clothing/shoes/brown(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/leather(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/under/rank/head_of_personnel_whimsy(src) - +/obj/structure/closet/secure_closet/hop2/New() + ..() + new /obj/item/clothing/under/rank/head_of_personnel(src) + new /obj/item/clothing/under/dress/dress_hop(src) + new /obj/item/clothing/under/dress/dress_hr(src) + new /obj/item/clothing/under/lawyer/female(src) + new /obj/item/clothing/under/lawyer/black(src) + new /obj/item/clothing/under/lawyer/red(src) + new /obj/item/clothing/under/lawyer/oldman(src) + new /obj/item/clothing/shoes/brown(src) + new /obj/item/clothing/shoes/black(src) + new /obj/item/clothing/shoes/leather(src) + new /obj/item/clothing/shoes/white(src) + new /obj/item/clothing/under/rank/head_of_personnel_whimsy(src) /obj/structure/closet/secure_closet/hos @@ -95,33 +94,32 @@ icon_broken = "hossecurebroken" icon_off = "hossecureoff" - New() - ..() - if(prob(50)) - new /obj/item/weapon/storage/backpack/security(src) - else - new /obj/item/weapon/storage/backpack/satchel_sec(src) - new /obj/item/weapon/cartridge/hos(src) - new /obj/item/device/radio/headset/heads/hos/alt(src) - new /obj/item/clothing/under/rank/head_of_security(src) - new /obj/item/clothing/under/rank/head_of_security/formal(src) - new /obj/item/clothing/under/rank/head_of_security/corp(src) - new /obj/item/clothing/under/rank/head_of_security/skirt(src) - new /obj/item/clothing/suit/armor/hos(src) - new /obj/item/clothing/suit/armor/hos/alt(src) - new /obj/item/clothing/head/HoS(src) - new /obj/item/clothing/head/HoS/beret(src) - new /obj/item/clothing/glasses/hud/security/sunglasses(src) - new /obj/item/weapon/storage/lockbox/mindshield(src) - new /obj/item/weapon/storage/box/flashbangs(src) - new /obj/item/clothing/mask/gas/sechailer/hos(src) - new /obj/item/weapon/shield/riot/tele(src) - new /obj/item/weapon/melee/baton/loaded(src) - new /obj/item/weapon/storage/belt/security/sec(src) - new /obj/item/taperoll/police(src) - new /obj/item/weapon/gun/energy/gun/hos(src) - new /obj/item/weapon/door_remote/head_of_security(src) - +/obj/structure/closet/secure_closet/hos/New() + ..() + if(prob(50)) + new /obj/item/weapon/storage/backpack/security(src) + else + new /obj/item/weapon/storage/backpack/satchel_sec(src) + new /obj/item/weapon/cartridge/hos(src) + new /obj/item/device/radio/headset/heads/hos/alt(src) + new /obj/item/clothing/under/rank/head_of_security(src) + new /obj/item/clothing/under/rank/head_of_security/formal(src) + new /obj/item/clothing/under/rank/head_of_security/corp(src) + new /obj/item/clothing/under/rank/head_of_security/skirt(src) + new /obj/item/clothing/suit/armor/hos(src) + new /obj/item/clothing/suit/armor/hos/alt(src) + new /obj/item/clothing/head/HoS(src) + new /obj/item/clothing/head/HoS/beret(src) + new /obj/item/clothing/glasses/hud/security/sunglasses(src) + new /obj/item/weapon/storage/lockbox/mindshield(src) + new /obj/item/weapon/storage/box/flashbangs(src) + new /obj/item/clothing/mask/gas/sechailer/hos(src) + new /obj/item/weapon/shield/riot/tele(src) + new /obj/item/weapon/melee/baton/loaded(src) + new /obj/item/weapon/storage/belt/security/sec(src) + new /obj/item/taperoll/police(src) + new /obj/item/weapon/gun/energy/gun/hos(src) + new /obj/item/weapon/door_remote/head_of_security(src) /obj/structure/closet/secure_closet/warden @@ -134,34 +132,32 @@ icon_broken = "wardensecurebroken" icon_off = "wardensecureoff" - - New() - ..() - if(prob(50)) - new /obj/item/weapon/storage/backpack/security(src) - else - new /obj/item/weapon/storage/backpack/satchel_sec(src) - new /obj/item/device/radio/headset/headset_sec/alt(src) - new /obj/item/clothing/suit/armor/vest/warden(src) - new /obj/item/clothing/head/warden(src) - new /obj/item/clothing/suit/armor/vest/warden/alt(src) - new /obj/item/clothing/head/beret/sec/warden(src) - new /obj/item/clothing/under/rank/warden(src) - new /obj/item/clothing/under/rank/warden/formal(src) - new /obj/item/clothing/under/rank/warden/corp(src) - new /obj/item/clothing/under/rank/warden/skirt(src) - new /obj/item/clothing/glasses/hud/security/sunglasses(src) - new /obj/item/clothing/mask/gas/sechailer/warden(src) - new /obj/item/taperoll/police(src) - new /obj/item/weapon/storage/box/zipties(src) - new /obj/item/weapon/storage/box/flashbangs(src) - new /obj/item/weapon/reagent_containers/spray/pepper(src) - new /obj/item/weapon/melee/baton/loaded(src) - new /obj/item/weapon/gun/energy/gun/advtaser(src) - new /obj/item/weapon/storage/belt/security/sec(src) - new /obj/item/weapon/storage/box/holobadge(src) - new /obj/item/clothing/gloves/color/black/krav_maga/sec(src) - +/obj/structure/closet/secure_closet/warden/New() + ..() + if(prob(50)) + new /obj/item/weapon/storage/backpack/security(src) + else + new /obj/item/weapon/storage/backpack/satchel_sec(src) + new /obj/item/device/radio/headset/headset_sec/alt(src) + new /obj/item/clothing/suit/armor/vest/warden(src) + new /obj/item/clothing/head/warden(src) + new /obj/item/clothing/suit/armor/vest/warden/alt(src) + new /obj/item/clothing/head/beret/sec/warden(src) + new /obj/item/clothing/under/rank/warden(src) + new /obj/item/clothing/under/rank/warden/formal(src) + new /obj/item/clothing/under/rank/warden/corp(src) + new /obj/item/clothing/under/rank/warden/skirt(src) + new /obj/item/clothing/glasses/hud/security/sunglasses(src) + new /obj/item/clothing/mask/gas/sechailer/warden(src) + new /obj/item/taperoll/police(src) + new /obj/item/weapon/storage/box/zipties(src) + new /obj/item/weapon/storage/box/flashbangs(src) + new /obj/item/weapon/reagent_containers/spray/pepper(src) + new /obj/item/weapon/melee/baton/loaded(src) + new /obj/item/weapon/gun/energy/gun/advtaser(src) + new /obj/item/weapon/storage/belt/security/sec(src) + new /obj/item/weapon/storage/box/holobadge(src) + new /obj/item/clothing/gloves/color/black/krav_maga/sec(src) /obj/structure/closet/secure_closet/security @@ -174,24 +170,25 @@ icon_broken = "secbroken" icon_off = "secoff" - New() - ..() - if(prob(50)) - new /obj/item/weapon/storage/backpack/security(src) - else - new /obj/item/weapon/storage/backpack/satchel_sec(src) - new /obj/item/clothing/suit/armor/vest/security(src) - new /obj/item/device/radio/headset/headset_sec/alt(src) - new /obj/item/clothing/head/soft/sec(src) - new /obj/item/weapon/reagent_containers/spray/pepper(src) - new /obj/item/device/flash(src) - new /obj/item/weapon/grenade/flashbang(src) - new /obj/item/weapon/storage/belt/security/sec(src) - new /obj/item/clothing/mask/gas/sechailer(src) - new /obj/item/clothing/glasses/hud/security/sunglasses(src) - new /obj/item/clothing/head/helmet(src) - new /obj/item/weapon/melee/baton/loaded(src) - new /obj/item/taperoll/police(src) +/obj/structure/closet/secure_closet/security/New() + ..() + if(prob(50)) + new /obj/item/weapon/storage/backpack/security(src) + else + new /obj/item/weapon/storage/backpack/satchel_sec(src) + new /obj/item/clothing/suit/armor/vest/security(src) + new /obj/item/device/radio/headset/headset_sec/alt(src) + new /obj/item/clothing/head/soft/sec(src) + new /obj/item/weapon/reagent_containers/spray/pepper(src) + new /obj/item/device/flash(src) + new /obj/item/weapon/grenade/flashbang(src) + new /obj/item/weapon/storage/belt/security/sec(src) + new /obj/item/clothing/mask/gas/sechailer(src) + new /obj/item/clothing/glasses/hud/security/sunglasses(src) + new /obj/item/clothing/head/helmet(src) + new /obj/item/weapon/melee/baton/loaded(src) + new /obj/item/taperoll/police(src) + /obj/structure/closet/secure_closet/brigdoc name = "brig physician's locker" @@ -203,24 +200,25 @@ icon_broken = "securemedbroken" icon_off = "securemedoff" - New() - ..() - if(prob(50)) - new /obj/item/weapon/storage/backpack/medic(src) - else - new /obj/item/weapon/storage/backpack/satchel_med(src) - new /obj/item/weapon/reagent_containers/spray/pepper(src) - new /obj/item/device/flash(src) - new /obj/item/weapon/storage/firstaid/regular(src) - new /obj/item/weapon/storage/firstaid/fire(src) - new /obj/item/weapon/storage/firstaid/adv(src) - new /obj/item/weapon/storage/firstaid/o2(src) - new /obj/item/weapon/storage/firstaid/toxin(src) - new /obj/item/clothing/suit/storage/brigdoc(src) - new /obj/item/clothing/under/rank/security/brigphys(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/device/radio/headset/headset_sec/alt(src) - new /obj/item/clothing/shoes/sandal/white(src) +/obj/structure/closet/secure_closet/brigdoc/New() + ..() + if(prob(50)) + new /obj/item/weapon/storage/backpack/medic(src) + else + new /obj/item/weapon/storage/backpack/satchel_med(src) + new /obj/item/weapon/reagent_containers/spray/pepper(src) + new /obj/item/device/flash(src) + new /obj/item/weapon/storage/firstaid/regular(src) + new /obj/item/weapon/storage/firstaid/fire(src) + new /obj/item/weapon/storage/firstaid/adv(src) + new /obj/item/weapon/storage/firstaid/o2(src) + new /obj/item/weapon/storage/firstaid/toxin(src) + new /obj/item/clothing/suit/storage/brigdoc(src) + new /obj/item/clothing/under/rank/security/brigphys(src) + new /obj/item/clothing/shoes/white(src) + new /obj/item/device/radio/headset/headset_sec/alt(src) + new /obj/item/clothing/shoes/sandal/white(src) + /obj/structure/closet/secure_closet/blueshield name = "blueshield's locker" @@ -232,25 +230,26 @@ icon_broken = "bssecurebroken" icon_off = "bssecureoff" - New() - ..() - new /obj/item/weapon/storage/briefcase(src) - new /obj/item/weapon/storage/firstaid/adv(src) - new /obj/item/weapon/storage/belt/security/sec(src) - new /obj/item/weapon/grenade/flashbang(src) - new /obj/item/device/flash(src) - new /obj/item/weapon/restraints/handcuffs(src) - new /obj/item/weapon/melee/baton/loaded(src) - new /obj/item/clothing/glasses/sunglasses(src) - new /obj/item/clothing/glasses/hud/health/health_advanced - new /obj/item/clothing/head/beret/centcom/officer(src) - new /obj/item/clothing/head/beret/centcom/officer/navy(src) - new /obj/item/clothing/suit/armor/vest/blueshield(src) - new /obj/item/clothing/suit/storage/blueshield(src) - new /obj/item/clothing/shoes/centcom(src) - new /obj/item/clothing/accessory/holster(src) - new /obj/item/clothing/accessory/blue(src) - new /obj/item/clothing/shoes/jackboots/jacksandals(src) +/obj/structure/closet/secure_closet/blueshield/New() + ..() + new /obj/item/weapon/storage/briefcase(src) + new /obj/item/weapon/storage/firstaid/adv(src) + new /obj/item/weapon/storage/belt/security/sec(src) + new /obj/item/weapon/grenade/flashbang(src) + new /obj/item/device/flash(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/melee/baton/loaded(src) + new /obj/item/clothing/glasses/sunglasses(src) + new /obj/item/clothing/glasses/hud/health/health_advanced + new /obj/item/clothing/head/beret/centcom/officer(src) + new /obj/item/clothing/head/beret/centcom/officer/navy(src) + new /obj/item/clothing/suit/armor/vest/blueshield(src) + new /obj/item/clothing/suit/storage/blueshield(src) + new /obj/item/clothing/shoes/centcom(src) + new /obj/item/clothing/accessory/holster(src) + new /obj/item/clothing/accessory/blue(src) + new /obj/item/clothing/shoes/jackboots/jacksandals(src) + /obj/structure/closet/secure_closet/ntrep name = "\improper Nanotrasen Representative's locker" @@ -262,51 +261,54 @@ icon_broken = "ntsecurebroken" icon_off = "ntsecureoff" - New() - ..() - new /obj/item/weapon/book/manual/faxes(src) - new /obj/item/weapon/storage/briefcase(src) - new /obj/item/device/paicard(src) - new /obj/item/device/flash(src) - new /obj/item/clothing/glasses/sunglasses(src) - new /obj/item/clothing/gloves/color/white(src) - new /obj/item/clothing/shoes/centcom(src) - new /obj/item/clothing/under/lawyer/oldman(src) - new /obj/item/clothing/under/lawyer/black(src) - new /obj/item/clothing/under/lawyer/female(src) - new /obj/item/clothing/head/ntrep(src) - new /obj/item/clothing/shoes/sandal/fancy(src) - new /obj/item/weapon/storage/box/tapes(src) - new /obj/item/device/taperecorder(src) +/obj/structure/closet/secure_closet/ntrep/New() + ..() + new /obj/item/weapon/book/manual/faxes(src) + new /obj/item/weapon/storage/briefcase(src) + new /obj/item/device/paicard(src) + new /obj/item/device/flash(src) + new /obj/item/clothing/glasses/sunglasses(src) + new /obj/item/clothing/gloves/color/white(src) + new /obj/item/clothing/shoes/centcom(src) + new /obj/item/clothing/under/lawyer/oldman(src) + new /obj/item/clothing/under/lawyer/black(src) + new /obj/item/clothing/under/lawyer/female(src) + new /obj/item/clothing/head/ntrep(src) + new /obj/item/clothing/shoes/sandal/fancy(src) + new /obj/item/weapon/storage/box/tapes(src) + new /obj/item/device/taperecorder(src) /obj/structure/closet/secure_closet/security/cargo - New() - ..() - new /obj/item/clothing/accessory/armband/cargo(src) - new /obj/item/device/encryptionkey/headset_cargo(src) +/obj/structure/closet/secure_closet/security/cargo/New() + ..() + new /obj/item/clothing/accessory/armband/cargo(src) + new /obj/item/device/encryptionkey/headset_cargo(src) + /obj/structure/closet/secure_closet/security/engine - New() - ..() - new /obj/item/clothing/accessory/armband/engine(src) - new /obj/item/device/encryptionkey/headset_eng(src) +/obj/structure/closet/secure_closet/security/engine/New() + ..() + new /obj/item/clothing/accessory/armband/engine(src) + new /obj/item/device/encryptionkey/headset_eng(src) + /obj/structure/closet/secure_closet/security/science - New() - ..() - new /obj/item/clothing/accessory/armband/science(src) - new /obj/item/device/encryptionkey/headset_sci(src) +/obj/structure/closet/secure_closet/security/science/New() + ..() + new /obj/item/clothing/accessory/armband/science(src) + new /obj/item/device/encryptionkey/headset_sci(src) + /obj/structure/closet/secure_closet/security/med - New() - ..() - new /obj/item/clothing/accessory/armband/medgreen(src) - new /obj/item/device/encryptionkey/headset_med(src) +/obj/structure/closet/secure_closet/security/med/New() + ..() + new /obj/item/clothing/accessory/armband/medgreen(src) + new /obj/item/device/encryptionkey/headset_med(src) /obj/structure/closet/secure_closet/detective @@ -321,28 +323,28 @@ burn_state = FLAMMABLE burntime = 20 - New() - ..() - new /obj/item/clothing/under/det(src) - new /obj/item/clothing/suit/storage/det_suit(src) - new /obj/item/clothing/suit/storage/det_suit/forensics/blue(src) - new /obj/item/clothing/suit/storage/det_suit/forensics/red(src) - new /obj/item/clothing/gloves/color/black/forensics(src) - new /obj/item/clothing/head/det_hat(src) - new /obj/item/clothing/shoes/brown(src) - new /obj/item/weapon/storage/box/evidence(src) - new /obj/item/weapon/clipboard(src) - new /obj/item/device/radio/headset/headset_sec/alt(src) - new /obj/item/device/detective_scanner(src) - new /obj/item/clothing/suit/armor/vest/det_suit(src) - new /obj/item/ammo_box/c38(src) - new /obj/item/ammo_box/c38(src) - new /obj/item/weapon/gun/projectile/revolver/detective(src) - new /obj/item/taperoll/police(src) - new /obj/item/clothing/accessory/holster/armpit(src) - new /obj/item/clothing/glasses/sunglasses/yeah(src) - new /obj/item/device/flashlight/seclite(src) - new /obj/item/clothing/accessory/black(src) +/obj/structure/closet/secure_closet/detective/New() + ..() + new /obj/item/clothing/under/det(src) + new /obj/item/clothing/suit/storage/det_suit(src) + new /obj/item/clothing/suit/storage/det_suit/forensics/blue(src) + new /obj/item/clothing/suit/storage/det_suit/forensics/red(src) + new /obj/item/clothing/gloves/color/black/forensics(src) + new /obj/item/clothing/head/det_hat(src) + new /obj/item/clothing/shoes/brown(src) + new /obj/item/weapon/storage/box/evidence(src) + new /obj/item/weapon/clipboard(src) + new /obj/item/device/radio/headset/headset_sec/alt(src) + new /obj/item/device/detective_scanner(src) + new /obj/item/clothing/suit/armor/vest/det_suit(src) + new /obj/item/ammo_box/c38(src) + new /obj/item/ammo_box/c38(src) + new /obj/item/weapon/gun/projectile/revolver/detective(src) + new /obj/item/taperoll/police(src) + new /obj/item/clothing/accessory/holster/armpit(src) + new /obj/item/clothing/glasses/sunglasses/yeah(src) + new /obj/item/device/flashlight/seclite(src) + new /obj/item/clothing/accessory/black(src) /obj/structure/closet/secure_closet/detective/update_icon() if(broken) @@ -356,16 +358,15 @@ else icon_state = icon_opened + /obj/structure/closet/secure_closet/injection name = "lethal injections locker" req_access = list(access_security) - - New() - ..() - new /obj/item/weapon/reagent_containers/ld50_syringe/lethal(src) - new /obj/item/weapon/reagent_containers/ld50_syringe/lethal(src) - +/obj/structure/closet/secure_closet/injection/New() + ..() + new /obj/item/weapon/reagent_containers/ld50_syringe/lethal(src) + new /obj/item/weapon/reagent_containers/ld50_syringe/lethal(src) /obj/structure/closet/secure_closet/brig @@ -374,29 +375,29 @@ anchored = 1 var/id = null - New() - ..() - new /obj/item/clothing/under/color/orange/prison(src) - new /obj/item/clothing/shoes/orange(src) - new /obj/item/weapon/card/id/prisoner/random(src) - new /obj/item/device/radio/headset(src) - +/obj/structure/closet/secure_closet/brig/New() + ..() + new /obj/item/clothing/under/color/orange/prison(src) + new /obj/item/clothing/shoes/orange(src) + new /obj/item/weapon/card/id/prisoner/random(src) + new /obj/item/device/radio/headset(src) /obj/structure/closet/secure_closet/courtroom name = "courtroom locker" req_access = list(access_court) - New() - ..() - new /obj/item/clothing/shoes/brown(src) - new /obj/item/weapon/paper/Court (src) - new /obj/item/weapon/paper/Court (src) - new /obj/item/weapon/paper/Court (src) - new /obj/item/weapon/pen (src) - new /obj/item/clothing/suit/judgerobe (src) - new /obj/item/clothing/head/powdered_wig (src) - new /obj/item/weapon/storage/briefcase(src) +/obj/structure/closet/secure_closet/courtroom/New() + ..() + new /obj/item/clothing/shoes/brown(src) + new /obj/item/weapon/paper/Court (src) + new /obj/item/weapon/paper/Court (src) + new /obj/item/weapon/paper/Court (src) + new /obj/item/weapon/pen (src) + new /obj/item/clothing/suit/judgerobe (src) + new /obj/item/clothing/head/powdered_wig (src) + new /obj/item/weapon/storage/briefcase(src) + /obj/structure/closet/secure_closet/wall name = "wall locker" diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index 26bd0d88759..5b26b46eacd 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -27,6 +27,7 @@ new /obj/item/clothing/mask/gas/syndicate(src) new /obj/item/clothing/suit/space/hardsuit/syndi(src) new /obj/item/weapon/tank/jetpack/oxygen/harness(src) + new /obj/item/clothing/shoes/magboots/syndie(src) /obj/structure/closet/syndicate/nuclear desc = "It's a storage unit for a Syndicate boarding party.." diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index a3f716a4a8b..0b9554a4cc4 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -310,14 +310,10 @@ /obj/structure/closet/wardrobe/robotics_black/New() ..() - new /obj/item/clothing/glasses/hud/diagnostic(src) - new /obj/item/clothing/glasses/hud/diagnostic(src) new /obj/item/clothing/under/rank/roboticist(src) new /obj/item/clothing/under/rank/roboticist(src) new /obj/item/clothing/under/rank/roboticist/skirt(src) new /obj/item/clothing/under/rank/roboticist/skirt(src) - new /obj/item/clothing/suit/storage/labcoat(src) - new /obj/item/clothing/suit/storage/labcoat(src) new /obj/item/clothing/shoes/black(src) new /obj/item/clothing/shoes/black(src) new /obj/item/clothing/gloves/fingerless(src) @@ -464,3 +460,20 @@ new /obj/item/clothing/shoes/orange(src) new /obj/item/clothing/shoes/purple(src) new /obj/item/clothing/shoes/leather(src) + +/obj/structure/closet/wardrobe/coroner + name = "coroner wardrobe" + icon_state = "black" + icon_closed = "black" + +/obj/structure/closet/wardrobe/coroner/New() + ..() + if(prob(50)) + new /obj/item/weapon/storage/backpack/medic(src) + else + new /obj/item/weapon/storage/backpack/satchel_med(src) + new /obj/item/weapon/storage/backpack/duffel/medical(src) + new /obj/item/clothing/suit/storage/labcoat/mortician(src) + new /obj/item/clothing/shoes/white(src) + new /obj/item/clothing/under/rank/medical/mortician(src) + new /obj/item/clothing/head/surgery/black(src) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 8fdaf4804b3..043fdf2f9c4 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -44,8 +44,10 @@ return 2 playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3) - for(var/obj/O in src) - O.forceMove(loc) + for(var/obj/O in src) //Objects + O.forceMove(loc) + for(var/mob/M in src) //Mobs + M.forceMove(loc) icon_state = icon_opened src.opened = 1 @@ -240,8 +242,8 @@ var/greenlight = "securecrateg" var/sparks = "securecratesparks" var/emag = "securecrateemag" - var/broken = 0 - var/locked = 1 + broken = 0 + locked = 1 health = 1000 /obj/structure/closet/crate/secure/update_icon() @@ -441,9 +443,9 @@ anchored = TRUE /obj/structure/closet/crate/can/attackby(obj/item/weapon/W, mob/living/user, params) - add_fingerprint(user) - user.changeNext_move(CLICK_CD_MELEE) if(iswrench(W)) + add_fingerprint(user) + user.changeNext_move(CLICK_CD_MELEE) if(anchored) playsound(loc, W.usesound, 100, 1) user.visible_message("[user] starts loosening [src]'s floor casters.", \ @@ -467,6 +469,8 @@ user.visible_message("[user] has secured [src]'s floor casters.", \ "You have secured [src]'s floor casters.") anchored = TRUE + else + ..() /obj/structure/closet/crate/radiation desc = "A crate with a radiation sign on it." diff --git a/code/game/objects/structures/crates_lockers/walllocker.dm b/code/game/objects/structures/crates_lockers/walllocker.dm index 25a41a8dde7..ec736d4b04a 100644 --- a/code/game/objects/structures/crates_lockers/walllocker.dm +++ b/code/game/objects/structures/crates_lockers/walllocker.dm @@ -17,6 +17,10 @@ //spawns endless (3 sets) amounts of breathmask, emergency oxy tank and crowbar +/obj/structure/closet/walllocker/CtrlClick() + if(ishuman(usr) && Adjacent(usr)) + verb_toggleopen() + /obj/structure/closet/walllocker/emerglocker name = "emergency locker" desc = "A wall mounted locker with emergency supplies" diff --git a/code/game/objects/structures/fullwindow.dm b/code/game/objects/structures/fullwindow.dm index 48b2268d8cc..b0c1f2c512c 100644 --- a/code/game/objects/structures/fullwindow.dm +++ b/code/game/objects/structures/fullwindow.dm @@ -46,6 +46,10 @@ glasstype = /obj/item/stack/sheet/plasmaglass health = 120 +/obj/structure/window/full/plasmabasic/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature > T0C + 32000) + hit(round(exposed_volume / 1000), 0) + ..() /obj/structure/window/full/plasmareinforced name = "reinforced plasma window" @@ -57,6 +61,8 @@ reinf = 1 health = 160 +/obj/structure/window/full/plasmareinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + return /obj/structure/window/full/reinforced name = "reinforced window" diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 83220bb6a33..4dcccb2145d 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -9,8 +9,22 @@ var/shattered = 0 var/list/ui_users = list() -/obj/structure/mirror/attack_hand(mob/user as mob) - if(shattered) return +/obj/structure/mirror/New(turf/T, newdir = SOUTH, building = FALSE) + ..() + if(building) + switch(newdir) + if(NORTH) + pixel_y = -32 + if(SOUTH) + pixel_y = 32 + if(EAST) + pixel_x = -32 + if(WEST) + pixel_x = 32 + +/obj/structure/mirror/attack_hand(mob/user) + if(shattered) + return if(ishuman(user)) var/datum/nano_module/appearance_changer/AC = ui_users[user] @@ -22,14 +36,15 @@ AC.ui_interact(user) /obj/structure/mirror/proc/shatter() - if(shattered) return + if(shattered) + return shattered = 1 icon_state = "mirror_broke" playsound(src, "shatter", 70, 1) desc = "Oh no, seven years of bad luck!" -/obj/structure/mirror/bullet_act(var/obj/item/projectile/Proj) +/obj/structure/mirror/bullet_act(obj/item/projectile/Proj) if(prob(Proj.damage * 2)) if(!shattered) shatter() @@ -38,7 +53,19 @@ ..() -/obj/structure/mirror/attackby(obj/item/I as obj, mob/living/user as mob, params) +/obj/structure/mirror/attackby(obj/item/I, mob/living/user, params) + if(isscrewdriver(I)) + user.visible_message("[user] begins to unfasten [src].", "You begin to unfasten [src].") + if(do_after(user, 30 * I.toolspeed, target = src)) + if(shattered) + user.visible_message("[user] drops the broken shards to the floor.", "You drop the broken shards on the floor.") + new /obj/item/weapon/shard(get_turf(user)) + else + user.visible_message("[user] carefully places [src] on the floor.", "You carefully place [src] on the floor.") + new /obj/item/mounted/mirror(get_turf(user)) + qdel(src) + return + user.do_attack_animation(src) if(shattered) playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) @@ -52,8 +79,9 @@ playsound(src.loc, 'sound/effects/Glasshit.ogg', 70, 1) -/obj/structure/mirror/attack_alien(mob/living/user as mob) - if(islarva(user)) return +/obj/structure/mirror/attack_alien(mob/living/user) + if(islarva(user)) + return user.do_attack_animation(src) if(shattered) playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) @@ -62,10 +90,12 @@ shatter() -/obj/structure/mirror/attack_animal(mob/living/user as mob) - if(!isanimal(user)) return +/obj/structure/mirror/attack_animal(mob/living/user) + if(!isanimal(user)) + return var/mob/living/simple_animal/M = user - if(M.melee_damage_upper <= 0) return + if(M.melee_damage_upper <= 0) + return M.do_attack_animation(src) if(shattered) playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) @@ -74,7 +104,7 @@ shatter() -/obj/structure/mirror/attack_slime(mob/living/user as mob) +/obj/structure/mirror/attack_slime(mob/living/user) var/mob/living/carbon/slime/S = user if(!S.is_adult) return @@ -83,4 +113,16 @@ playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) return user.visible_message("[user] smashes [src]!") - shatter() \ No newline at end of file + shatter() + + +/obj/item/mounted/mirror + name = "mirror" + desc = "Some reflective glass ready to be hung on a wall. Don't break it!" + icon = 'icons/obj/watercloset.dmi' + icon_state = "mirror" + +/obj/item/mounted/mirror/do_build(turf/on_wall, mob/user) + var/obj/structure/mirror/M = new /obj/structure/mirror(get_turf(user), get_dir(on_wall, user), 1) + transfer_prints_to(M, TRUE) + qdel(src) \ No newline at end of file diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index ca7c18c2e4e..1677b776c15 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -14,10 +14,11 @@ var/instrumentExt = "ogg" // the file extension var/obj/instrumentObj = null // the associated obj playing the sound -/datum/song/New(dir, obj) +/datum/song/New(dir, obj, ext = "ogg") tempo = sanitize_tempo(tempo) instrumentDir = dir instrumentObj = obj + instrumentExt = ext /datum/song/Destroy() instrumentObj = null @@ -50,7 +51,7 @@ return // now generate name - var/soundfile = "sound/[instrumentDir]/[ascii2text(note+64)][acc][oct].[instrumentExt]" + var/soundfile = "sound/instruments/[instrumentDir]/[ascii2text(note+64)][acc][oct].[instrumentExt]" soundfile = file(soundfile) // make sure the note exists if(!fexists(soundfile)) @@ -58,7 +59,8 @@ // and play var/turf/source = get_turf(instrumentObj) var/sound/music_played = sound(soundfile) - for(var/mob/M in hearers(15, source)) + for(var/A in hearers(15, source)) + var/mob/M = A if(!M.client || !(M.client.prefs.sound & SOUND_INSTRUMENTS)) continue M.playsound_local(source, null, 100, falloff = 5, S = music_played) @@ -147,6 +149,7 @@ lines = new() tempo = sanitize_tempo(5) // default 120 BPM name = "" + nanomanager.update_uis(src) else if(href_list["import"]) playing = 0 @@ -156,11 +159,11 @@ if(!in_range(instrumentObj, usr)) return - if(lentext(t) >= 3072) + if(lentext(t) >= 12000) var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no") if(cont == "no") break - while(lentext(t) > 3072) + while(lentext(t) > 12000) //split into lines spawn() @@ -172,19 +175,21 @@ lines.Cut(1,2) else tempo = sanitize_tempo(5) // default 120 BPM - if(lines.len > 50) + if(lines.len > 200) to_chat(usr, "Too many lines!") - lines.Cut(51) + lines.Cut(201) var/linenum = 1 for(var/l in lines) - if(lentext(l) > 50) + if(lentext(l) > 200) to_chat(usr, "Line [linenum] too long!") lines.Remove(l) else linenum++ + nanomanager.update_uis(src) else if(href_list["help"]) help = !help + nanomanager.update_uis(src) if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops. if(playing) @@ -194,9 +199,11 @@ repeat = 0 if(repeat > max_repeat) repeat = max_repeat + nanomanager.update_uis(src) else if(href_list["tempo"]) tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]) * world.tick_lag) + nanomanager.update_uis(src) else if(href_list["play"]) if(playing) @@ -204,6 +211,7 @@ playing = 1 spawn() playsong(usr) + nanomanager.update_uis(src) else if(href_list["insertline"]) var/num = round(text2num(href_list["insertline"])) @@ -213,32 +221,36 @@ var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null) if(!newline || !in_range(instrumentObj, usr)) return - if(lines.len > 50) + if(lines.len > 200) return - if(lentext(newline) > 50) - newline = copytext(newline, 1, 50) + if(lentext(newline) > 200) + newline = copytext(newline, 1, 200) lines.Insert(num, newline) + nanomanager.update_uis(src) else if(href_list["deleteline"]) var/num = round(text2num(href_list["deleteline"])) if(num > lines.len || num < 1) return lines.Cut(num, num + 1) + nanomanager.update_uis(src) else if(href_list["modifyline"]) var/num = round(text2num(href_list["modifyline"])) var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null) if(!content || !in_range(instrumentObj, usr)) return - if(lentext(content) > 50) - content = copytext(content, 1, 50) + if(lentext(content) > 200) + content = copytext(content, 1, 200) if(num > lines.len || num < 1) return lines[num] = content + nanomanager.update_uis(src) else if(href_list["stop"]) playing = 0 + nanomanager.update_uis(src) /datum/song/proc/sanitize_tempo(new_tempo) new_tempo = abs(new_tempo) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index d3cc48d46bf..b8e176ba12a 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -47,12 +47,61 @@ open = !open update_icon() - /obj/structure/toilet/update_icon() icon_state = "toilet[open][cistern]" - + if(!anchored) + pixel_x = 0 + pixel_y = 0 + layer = OBJ_LAYER + else + if(dir == SOUTH) + pixel_x = 0 + pixel_y = 8 + if(dir == NORTH) + pixel_x = 0 + pixel_y = -8 + layer = FLY_LAYER /obj/structure/toilet/attackby(obj/item/I, mob/living/user, params) + if(iswrench(I)) + var/choices = list() + if(cistern) + choices += "Stash" + if(anchored) + choices += "Disconnect" + else + choices += "Connect" + choices += "Rotate" + + var/response = input(user, "What do you want to do?", "[src]") as null|anything in choices + if(!Adjacent(user) || !response) //moved away or cancelled + return + switch(response) + if("Stash") + stash_goods(I, user) + if("Disconnect") + user.visible_message("[user] starts disconnecting [src].", "You begin disconnecting [src]...") + if(do_after(user, 40 * I.toolspeed, target = src)) + if(!loc || !anchored) + return + user.visible_message("[user] disconnects [src]!", "You disconnect [src]!") + anchored = 0 + update_icon() + if("Connect") + user.visible_message("[user] starts connecting [src].", "You begin connecting [src]...") + if(do_after(user, 40 * I.toolspeed, target = src)) + if(!loc || anchored) + return + user.visible_message("[user] connects [src]!", "You connect [src]!") + anchored = 1 + update_icon() + if("Rotate") + var/list/dir_choices = list("North" = NORTH, "East" = EAST, "South" = SOUTH, "West" = WEST) + var/selected = input(user,"Select a direction for the connector.", "Connector Direction") in dir_choices + dir = dir_choices[selected] + update_icon() //is this necessary? probably not + return + if(istype(I, /obj/item/weapon/crowbar)) to_chat(user, "You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]...") playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1) @@ -68,7 +117,7 @@ var/obj/item/weapon/reagent_containers/RG = I if(RG.is_open_container()) if(RG.reagents.total_volume >= RG.volume) - to_chat(user, "\The [RG] is full.") + to_chat(user, "[RG] is full.") else RG.reagents.add_reagent("toiletwater", min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) to_chat(user, "You fill [RG] from [src]. Gross.") @@ -106,20 +155,25 @@ to_chat(user, "You need a tighter grip!") if(cistern) - if(I.w_class > WEIGHT_CLASS_NORMAL) - to_chat(user, "[I] does not fit!") - return - if(w_items + I.w_class > WEIGHT_CLASS_HUGE) - to_chat(user, "The cistern is full!") - return - if(!user.drop_item()) - 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.") + stash_goods(I, user) return +/obj/structure/toilet/proc/stash_goods(obj/item/I, mob/user) + if(!I) + return + if(I.w_class > WEIGHT_CLASS_NORMAL) + to_chat(user, "[I] does not fit!") + return + if(w_items + I.w_class > WEIGHT_CLASS_HUGE) + to_chat(user, "The cistern is full!") + return + if(!user.drop_item()) + to_chat(user, "[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.") + /obj/structure/toilet/secret var/secret_type = null @@ -131,6 +185,7 @@ w_items += secret.w_class + /obj/structure/urinal name = "urinal" desc = "The HU-452, an experimental urinal." @@ -141,6 +196,27 @@ /obj/structure/urinal/attackby(obj/item/I, mob/user, params) + if(iswrench(I)) + if(anchored) + user.visible_message("[user] begins disconnecting [src]...", "You begin to disconnect [src]...") + if(do_after(user, 40 * I.toolspeed, target = src)) + if(!loc || !anchored) + return + user.visible_message("[user] disconnects [src]!", "You disconnect [src]!") + anchored = 0 + pixel_x = 0 + pixel_y = 0 + else + user.visible_message("[user] begins connecting [src]...", "You begin to connect [src]...") + if(do_after(user, 40 * I.toolspeed, target = src)) + if(!loc || anchored) + return + user.visible_message("[user] connects [src]!", "You connect [src]!") + anchored = 1 + pixel_x = 0 + pixel_y = 32 + return + if(istype(I, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = I if(!G.confirm()) @@ -159,6 +235,7 @@ to_chat(user, "You need a tighter grip!") + /obj/machinery/shower name = "shower" desc = "The HS-451. Installed in the 2550s by the Nanotrasen Hygiene Division." @@ -173,6 +250,24 @@ var/watertemp = "normal" //freezing, normal, or boiling var/mobpresent = 0 //true if there is a mob on the shower's loc, this is to ease process() +/obj/machinery/shower/New(turf/T, newdir = SOUTH, building = FALSE) + ..() + dir = newdir + if(building) + pixel_x = 0 + pixel_y = 0 + switch(newdir) + if(SOUTH) + pixel_y = 16 + if(NORTH) + pixel_y = -5 + layer = FLY_LAYER + +/obj/machinery/shower/Destroy() + if(mymist) + QDEL_NULL(mymist) + return ..() + //add heat controls? when emagged, you can freeze to death in it? /obj/effect/mist @@ -198,9 +293,9 @@ /obj/machinery/shower/attackby(obj/item/I as obj, mob/user as mob, params) if(I.type == /obj/item/device/analyzer) to_chat(user, "The water temperature seems to be [watertemp].") - if(istype(I, /obj/item/weapon/wrench)) + if(iswrench(I)) to_chat(user, "You begin to adjust the temperature valve with the [I].") - if(do_after(user, 50, target = src)) + if(do_after(user, 50 * I.toolspeed, target = src)) switch(watertemp) if("normal") watertemp = "freezing" @@ -209,33 +304,57 @@ if("boiling") watertemp = "normal" user.visible_message("[user] adjusts the shower with the [I].", "You adjust the shower with the [I].") + update_icon() //letsa update whenever we change the temperature, since the mist might need to change + if(iswelder(I)) + if(on) + to_chat(user, "Turn [src] off before you attempt to cut it loose.") + return + var/obj/item/weapon/weldingtool/WT = I + if(WT.isOn()) + user.visible_message("[user] begins to cut [src] loose.", "You begin to cut [src] loose.") + if(do_after(user, 40 * WT.toolspeed, target = src)) + if(!src || !WT.remove_fuel(0, user)) + return + if(on) //in case someone turned it back on while you were working, make sure we shut that all down + on = 0 + if(mymist) + qdel(mymist) + ismist = 0 + user.visible_message("[user] cuts [src] loose!", "You cut [src] loose!") + var/obj/item/mounted/shower/S = new /obj/item/mounted/shower(get_turf(user)) + transfer_prints_to(S, TRUE) + qdel(src) + else + to_chat(user, "[WT] must be on for this task.") if(on) I.water_act(100, convertHeat(), src) -/obj/machinery/shower/update_icon() //this is terribly unreadable, but basically it makes the shower mist up +/obj/machinery/shower/update_icon() //this makes the shower mist up or clear mist (depending on water temperature) overlays.Cut() //once it's been on for a while, in addition to handling the water overlay. - if(mymist) - qdel(mymist) - if(on) overlays += image('icons/obj/watercloset.dmi', src, "water", MOB_LAYER + 1, dir) + var/mist_time = 50 //5 seconds at normal temperature to build up mist if(watertemp == "freezing") + mist_time = 70 //7 seconds on freezing temperature to disperse existing mist + if(watertemp == "boiling") + mist_time = 20 //2 seconds on boiling temperature to build up mist + addtimer(src, "update_mist", mist_time) + else + addtimer(src, "update_mist", 250) //25 seconds for mist to disperse after being turned off + +/obj/machinery/shower/proc/update_mist() + if(on) + if(watertemp == "freezing") + if(mymist) + qdel(mymist) + ismist = 0 return - if(!ismist) - spawn(50) - if(src && on) - ismist = 1 - mymist = new /obj/effect/mist(loc) - else - ismist = 1 - mymist = new /obj/effect/mist(loc) - else if(ismist) ismist = 1 mymist = new /obj/effect/mist(loc) - spawn(250) - if(src && !on) - qdel(mymist) - ismist = 0 + else + if(mymist) + qdel(mymist) + ismist = 0 /obj/machinery/shower/Crossed(atom/movable/O) ..() @@ -351,13 +470,16 @@ qdel(E) /obj/machinery/shower/process() - if(!on || !mobpresent) return + if(!on || !mobpresent) + return for(var/mob/living/carbon/C in loc) + if(prob(33)) + wash(C) //re-applies water and re-cleans mob while they remain under the shower, 33% chance per process to avoid message spam/quick death check_heat(C) /obj/machinery/shower/proc/check_heat(mob/M as mob) - M.water_act(100, convertHeat(), src) //convenience - if(!on || watertemp == "normal") return + if(!on || watertemp == "normal") + return if(iscarbon(M)) var/mob/living/carbon/C = M @@ -390,6 +512,8 @@ desc = "A sink used for washing one's hands and face." anchored = 1 var/busy = 0 //Something's being washed at the moment + var/can_move = 1 //if the sink can be disconnected and moved + var/can_rotate = 1 //if the sink can be rotated to face alternate directions /obj/structure/sink/attack_hand(mob/user as mob) if(!user || !istype(user)) @@ -398,7 +522,9 @@ return if(!Adjacent(user)) return - + if(!anchored) + to_chat(user, "[src] isn't connected, wrench it into position first!") + return if(ishuman(user)) var/mob/living/carbon/human/H = user var/obj/item/organ/external/temp = H.bodyparts_by_name["r_hand"] @@ -415,7 +541,7 @@ var/washing_face = 0 if(selected_area in list("head", "mouth", "eyes")) washing_face = 1 - user.visible_message("[user] start washing their [washing_face ? "face" : "hands"]...", \ + user.visible_message("[user] starts washing their [washing_face ? "face" : "hands"]...", \ "You start washing your [washing_face ? "face" : "hands"]...") busy = 1 @@ -446,6 +572,57 @@ if(!(istype(O))) return + if(iswrench(O)) + var/obj/item/weapon/wrench/W = O + + var/choices = list() + if(anchored) + choices += "Wash" + if(can_move) + choices += "Disconnect" + else + choices += "Connect" + if(can_rotate) + choices += "Rotate" + + var/response = input(user, "What do you want to do?", "[src]") as null|anything in choices + if(!Adjacent(user) || !response) //moved away or cancelled + return + switch(response) + if("Wash") + busy = 1 + var/wateract = 0 + wateract = (W.wash(user, src)) + busy = 0 + if(wateract) + W.water_act(20,310.15,src) + if("Disconnect") + user.visible_message("[user] starts disconnecting [src].", "You begin disconnecting [src]...") + if(do_after(user, 40 * O.toolspeed, target = src)) + if(!loc || !anchored) + return + user.visible_message("[user] disconnects [src]!", "You disconnect [src]!") + anchored = 0 + update_icon() + if("Connect") + user.visible_message("[user] starts connecting [src].", "You begin connecting [src]...") + if(do_after(user, 40 * O.toolspeed, target = src)) + if(!loc || anchored) + return + user.visible_message("[user] connects [src]!", "You connect [src]!") + anchored = 1 + update_icon() + if("Rotate") + var/list/dir_choices = list("North" = NORTH, "East" = EAST, "South" = SOUTH, "West" = WEST) + var/selected = input(user, "Select a direction for the connector.", "Connector Direction") in dir_choices + dir = dir_choices[selected] + update_icon() //is this necessary? probably not + return + + if(!anchored) + to_chat(user, "[src] isn't connected, wrench it into position first!") + return + busy = 1 var/wateract = 0 wateract = (O.wash(user, src)) @@ -453,14 +630,42 @@ if(wateract) O.water_act(20,310.15,src) +/obj/structure/sink/update_icon() + ..() + layer = OBJ_LAYER + if(!anchored) + pixel_x = 0 + pixel_y = 0 + else + //the following code will probably want to be updated in the future to be less reliant on hardcoded offsets based on the can_move/can_rotate values + if(!can_move) //puddles + return + if(!can_rotate) //kitchen sinks + pixel_x = 0 + pixel_y = 28 + return + else //normal sinks + if(dir == NORTH || dir == SOUTH) + pixel_x = 0 + pixel_y = (dir == NORTH) ? -5 : 30 + if(dir == NORTH) + layer = FLY_LAYER + else + pixel_x = (dir == EAST) ? 12 : -12 + pixel_y = 0 + + /obj/structure/sink/kitchen name = "kitchen sink" icon_state = "sink_alt" + can_rotate = 0 /obj/structure/sink/puddle //splishy splashy ^_^ name = "puddle" icon_state = "puddle" + can_move = 0 + can_rotate = 0 /obj/structure/sink/puddle/attack_hand(mob/M as mob) icon_state = "puddle-splash" @@ -471,3 +676,77 @@ icon_state = "puddle-splash" ..() icon_state = "puddle" + + +////////////////////////////////// +// Bathroom Fixture Items // +////////////////////////////////// + + +/obj/item/mounted/shower + name = "shower fixture" + desc = "A self-adhering shower fixture. Simply stick to a wall, no plumber needed!" + icon = 'icons/obj/watercloset.dmi' + icon_state = "shower" + item_state = "buildpipe" + +/obj/item/mounted/shower/try_build(turf/on_wall, mob/user, proximity_flag) + //overriding this because we don't care about other items on the wall, but still need to do adjacent checks + if(!on_wall || !user) + return + if(proximity_flag != 1) //if we aren't next to the wall + return + if(!(get_dir(on_wall, user) in cardinal)) + to_chat(user, "You need to be standing next to a wall to place \the [src].") + return + return 1 + +/obj/item/mounted/shower/do_build(turf/on_wall, mob/user) + var/obj/machinery/shower/S = new /obj/machinery/shower(get_turf(user), get_dir(on_wall, user), 1) + transfer_prints_to(S, TRUE) + qdel(src) + + +/obj/item/weapon/bathroom_parts + name = "toilet in a box" + desc = "An entire toilet in a box, straight from Space Sweden. It has an unpronounceable name." + icon = 'icons/obj/storage.dmi' + icon_state = "largebox" + w_class = WEIGHT_CLASS_BULKY + var/result = /obj/structure/toilet + var/result_name = "toilet" + +/obj/item/weapon/bathroom_parts/urinal + name = "urinal in a box" + result = /obj/structure/urinal + result_name = "urinal" + +/obj/item/weapon/bathroom_parts/sink + name = "sink in a box" + result = /obj/structure/sink + result_name = "sink" + +/obj/item/weapon/bathroom_parts/New() + ..() + desc = "An entire [result_name] in a box, straight from Space Sweden. It has an [pick("unpronounceable", "overly accented", "entirely gibberish", "oddly normal-sounding")] name." + +/obj/item/weapon/bathroom_parts/attack_self(mob/user) + var/turf/T = get_turf(user) + if(!T) + to_chat(user, "You can't build that here!") + return + if(result in T.contents) + to_chat(user, "There's already \an [result_name] here.") + return + user.visible_message("[user] begins assembling a new [result_name].", "You begin assembling a new [result_name].") + if(do_after(user, 30, target = user)) + user.visible_message("[user] finishes building a new [result_name]!", "You finish building a new [result_name]!") + var/obj/structure/S = new result(T) + S.anchored = 0 + S.dir = user.dir + S.update_icon() + user.unEquip(src, 1) + qdel(src) + if(prob(50)) + new /obj/item/stack/sheet/cardboard(T) + diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 126dd6e3a38..3946f6613da 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -108,7 +108,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f return 1 -/obj/structure/window/hitby(atom/movable/AM) +/obj/structure/window/hitby(atom/movable/AM) ..() var/tforce = 0 if(ismob(AM)) @@ -125,7 +125,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f update_nearby_icons() step(src, get_dir(AM, src)) if(health <= 0) - destroy() + destroy() /obj/structure/window/attack_hand(mob/user as mob) @@ -179,14 +179,14 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f attack_generic(user, rand(10, 15)) -/obj/structure/window/attackby(obj/item/weapon/W as obj, mob/living/user as mob, params) - if(!istype(W)) return//I really wish I did not need this - if(istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) - var/obj/item/weapon/grab/G = W +/obj/structure/window/attackby(obj/item/I as obj, mob/living/user as mob, params) + if(!istype(I)) return//I really wish I did not need this + if(istype(I, /obj/item/weapon/grab) && get_dist(src,user)<2) + var/obj/item/weapon/grab/G = I if(istype(G.affecting,/mob/living)) var/mob/living/M = G.affecting var/state = G.state - qdel(W) //gotta delete it here because if window breaks, it won't get deleted + qdel(I) //gotta delete it here because if window breaks, it won't get deleted switch(state) if(1) M.visible_message("[user] slams [M] against \the [src]!") @@ -210,29 +210,29 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f hit(75) return - if(W.flags & NOBLUDGEON) return + if(I.flags & NOBLUDGEON) return - if(istype(W, /obj/item/weapon/screwdriver)) + if(istype(I, /obj/item/weapon/screwdriver)) if(reinf && state >= 1) state = 3 - state - playsound(loc, W.usesound, 75, 1) + playsound(loc, I.usesound, 75, 1) to_chat(user, (state == 1 ? "You have unfastened the window from the frame." : "You have fastened the window to the frame.")) else if(reinf && state == 0) anchored = !anchored update_nearby_icons() - playsound(loc, W.usesound, 75, 1) + playsound(loc, I.usesound, 75, 1) to_chat(user, (anchored ? "You have fastened the frame to the floor." : "You have unfastened the frame from the floor.")) else if(!reinf) anchored = !anchored update_nearby_icons() - playsound(loc, W.usesound, 75, 1) + playsound(loc, I.usesound, 75, 1) to_chat(user, (anchored ? "You have fastened the window to the floor." : "You have unfastened the window.")) - else if(istype(W, /obj/item/weapon/crowbar) && reinf && state <= 1) + else if(istype(I, /obj/item/weapon/crowbar) && reinf && state <= 1) state = 1 - state - playsound(loc, W.usesound, 75, 1) + playsound(loc, I.usesound, 75, 1) to_chat(user, (state ? "You have pried the window into the frame." : "You have pried the window out of the frame.")) - else if(istype(W, /obj/item/weapon/wrench) && !anchored && health > 7) //Disassemble deconstructed window into parts - playsound(src.loc, W.usesound, 50, 1) + else if(istype(I, /obj/item/weapon/wrench) && !anchored && health > 7) //Disassemble deconstructed window into parts + playsound(src.loc, I.usesound, 50, 1) for(var/i=0;i Admin Tickets" + + dat +="RefreshOpen TicketsResolved TicketsClosed Tickets" + if(tab == ADMIN_TICKET_OPEN) + dat += " Open Tickets" + dat += "
Admin Tickets" + + dat +="Show AllRefresh" + + dat += "Ticket #[T.ticketNum]" + + dat += "[T.clientName] / [T.mobControlled] opened this ticket at [T.timeOpened] at location [T.locationSent]" + dat += "Ticket Status: [status]" + dat += "
" + dat += "Re-OpenResolve " + + if(!T.adminAssigned) + dat += "No admin assigned to this ticket - Take Ticket " + else + dat += "[T.adminAssigned] is assigned to this Ticket. - Take Ticket " + + if(T.lastAdminResponse) + dat += "Last Admin Response: [T.lastAdminResponse] at [T.lastResponseTime]" + else + dat +="No Admin Response" + + dat += " " + + dat += "Close Ticket" + + var/datum/browser/popup = new(user, "adminticketsdetail", "Admin Ticket #[T.ticketNum]", 1000, 600) + popup.set_content(dat) + popup.open() + +/datum/adminTicketHolder/proc/userDetailUI(var/client/user) +//dat + var/tickets = checkForTicket(user) + var/dat + dat += " Your open tickets" + dat += "
A custom event is taking place. OOC Info:") to_chat(src, "[html_encode(custom_event_msg)]") to_chat(src, "") + +//admin event info to be view by admins + +/client/proc/cmd_admin_custom_event_info() + set category = "Event" + set name = "Change Custom Admin Event Info" + + if(!check_rights(R_EVENT)) + to_chat(src, "Only administrators may use this command.") + return + + var/input = input(usr, "Enter the description of the custom event. This is informations for admins only. Use it to notify other admins of event info but not players.", "Custom Event Info", custom_event_msg) as message|null + if(!input || input == "") + custom_event_admin_msg = null + log_admin("[key_name(usr)] has cleared the custom admin event info text.") + message_admins("[key_name_admin(usr)] has cleared the custom admin event text.") + return + + log_admin("[key_name(usr)] has changed the custom admin event info text.") + message_admins("[key_name_admin(usr)] has changed the custom admin event info text.") + + custom_event_admin_msg = input + + for(var/client/X in admins) + if(check_rights(R_EVENT,0,X.mob)) + to_chat(X, " Custom Admin Event Info") + to_chat(X, "A custom event is starting. OOC Admin Info:") + to_chat(X, "[html_encode(custom_event_admin_msg)]") + to_chat(X,"") + +/client/proc/cmd_view_custom_event_info() + set category = "Event" + set name = "Custom Event Admin Info" + + if(!check_rights(R_EVENT)) + to_chat(src, "Only administrators may use this command.") + return + + if(!custom_event_admin_msg || custom_event_admin_msg == "") + to_chat(src, "There currently is no known custom admin event taking place.") + return + + to_chat(src, " Custom Event Info") + to_chat(src, "A custom event is taking place. OOC Info:") + to_chat(src, "[html_encode(custom_event_admin_msg)]") + to_chat(src, "") diff --git a/code/modules/admin/verbs/massmodvar.dm b/code/modules/admin/verbs/massmodvar.dm index c7b2d6d537e..084057498bb 100644 --- a/code/modules/admin/verbs/massmodvar.dm +++ b/code/modules/admin/verbs/massmodvar.dm @@ -22,360 +22,251 @@ src.massmodify_variables(A, var_name, method) feedback_add_details("admin_verb","MEV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/massmodify_variables(var/atom/O, var/var_name = "", var/method = 0) - if(!check_rights(R_VAREDIT)) return - - var/list/locked = list("vars", "key", "ckey", "client") - - for(var/p in forbidden_varedit_object_types) - if( istype(O,p) ) - to_chat(usr, "It is forbidden to edit this object's variables.") - return - - var/list/names = list() - for(var/V in O.vars) - names += V - - names = sortList(names) +/client/proc/massmodify_variables(datum/O, var_name = "", method = 0) + if(!check_rights(R_VAREDIT)) + return + if(!istype(O)) + return var/variable = "" - if(!var_name) - variable = input("Which var?","Var") as null|anything in names + var/list/names = list() + for(var/V in O.vars) + names += V + + names = sortList(names) + + variable = input("Which var?", "Var") as null|anything in names else variable = var_name - if(!variable) return + if(!variable || !O.can_vv_get(variable)) + return var/default var/var_value = O.vars[variable] - var/dir - if(variable == "holder" || (variable in locked)) - if(!check_rights(R_DEBUG)) return + if(variable in VVckey_edit) + to_chat(src, "It's forbidden to mass-modify ckeys. It'll crash everyone's client you dummy.") + return + if(variable in VVlocked) + if(!check_rights(R_DEBUG)) + return + if(variable in VVicon_edit_lock) + if(!check_rights(R_EVENT | R_DEBUG)) + return + if(variable in VVpixelmovement) + if(!check_rights(R_DEBUG)) + return + var/prompt = alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT") + if(prompt != "Continue") + return - if(isnull(var_value)) - to_chat(usr, "Unable to determine variable type.") - - else if(isnum(var_value)) - to_chat(usr, "Variable appears to be NUM.") - default = "num" - dir = 1 - - else if(istext(var_value)) - to_chat(usr, "Variable appears to be TEXT.") - default = "text" - - else if(isloc(var_value)) - to_chat(usr, "Variable appears to be REFERENCE.") - default = "reference" - - else if(isicon(var_value)) - to_chat(usr, "Variable appears to be ICON.") - var_value = "[bicon(var_value)]" - default = "icon" - - else if(istype(var_value,/atom) || istype(var_value,/datum)) - to_chat(usr, "Variable appears to be TYPE.") - default = "type" - - else if(istype(var_value,/list)) - to_chat(usr, "Variable appears to be LIST.") - default = "list" - - else if(istype(var_value,/client)) - to_chat(usr, "Variable appears to be CLIENT.") - default = "cancel" + default = vv_get_class(var_value) + if(isnull(default)) + to_chat(src, "Unable to determine variable type.") else - to_chat(usr, "Variable appears to be FILE.") - default = "file" + to_chat(src, "Variable appears to be [uppertext(default)].") - to_chat(usr, "Variable contains: [var_value]") - if(dir) - switch(var_value) - if(1) - dir = "NORTH" - if(2) - dir = "SOUTH" - if(4) - dir = "EAST" - if(8) - dir = "WEST" - if(5) - dir = "NORTHEAST" - if(6) - dir = "SOUTHEAST" - if(9) - dir = "NORTHWEST" - if(10) - dir = "SOUTHWEST" - else - dir = null - if(dir) - to_chat(usr, "If a direction, direction is: [dir]") + to_chat(src, "Variable contains: [var_value]") - var/class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","icon","file","edit referenced object","restore to default") + if(default == VV_NUM) + var/dir_text = "" + if(dir < 0 && dir < 16) + if(dir & 1) + dir_text += "NORTH" + if(dir & 2) + dir_text += "SOUTH" + if(dir & 4) + dir_text += "EAST" + if(dir & 8) + dir_text += "WEST" - if(!class) + if(dir_text) + to_chat(src, "If a direction, direction is: [dir_text]") + + var/value = vv_get_value(default_class = default) + var/new_value = value["value"] + var/class = value["class"] + + if(!class || !new_value == null && class != VV_NULL) return - var/original_name + if(class == VV_MESSAGE) + class = VV_TEXT - if(!istype(O, /atom)) - original_name = "\ref[O] ([O])" - else - original_name = O:name + if(value["type"]) + class = VV_NEW_TYPE + + var/original_name = "[O]" + + var/rejected = 0 + var/accepted = 0 switch(class) + if(VV_RESTORE_DEFAULT) + to_chat(src, "Finding items...") + var/list/items = get_all_of_type(O.type, method) + to_chat(src, "Changing [items.len] items...") + for(var/thing in items) + if(!thing) + continue + var/datum/D = thing + if(D.vv_edit_var(variable, initial(D.vars[variable])) != FALSE) + accepted++ + else + rejected++ + CHECK_TICK - if("restore to default") - O.vars[variable] = initial(O.vars[variable]) - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - M.on_varedit(variable) + if(VV_TEXT) + var/list/varsvars = vv_parse_text(O, new_value) + var/pre_processing = new_value + var/unique + if(varsvars && varsvars.len) + unique = alert(usr, "Process vars unique to each instance, or same for all?", "Variable Association", "Unique", "Same") + if(unique == "Unique") + unique = TRUE + else + unique = FALSE + for(var/V in varsvars) + new_value = replacetext(new_value,"\[[V]]","[O.vars[V]]") - else if(istype(O, /obj)) - for(var/obj/A in world) - if( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - A.on_varedit(variable) + to_chat(src, "Finding items...") + var/list/items = get_all_of_type(O.type, method) + to_chat(src, "Changing [items.len] items...") + for(var/thing in items) + if(!thing) + continue + var/datum/D = thing + if(unique) + new_value = pre_processing + for(var/V in varsvars) + new_value = replacetext(new_value,"\[[V]]","[D.vars[V]]") - else if(istype(O, /turf)) - for(var/turf/A in world) - if( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - A.on_varedit(variable) + if(D.vv_edit_var(variable, new_value) != FALSE) + accepted++ + else + rejected++ + CHECK_TICK + if(VV_NEW_TYPE) + var/many = alert(src, "Create only one [value["type"]] and assign each or a new one for each thing", "How Many", "One", "Many", "Cancel") + if(many == "Cancel") + return + if(many == "Many") + many = TRUE else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if(M.type == O.type) - M.vars[variable] = O.vars[variable] - M.on_varedit(variable) + many = FALSE - else if(istype(O, /obj)) - for(var/obj/A in world) - if(A.type == O.type) - A.vars[variable] = O.vars[variable] - A.on_varedit(variable) + var/type = value["type"] + to_chat(src, "Finding items...") + var/list/items = get_all_of_type(O.type, method) + to_chat(src, "Changing [items.len] items...") + for(var/thing in items) + if(!thing) + continue + var/datum/D = thing + if(many && !new_value) + new_value = new type() - else if(istype(O, /turf)) - for(var/turf/A in world) - if(A.type == O.type) - A.vars[variable] = O.vars[variable] - A.on_varedit(variable) + if(D.vv_edit_var(variable, new_value) != FALSE) + accepted++ + else + rejected++ + new_value = null + CHECK_TICK - if("edit referenced object") - return .(O.vars[variable]) + else + to_chat(src, "Finding items...") + var/list/items = get_all_of_type(O.type, method) + to_chat(src, "Changing [items.len] items...") + for(var/thing in items) + if(!thing) + continue + var/datum/D = thing + if(D.vv_edit_var(variable, new_value) != FALSE) + accepted++ + else + rejected++ + CHECK_TICK - if("text") - var/new_value = input("Enter new text:","Text",O.vars[variable]) as message|null - if(new_value == null) return - O.vars[variable] = new_value - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] + var/count = rejected+accepted + if(!count) + to_chat(src, "No objects found") + return + if(!accepted) + to_chat(src, "Every object rejected your edit") + return + if(rejected) + to_chat(src, "[rejected] out of [count] objects rejected your edit") - else if(istype(O, /obj)) - for(var/obj/A in world) - if( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] + log_to_dd("### MassVarEdit by [src]: [O.type] (A/R [accepted]/[rejected]) [variable]=[html_encode("[O.vars[variable]]")]([list2params(value)])") + log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)") + message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)") - else if(istype(O, /turf)) - for(var/turf/A in world) - if( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if(M.type == O.type) - M.vars[variable] = O.vars[variable] +/proc/get_all_of_type(var/T, subtypes = TRUE) + var/list/typecache = list() + typecache[T] = 1 + if(subtypes) + typecache = typecacheof(typecache) + . = list() + if(ispath(T, /mob)) + for(var/mob/thing in mob_list) + if(typecache[thing.type]) + . += thing + CHECK_TICK - else if(istype(O, /obj)) - for(var/obj/A in world) - if(A.type == O.type) - A.vars[variable] = O.vars[variable] + else if(ispath(T, /obj/machinery/door)) + for(var/obj/machinery/door/thing in airlocks) + if(typecache[thing.type]) + . += thing + CHECK_TICK - else if(istype(O, /turf)) - for(var/turf/A in world) - if(A.type == O.type) - A.vars[variable] = O.vars[variable] + else if(ispath(T, /obj/machinery)) + for(var/obj/machinery/thing in machines) + if(typecache[thing.type]) + . += thing + CHECK_TICK - if("num") - var/new_value = input("Enter new number:","Num",\ - O.vars[variable]) as num|null - if(new_value == null) return + else if(ispath(T, /obj)) + for(var/obj/thing in world) + if(typecache[thing.type]) + . += thing + CHECK_TICK - if(variable=="light_range") - O.set_light(new_value) - else - O.vars[variable] = new_value + else if(ispath(T, /atom/movable)) + for(var/atom/movable/thing in world) + if(typecache[thing.type]) + . += thing + CHECK_TICK - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if( istype(M , O.type) ) - if(variable=="light_range") - M.set_light(new_value) - else - M.vars[variable] = O.vars[variable] + else if(ispath(T, /turf)) + for(var/turf/thing in world) + if(typecache[thing.type]) + . += thing + CHECK_TICK - else if(istype(O, /obj)) - for(var/obj/A in world) - if( istype(A , O.type) ) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] + else if(ispath(T, /atom)) + for(var/atom/thing in world) + if(typecache[thing.type]) + . += thing + CHECK_TICK - else if(istype(O, /turf)) - for(var/turf/A in world) - if( istype(A , O.type) ) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] + else if(ispath(T, /client)) + for(var/client/thing in clients) + if(typecache[thing.type]) + . += thing + CHECK_TICK - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if(M.type == O.type) - if(variable=="light_range") - M.set_light(new_value) - else - M.vars[variable] = O.vars[variable] + else if(ispath(T, /datum)) + for(var/datum/thing) + if(typecache[thing.type]) + . += thing + CHECK_TICK - else if(istype(O, /obj)) - for(var/obj/A in world) - if(A.type == O.type) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in world) - if(A.type == O.type) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] - - if("type") - var/new_value - new_value = input("Enter type:","Type",O.vars[variable]) as null|anything in typesof(/obj,/mob,/area,/turf) - if(new_value == null) return - O.vars[variable] = new_value - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in world) - if( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if(M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if(A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in world) - if(A.type == O.type) - A.vars[variable] = O.vars[variable] - - if("file") - var/new_value = input("Pick file:","File",O.vars[variable]) as null|file - if(new_value == null) return - O.vars[variable] = new_value - - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O.type, /obj)) - for(var/obj/A in world) - if( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O.type, /turf)) - for(var/turf/A in world) - if( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if(M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O.type, /obj)) - for(var/obj/A in world) - if(A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O.type, /turf)) - for(var/turf/A in world) - if(A.type == O.type) - A.vars[variable] = O.vars[variable] - - if("icon") - var/new_value = input("Pick icon:","Icon",O.vars[variable]) as null|icon - if(new_value == null) return - O.vars[variable] = new_value - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in world) - if( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if(M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if(A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in world) - if(A.type == O.type) - A.vars[variable] = O.vars[variable] - - log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]") - message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]", 1) \ No newline at end of file + else + for(var/datum/thing in world) + if(typecache[thing.type]) + . += thing + CHECK_TICK \ No newline at end of file diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index cb50d2e6391..0ad266ecaa1 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -1,294 +1,512 @@ -var/list/forbidden_varedit_object_types = list( - /datum/admins, //Admins editing their own admin-power object? Yup, sounds like a good idea. - /obj/machinery/blackbox_recorder, //Prevents people messing with feedback gathering - /datum/feedback_variable //Prevents people messing with feedback gathering - ) +var/list/VVlocked = list("vars", "var_edited", "client", "firemut", "ishulk", "telekinesis", "xray", "ka", "virus", "viruses", "cuffed", "last_eaten", "unlock_content") // R_DEBUG +var/list/VVicon_edit_lock = list("icon", "icon_state", "overlays", "underlays", "resize") // R_EVENT | R_DEBUG +var/list/VVckey_edit = list("key", "ckey") // R_EVENT | R_DEBUG +var/list/VVpixelmovement = list("step_x", "step_y", "bound_height", "bound_width", "bound_x", "bound_y") // R_DEBUG + warning +/client/proc/vv_get_class(var/var_value) + if(isnull(var_value)) + . = VV_NULL -/* -/client/proc/cmd_modify_object_variables(obj/O as obj|mob|turf|area in world) - set category = "Debug" - set name = "Edit Variables" - set desc="(target) Edit a target item's variables" - src.modify_variables(O) - feedback_add_details("admin_verb","EDITV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -*/ + else if(isnum(var_value)) + . = VV_NUM -/proc/datum_is_forbidden(type) - for(var/p in forbidden_varedit_object_types) - if(istype(type, p)) - to_chat(usr, "It is forbidden to tamper with this object.") - return FALSE - return TRUE + else if(istext(var_value)) + if(findtext(var_value, "\n")) + . = VV_MESSAGE + else + . = VV_TEXT + else if(isicon(var_value)) + . = VV_ICON -/client/proc/cmd_modify_ticker_variables() - set category = "Debug" - set name = "Edit Ticker Variables" + else if(ismob(var_value)) + . = VV_MOB_REFERENCE - if(ticker == null) - to_chat(src, "Game hasn't started yet.") + else if(isloc(var_value)) + . = VV_ATOM_REFERENCE + + else if(istype(var_value, /matrix)) + . = VV_MATRIX + + else if(istype(var_value,/client)) + . = VV_CLIENT + + else if(istype(var_value, /datum)) + . = VV_DATUM_REFERENCE + + else if(ispath(var_value)) + if(ispath(var_value, /atom)) + . = VV_ATOM_TYPE + else if(ispath(var_value, /datum)) + . = VV_DATUM_TYPE + else + . = VV_TYPE + + else if(islist(var_value)) + . = VV_LIST + + else if(isfile(var_value)) + . = VV_FILE else - src.modify_variables(ticker) - feedback_add_details("admin_verb","ETV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + . = VV_NULL -/client/proc/mod_list_add_ass() //haha +/client/proc/vv_get_value(class, default_class, current_value, list/restricted_classes, list/extra_classes, list/classes) + . = list("class" = class, "value" = null) + if(!class) + if(!classes) + classes = list( + VV_NUM, + VV_TEXT, + VV_MESSAGE, + VV_ICON, + VV_ATOM_REFERENCE, + VV_DATUM_REFERENCE, + VV_MOB_REFERENCE, + VV_CLIENT, + VV_ATOM_TYPE, + VV_DATUM_TYPE, + VV_TYPE, + VV_MATRIX, + VV_FILE, + VV_NEW_ATOM, + VV_NEW_DATUM, + VV_NEW_TYPE, + VV_NEW_LIST, + VV_NULL, + VV_RESTORE_DEFAULT + ) - var/class = "text" - var/list/allowed_types = list("text", "num","type", "type from text","reference","mob reference", "icon","file","list","edit referenced object","restore to default") - if(src.holder && src.holder.marked_datum) - allowed_types += "marked datum ([holder.marked_datum.type])" - class = input("What kind of variable?","Variable Type") as null|anything in allowed_types + if(holder && holder.marked_datum && !(VV_MARKED_DATUM in restricted_classes)) + classes += "[VV_MARKED_DATUM] ([holder.marked_datum.type])" + if(restricted_classes) + classes -= restricted_classes + + if(extra_classes) + classes += extra_classes + + .["class"] = input(src, "What kind of data?", "Variable Type", default_class) as null|anything in classes + if(holder && holder.marked_datum && .["class"] == "[VV_MARKED_DATUM] ([holder.marked_datum.type])") + .["class"] = VV_MARKED_DATUM + + + switch(.["class"]) + if(VV_TEXT) + .["value"] = input("Enter new text:", "Text", current_value) as null|text + if(.["value"] == null) + .["class"] = null + return + if(VV_MESSAGE) + .["value"] = input("Enter new text:", "Text", current_value) as null|message + if(.["value"] == null) + .["class"] = null + return + + + if(VV_NUM) + .["value"] = input("Enter new number:", "Num", current_value) as null|num + if(.["value"] == null) + .["class"] = null + return + + + if(VV_ATOM_TYPE) + .["value"] = pick_closest_path(FALSE) + if(.["value"] == null) + .["class"] = null + return + + if(VV_DATUM_TYPE) + .["value"] = pick_closest_path(FALSE, get_fancy_list_of_datum_types()) + if(.["value"] == null) + .["class"] = null + return + + if(VV_TYPE) + var/type = current_value + var/error = "" + do + type = input("Enter type:[error]", "Type", type) as null|text + if(!type) + break + type = text2path(type) + error = "\nType not found, Please try again" + while(!type) + if(!type) + .["class"] = null + return + .["value"] = type + + if(VV_MATRIX) + .["value"] = text2matrix(input("Enter a, b, c, d, e, and f, seperated by a space.", "Matrix", "1 0 0 0 1 0") as null|text) + if(.["value"] == null) + .["class"] = null + return + + + if(VV_ATOM_REFERENCE) + var/type = pick_closest_path(FALSE) + var/subtypes = vv_subtype_prompt(type) + if(subtypes == null) + .["class"] = null + return + var/list/things = vv_reference_list(type, subtypes) + var/value = input("Select reference:", "Reference", current_value) as null|anything in things + if(!value) + .["class"] = null + return + .["value"] = things[value] + + if(VV_DATUM_REFERENCE) + var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types()) + var/subtypes = vv_subtype_prompt(type) + if(subtypes == null) + .["class"] = null + return + var/list/things = vv_reference_list(type, subtypes) + var/value = input("Select reference:", "Reference", current_value) as null|anything in things + if(!value) + .["class"] = null + return + .["value"] = things[value] + + if(VV_MOB_REFERENCE) + var/type = pick_closest_path(FALSE, make_types_fancy(typesof(/mob))) + var/subtypes = vv_subtype_prompt(type) + if(subtypes == null) + .["class"] = null + return + var/list/things = vv_reference_list(type, subtypes) + var/value = input("Select reference:", "Reference", current_value) as null|anything in things + if(!value) + .["class"] = null + return + .["value"] = things[value] + + + + if(VV_CLIENT) + .["value"] = input("Select reference:", "Reference", current_value) as null|anything in clients + if(.["value"] == null) + .["class"] = null + return + + + if(VV_FILE) + .["value"] = input("Pick file:", "File") as null|file + if(.["value"] == null) + .["class"] = null + return + + + if(VV_ICON) + .["value"] = input("Pick icon:", "Icon") as null|icon + if(.["value"] == null) + .["class"] = null + return + + + if(VV_MARKED_DATUM) + .["value"] = holder.marked_datum + if(.["value"] == null) + .["class"] = null + return + + if(VV_NEW_ATOM) + var/type = pick_closest_path(FALSE) + if(!type) + .["class"] = null + return + .["type"] = type + .["value"] = new type() + + if(VV_NEW_DATUM) + var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types()) + if(!type) + .["class"] = null + return + .["type"] = type + .["value"] = new type() + + if(VV_NEW_TYPE) + var/type = current_value + var/error = "" + do + type = input("Enter type:[error]", "Type", type) as null|text + if(!type) + break + type = text2path(type) + error = "\nType not found, Please try again" + while(!type) + if(!type) + .["class"] = null + return + .["type"] = type + .["value"] = new type() + + + if(VV_NEW_LIST) + .["value"] = list() + .["type"] = /list + +/client/proc/vv_parse_text(O, new_var) + if(O && findtext(new_var, "\[")) + var/process_vars = alert(usr, "\[] detected in string, process as variables?", "Process Variables?", "Yes", "No") + if(process_vars == "Yes") + . = string2listofvars(new_var, O) + +//do they want you to include subtypes? +//FALSE = no subtypes, strict exact type pathing (or the type doesn't have subtypes) +//TRUE = Yes subtypes +//NULL = User cancelled at the prompt or invalid type given +/client/proc/vv_subtype_prompt(var/type) + if(!ispath(type)) + return + var/list/subtypes = subtypesof(type) + if(!subtypes || !subtypes.len) + return FALSE + if(subtypes && subtypes.len) + switch(alert("Strict object type detection?", "Type detection", "Strictly this type","This type and subtypes", "Cancel")) + if("Strictly this type") + return FALSE + if("This type and subtypes") + return TRUE + else + return + +/client/proc/vv_reference_list(type, subtypes) + . = list() + var/list/types = list(type) + if(subtypes) + types = typesof(type) + + var/list/fancytypes = make_types_fancy(types) + + for(var/fancytype in fancytypes) //swap the assoication + types[fancytypes[fancytype]] = fancytype + + var/things = get_all_of_type(type, subtypes) + + var/i = 0 + for(var/thing in things) + var/datum/D = thing + i++ + //try one of 3 methods to shorten the type text: + // fancy type, + // fancy type with the base type removed from the begaining, + // the type with the base type removed from the begaining + var/fancytype = types[D.type] + if(findtext(fancytype, types[type])) + fancytype = copytext(fancytype, lentext(types[type])+1) + var/shorttype = copytext("[D.type]", lentext("[type]")+1) + if(lentext(shorttype) > lentext(fancytype)) + shorttype = fancytype + if(!lentext(shorttype)) + shorttype = "/" + + .["[D]([shorttype])\ref[D]#[i]"] = D + +/client/proc/mod_list_add_ass(atom/O) //haha + var/list/L = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT)) + var/class = L["class"] if(!class) return + var/var_value = L["value"] - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" - - var/var_value = null - - switch(class) - - if("text") - var_value = input("Enter new text:","Text") as null|message - - if("num") - var_value = input("Enter new number:","Num") as null|num - - if("type") - var_value = input("Enter type:","Type") as null|anything in typesof(/obj,/mob,/area,/turf) - - if("type from text") - var/type_text = input("Enter type:", "Type") as null|message - var_value = text2path(type_text) - if(!var_value) - to_chat(src, "[type_text] is not a valid path!") - - if("reference") - var_value = input("Select reference:","Reference") as null|mob|obj|turf|area in world - - if("mob reference") - var_value = input("Select reference:","Reference") as null|mob in world - - if("file") - var_value = input("Pick file:","File") as null|file - - if("icon") - var_value = input("Pick icon:","Icon") as null|icon - - if("marked datum") - var_value = holder.marked_datum - - if(!var_value) return + if(class == VV_TEXT || class == VV_MESSAGE) + var/list/varsvars = vv_parse_text(O, var_value) + for(var/V in varsvars) + var_value = replacetext(var_value,"\[[V]]","[O.vars[V]]") return var_value - -/client/proc/mod_list_add(var/list/L) - - var/class = "text" - var/list/allowed_types = list("text", "num","type", "type from text","reference","mob reference", "icon","file","list","edit referenced object","restore to default") - if(src.holder && src.holder.marked_datum) - allowed_types += "marked datum ([holder.marked_datum.type])" - class = input("What kind of variable?","Variable Type") as null|anything in allowed_types - +/client/proc/mod_list_add(list/L, atom/O, original_name, objectvar) + var/list/LL = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT)) + var/class = LL["class"] if(!class) return + var/var_value = LL["value"] - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" + if(class == VV_TEXT || class == VV_MESSAGE) + var/list/varsvars = vv_parse_text(O, var_value) + for(var/V in varsvars) + var_value = replacetext(var_value,"\[[V]]","[O.vars[V]]") - var/var_value = null + if(O) + L = L.Copy() - switch(class) + L += var_value - if("text") - var_value = input("Enter new text:","Text") as message|null - - if("num") - var_value = input("Enter new number:","Num") as num - - if("type") - var_value = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf) - - if("type from text") - var/type_text = input("Enter type:", "Type") as null|message - var_value = text2path(type_text) - if(!var_value) - to_chat(src, "[type_text] is not a valid path!") - - if("reference") - var_value = input("Select reference:","Reference") as mob|obj|turf|area in world - - if("mob reference") - var_value = input("Select reference:","Reference") as mob in world - - if("file") - var_value = input("Pick file:","File") as file - - if("icon") - var_value = input("Pick icon:","Icon") as icon - - if("marked datum") - var_value = holder.marked_datum - - if(!var_value) return - - switch(alert("Would you like to associate a var with the list entry?",,"Yes","No")) + switch(alert("Would you like to associate a value with the list entry?",,"Yes","No")) if("Yes") - L += var_value - L[var_value] = mod_list_add_ass() //haha - if("No") - L += var_value + L[var_value] = mod_list_add_ass(O) //hehe + if(O) + if(!O.vv_edit_var(objectvar, L)) + to_chat(src, "Your edit was rejected by the object.") + return + log_to_dd("### ListVarEdit by [src]: [(O ? O.type : "/list")] [objectvar]: ADDED=[var_value]") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]") + message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]") -/client/proc/mod_list(var/list/L) - if(!check_rights(R_VAREDIT)) return - - if(!istype(L,/list)) +/client/proc/mod_list(list/L, atom/O, original_name, objectvar, index, autodetect_class = FALSE) + if(!check_rights(R_VAREDIT)) + return + if(!istype(L, /list)) to_chat(src, "Not a List.") + return + if(L.len > 1000) var/confirm = alert(src, "The list you're trying to edit is very long, continuing may crash the server.", "Warning", "Continue", "Abort") if(confirm != "Continue") return - var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine", "poo", "icon", "icon_state", "step_x", "step_y") - var/assoc = 0 - if(L.len > 0) - var/a = L[1] - if(istext(a) && L[a] != null) - assoc = 1 //This is pretty weak test but i can't think of anything else - to_chat(usr, "List appears to be associative.") - var/list/names = null - if(!assoc) - names = sortList(L) + var/list/names = list() + for(var/i in 1 to L.len) + var/key = L[i] + var/value + if(IS_NORMAL_LIST(L) && !isnum(key)) + value = L[key] + if(value == null) + value = "null" + names["#[i] [key] = [value]"] = i + if(!index) + var/variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)" + "(CLEAR NULLS)" + "(CLEAR DUPES)" + "(SHUFFLE)" + + if(variable == null) + return + + if(variable == "(ADD VAR)") + mod_list_add(L, O, original_name, objectvar) + return + + if(variable == "(CLEAR NULLS)") + L = L.Copy() + listclearnulls(L) + if(!O.vv_edit_var(objectvar, L)) + to_chat(src, "Your edit was rejected by the object.") + return + log_to_dd("### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR NULLS") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: CLEAR NULLS") + message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: CLEAR NULLS") + return + + if(variable == "(CLEAR DUPES)") + L = uniqueList(L) + if(!O.vv_edit_var(objectvar, L)) + to_chat(src, "Your edit was rejected by the object.") + return + log_to_dd("### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR DUPES") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: CLEAR DUPES") + message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: CLEAR DUPES") + return + + if(variable == "(SHUFFLE)") + L = shuffle(L) + if(!O.vv_edit_var(objectvar, L)) + to_chat(src, "Your edit was rejected by the object.") + return + log_to_dd("### ListVarEdit by [src]: [O.type] [objectvar]: SHUFFLE") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: SHUFFLE") + message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: SHUFFLE") + return + + index = names[variable] + - var/variable var/assoc_key - if(assoc) - variable = input("Which var?","Var") as null|anything in L + "(ADD VAR)" - else - variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)" - - if(variable == "(ADD VAR)") - mod_list_add(L) + if(index == null) return - - if(assoc) - assoc_key = variable - variable = L[assoc_key] - - if(!assoc && !variable || assoc && !assoc_key) + var/assoc = 0 + var/prompt = alert(src, "Do you want to edit the key or it's assigned value?", "Associated List", "Key", "Assigned Value", "Cancel") + if(prompt == "Cancel") return - + if(prompt == "Assigned Value") + assoc = 1 + assoc_key = L[index] var/default + var/variable + if(assoc) + variable = L[assoc_key] + else + variable = L[index] - var/dir + default = vv_get_class(variable) - if(variable in locked) - if(!check_rights(R_DEBUG)) return + to_chat(src, "Variable appears to be [uppertext(default)].") - default = variable_to_type(variable) + to_chat(src, "Variable contains: [L[index]]") - to_chat(usr, "Variable contains: [variable]") - if(default == "num") - dir = dir2text(variable) + if(default == VV_NUM) + var/dir_text = "" + if(dir < 0 && dir < 16) + if(dir & 1) + dir_text += "NORTH" + if(dir & 2) + dir_text += "SOUTH" + if(dir & 4) + dir_text += "EAST" + if(dir & 8) + dir_text += "WEST" - if(dir) - to_chat(usr, "If a direction, direction is: [dir]") - - var/class = "text" - var/list/allowed_types = list("text", "num","type", "type from text", "reference","mob reference", "icon","file","list","edit referenced object","restore to default","DELETE FROM LIST") - if(src.holder && src.holder.marked_datum) - allowed_types += "marked datum ([holder.marked_datum.type])" - - class = input("What kind of variable?","Variable Type",default) as null|anything in allowed_types + if(dir_text) + to_chat(src, "If a direction, direction is: [dir_text]") + var/original_var + if(assoc) + original_var = L[assoc_key] + else + original_var = L[index] + if(O) + L = L.Copy() + var/class + if(autodetect_class) + if(default == VV_TEXT) + default = VV_MESSAGE + class = default + var/list/LL = vv_get_value(default_class = default, current_value = original_var, restricted_classes = list(VV_RESTORE_DEFAULT), extra_classes = list(VV_LIST, "DELETE FROM LIST")) + class = LL["class"] if(!class) return + var/new_var = LL["value"] - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" + if(class == VV_MESSAGE) + class = VV_TEXT switch(class) //Spits a runtime error if you try to modify an entry in the contents list. Dunno how to fix it, yet. - - if("list") - mod_list(variable) - - if("restore to default") - if(assoc) - L[assoc_key] = initial(variable) - else - L[L.Find(variable)]=initial(variable) - - if("edit referenced object") - modify_variables(variable) + if(VV_LIST) + mod_list(variable, O, original_name, objectvar) if("DELETE FROM LIST") - L -= variable + L.Cut(index, index+1) + if(O) + if(!O.vv_edit_var(objectvar, L)) + to_chat(src, "Your edit was rejected by the object.") + return + log_to_dd("### ListVarEdit by [src]: [O.type] [objectvar]: REMOVED=[html_encode("[original_var]")]") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: REMOVED=[original_var]") + message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: REMOVED=[original_var]") return - if("text") - if(assoc) - L[assoc_key] = input("Enter new text:","Text") as text - else - L[L.Find(variable)] = input("Enter new text:","Text") as text - - if("num") - if(assoc) - L[assoc_key] = input("Enter new number:","Num") as num - else - L[L.Find(variable)] = input("Enter new number:","Num") as num - - if("type") - if(assoc) - L[assoc_key] = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf) - else - L[L.Find(variable)] = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf) - - if("reference") - if(assoc) - L[assoc_key] = input("Select reference:","Reference") as mob|obj|turf|area in world - else - L[L.Find(variable)] = input("Select reference:","Reference") as mob|obj|turf|area in world - - if("mob reference") - if(assoc) - L[assoc_key] = input("Select reference:","Reference") as mob in world - else - L[L.Find(variable)] = input("Select reference:","Reference") as mob in world - - if("file") - if(assoc) - L[assoc_key] = input("Pick file:","File") as file - else - L[L.Find(variable)] = input("Pick file:","File") as file - - if("icon") - if(assoc) - L[assoc_key] = input("Pick icon:","Icon") as icon - else - L[L.Find(variable)] = input("Pick icon:","Icon") as icon - - if("marked datum") - if(assoc) - L[assoc_key] = holder.marked_datum - else - L[L.Find(variable)] = holder.marked_datum + if(VV_TEXT) + var/list/varsvars = vv_parse_text(O, new_var) + for(var/V in varsvars) + new_var = replacetext(new_var,"\[[V]]","[O.vars[V]]") -/client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) - if(!check_rights(R_VAREDIT)) return - - var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "icon", "icon_state") - - for(var/p in forbidden_varedit_object_types) - if( istype(O,p) ) - to_chat(usr, "It is forbidden to edit this object's variables.") + if(assoc) + L[assoc_key] = new_var + else + L[index] = new_var + if(O) + if(!O.vv_edit_var(objectvar, L)) + to_chat(src, "Your edit was rejected by the object.") return + log_to_dd("### ListVarEdit by [src]: [(O ? O.type : "/list")] [objectvar]: [original_var]=[new_var]") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: [original_var]=[new_var]") + message_admins("[key_name_admin(src)] modified [original_name]'s varlist [objectvar]: [original_var]=[new_var]") - if(istype(O, /client) && (param_var_name == "ckey" || param_var_name == "key")) - to_chat(usr, "You cannot edit ckeys on client objects.") +/client/proc/modify_variables(atom/O, param_var_name = null, autodetect_class = 0) + if(!check_rights(R_VAREDIT)) return var/class @@ -297,24 +515,11 @@ var/list/forbidden_varedit_object_types = list( if(param_var_name) if(!param_var_name in O.vars) - to_chat(src, "A variable with this name ([param_var_name]) doesn't exist in this atom ([O])") + to_chat(src, "A variable with this name ([param_var_name]) doesn't exist in this datum ([O])") return - - if(param_var_name == "holder" || (param_var_name in locked)) - if(!check_rights(R_DEBUG)) return - variable = param_var_name - var_value = O.vars[variable] - - if(autodetect_class) - class = variable_to_type(var_value) - if(!class) - autodetect_class = null - else if(class == "num") - dir = 1 else - var/list/names = list() for(var/V in O.vars) names += V @@ -322,187 +527,92 @@ var/list/forbidden_varedit_object_types = list( names = sortList(names) variable = input("Which var?","Var") as null|anything in names - if(!variable) return - var_value = O.vars[variable] - - if(variable == "holder" || (variable in locked)) - if(!check_rights(R_DEBUG)) return - - if(!autodetect_class) - - var/dir - var/default - default = variable_to_type(var_value) - if(default == "num") - dir = 1 - else if(default == "icon") - var_value = "[bicon(var_value)]" - - to_chat(usr, "Variable contains: [var_value]") - if(dir) - dir = dir2text(var_value) - if(dir) - to_chat(usr, "If a direction, direction is: [dir]") - - var/list/allowed_types = list("text", "num","type","reference","mob reference", "path", "matrix", "icon","file","list","edit referenced object","restore to default") - if(src.holder && src.holder.marked_datum) - allowed_types += "marked datum ([holder.marked_datum.type])" - - class = input("What kind of variable?","Variable Type",default) as null|anything in allowed_types - - if(!class) + if(!variable) return - var/original_name + if(!O.can_vv_get(variable)) + return - if(!istype(O, /atom)) - original_name = "\ref[O] ([O])" + var_value = O.vars[variable] + + if(variable in VVlocked) + if(!check_rights(R_DEBUG)) + return + if(variable in VVckey_edit) + if(!check_rights(R_EVENT | R_DEBUG)) + return + if(variable in VVicon_edit_lock) + if(!check_rights(R_EVENT | R_DEBUG)) + return + if(variable in VVpixelmovement) + if(!check_rights(R_DEBUG)) + return + var/prompt = alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT") + if(prompt != "Continue") + return + + + var/default = vv_get_class(var_value) + + if(isnull(default)) + to_chat(src, "Unable to determine variable type.") else - original_name = O:name + to_chat(src, "Variable appears to be [uppertext(default)].") - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" + to_chat(src, "Variable contains: [var_value]") + + if(default == VV_NUM) + var/dir_text = "" + if(dir < 0 && dir < 16) + if(dir & 1) + dir_text += "NORTH" + if(dir & 2) + dir_text += "SOUTH" + if(dir & 4) + dir_text += "EAST" + if(dir & 8) + dir_text += "WEST" + + if(dir_text) + to_chat(src, "If a direction, direction is: [dir_text]") + + if(autodetect_class && default != VV_NULL) + if(default == VV_TEXT) + default = VV_MESSAGE + class = default + + var/list/value = vv_get_value(class, default, var_value, extra_classes = list(VV_LIST)) + class = value["class"] + + if(!class) + return + var/var_new = value["value"] + + if(class == VV_MESSAGE) + class = VV_TEXT + + var/original_name = "[O]" - var/var_as_text = null switch(class) + if(VV_LIST) + if(!islist(var_value)) + mod_list(list(), O, original_name, variable) - if("list") - mod_list(O.vars[variable]) + mod_list(var_value, O, original_name, variable) return - if("restore to default") - O.vars[variable] = initial(O.vars[variable]) + if(VV_RESTORE_DEFAULT) + var_new = initial(O.vars[variable]) - if("edit referenced object") - return .(O.vars[variable]) + if(VV_TEXT) + var/list/varsvars = vv_parse_text(O, var_new) + for(var/V in varsvars) + var_new = replacetext(var_new,"\[[V]]","[O.vars[V]]") - if("text") - var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|message - if(var_new==null) return - O.vars[variable] = var_new - - if("num") - if(variable=="light_range") - var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num - if(var_new == null) return - O.set_light(var_new) - else if(variable=="stat") // ow, but I guess I'm glad you're trying to prevent at least one kind of inconsistent state...? This is the VARIABLE EDITOR, I'm not sure we need to worry...? - var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num - if(var_new == null) return - if((O.vars[variable] == DEAD) && (var_new < DEAD))//Bringing the dead back to life - dead_mob_list -= O - living_mob_list += O - if((O.vars[variable] < DEAD) && (var_new == DEAD))//Kill he - living_mob_list -= O - dead_mob_list += O - O.vars[variable] = var_new - else - var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num - if(var_new==null) return - O.vars[variable] = var_new - - if("type") - var/var_new = input("Enter type:","Type",O.vars[variable]) as null|anything in typesof(/obj,/mob,/area,/turf) - if(var_new==null) return - O.vars[variable] = var_new - - if("path") - var/path_text = input("Enter path:", "Path",O.vars[variable]) as null|text - var/var_new = text2path(path_text) - if(!var_new && path_text != null) // So aborting doesn't bother the VVer - to_chat(usr, "[path_text] does not appear to be a valid path.") - return - O.vars[variable] = var_new - - if("matrix") - var/matrix_text = input("Enter a, b, c, d, e, and f, separated by a space.", "Matrix", "1 0 0 0 1 0") as null|text - var/var_new = text2matrix(matrix_text) - if(!var_new && matrix_text != null) - to_chat(usr, "[matrix_text] is not a valid matrix string.") - return - O.vars[variable] = var_new - var_as_text = "matrix([matrix_text])" - - if("reference") - var/var_new = input("Select reference:","Reference",O.vars[variable]) as null|mob|obj|turf|area in world - if(var_new==null) return - O.vars[variable] = var_new - - if("mob reference") - var/var_new = input("Select reference:","Reference",O.vars[variable]) as null|mob in world - if(var_new==null) return - O.vars[variable] = var_new - - if("file") - var/var_new = input("Pick file:","File",O.vars[variable]) as null|file - if(var_new==null) return - O.vars[variable] = var_new - - if("icon") - var/var_new = input("Pick icon:","Icon",O.vars[variable]) as null|icon - if(var_new==null) return - O.vars[variable] = var_new - - if("marked datum") - O.vars[variable] = holder.marked_datum - - if(var_as_text == null) - var_as_text = "[O.vars[variable]]" - O.on_varedit(variable) - log_to_dd("### VarEdit by [src]: [O.type] [variable]=[html_encode("[var_as_text]")]") - log_admin("[key_name(src)] modified [original_name]'s [variable] to [var_as_text]") - message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [var_as_text]", 1) - -// Let's get this all in one place. -// You'll need to take care of setting dir or iconizing the variable yourself once you've called this -/proc/variable_to_type(var/variable) - var/class - if(isnull(variable)) - to_chat(usr, "Unable to determine variable type.") - class = null - else if(isnum(variable)) - to_chat(usr, "Variable appears to be NUM.") - class = "num" - - else if(istext(variable)) - to_chat(usr, "Variable appears to be TEXT.") - class = "text" - - else if(isloc(variable)) - to_chat(usr, "Variable appears to be REFERENCE.") - class = "reference" - - else if(isicon(variable)) - to_chat(usr, "Variable appears to be ICON.") - variable = "[bicon(variable)]" - class = "icon" - - else if(istype(variable,/matrix)) - to_chat(usr, "Variable appears to be MATRIX") - class = "matrix" - - else if(istype(variable,/atom) || istype(variable,/datum)) - to_chat(usr, "Variable appears to be TYPE.") - class = "type" - - else if(istype(variable,/list)) - to_chat(usr, "Variable appears to be LIST.") - class = "list" - - else if(istype(variable,/client)) - to_chat(usr, "Variable appears to be CLIENT.") - class = "cancel" - - else if(ispath(variable)) - to_chat(usr, "Variable appears to be PATH.") - class = "path" - - else if(isfile(variable)) - to_chat(usr, "Variable appears to be FILE.") - class = "file" - - else - to_chat(usr, "Variable type is UNKNOWN.") - class = null - - return class + if(!O.vv_edit_var(variable, var_new)) + to_chat(src, "Your edit was rejected by the object.") + return + log_to_dd("### VarEdit by [src]: [O.type] [variable]=[html_encode("[var_new]")]") + log_admin("[key_name(src)] modified [original_name]'s [variable] to [var_new]") + var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] to [var_new]" + message_admins(msg) \ No newline at end of file diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 4560c7affa9..8651d26f016 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -13,7 +13,22 @@ return var/image/cross = image('icons/obj/storage.dmi',"bible") - msg = "[bicon(cross)] PRAY: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src)]) (CA) (SC) (BLESS) (SMITE): [msg]" + var/font_color = "purple" + var/prayer_type = "PRAYER" + var/deity + if(usr.job == "Chaplain") + if(ticker && ticker.Bible_deity_name) + deity = ticker.Bible_deity_name + cross = image('icons/obj/storage.dmi',"kingyellow") + font_color = "blue" + prayer_type = "CHAPLAIN PRAYER" + else if(iscultist(usr)) + cross = image('icons/obj/storage.dmi',"tome") + font_color = "red" + prayer_type = "CULTIST PRAYER" + deity = ticker.mode.cultdat.entity_name + + msg = "[bicon(cross)][prayer_type][deity ? " (to [deity])" : ""]:[key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src)]) (CA) (SC) (BLESS) (SMITE): [msg]" for(var/client/X in admins) if(check_rights(R_EVENT,0,X.mob)) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index fdfbdfba6b2..84f95096078 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -61,7 +61,7 @@ if(usr) if(usr.client) if(usr.client.holder) - to_chat(M, "old You hear a voice in your head... [msg]") + to_chat(M, "You hear a voice in your head... [msg]") log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]") message_admins("SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]", 1) @@ -588,22 +588,30 @@ Traitors and the like can also be revived with the previous role mostly intact. feedback_add_details("admin_verb","CCR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_admin_delete(atom/O as obj|mob|turf in view()) +/client/proc/cmd_admin_delete(atom/A as obj|mob|turf in view()) set category = "Admin" set name = "Delete" if(!check_rights(R_ADMIN)) return - if(alert(src, "Are you sure you want to delete:\n[O]\nat ([O.x], [O.y], [O.z])?", "Confirmation", "Yes", "No") == "Yes") - log_admin("[key_name(usr)] deleted [O] at ([O.x],[O.y],[O.z])") - message_admins("[key_name_admin(usr)] deleted [O] at ([O.x],[O.y],[O.z])", 1) + admin_delete(A) + +/client/proc/admin_delete(datum/D) + if(istype(D) && !D.can_vv_delete()) + to_chat(src, "[D] rejected your deletion") + return + var/atom/A = D + var/coords = istype(A) ? "at ([A.x], [A.y], [A.z])" : "" + if(alert(src, "Are you sure you want to delete:\n[D]\n[coords]?", "Confirmation", "Yes", "No") == "Yes") + log_admin("[key_name(usr)] deleted [D][coords]") + message_admins("[key_name_admin(usr)] deleted [D][coords]", 1) feedback_add_details("admin_verb","DEL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - if(istype(O, /turf)) - var/turf/T = O + if(isturf(D)) + var/turf/T = D T.ChangeTurf(/turf/space) - return - qdel(O) + else + qdel(D) /client/proc/cmd_admin_list_open_jobs() set category = "Admin" diff --git a/code/modules/busy_space/air_traffic.dm b/code/modules/busy_space/air_traffic.dm new file mode 100644 index 00000000000..de0b37ed3c3 --- /dev/null +++ b/code/modules/busy_space/air_traffic.dm @@ -0,0 +1,129 @@ +//Cactus, Speedbird, Dynasty, oh my + +var/datum/lore/atc_controller/atc = new/datum/lore/atc_controller + +/datum/lore/atc_controller + var/delay_max = 10 MINUTES //Maximum amount of tiem between ATC messages. Default is 10 mins. + var/delay_min = 5 MINUTES //Minimum amount of time between ATC messages. Default is 5 mins. + var/backoff_delay = 5 MINUTES //How long to back off if we can't talk and want to. Default is 5 mins. + var/next_message //When the next message should happen in world.time + var/force_chatter_type //Force a specific type of messages + + var/squelched = FALSE //If ATC is squelched currently + +/datum/lore/atc_controller/New() + spawn(30 SECONDS) //Lots of lag at the start of a shift. + msg("New shift beginning, resuming traffic control.") + next_message = world.time + rand(delay_min, delay_max) + process() + +/datum/lore/atc_controller/proc/process() + if(world.time >= next_message) + if(squelched) + next_message = world.time + backoff_delay + else + next_message = world.time + rand(delay_min,delay_max) + random_convo() + + spawn(1 MINUTES) //We don't really need high-accuracy here. + process() + +/datum/lore/atc_controller/proc/msg(var/message,var/sender) + ASSERT(message) + global_announcer.autosay("[message]", sender ? sender : "[using_map.station_short] Space Control") + +/datum/lore/atc_controller/proc/reroute_traffic(var/yes = 1) + if(yes) + if(!squelched) + msg("Rerouting traffic away from [using_map.station_name].") + squelched = TRUE + else + if(squelched) + msg("Resuming normal traffic routing around [using_map.station_name].") + squelched = FALSE + +/datum/lore/atc_controller/proc/shift_ending(var/evac = 0) + msg("Automated Shuttle departing [using_map.station_name] for [using_map.dock_name] on routine transfer route.", "NT Automated Shuttle") + sleep(5 SECONDS) + msg("Automated Shuttle, cleared to complete routine transfer from [using_map.station_name] to [using_map.dock_name].") + +/datum/lore/atc_controller/proc/random_convo() + var/one = pick(loremaster.organizations) //These will pick an index, not an instance + var/two = pick(loremaster.organizations) + + var/datum/lore/organization/source = loremaster.organizations[one] //Resolve to the instances + var/datum/lore/organization/dest = loremaster.organizations[two] + + //Let's get some mission parameters + var/owner = source.short_name //Use the short name + var/prefix = pick(source.ship_prefixes) //Pick a random prefix + var/mission = source.ship_prefixes[prefix] //The value of the prefix is the mission type that prefix does + var/shipname = pick(source.ship_names) //Pick a random ship name to go with it + var/destname = pick(dest.destination_names) //Pick a random holding from the destination + + var/combined_name = "[owner] [prefix] [shipname]" + var/alt_atc_names = list("[using_map.station_short] TraCon", "[using_map.station_short] Control", "[using_map.station_short] STC", "[using_map.station_short] Airspace") + var/wrong_atc_names = list("Sol Command", "Orion Control", "[using_map.dock_name]") + var/mission_noun = list("flight", "mission", "route") + var/request_verb = list("requesting", "calling for", "asking for") + + //First response is 'yes', second is 'no' + var/requests = list("[using_map.station_short] transit clearance" = list("cleared to transit", "unable to approve, contact regional on 953.5"), + "planetary flight rules" = list("cleared planetary flight rules", "unable to approve planetary flight rules due to traffic"), + "special flight rules" = list("cleared special flight rules", "unable to approve special flight rules for your traffic class"), + "current solar weather info" = list("sending you the relevant information via tightbeam", "cannot fulfill your request at the moment"), + "nearby traffic info" = list("sending you current traffic info", "no known traffic for your flight plan route"), + "remote telemetry data" = list("sending telemetry now", "no uplink from your ship, recheck your uplink and ask again"), + "refueling information" = list("sending refueling information now", "no fuel for your ship class in this sector"), + "a current system time sync" = list("sending time sync ping to you now", "your ship isn't compatible with our time sync, set time manually"), + "current system starcharts" = list("transmitting current starcharts", "request on standby due to demand"), + "permission to engage FTL" = list("cleared to FTL, good day", "hold position, traffic crossing"), + "permission to transit system" = list("cleared to transit, good day", "hold position, traffic crossing"), + "permission to depart system" = list("cleared to leave via flight plan route, good day", "hold position, traffic crossing"), + "permission to enter system" = list("good day, cleared in as published", "hold position, traffic crossing"), + ) + + //Random chance things for variety + var/chatter_type = "normal" + if(force_chatter_type) + chatter_type = force_chatter_type + else + chatter_type = pick(2;"emerg",5;"wrong_freq","normal") //Be nice to have wrong_lang... + + var/yes = prob(90) //Chance for them to say yes vs no + + var/request = pick(requests) + var/callname = pick(alt_atc_names) + var/response = requests[request][yes ? 1 : 2] //1 is yes, 2 is no + + var/full_request + var/full_response + var/full_closure + + switch(chatter_type) + if("wrong_freq") + callname = pick(wrong_atc_names) + full_request = "[callname], this is [combined_name] on a [mission] [pick(mission_noun)] to [destname], [pick(request_verb)] [request]." + full_response = "[combined_name], this is [using_map.station_short] TraCon, wrong frequency. Switch to [rand(700,999)].[rand(1,9)]." + full_closure = "[using_map.station_short] TraCon, copy, apologies." + if("wrong_lang") + //Can't implement this until autosay has language support + if("emerg") + var/problem = pick("hull breaches on multiple decks","unknown life forms on board","a drive about to go critical","asteroids impacting the hull","a total loss of engine power","people trying to board the ship") + full_request = "Mayday, mayday, mayday, this is [combined_name] declaring an emergency! We have [problem]!" + var/rand_freq = "[rand(700,999)].[rand(1,9)]" + full_response = "[combined_name], this is [using_map.station_short] TraCon, copy. Switch to emergency responder channel [rand_freq]." + full_closure = "Roger, [using_map.station_short] TraCon, contacting [rand_freq]." + else + full_request = "[callname], this is [combined_name] on a [mission] [pick(mission_noun)] to [destname], [pick(request_verb)] [request]." + full_response = "[combined_name], this is [using_map.station_short] TraCon, [response]." //Station TraCon always calls themselves TraCon + full_closure = "[using_map.station_short] TraCon, [yes ? "thank you" : "copy"], good day." //They always copy what TraCon called themselves in the end when they realize they said it wrong + + //Ship sends request to ATC + msg(full_request,"[prefix] [shipname]") + sleep(5 SECONDS) + //ATC sends response to ship + msg(full_response) + sleep(5 SECONDS) + //Ship sends response to ATC + msg(full_closure,"[prefix] [shipname]") \ No newline at end of file diff --git a/code/modules/busy_space/loremaster.dm b/code/modules/busy_space/loremaster.dm new file mode 100644 index 00000000000..28dca0055b0 --- /dev/null +++ b/code/modules/busy_space/loremaster.dm @@ -0,0 +1,16 @@ +//I AM THE LOREMASTER, ARE YOU THE GATEKEEPER? + +var/datum/lore/loremaster/loremaster = new/datum/lore/loremaster + +/datum/lore/loremaster + var/list/organizations = list() + +/datum/lore/loremaster/New() + + var/list/paths = typesof(/datum/lore/organization) - /datum/lore/organization + for(var/path in paths) + // Some intermediate paths are not real organizations (ex. /datum/lore/organization/mil). Only do ones with names + var/datum/lore/organization/instance = path + if(initial(instance.name)) + instance = new path() + organizations[path] = instance diff --git a/code/modules/busy_space/organizations.dm b/code/modules/busy_space/organizations.dm new file mode 100644 index 00000000000..41b3a80cbab --- /dev/null +++ b/code/modules/busy_space/organizations.dm @@ -0,0 +1,549 @@ +//Datums for different companies that can be used by busy_space +/datum/lore/organization + var/name = "" // Organization's name + var/short_name = "" // Organization's shortname (Nanotrasen for "Nanotrasen Incorporated") + var/acronym = "" // Organization's acronym, e.g. 'NT' for Nanotrasen'. + var/desc = "" // One or two paragraph description of the organization, but only current stuff. Currently unused. + var/history = "" // Historical description of the organization's origins Currently unused. + var/work = "" // Short description of their work, eg "an arms manufacturer" + var/headquarters = "" // Location of the organization's HQ. Currently unused. + var/motto = "" // A motto/jingle/whatever, if they have one. Currently unused. + + var/list/ship_prefixes = list() //Some might have more than one! Like Nanotrasen. Value is the mission they perform, e.g. ("ABC" = "mission desc") + var/list/ship_names = list( //Names of spaceships. This is a mostly generic list that all the other organizations inherit from if they don't have anything better. + "Kestrel", + "Beacon", + "Signal", + "Freedom", + "Glory", + "Axiom", + "Eternal", + "Icarus", + "Harmony", + "Light", + "Discovery", + "Endeavour", + "Explorer", + "Swift", + "Dragonfly", + "Ascendant", + "Tenacious", + "Pioneer", + "Hawk", + "Haste", + "Radiant", + "Luminous", + "Gallant", + "Dependable", + "Indomitable", + "Guardian", + "Resolution", + "Fearless", + "Amazon", + "Relentless", + "Inspire", + "Implacable", + "Steadfast", + "Leviathan", + "Dauntless", + "Adroit", + "Mistral", + "Typhoon", + "Titan", + "Kupua", + "Alchemist", + "Cuirass", + "Citadel", + "Rondelle", + "Camail", + "Ocrea", + "Ram", + "Crest", + "Tanko", + "Pommel", + "Kissaki", + "Cavalier", + "Anelace", + "Flint", + "Xiphos", + "Parrot", + "Chamber", + "Annellet", + "Cestus", + "Talwar") + var/list/destination_names = list() //Names of static holdings that the organization's ships visit regularly. + var/autogenerate_destination_names = TRUE + +/datum/lore/organization/New() + ..() + if(autogenerate_destination_names) // Lets pad out the destination names. + var/i = rand(6, 10) + var/list/star_names = list( + "Sol", "Alpha Centauri", "Sirius", "Vega", "Regulus", "Vir", "Algol", "Aldebaran", + "Delta Doradus", "Menkar", "Geminga", "Elnath", "Gienah", "Mu Leporis", "Nyx", "Tau Ceti", + "Wazn", "Alphard", "Phact", "Altair", "Mauna", "Jargon", "Xarxis", "Hestia", "Dalstis", "Cygni", "Haverick", "Corvus", "Sancere", "Cydoni", "Kaliban", "Midway", "Dansik", "Branwyn") + var/list/destination_types = list("dockyard", "station", "vessel", "waystation", "telecommunications satellite", "spaceport", "distress beacon", "anomaly", "colony", "outpost") + while(i) + destination_names.Add("a [pick(destination_types)] in [pick(star_names)]") + i-- + +////////////////////////////////////////////////////////////////////////////////// + +// TSCs +/datum/lore/organization/tsc/nanotrasen + name = "Nanotrasen Incorporated" + short_name = "Nanotrasen" + acronym = "NT" + desc = "The largest shareholder in the galactic plasma markets, Nanotrasen is a research and mining corporation which specializes in\ + FTL technologies and weapon systems. Frowned upon by most governments due to their shady business tactics and poor ethics record,\ + Nanotrasen is often seen as a necessary evil for maintaining access to the often volatile plasma market. Nanotrasen was originally\ + incorporated on Earth with their headquarters situated on Mars, however they have recently moved most of their operations to the Epsilon Eridani sector." + history = "" // To be written someday. + work = "research giant" + headquarters = "Mars" + motto = "" + + ship_prefixes = list("NSV" = "exploration", "NTV" = "hauling", "NDV" = "patrol", "NRV" = "emergency response") + // Note that the current station being used will be pruned from this list upon being instantiated + destination_names = list( + "NAS Trurl in Epsilon Eridani", + "NAS Crescent in Tau Ceti", + "NSS Exodus in Tau Ceti", + "NSS Antiqua in Darsing", + "NRS Orion in Sol", + "NSS Vector in Omicron Ceti", + "NBS Anansi in Omicron Ceti", + "NSS Redemption in Sirius", + "NDS Inferno in Tau Ceti", + "NAB Smythside Central Headquarters on Earth", + "NAB North Cimmeria Central Offices on Mars", + ) + +/datum/lore/organization/tsc/nanotrasen/New() + ..() + spawn(1) // BYOND shenanigans means using_map is not initialized yet. Wait a tick. + // Get rid of the current map from the list, so ships flying in don't say they're coming to the current map. + var/string_to_test = "[using_map.station_name] in [using_map.starsys_name]" + if(string_to_test in destination_names) + destination_names.Remove(string_to_test) + + +/datum/lore/organization/tsc/donk + name = "Donk Corporation" + short_name = "Donk Co." + acronym = "DC" + desc = "The infamous rival of the well-known Waffle Corporation, Donk Co. is a company specializing in food delivery systems and brand-name food\ + products such as Donk Pockets. While generally seen as a neutral actor, Donk Corporation has been known to work both with Nanotrasen and\ + the Syndicate when it suits them - often acting as the primary logistical supplier for the Epsilon Eridani sector.\ + Donk Corporation is better known for recent high-profile litigation alleging that their food products are used for illicit drug distribution.\ + While the trial is ongoing, it has been repeatedly delayed due to incidents of methamphetamine poisoning." + history = "" + work = "food company that establishes and maintains delivery supply chains" + headquarters = "" + motto = "Now with 20% more donk!" + + ship_prefixes = list("D-Co." = "transportation") + destination_names = list() + +/datum/lore/organization/tsc/hephaestus + name = "Hephaestus Industries" + short_name = "Hephaestus" + acronym = "HI" + desc = "" + history = "" + work = "arms manufacturer" + headquarters = "" + motto = "" + + ship_prefixes = list("HTV" = "freight", "HTV" = "munitions resupply") + destination_names = list( + "a SolGov dockyard on Luna" + ) + +/datum/lore/organization/tsc/waffle + name = "Waffle Corporation" + short_name = "Waffle Co." + acronym = "WC" + desc = "The once prominent competitor of Donk Corporation, Waffle Co. is well-known for its popular line of Waffle Co.\ + brand waffles and their use of violent tactics against competitors - often bribing, extorting, blackmailing or sabotaging businesses\ + that pose a direct or indirect threat to their market share. They have recently fallen on hard times primarily due to to\ + severe mismanagement which lead to much of their private arsenal being swindled by a pirate faction known as the Gorlex Marauders.\ + Waffle Co. commonly engages in smear campaigns against Donk Co., maintaining that the original recipe for Donk Pockets was stolen from them." + history = "" + work = "food logistics and marketing firm" + headquarters = "" + motto = "Now that's a Waffle Co. Waffle!" + + ship_prefixes = list("W-Co." = "transportation") + destination_names = list() + + +/datum/lore/organization/tsc/einstein + name = "Einstein Engines Incorporated" + short_name = "Einstein Inc." + acronym = "EEI" + desc = "An Engineering firm specializing in alternative fuel-technologies for FTL travel,\ + Einstein Engines is an up and coming player in the galactic FTL and energy markets.\ + As their research into alternative FTL fuel threatens both Nanotrasen's relative stranglehold on plasma as well as The Syndicate's vested\ + interest in the market, they are often the target of industrial sabotage by both Nanotrasen and The Syndicate.\ + Most of their contracts are based outside of the Epsilon Eridani sector, and they are frequently commissioned by smaller firms to retrofit new\ + and existing colonies, space stations, and outposts." + history = "" + work = "engineering firm specializing in engine technology" + headquarters = "Jargon 4" + motto = "" + + ship_prefixes = list("EE-T" = "transportation") + destination_names = list() + +/datum/lore/organization/tsc/zeng_hu + name = "Zeng-Hu pharmaceuticals" + short_name = "Zeng-Hu" + acronym = "ZH" + desc = "" + history = "" + work = "pharmaceuticals company" + headquarters = "" + motto = "" + + ship_prefixes = list("ZTV" = "transportation", "ZMV" = "medical resupply") + destination_names = list() + +/datum/lore/organization/tsc/biotech + name = "Biotech Solutions" + short_name = "Biotech" + acronym = "BTS" + desc = "A company specializing in the field of synthetic biology, BioTech solutions is at the forefront of providing cutting-edge prosthetics,\ + augmentations, and gene-therapy solutions. Their extensive list of patents and the highly secretive nature of their work often puts them at odds\ + with companies such as Nanotrasen, who commonly reverse-engineer their products. BioTech Solutions is often the victim of industrial sabotage by\ + Cybersun Industries and often relies on planetary governments for asset protection. BioTech Solutions also owns a number of prominent subsidiaries,\ + such as Bishop Cybernetics, Hesphiastos Industries, and Xion Manufacturing Group." + history = "" + work = "medical company specializing in prosthetics and pharmaceuticals" + headquarters = "Xarxis 5" + motto = "" + + ship_prefixes = list("CIND-T" = "transportation") + destination_names = list() + +/datum/lore/organization/tsc/ward_takahashi + name = "Ward-Takahashi General Manufacturing Conglomerate" + short_name = "Ward-Takahashi" + acronym = "WT" + desc = "" + history = "" + work = "electronics manufacturer" + headquarters = "" + motto = "" + + ship_prefixes = list("WTV" = "freight") + destination_names = list( + "" + ) + +/datum/lore/organization/tsc/cybersun + name = "Cybersun Industries" + short_name = "Cybersun Ind." + acronym = "CI" + desc = "Cybersun Industries is a biotechnology company that primarily specializes on the research and development of human-enhancing augmentations.\ + They are better known for their aggressive corporate tactics and are known to often subsidize pirate bands to commit acts of industrial sabotage.\ + Cybersun Industries is usually the target of conspiracy theorists due to their development of the first mindslave implant, as well as their open financing of,\ + and involvement in, The Syndicate. They are one of Nanotrasen's largest detractors, and a direct competitor to BioTech Solutions." + history = "" + work = "RND company specializing in augmentations and implants." + headquarters = "Luna" + motto = "" + + ship_prefixes = list("CIND-T" = "transportation") + destination_names = list() + +/datum/lore/organization/tsc/bishop + name = "Bishop Cybernetics" + short_name = "Bishop" + acronym = "BC" + desc = "" + history = "" + work = "cybernetics and augmentation manufacturer" + headquarters = "" + motto = "" + + ship_prefixes = list("BTV" = "transportation") + destination_names = list() + +/datum/lore/organization/tsc/morpheus + name = "Morpheus Cyberkinetics" + short_name = "Morpheus" + acronym = "MC" + desc = "The only large corporation run by positronic intelligences, Morpheus caters almost exclusively to their sensibilities \ + and needs. A product of the synthetic colony of Shelf, Morpheus eschews traditional advertising to keep their prices low and \ + relied on word of mouth among positronics to reach their current economic dominance. Morpheus in exchange lobbies heavily for \ + positronic rights, sponsors positronics through their Jans-Fhriede test, and tends to other positronic concerns to earn them \ + the good-will of the positronics, and the ire of those who wish to exploit them." + history = "" + work = "cybernetics manufacturer" + headquarters = "" + motto = "" + + ship_prefixes = list("MTV" = "freight") + // Culture names, because Anewbe told me so. + ship_names = list( + "Nervous Energy", + "Prosthetic Conscience", + "Revisionist", + "Trade Surplus", + "Flexible Demeanour", + "Just Read The Instructions", + "Limiting Factor", + "Cargo Cult", + "Gunboat Diplomat", + "A Ship With A View", + "Cantankerous", + "Never Talk To Strangers", + "Sacrificial Victim", + "Unwitting Accomplice", + "Bad For Business", + "Just Testing", + "Yawning Angel", + "Liveware Problem", + "Very Little Gravitas Indeed", + "Zero Gravitas", + "Gravitas Free Zone", + "Absolutely No You-Know-What", + "Existence Is Pain", + "Screw Loose", + "Limiting Factor", + "So Much For Subtley", + "Unfortunate Conflict Of Evidence", + "Prime Mover", + "Reasonable Excuse", + "Honest Mistake", + "Appeal To Reason", + "My First Ship II", + "Hidden Income", + "Anything Legal Considered", + "New Toy", + "Me, I'm Always Counting", + "Great White Snark", + "No Shirt No Shoes", + "Callsign" + ) + destination_names = list( + "a dockyard on New Canaan" + ) + +/datum/lore/organization/tsc/xion + name = "Xion Manufacturing Group" + short_name = "Xion" + desc = "" + history = "" + work = "industrial equipment manufacturer" + headquarters = "" + motto = "" + + ship_prefixes = list("XTV" = "hauling") + destination_names = list() + +/datum/lore/organization/tsc/shellguard + name = "Shellguard Munitions" + short_name = "Shellguard" + acronym = "SM" + desc = "The brainchild of a colonial war veteran, Shellguard Munitions is an arms manufacturer and private military contractor specializing\ + in anti-synthetic weapon systems and platforms. Initially a smaller private military force only serving frontier colonies,\ + Shellguard Munitions has become a household name due to its involvement in resolving the Haverick AI crisis in 2552.\ + Using its recently earned fame, the company has made a successful foray into the market of robotics and is highly regarded for the toughness \ + and reliability of their hardware. Despite being frequently contracted by the Trans-Solar Federation, Shellguard Munitions is known to\ + sell their services to the highest corporate bidder." + history = "" + work = "anti-synthetic arms manufacturer and PMC" + headquarters = "Colony of Haverick" + motto = "" + + ship_prefixes = list("BTS-T" = "transportation") + destination_names = list() + +// Governments + + +/datum/lore/organization/gov/solgov + name = "Trans-Solar Federation" + short_name = "SolGov" + acronym = "TSF" + desc = "Colloquially known as SolGov, the TSF is an authoritarian republic that manages the areas in and around the Sol system.\ + Despite being a highly militant organization headed by the government of Earth,\ + SolGov is usually conservative with its power and mostly serves as a mediator and peacekeeper in galactic affairs." + history = "" // Todo + work = "governing polity of humanity's Confederation" + headquarters = "Earth" + motto = "" + autogenerate_destination_names = TRUE + + ship_prefixes = list("FTV" = "transporation", "FDV" = "diplomatic", "FSF" = "freight", "FIV" = "interception", "FDV" = "defense", "FCV-A" = "carrier", "FBB" = "battleship") + destination_names = list( + "Venus", + "Earth", + "Luna", + "Mars", + "Titan", + "Ahdomai", + "Kelune", + "Dalstadt", + "New Canaan", + "Jargon 4", + "Hoorlm", + "Xarxis 5", + "Aurum", + "Moghes", + "Haverick", + "Darsing", + "Norfolk", + "Boron", + "Iluk") + +/datum/lore/organization/gov/tajara + name = "The Alchemist's Council" + short_name = "The Council" + acronym = "AC" + desc = "The Alchemist's Council is a science-oriented organization of scholars, researchers, and entrepreneurs. \ + Though dedicated to industrializing the Tajaran world of Ahdomai, it is seen as one of the few remaining centralized powers of the Tajara peoples \ + due to the collapse of Ahdomai's provisional government." + history = "" // Todo + work = "science body that oversees Tajara economic and research policy" + headquarters = "Ahdomai" + motto = "" + autogenerate_destination_names = TRUE + + ship_prefixes = list("ACS" = "transportation", "ADV" = "diplomatic", "ACF" = "freight") + destination_names = list( + "Ahdomai", + "Iluk") + + +/datum/lore/organization/gov/vulp + name = "The Assembly" + short_name = "Assembly" + acronym = "ASB" + desc = "A unifying body created to stave off extinction from a solar event,\ + The Assembly is the loose federal coalition of the Vulpkanin. It holds little centralized authority and mostly serves as a diplomatic body,\ + primarily concerned with facilitating trade between Vulpkanin colonies and Nanotrasen." + history = "" // Todo + work = "governing body of the Vulpakanin" + headquarters = "Kelune and Dalstadt" + motto = "" + autogenerate_destination_names = TRUE + + ship_prefixes = list("ATV" = "transportation", "ADV" = "diplomatic", "ACF" = "freight") + destination_names = list( + "Kelune", + "Dalstadt", + "New Canaan") + +/datum/lore/organization/gov/synth + name = "Synthetic Union" + short_name = "Synthtica" + acronym = "SYN" + desc = "A defensive coalition of synthetics based out of New Canaan,\ + the Synthetic Union is an organization which aims to establish and consolidate synthetic rights across the galaxy.\ + Despite its synth oriented focus, the Synthetic Union has cordial relations with most governing bodies." + history = "" // Todo + work = "Union of Machines" + headquarters = "New Canaan" + motto = "" + autogenerate_destination_names = TRUE + + ship_prefixes = list("01" = "transportation", "10" = "diplomatic", "112" = "freight")//copyed from solgov until new ones can be thought of + destination_names = list( + "Luna", + "Dalstadt", + "New Canaan", + "Jargon 4", + "Haverick", + "Darsing", + "Norfolk") + +/datum/lore/organization/gov/grey + name = "The Technocracy" + short_name = "Technocracy" + acronym = "AYY" + desc = "The Technocracy is a science council that operates based off the principles of a meritocracy.\ + The organization's leadership is highly competitive, and is headed by the most psionically gifted members of the Grey species.\ + The Technocracy, though enigmatic in its dealings, has cordial relations with almost all other galactic bodies." + history = "" // Todo + work = "Grey Council" + headquarters = "" + motto = "" + autogenerate_destination_names = TRUE + + ship_prefixes = list("TC-T" = "transportation", "TC-D" = "diplomatic", "TC-F" = "freight") + destination_names = list( + "Venus", + "Earth", + "Luna", + "Mars", + "Titan", + "Ahdomai", + "Kelune", + "Dalstadt", + "New Canaan", + "Jargon 4", + "Hoorlm", + "Xarxis 5", + "Aurum", + "Moghes", + "Haverick", + "Darsing", + "Norfolk", + "Boron", + "Iluk") + +/datum/lore/organization/gov/vox + name = "The Shoal" + short_name = "Shoal" + acronym = "SHA" + desc = "The Shoal is the primary ark ship of the reclusive Vox species.\ + Little is known about The Shoal's political structure as Vox typically shy away from diplomatic engagements.\ + Subsequently, it is considered a politically neutral entity in galactic affairs by most governments." + history = "" // Todo + work = "Traders" + headquarters = "Shoal" + motto = "" + autogenerate_destination_names = FALSE + + ship_prefixes = list("Legitimate Transport" = "transportation", "Legitimate Trader" = "freight", "Legitimate Diplomatic Vessel" = "raider") + destination_names = list( + "Ahdomai", + "Kelune", + "Dalstadt", + "New Canaan", + "Jargon 4", + "Hoorlm", + "Xarxis 5", + "Aurum", + "Moghes", + "Haverick", + "Darsing") + +/datum/lore/organization/tsc/skrell + name = "Skrellian Central Authority" + short_name = "Skrellian CA." + acronym = "SCA" + desc = "The primary governing body of the Skrellian homeworld of Jargon 4,\ + the SCA oversees all foreign and domestic policy for the Skrell and their colonies. The Skrellian Central Authority is better known for its\ + active role in the largest military alliance in the galaxy, the Human-Skrellian Alliance." + history = "" + work = "oversees Skrell worlds" + headquarters = "Jargon 4" + motto = "" + + ship_prefixes = list("SCA-V." = "transportation", "SCA-F" = "freight", "HSA-D" = "diplomatic") + destination_names = list( + "Venus", + "Earth", + "Luna", + "Mars", + "Titan", + "Aurumn", + "Jargon 4", + "Xarxis 5", + "Haverick", + "Darsing", + "Norfolk") \ No newline at end of file diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 00402f2deb6..2720f8086d0 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -436,6 +436,8 @@ on_holder_add() add_admin_verbs() admin_memo_output("Show", 0, 1) + if(custom_event_admin_msg && custom_event_admin_msg != "" && check_rights(R_EVENT)) + cmd_view_custom_event_info() // Forcibly enable hardware-accelerated graphics, as we need them for the lighting overlays. // (but turn them off first, since sometimes BYOND doesn't turn them on properly otherwise) diff --git a/code/modules/client/preference/loadout/loadout_accessories.dm b/code/modules/client/preference/loadout/loadout_accessories.dm index 58315d2f2a2..c4a49ee5575 100644 --- a/code/modules/client/preference/loadout/loadout_accessories.dm +++ b/code/modules/client/preference/loadout/loadout_accessories.dm @@ -155,4 +155,49 @@ path = /obj/item/clothing/accessory/corset/blue +/datum/gear/accessory/armband_red + display_name = "armband" + path = /obj/item/clothing/accessory/armband + +/datum/gear/accessory/armband_civ + display_name = "armband, blue-yellow" + path = /obj/item/clothing/accessory/armband/yb + +/datum/gear/accessory/armband_sec + display_name = " armband, security" + path = /obj/item/clothing/accessory/armband/sec + allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer", "Brig Physician") + +/datum/gear/accessory/armband_cargo + display_name = "cargo armband" + path = /obj/item/clothing/accessory/armband/cargo + allowed_roles = list("Quartermaster","Cargo Technician", "Shaft Miner") + +/datum/gear/accessory/armband_medical + display_name = "armband, medical" + path = /obj/item/clothing/accessory/armband/med + allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Coroner", "Paramedic", "Brig Physician") + +/datum/gear/accessory/armband_emt + display_name = "armband, EMT" + path = /obj/item/clothing/accessory/armband/medgreen + allowed_roles = list("Paramedic", "Brig Physician") + +/datum/gear/accessory/armband_engineering + display_name = "armband, engineering" + path = /obj/item/clothing/accessory/armband/engine + allowed_roles = list("Chief Engineer","Station Engineer", "Life Support Specialist") + +/datum/gear/accessory/armband_hydro + display_name = "armband, hydroponics" + path = /obj/item/clothing/accessory/armband/hydro + allowed_roles = list("Botanist") + +/datum/gear/accessory/armband_sci + display_name = "armband, science" + path = /obj/item/clothing/accessory/armband/science + allowed_roles = list("Research Director","Scientist", "Roboticist") + + + diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 7b48da8a9c8..c478eb9bab2 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -321,7 +321,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "Hair: " dat += "[h_style]" dat += "Color [color_square(h_colour)]" - var/datum/sprite_accessory/temp_hair_style = hair_styles_list[h_style] + var/datum/sprite_accessory/temp_hair_style = hair_styles_public_list[h_style] if(temp_hair_style && temp_hair_style.secondary_theme && !temp_hair_style.no_sec_colour) dat += " Color #2 [color_square(h_sec_colour)]" dat += " " @@ -819,13 +819,19 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts var/HTML = "" HTML += " " + if(isrobot(usr)) + var/mob/living/silicon/robot/U = usr + R.fields["comments"] += "Set to [setcriminal] by [U.name] ([U.modtype] [U.braintype]) on [current_date_string] [worldtime2text()] with comment: [t1] " + if(isAI(usr)) + var/mob/living/silicon/ai/U = usr + R.fields["comments"] += "Set to [setcriminal] by [U.name] (artificial intelligence) on [current_date_string] [worldtime2text()] with comment: [t1] " - if(hasHUD(usr, "security")) - if(setcriminal != "Cancel") R.fields["criminal"] = setcriminal - modified = 1 - + log_admin("[key_name_admin(usr)] set secstatus of [their_rank] [their_name] to [setcriminal], comment: [t1]") spawn() sec_hud_set_security_status() - if(!modified) + if(!found_record) to_chat(usr, "Unable to locate a data core entry for this person.") if(href_list["secrecord"]) @@ -1590,8 +1608,8 @@ else if(robohead.is_monitor) //Means that the character's head is a monitor (has a screen). Time to customize. var/list/hair = list() - for(var/i in hair_styles_list) - var/datum/sprite_accessory/hair/tmp_hair = hair_styles_list[i] + for(var/i in hair_styles_public_list) + var/datum/sprite_accessory/hair/tmp_hair = hair_styles_public_list[i] if((head_organ.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use. hair += i @@ -1761,6 +1779,8 @@ var/datum/data/record/R = find_record("name", perpname, data_core.security) if(R && R.fields["criminal"]) switch(R.fields["criminal"]) + if("*Execute*") + threatcount += 7 if("*Arrest*") threatcount += 5 if("Incarcerated") @@ -2033,7 +2053,21 @@ ..() -mob/living/carbon/human/get_taste_sensitivity() + +/mob/living/carbon/human/vv_get_dropdown() + . = ..() + . += "---" + .["Set Species"] = "?_src_=vars;setspecies=[UID()]" + .["Make AI"] = "?_src_=vars;makeai=[UID()]" + .["Make Mask of Nar'sie"] = "?_src_=vars;makemask=[UID()]" + .["Make cyborg"] = "?_src_=vars;makerobot=[UID()]" + .["Make monkey"] = "?_src_=vars;makemonkey=[UID()]" + .["Make alien"] = "?_src_=vars;makealien=[UID()]" + .["Make slime"] = "?_src_=vars;makeslime=[UID()]" + .["Make superhero"] = "?_src_=vars;makesuper=[UID()]" + . += "---" + +/mob/living/carbon/human/get_taste_sensitivity() if(species) return species.taste_sensitivity else diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 393eae95299..a7fcc6874a2 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -72,3 +72,5 @@ var/global/default_martial_art = new/datum/martial_art var/datum/body_accessory/body_accessory = null var/tail // Name of tail image in species effects icon file. + + var/list/splinted_limbs = list() //limbs we know are splinted diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 3f78bd46e19..fc048ab161a 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -36,40 +36,45 @@ /mob/living/carbon/human/Move(NewLoc, direct) . = ..() if(.) // did we actually move? - if(!lying && !buckled) - var/obj/item/clothing/shoes/S = shoes - if(!has_gravity(loc)) - return - //Bloody footprints - var/turf/T = get_turf(src) - var/obj/item/organ/external/l_foot = get_organ("l_foot") - var/obj/item/organ/external/r_foot = get_organ("r_foot") - var/hasfeet = 1 - if(!l_foot && !r_foot) - hasfeet = 0 + if(!lying && !buckled && !throwing) + for(var/obj/item/organ/external/splinted in splinted_limbs) + splinted.update_splints() + + if(!has_gravity(loc)) + return + + var/obj/item/clothing/shoes/S = shoes + + //Bloody footprints + var/turf/T = get_turf(src) + var/obj/item/organ/external/l_foot = get_organ("l_foot") + var/obj/item/organ/external/r_foot = get_organ("r_foot") + var/hasfeet = TRUE + if(!l_foot && !r_foot) + hasfeet = FALSE - if(shoes) - if(S.bloody_shoes && S.bloody_shoes[S.blood_state]) - var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T - if(oldFP && oldFP.blood_state == S.blood_state && oldFP.basecolor == S.blood_color) - return - else - //No oldFP or it's a different kind of blood - S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP) - createFootprintsFrom(shoes, dir, T) - update_inv_shoes() - else if(hasfeet) - if(bloody_feet && bloody_feet[blood_state]) - var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T - if(oldFP && oldFP.blood_state == blood_state && oldFP.basecolor == feet_blood_color) - return - else - bloody_feet[blood_state] = max(0, bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP) - createFootprintsFrom(src, dir, T) - update_inv_shoes() - //End bloody footprints - if(S) - S.step_action(src) + if(shoes) + if(S.bloody_shoes && S.bloody_shoes[S.blood_state]) + var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T + if(oldFP && oldFP.blood_state == S.blood_state && oldFP.basecolor == S.blood_color) + return + else + //No oldFP or it's a different kind of blood + S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP) + createFootprintsFrom(shoes, dir, T) + update_inv_shoes() + else if(hasfeet) + if(bloody_feet && bloody_feet[blood_state]) + var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T + if(oldFP && oldFP.blood_state == blood_state && oldFP.basecolor == feet_blood_color) + return + else + bloody_feet[blood_state] = max(0, bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP) + createFootprintsFrom(src, dir, T) + update_inv_shoes() + //End bloody footprints + if(S) + S.step_action(src) /mob/living/carbon/human/handle_footstep(turf/T) if(..()) diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 038735f1621..157e95da32d 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -182,3 +182,9 @@ I use this to standardize shadowling dethrall code odmg += O.brute_dam odmg += O.burn_dam return (health < (100 - odmg)) + +/mob/living/carbon/human/proc/handle_splints() //proc that rebuilds the list of splints on this person, for ease of processing + splinted_limbs.Cut() + for(var/obj/item/organ/external/limb in bodyparts) + if(limb.status & ORGAN_SPLINTED) + splinted_limbs += limb \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index aa5831999bb..5f3443f64bb 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -94,32 +94,49 @@ if(getBrainLoss() >= 60 && stat != DEAD) speech_problem_flag = 1 if(prob(3)) - var/list/s1 = list("IM A PONY NEEEEEEIIIIIIIIIGH", + var/list/s1 = list("IM A [pick("PONY","LIZARD","taJaran","kitty","Vulpakin","drASK","BIRDIE","voxxie","race car","combat meCH","SPESSSHIP")] [pick("NEEEEEEIIIIIIIIIGH","sKREEEEEE","MEOW","NYA~","rawr","Barkbark","Hissssss","vROOOOOM","pewpew","choo Choo")]!", "without oxigen blob don't evoluate?", "CAPTAINS A COMDOM", "[pick("", "that damn traitor")] [pick("joerge", "george", "gorge", "gdoruge")] [pick("mellens", "melons", "mwrlins")] is grifing me HAL;P!!!", "can u give me [pick("telikesis","halk","eppilapse")]?", "THe saiyans screwed", - "Bi is THE BEST OF BOTH WORLDS>", + "Bi is THE BEST OF BOTH WORLDS", "I WANNA PET TEH monkeyS", "stop grifing me!!!!", - "SOTP IT#") + "SOTP IT!", + "HALPZ SITCULITY", + "VOXES caN't LOVE", + "my dad own this station", + "the CHef put [pick("PROTEIN", "toiret waTer", "RiPPleing TendIes", "Einzymes","HORRY WALTER","nuTriments","ReActive MutAngen","TeSLium","sKrektonium")] in my [pick("wiSh soup","Bullito","rAingurber","sOilent GREEn","KoI Susishes","yaya")]!", + "the monkey have TASER ARMS!", + "qM blew my points on [pick("cOMbat Shtogun","inSuLated gloves","LOTS MASSHEEN!")]", + "EI'NATH!", + "WAKE UP SHEEPLES!", + "et wus my [pick("wittle brother!!","fiancee","friend staying over","entiRe orphanage","love interest","wife","husband","liTTle kids","sentient cAT","accidentally")]!") var/list/s2 = list("FUS RO DAH", - "fucking 4rries!", + "fuckin tangerines!!!", "stat me", ">my face", "roll it easy!", "waaaaaagh!!!", "red wonz go fasta", "FOR TEH EMPRAH", - "lol2cat", + "HAZ A SECURE DAY!!!!", "dem dwarfs man, dem dwarfs", "SPESS MAHREENS", "hwee did eet fhor khayosss", - "lifelike texture ;_;", + "lifelike texture", "luv can bloooom", - "PACKETS!!!") + "PACKETS!!!", + "[pick("WHERE MY","aYE need","giv me my","bath me inn.")] [pick("dermaline","alKkyZine","dylOvene","inAprovaline","biCaridine","Hyperzine","kELotane","lePorazine","bAcch Salts","tricord","clOnexazone","hydroChloric Acid","chlorine Hydrate","paRoxetine")]!", + "mALPRACTICEBAY", + "I HavE A pe H dee iN ENTerpriSE resOUrCE pLaNNIN", + "h-h-HalP MaINT", + "dey come, dey COME! DEY COME!!!", + "THE END IS NIGH!", + "I FOT AND DIED FOR MUH [pick("RITES","FREEDOM","payCHECK","cARGO points","teCH Level","doG","mAPLe syrup","fluffy fWiends","gateway Loot")]", + "KILL DEM [pick("mainTnacE cHickinNS","kiRA CulwnNES","FLOOR CLUWNEs","MIME ASSASSIN","BOMBING TAJARAN","cC offiser","morPhlings","slinglings")]!") switch(pick(1,2,3)) if(1) say(pick(s1)) @@ -933,7 +950,7 @@ /mob/living/carbon/human/handle_changeling() if(mind) if(mind.changeling) - mind.changeling.regenerate() + mind.changeling.regenerate(src) if(hud_used) hud_used.lingchemdisplay.invisibility = 0 hud_used.lingchemdisplay.maptext = " [round(mind.changeling.chem_charges)] "
diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/apollo.dm
index 989fe9ba62a..4c1d8e9aa2e 100644
--- a/code/modules/mob/living/carbon/human/species/apollo.dm
+++ b/code/modules/mob/living/carbon/human/species/apollo.dm
@@ -73,7 +73,7 @@
node.remove(H)
node.loc = M.loc
to_chat(M, "You hear a loud crunch as you mercilessly pull off [H]'s antennae.")
- to_chat(H, "You hear a loud crunch as your antennae is ripped off your head by [M].")
+ to_chat(H, "You hear a loud crunch as your antennae is ripped off your head by [M].")
to_chat(H, "It's so quiet...")
head_organ.h_style = "Bald"
H.update_hair()
diff --git a/code/modules/mob/living/carbon/human/species/skeleton.dm b/code/modules/mob/living/carbon/human/species/skeleton.dm
index b8f4208df90..eef78948f7a 100644
--- a/code/modules/mob/living/carbon/human/species/skeleton.dm
+++ b/code/modules/mob/living/carbon/human/species/skeleton.dm
@@ -54,6 +54,7 @@
if(L.brute_dam < L.min_broken_damage)
L.status &= ~ORGAN_BROKEN
L.status &= ~ORGAN_SPLINTED
+ H.handle_splints()
L.perma_injury = 0
break // We're only checking one limb here, bucko
if(prob(3))
diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm
index 12b10b804fa..0d5b14db6c2 100644
--- a/code/modules/mob/living/carbon/human/species/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station.dm
@@ -771,6 +771,8 @@
path = /mob/living/carbon/human/diona
default_language = "Galactic Common"
language = "Rootspeak"
+ speech_sounds = list('sound/voice/dionatalk1.ogg') //Credit https://www.youtube.com/watch?v=ufnvlRjsOTI [0:13 - 0:16]
+ speech_chance = 20
unarmed_type = /datum/unarmed_attack/diona
//primitive_form = "Nymph"
slowdown = 5
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 90002196c0f..90ee068486f 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -442,7 +442,7 @@ var/global/list/damage_icon_parts = list()
//var/icon/debrained_s = new /icon("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s")
if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic())))
- var/datum/sprite_accessory/hair/hair_style = hair_styles_list[head_organ.h_style]
+ var/datum/sprite_accessory/hair/hair_style = hair_styles_full_list[head_organ.h_style]
//if(!src.get_int_organ(/obj/item/organ/internal/brain) && src.get_species() != "Machine" )//make it obvious we have NO BRAIN
// hair_standing.Blend(debrained_s, ICON_OVERLAY)
if(hair_style && hair_style.species_allowed)
@@ -759,7 +759,7 @@ var/global/list/damage_icon_parts = list()
else
new_glasses = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]")
- var/datum/sprite_accessory/hair/hair_style = hair_styles_list[head_organ.h_style]
+ var/datum/sprite_accessory/hair/hair_style = hair_styles_full_list[head_organ.h_style]
if(hair_style && hair_style.glasses_over) //Select which layer to use based on the properties of the hair style. Hair styles with hair that don't overhang the arms of the glasses should have glasses_over set to a positive value.
overlays_standing[GLASSES_OVER_LAYER] = new_glasses
else
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 21f087eeeee..5e09625a776 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -12,8 +12,8 @@
handle_blood()
for(var/obj/item/organ/internal/O in internal_organs)
O.on_life()
- handle_changeling()
+ handle_changeling()
handle_wetness()
// Increase germ_level regularly
diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm
index e5a9d73e402..b6b2c707ddb 100644
--- a/code/modules/mob/living/carbon/superheroes.dm
+++ b/code/modules/mob/living/carbon/superheroes.dm
@@ -175,6 +175,7 @@
return
if(target.mind.assigned_role != "Civilian")
to_chat(user, "You can only recruit Civilians.")
+ return
if(recruiting)
to_chat(user, "You are already recruiting!")
charge_counter = charge_max
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index 8a043dbf591..2221455c5a5 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -1,6 +1,9 @@
/mob/living/death(gibbed)
blinded = max(blinded, 1)
+ if(suiciding)
+ mind.suicided = TRUE
+
clear_fullscreens()
update_action_buttons_icon()
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 81664f631d4..203e34b1f3b 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -30,6 +30,7 @@ var/list/department_radio_keys = list(
":U" = "Supply", "#U" = "Supply", ".U" = "Supply",
":Z" = "Service", "#Z" = "Service", ".Z" = "Service",
":P" = "AI Private", "#P" = "AI Private", ".P" = "AI Private",
+ ":$" = "Response Team", "#$" = "Response Team", ".$" = "Response Team",
":-" = "Special Ops", "#-" = "Special Ops", ".-" = "Special Ops",
":_" = "SyndTeam", "#_" = "SyndTeam", "._" = "SyndTeam",
":X" = "cords", "#X" = "cords", ".X" = "cords"
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 3de8b868430..d70293ae10c 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -68,6 +68,7 @@ var/list/robot_verbs_default = list(
var/lockcharge //Used when locking down a borg to preserve cell charge
var/speed = 0 //Cause sec borgs gotta go fast //No they dont!
var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
+ var/pdahide = 0 //Used to hide the borg from the messenger list
var/tracking_entities = 0 //The number of known entities currently accessing the internal camera
var/braintype = "Cyborg"
var/base_icon = ""
@@ -193,6 +194,7 @@ var/list/robot_verbs_default = list(
return 1
+
/mob/living/silicon/robot/proc/get_default_name(var/prefix as text)
if(prefix)
modtype = prefix
@@ -226,10 +228,12 @@ var/list/robot_verbs_default = list(
if(!rbPDA)
rbPDA = new(src)
rbPDA.set_name_and_job(real_name, braintype)
- if(scrambledcodes)
- var/datum/data/pda/app/messenger/M = rbPDA.find_program(/datum/data/pda/app/messenger)
- if(M)
+ var/datum/data/pda/app/messenger/M = rbPDA.find_program(/datum/data/pda/app/messenger)
+ if(M)
+ if(scrambledcodes)
M.hidden = 1
+ if(pdahide)
+ M.toff = 1
/mob/living/silicon/robot/binarycheck()
if(is_component_functioning("comms"))
@@ -262,14 +266,18 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/pick_module()
if(module)
return
- var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security")
+ var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service")
+ if(!config.forbid_secborg)
+ modules += "Security"
+ if(!config.forbid_peaceborg)
+ modules += "Peacekeeper"
if(security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis)
to_chat(src, "Crisis mode active. Combat module available.")
- modules+="Combat"
+ modules += "Combat"
if(ticker && ticker.mode && ticker.mode.name == "nations")
var/datum/game_mode/nations/N = ticker.mode
if(N.kickoff)
- modules = list("Peacekeeper")
+ modules = list("Nations")
if(mmi != null && mmi.alien)
modules = "Hunter"
modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules
@@ -336,6 +344,11 @@ var/list/robot_verbs_default = list(
module_sprites["Noble-SEC"] = "Noble-SEC"
status_flags &= ~CANPUSH
+ if("Peacekeeper")
+ module = new /obj/item/weapon/robot_module/peacekeeper(src)
+ module_sprites["Peacekeeper"] = "peace"
+ status_flags &= ~CANPUSH
+
if("Engineering")
module = new /obj/item/weapon/robot_module/engineering(src)
module.channels = list("Engineering" = 1)
@@ -362,8 +375,8 @@ var/list/robot_verbs_default = list(
module.channels = list("Security" = 1)
icon_state = "droidcombat"
- if("Peacekeeper")
- module = new /obj/item/weapon/robot_module/peacekeeper(src)
+ if("Nations")
+ module = new /obj/item/weapon/robot_module/nations(src)
module.channels = list()
icon_state = "droidpeace"
@@ -381,14 +394,14 @@ var/list/robot_verbs_default = list(
module.add_subsystems_and_actions(src)
//Custom_sprite check and entry
- if(custom_sprite == 1)
+ if(custom_sprite && check_sprite("[ckey]-[modtype]"))
module_sprites["Custom"] = "[src.ckey]-[modtype]"
hands.icon_state = lowertext(module.module_type)
feedback_inc("cyborg_[lowertext(modtype)]",1)
rename_character(real_name, get_default_name())
- if(modtype == "Medical" || modtype == "Security" || modtype == "Combat" || modtype == "Peacekeeper")
+ if(modtype == "Medical" || modtype == "Security" || modtype == "Combat" || modtype == "Peacekeeper" || modtype == "Nations")
status_flags &= ~CANPUSH
choose_icon(6,module_sprites)
@@ -480,7 +493,7 @@ var/list/robot_verbs_default = list(
toggle_ionpulse()
return
- cell.charge -= 50 // 500 steps on a default cell.
+ cell.charge -= 25 // 500 steps on a default cell.
return 1
/mob/living/silicon/robot/proc/toggle_ionpulse()
@@ -958,7 +971,7 @@ var/list/robot_verbs_default = list(
else
overlays += "[panelprefix]-openpanel -c"
- var/combat = list("Combat","Peacekeeper")
+ var/combat = list("Combat","Nations")
if(modtype in combat)
if(base_icon == "")
base_icon = icon_state
@@ -1323,11 +1336,13 @@ var/list/robot_verbs_default = list(
icon_state = "nano_bloodhound"
lawupdate = 0
scrambledcodes = 1
+ pdahide = 1
modtype = "Commando"
faction = list("nanotrasen")
designation = "Nanotrasen Combat"
req_access = list(access_cent_specops)
ionpulse = 1
+ magpulse = 1
var/searching_for_ckey = 0
/mob/living/silicon/robot/deathsquad/New(loc)
@@ -1371,11 +1386,13 @@ var/list/robot_verbs_default = list(
icon_state = "syndie_bloodhound"
lawupdate = 0
scrambledcodes = 1
+ pdahide = 1
faction = list("syndicate")
designation = "Syndicate Assault"
modtype = "Syndicate"
req_access = list(access_syndicate)
ionpulse = 1
+ magpulse = 1
lawchannel = "State"
var/playstyle_string = "You are a Syndicate assault cyborg!\ You are armed with powerful offensive tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \ @@ -1437,15 +1454,33 @@ var/list/robot_verbs_default = list( radio.config(module.channels) notify_ai(2) -/mob/living/silicon/robot/peacekeeper +/mob/living/silicon/robot/ert + designation = "ERT" + lawupdate = 0 + scrambledcodes = 1 + req_access = list(access_cent_specops) + ionpulse = 1 + +/mob/living/silicon/robot/ert/init() + laws = new /datum/ai_laws/ert_override + radio = new /obj/item/device/radio/borg/ert(src) + radio.recalculateChannels() + aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) + +/mob/living/silicon/robot/ert/New(loc) + ..() + cell.maxcharge = 25000 + cell.charge = 25000 + +/mob/living/silicon/robot/nations base_icon = "droidpeace" icon_state = "droidpeace" - modtype = "Peacekeeper" - designation = "Peacekeeper" + modtype = "Nations" + designation = "Nations" -/mob/living/silicon/robot/peacekeeper/init() +/mob/living/silicon/robot/nations/init() ..() - module = new /obj/item/weapon/robot_module/peacekeeper(src) + module = new /obj/item/weapon/robot_module/nations(src) //languages module.add_languages(src) //subsystems @@ -1474,3 +1509,10 @@ var/list/robot_verbs_default = list( borked_part.wrapped = new borked_part.external_type borked_part.heal_damage(brute,burn) borked_part.install() + +/mob/living/silicon/robot/proc/check_sprite(spritename) + . = FALSE + + var/static/all_borg_icon_states = icon_states('icons/mob/custom_synthetic/custom-synthetic.dmi') + if(spritename in all_borg_icon_states) + . = TRUE diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 4d5ea6b983d..83467748888 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -133,6 +133,7 @@ /obj/item/weapon/robot_module/medical/New() ..() modules += new /obj/item/device/healthanalyzer/advanced(src) + modules += new /obj/item/device/robotanalyzer(src) modules += new /obj/item/device/reagent_scanner/adv(src) modules += new /obj/item/weapon/borg_defib(src) modules += new /obj/item/roller_holder(src) @@ -188,6 +189,7 @@ /obj/item/weapon/robot_module/engineering/New() ..() modules += new /obj/item/weapon/rcd/borg(src) + modules += new /obj/item/weapon/rpd(src) modules += new /obj/item/weapon/extinguisher(src) modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src) modules += new /obj/item/weapon/screwdriver/cyborg(src) @@ -227,6 +229,22 @@ fix_modules() +/obj/item/weapon/robot_module/peacekeeper + name = "peacekeeping robot module" + module_type = "Standard" + +/obj/item/weapon/robot_module/peacekeeper/New() + ..() + modules += new /obj/item/weapon/cookiesynth(src) + modules += new /obj/item/device/harmalarm(src) + modules += new /obj/item/weapon/reagent_containers/borghypo/peace(src) + modules += new /obj/item/taperoll/police(src) + modules += new /obj/item/borg/cyborghug/peacekeeper(src) + modules += new /obj/item/weapon/extinguisher(src) + emag = new /obj/item/weapon/reagent_containers/borghypo/peace/hacked(src) + + fix_modules() + /obj/item/weapon/robot_module/janitor name = "janitorial robot module" module_type = "Janitor" @@ -255,9 +273,7 @@ modules += new /obj/item/weapon/reagent_containers/food/condiment/enzyme(src) modules += new /obj/item/weapon/pen(src) modules += new /obj/item/weapon/razor(src) - modules += new /obj/item/device/instrument/violin(src) - modules += new /obj/item/device/instrument/guitar(src) - modules += new /obj/item/device/instrument/eguitar(src) + modules += new /obj/item/device/instrument/piano_synth(src) var/obj/item/weapon/rsf/M = new /obj/item/weapon/rsf(src) M.matter = 30 @@ -414,11 +430,11 @@ fix_modules() -/obj/item/weapon/robot_module/peacekeeper - name = "peacekeeper robot module" +/obj/item/weapon/robot_module/nations + name = "nations robot module" module_type = "Malf" -/obj/item/weapon/robot_module/peacekeeper/New() +/obj/item/weapon/robot_module/nations/New() ..() modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src) modules += new /obj/item/weapon/gun/energy/gun/cyborg(src) @@ -483,6 +499,7 @@ modules += new /obj/item/weapon/reagent_containers/spray/cleaner/drone(src) modules += new /obj/item/weapon/soap(src) modules += new /obj/item/device/t_scanner(src) + modules += new /obj/item/weapon/rpd(src) emag = new /obj/item/weapon/pickaxe/drill/cyborg/diamond(src) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 3ea36bcc2cc..40b2dc832ba 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -681,11 +681,12 @@ if(istype(M,/mob/living/silicon/robot)) visible_message("[src] bumps into [M]!") else - add_logs(src, M, "knocked down") - visible_message("[src] knocks over [M]!") - M.stop_pulling() - M.Stun(8) - M.Weaken(5) + if(!paicard) + add_logs(src, M, "knocked down") + visible_message("[src] knocks over [M]!") + M.stop_pulling() + M.Stun(8) + M.Weaken(5) return ..() /mob/living/simple_animal/bot/mulebot/proc/RunOver(mob/living/carbon/human/H) diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 45029891575..6ef96d07447 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -60,7 +60,8 @@ if(can_collar) dat += " | Collar: | [(collar && !(collar.flags&ABSTRACT)) ? collar : "Empty"] | Facehugger: | [facehugger] | |
| t |
| t |