From f91dc76e1a8eb4698f75cf2086454c2a78e59d17 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 5 Oct 2017 10:21:14 -0400 Subject: [PATCH 01/28] Merge pull request #31310 from ShizCalev/lobby-timer-fix Fixes lobby timer showing as delayed when it's just waiting for more players --- code/modules/mob/dead/new_player/new_player.dm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 666fd767ba..8a978bc44b 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -79,9 +79,12 @@ if(SSticker.current_state == GAME_STATE_PREGAME) var/time_remaining = SSticker.GetTimeLeft() - if(time_remaining >= 0) - time_remaining /= 10 - stat("Time To Start:", (time_remaining >= 0) ? "[round(time_remaining)]s" : "DELAYED") + if(time_remaining > 0) + stat("Time To Start:", "[round(time_remaining/10)]s") + else if(time_remaining == -10) + stat("Time To Start:", "DELAYED") + else + stat("Time To Start:", "SOON") stat("Players:", "[SSticker.totalPlayers]") if(client.holder) From f45344ed8c7b1d8a4ff0d58362576521ee9d75ef Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 5 Oct 2017 16:23:06 +0200 Subject: [PATCH 03/28] Adds wigs --- code/game/machinery/vending.dm | 5 +- code/modules/clothing/head/misc_special.dm | 224 +++++++++++++++++++++ 2 files changed, 227 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index b3a7f99758..d4a06d0580 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1009,8 +1009,9 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C /obj/item/clothing/mask/joy = 1, /obj/item/clothing/head/cueball = 1, /obj/item/clothing/under/scratch = 1, - /obj/item/clothing/under/sailor = 1, - /obj/item/clothing/ears/headphones = 2) + /obj/item/clothing/under/sailor = 1, + /obj/item/clothing/ears/headphones = 2, + /obj/item/clothing/head/wig/random = 3) contraband = list(/obj/item/clothing/suit/judgerobe = 1, /obj/item/clothing/head/powdered_wig = 1, /obj/item/gun/magic/wand = 2, /obj/item/clothing/glasses/sunglasses/garb = 2, /obj/item/clothing/glasses/sunglasses/blindfold = 1, /obj/item/clothing/mask/muzzle = 2) premium = list(/obj/item/clothing/suit/pirate/captain = 2, /obj/item/clothing/head/pirate/captain = 2, /obj/item/clothing/head/helmet/roman = 1, /obj/item/clothing/head/helmet/roman/legionaire = 1, /obj/item/clothing/under/roman = 1, /obj/item/clothing/shoes/roman = 1, /obj/item/shield/riot/roman = 1, /obj/item/skub = 1) refill_canister = /obj/item/vending_refill/autodrobe diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 314f39f48b..d14ef81806 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /* * Contents: * Welding mask @@ -177,3 +178,226 @@ /obj/item/clothing/head/cardborg/dropped(mob/living/user) ..() user.remove_alt_appearance("standard_borg_disguise") +======= +/* + * Contents: + * Welding mask + * Cakehat + * Ushanka + * Pumpkin head + * Kitty ears + * Cardborg disguise + */ + +/* + * Welding mask + */ +/obj/item/clothing/head/welding + name = "welding helmet" + desc = "A head-mounted face cover designed to protect the wearer completely from space-arc eye." + icon_state = "welding" + flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH + item_state = "welding" + materials = list(MAT_METAL=1750, MAT_GLASS=400) +// var/up = 0 + flash_protect = 2 + tint = 2 + armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 60) + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE + actions_types = list(/datum/action/item_action/toggle) + visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE + visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH + resistance_flags = FIRE_PROOF + +/obj/item/clothing/head/welding/attack_self(mob/user) + weldingvisortoggle(user) + + +/* + * Cakehat + */ +/obj/item/clothing/head/hardhat/cakehat + name = "cakehat" + desc = "You put the cake on your head. Brilliant." + icon_state = "hardhat0_cakehat" + item_state = "hardhat0_cakehat" + item_color = "cakehat" + hitsound = 'sound/weapons/tap.ogg' + flags_inv = HIDEEARS|HIDEHAIR + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) + brightness_on = 2 //luminosity when on + flags_cover = HEADCOVERSEYES + heat = 1000 + +/obj/item/clothing/head/hardhat/cakehat/process() + var/turf/location = src.loc + if(ishuman(location)) + var/mob/living/carbon/human/M = location + if(M.is_holding(src) || M.head == src) + location = M.loc + + if(isturf(location)) + location.hotspot_expose(700, 1) + +/obj/item/clothing/head/hardhat/cakehat/turn_on() + ..() + force = 15 + throwforce = 15 + damtype = BURN + hitsound = 'sound/items/welder.ogg' + START_PROCESSING(SSobj, src) + +/obj/item/clothing/head/hardhat/cakehat/turn_off() + ..() + force = 0 + throwforce = 0 + damtype = BRUTE + hitsound = 'sound/weapons/tap.ogg' + STOP_PROCESSING(SSobj, src) + +/obj/item/clothing/head/hardhat/cakehat/is_hot() + return on * heat +/* + * Ushanka + */ +/obj/item/clothing/head/ushanka + name = "ushanka" + desc = "Perfect for winter in Siberia, da?" + icon_state = "ushankadown" + item_state = "ushankadown" + flags_inv = HIDEEARS|HIDEHAIR + var/earflaps = 1 + cold_protection = HEAD + min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT + + dog_fashion = /datum/dog_fashion/head/ushanka + +/obj/item/clothing/head/ushanka/attack_self(mob/user) + if(earflaps) + src.icon_state = "ushankaup" + src.item_state = "ushankaup" + earflaps = 0 + to_chat(user, "You raise the ear flaps on the ushanka.") + else + src.icon_state = "ushankadown" + src.item_state = "ushankadown" + earflaps = 1 + to_chat(user, "You lower the ear flaps on the ushanka.") + +/* + * Pumpkin head + */ +/obj/item/clothing/head/hardhat/pumpkinhead + name = "carved pumpkin" + desc = "A jack o' lantern! Believed to ward off evil spirits." + icon_state = "hardhat0_pumpkin" + item_state = "hardhat0_pumpkin" + item_color = "pumpkin" + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) + brightness_on = 2 //luminosity when on + flags_cover = HEADCOVERSEYES + +/* + * Kitty ears + */ +/obj/item/clothing/head/kitty + name = "kitty ears" + desc = "A pair of kitty ears. Meow!" + icon_state = "kitty" + color = "#999999" + dynamic_hair_suffix = "" + + dog_fashion = /datum/dog_fashion/head/kitty + +/obj/item/clothing/head/kitty/equipped(mob/living/carbon/human/user, slot) + if(ishuman(user) && slot == slot_head) + update_icon(user) + user.update_inv_head() //Color might have been changed by update_icon. + ..() + +/obj/item/clothing/head/kitty/update_icon(mob/living/carbon/human/user) + if(ishuman(user)) + add_atom_colour("#[user.hair_color]", FIXED_COLOUR_PRIORITY) + +/obj/item/clothing/head/kitty/genuine + desc = "A pair of kitty ears. A tag on the inside says \"Hand made from real cats.\"" + + +/obj/item/clothing/head/hardhat/reindeer + name = "novelty reindeer hat" + desc = "Some fake antlers and a very fake red nose." + icon_state = "hardhat0_reindeer" + item_state = "hardhat0_reindeer" + item_color = "reindeer" + flags_inv = 0 + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) + brightness_on = 1 //luminosity when on + dynamic_hair_suffix = "" + + dog_fashion = /datum/dog_fashion/head/reindeer + +/obj/item/clothing/head/cardborg + name = "cardborg helmet" + desc = "A helmet made out of a box." + icon_state = "cardborg_h" + item_state = "cardborg_h" + flags_cover = HEADCOVERSEYES + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + + dog_fashion = /datum/dog_fashion/head/cardborg + +/obj/item/clothing/head/cardborg/equipped(mob/living/user, slot) + ..() + if(ishuman(user) && slot == slot_head) + var/mob/living/carbon/human/H = user + if(istype(H.wear_suit, /obj/item/clothing/suit/cardborg)) + var/obj/item/clothing/suit/cardborg/CB = H.wear_suit + CB.disguise(user, src) + +/obj/item/clothing/head/cardborg/dropped(mob/living/user) + ..() + user.remove_alt_appearance("standard_borg_disguise") + + + +/obj/item/clothing/head/wig + name = "wig" + desc = "A bunch of hair without a head attached." + icon_state = "" + item_state = "pwig" + flags_inv = HIDEHAIR + var/hair_style = "Very Long Hair" + var/hair_color = "#000" + +/obj/item/clothing/head/wig/Initialize(mapload) + . = ..() + update_icon() + +/obj/item/clothing/head/wig/update_icon() + cut_overlays() + var/datum/sprite_accessory/S = GLOB.hair_styles_list[hair_style] + if(!S) + icon_state = "pwig" + else + var/mutable_appearance/M = mutable_appearance(S.icon,S.icon_state) + M.appearance_flags |= RESET_COLOR + M.color = hair_color + add_overlay(M) + +/obj/item/clothing/head/wig/worn_overlays(isinhands = FALSE, file2use) + . = list() + if(!isinhands) + var/datum/sprite_accessory/S = GLOB.hair_styles_list[hair_style] + if(!S) + return + var/mutable_appearance/M = mutable_appearance(S.icon, S.icon_state,layer = -HAIR_LAYER) + M.appearance_flags |= RESET_COLOR + M.color = hair_color + . += M + +/obj/item/clothing/head/wig/random/Initialize(mapload) + hair_style = pick(GLOB.hair_styles_list - "Bald") //Don't want invisible wig + hair_color = "#[random_short_color()]" + . = ..() +>>>>>>> d17d66f... Adds wigs (#31304) From 33364920b33d1d0da51926ff0e6b5ef132b5944b Mon Sep 17 00:00:00 2001 From: YPOQ <30683121+YPOQ@users.noreply.github.com> Date: Thu, 5 Oct 2017 08:24:34 -0600 Subject: [PATCH 04/28] Fixes crafting stacks without breaking crafted machinery (#31298) * Revert "Fixes stacking when crafting items" * Fixes crafted stacked items properly * Update stack.dm --- code/game/objects/items/stacks/stack.dm | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 6e7ffddeb3..7cef6094ea 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -151,7 +151,11 @@ if(!building_checks(R, multiplier)) return - var/obj/O = new R.result_type() + var/obj/O + if(R.max_res_amount > 1) //Is it a stack? + O = new R.result_type(usr.drop_location(), R.res_amount * multiplier) + else + O = new R.result_type(usr.drop_location()) O.setDir(usr.dir) use(R.req_amount * multiplier) @@ -164,16 +168,11 @@ W.ini_dir = W.dir //END: oh fuck i'm so sorry - //is it a stack ? - if (R.max_res_amount > 1) - var/obj/item/stack/new_item = O - new_item.amount = R.res_amount*multiplier - new_item.update_icon() + if (QDELETED(O)) + return //It's a stack and has already been merged if (isitem(O)) usr.put_in_hands(O) - else - O.forceMove(usr.drop_location()) O.add_fingerprint(usr) //BubbleWrap - so newly formed boxes are empty From 5b0b2fd5bb8f021c61296a76ec9bb254461f6d1e Mon Sep 17 00:00:00 2001 From: XDTM Date: Thu, 5 Oct 2017 17:52:47 +0200 Subject: [PATCH 06/28] Adds H.E.C.K. suits, spraycan_paintable component, and reworks item's attackby() --- code/_onclick/item_attack.dm | 2 +- code/datums/components/paintable.dm | 29 +++++++++ code/game/objects/effects/effects.dm | 6 +- code/game/objects/items.dm | 6 ++ code/game/objects/items/crayons.dm | 32 +++++----- code/game/objects/objs.dm | 1 + code/modules/clothing/head/helmet.dm | 22 +++++-- .../modules/mining/equipment/explorer_gear.dm | 61 +++++++++++++++++++ .../mining/lavaland/necropolis_chests.dm | 2 + .../living/simple_animal/bot/construction.dm | 22 ------- tgstation.dme | 1 + 11 files changed, 137 insertions(+), 47 deletions(-) create mode 100644 code/datums/components/paintable.dm diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 987818924f..4c0eeccf1d 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -20,7 +20,7 @@ return SendSignal(COMSIG_PARENT_ATTACKBY, W, user, params) /obj/attackby(obj/item/I, mob/living/user, params) - return ..() || I.attack_obj(src, user) + return ..() || (can_be_hit && I.attack_obj(src, user)) /mob/living/attackby(obj/item/I, mob/living/user, params) user.changeNext_move(CLICK_CD_MELEE) diff --git a/code/datums/components/paintable.dm b/code/datums/components/paintable.dm new file mode 100644 index 0000000000..2ea94334d0 --- /dev/null +++ b/code/datums/components/paintable.dm @@ -0,0 +1,29 @@ +/datum/component/spraycan_paintable + var/current_paint + +/datum/component/spraycan_paintable/Initialize() + RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/Repaint) + +/datum/component/spraycan_paintable/Destroy() + RemoveCurrentCoat() + return ..() + +/datum/component/spraycan_paintable/proc/RemoveCurrentCoat() + var/atom/A = parent + A.remove_atom_colour(FIXED_COLOUR_PRIORITY, current_paint) + +/datum/component/spraycan_paintable/proc/Repaint(obj/item/toy/crayon/spraycan/spraycan, mob/living/user) + if(!istype(spraycan) || user.a_intent == INTENT_HARM) + return FALSE + . = TRUE + if(spraycan.is_capped) + to_chat(user, "Take the cap off first!") + return + RemoveCurrentCoat() + if(spraycan.use_charges(user, 2)) + var/colour = spraycan.paint_color + current_paint = colour + var/atom/A = parent + A.add_atom_colour(colour, FIXED_COLOUR_PRIORITY) + playsound(spraycan, 'sound/effects/spray.ogg', 5, 1, 5) + to_chat(user, "You spray [spraycan] on [A], painting it.") diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index 4406c32fbd..d5f8e28d2a 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -4,9 +4,7 @@ /obj/effect icon = 'icons/effects/effects.dmi' resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF - -/obj/effect/attackby(obj/item/I, mob/living/user, params) - return + can_be_hit = FALSE /obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) return @@ -57,4 +55,4 @@ return /obj/effect/abstract/singularity_act() - return \ No newline at end of file + return diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 072896ac01..362148c801 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -26,6 +26,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) max_integrity = 200 + can_be_hit = FALSE + var/hitsound = null var/usesound = null var/throwhitsound = null @@ -322,6 +324,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) // Due to storage type consolidation this should get used more now. // I have cleaned it up a little, but it could probably use more. -Sayu // The lack of ..() is intentional, do not add one +// added one, fuck the police /obj/item/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/storage)) var/obj/item/storage/S = W @@ -346,9 +349,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) qdel(progress) to_chat(user, "You put everything you could [S.preposition] [S].") + return else if(S.can_be_inserted(src)) S.handle_item_insertion(src) + return + return ..() /obj/item/proc/handle_mass_pickup(obj/item/storage/S, list/things, atom/thing_loc, list/rejections, datum/progressbar/progress) for(var/obj/item/I in things) diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 23905200e9..882335d5e7 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -107,20 +107,19 @@ var/amount = weight * units_per_weight reagents.add_reagent(reagent, amount) -/obj/item/toy/crayon/proc/use_charges(amount) +/obj/item/toy/crayon/proc/use_charges(mob/user, amount = 1, requires_full = TRUE) // Returns number of charges actually used - switch(paint_mode) - if(PAINT_LARGE_HORIZONTAL) - amount *= 3 - if(charges == -1) . = amount refill() else - . = min(charges_left, amount) - charges_left -= . + if(check_empty(user, amount, requires_full)) + return 0 + else + . = min(charges_left, amount) + charges_left -= . -/obj/item/toy/crayon/proc/check_empty(mob/user) +/obj/item/toy/crayon/proc/check_empty(mob/user, amount = 1, requires_full = TRUE) // When eating a crayon, check_empty() can be called twice producing // two messages unless we check for being deleted first if(QDELETED(src)) @@ -131,10 +130,13 @@ if(charges == -1) . = FALSE else if(!charges_left) - to_chat(user, "There is no more of \the [src.name] left!") + to_chat(user, "There is no more of [src] left!") if(self_contained) qdel(src) . = TRUE + else if(charges_left < amount && requires_full) + to_chat(user, "There is not enough of [src] left!") + . = TRUE /obj/item/toy/crayon/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) // tgui is a plague upon this codebase @@ -298,7 +300,7 @@ var/takes_time = !instant var/wait_time = 50 - if(PAINT_LARGE_HORIZONTAL) + if(paint_mode == PAINT_LARGE_HORIZONTAL) wait_time *= 3 if(takes_time) @@ -343,7 +345,7 @@ var/cost = 1 if(paint_mode == PAINT_LARGE_HORIZONTAL) cost = 5 - . = use_charges(cost) + . = use_charges(user, cost) var/fraction = min(1, . / reagents.maximum_volume) if(affected_turfs.len) fraction /= affected_turfs.len @@ -355,7 +357,7 @@ /obj/item/toy/crayon/attack(mob/M, mob/user) if(edible && (M == user)) to_chat(user, "You take a bite of the [src.name]. Delicious!") - var/eaten = use_charges(5) + var/eaten = use_charges(user, 5, FALSE) if(check_empty(user)) //Prevents divsion by zero return var/fraction = min(eaten / reagents.total_volume, 1) @@ -527,7 +529,7 @@ H.lip_style = "spray_face" H.lip_color = paint_color H.update_body() - var/used = use_charges(10) + var/used = use_charges(user, 10, FALSE) var/fraction = min(1, used / reagents.maximum_volume) reagents.reaction(user, VAPOR, fraction * volume_multiplier) reagents.trans_to(user, used, volume_multiplier) @@ -583,7 +585,7 @@ H.update_body() // Caution, spray cans contain inflammable substances - . = use_charges(10) + . = use_charges(user, 10, FALSE) var/fraction = min(1, . / reagents.maximum_volume) reagents.reaction(C, VAPOR, fraction * volume_multiplier) @@ -596,7 +598,7 @@ target.set_opacity(255) else target.set_opacity(initial(target.opacity)) - . = use_charges(2) + . = use_charges(user, 2) var/fraction = min(1, . / reagents.maximum_volume) reagents.reaction(target, TOUCH, fraction * volume_multiplier) reagents.trans_to(target, ., volume_multiplier) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index f2537945db..fb5a4344f0 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -13,6 +13,7 @@ var/integrity_failure = 0 //0 if we have no special broken behavior var/resistance_flags = 0 // INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ON_FIRE | UNACIDABLE | ACID_PROOF + var/can_be_hit = TRUE //can this be bludgeoned by items? var/acid_level = 0 //how much acid is on that obj diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index d89671d06d..da4fe1cf5c 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -17,13 +17,25 @@ dog_fashion = /datum/dog_fashion/head/helmet - -/obj/item/clothing/head/helmet/Initialize() - . = ..() - /obj/item/clothing/head/helmet/sec can_flashlight = 1 +/obj/item/clothing/head/helmet/sec/attackby(obj/item/I, mob/user, params) + if(issignaler(I)) + var/obj/item/device/assembly/signaler/S = I + if(F) //Has a flashlight. Player must remove it, else it will be lost forever. + to_chat(user, "The mounted flashlight is in the way, remove it first!") + return + + if(S.secured) + qdel(S) + var/obj/item/secbot_assembly/A = new /obj/item/secbot_assembly + user.put_in_hands(A) + to_chat(user, "You add the signaler to the helmet.") + qdel(src) + return + return ..() + /obj/item/clothing/head/helmet/alt name = "bulletproof helmet" desc = "A bulletproof combat helmet that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent." @@ -281,7 +293,7 @@ qdel(THL) return - ..() + return ..() /obj/item/clothing/head/helmet/proc/toggle_helmlight() set name = "Toggle Helmetlight" diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index 1b21b88447..f2cdefa9a4 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -46,3 +46,64 @@ /obj/item/clothing/mask/gas/explorer/folded/New() ..() adjustmask() + +/obj/item/clothing/suit/space/hostile_environment + name = "H.E.C.K. suit" + desc = "Hostile Environiment Cross-Kinetic Suit: A suit designed to withstand the wide variety of hazards from Lavaland. It wasn't enough for its last owner." + icon_state = "hostile_env" + item_state = "hostile_env" + flags_1 = THICKMATERIAL_1 //not spaceproof + max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + resistance_flags = FIRE_PROOF | LAVA_PROOF + slowdown = 0 + armor = list("melee" = 70, "bullet" = 40, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/device/mining_scanner, /obj/item/device/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe) + +/obj/item/clothing/suit/space/hostile_environment/Initialize() + . = ..() + AddComponent(/datum/component/spraycan_paintable) + START_PROCESSING(SSobj, src) + +/obj/item/clothing/suit/space/hostile_environment/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/item/clothing/suit/space/hostile_environment/process() + var/mob/living/carbon/C = loc + if(istype(C) && prob(2)) //cursed by bubblegum + if(prob(15)) + new /datum/hallucination/oh_yeah(C) + to_chat(C, "[pick("I AM IMMORTAL.","I SHALL TAKE BACK WHAT'S MINE.","I SEE YOU.","YOU CANNOT ESCAPE ME FOREVER.","DEATH CANNOT HOLD ME.")]") + else + to_chat(C, "[pick("You hear faint whispers.","You smell ash.","You feel hot.","You hear a roar in the distance.")]") + +/obj/item/clothing/head/helmet/space/hostile_environment + name = "H.E.C.K. helmet" + desc = "Hostile Environiment Cross-Kinetic Helmet: A helmet designed to withstand the wide variety of hazards from Lavaland. It wasn't enough for its last owner." + icon_state = "hostile_env" + item_state = "hostile_env" + w_class = WEIGHT_CLASS_NORMAL + max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + flags_1 = THICKMATERIAL_1 // no space protection + armor = list("melee" = 70, "bullet" = 40, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + resistance_flags = FIRE_PROOF | LAVA_PROOF + +/obj/item/clothing/head/helmet/space/hostile_environment/Initialize() + . = ..() + AddComponent(/datum/component/spraycan_paintable) + update_icon() + +/obj/item/clothing/head/helmet/space/hostile_environment/update_icon() + ..() + cut_overlays() + var/mutable_appearance/glass_overlay = mutable_appearance(icon, "hostile_env_glass") + glass_overlay.appearance_flags = RESET_COLOR + add_overlay(glass_overlay) + +/obj/item/clothing/head/helmet/space/hostile_environment/worn_overlays(isinhands) + . = ..() + if(!isinhands) + var/mutable_appearance/M = mutable_appearance('icons/mob/head.dmi', "hostile_env_glass") + M.appearance_flags = RESET_COLOR + . += M + diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index e16077fec1..95c4898605 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -932,6 +932,8 @@ name = "bubblegum chest" /obj/structure/closet/crate/necropolis/bubblegum/PopulateContents() + new /obj/item/clothing/suit/space/hostile_environment(src) + new /obj/item/clothing/head/helmet/space/hostile_environment(src) var/loot = rand(1,3) switch(loot) if(1) diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index 0d1f346dcf..c53925e076 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -357,28 +357,6 @@ var/build_step = 0 var/created_name = "Securitron" //To preserve the name if it's a unique securitron I guess -/obj/item/clothing/head/helmet/attackby(obj/item/device/assembly/signaler/S, mob/user, params) - ..() - if(!issignaler(S)) - ..() - return - - if(type != /obj/item/clothing/head/helmet/sec) //Eh, but we don't want people making secbots out of space helmets. - return - - if(F) //Has a flashlight. Player must remove it, else it will be lost forever. - to_chat(user, "The mounted flashlight is in the way, remove it first!") - return - - if(S.secured) - qdel(S) - var/obj/item/secbot_assembly/A = new /obj/item/secbot_assembly - user.put_in_hands(A) - to_chat(user, "You add the signaler to the helmet.") - qdel(src) - else - return - /obj/item/secbot_assembly/attackby(obj/item/I, mob/user, params) ..() if(istype(I, /obj/item/weldingtool)) diff --git a/tgstation.dme b/tgstation.dme index 8b927cf2bb..b996531842 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -294,6 +294,7 @@ #include "code\datums\components\_component.dm" #include "code\datums\components\archaeology.dm" #include "code\datums\components\material_container.dm" +#include "code\datums\components\paintable.dm" #include "code\datums\components\slippery.dm" #include "code\datums\components\squeek.dm" #include "code\datums\diseases\_disease.dm" From a5f86b1e67e0ba1eeae99e35b41cba9a4ef41a1b Mon Sep 17 00:00:00 2001 From: Kevak Date: Thu, 5 Oct 2017 09:59:13 -0700 Subject: [PATCH 07/28] Fixes plasmaman sprites --- icons/obj/surgery.dmi | Bin 31018 -> 32112 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index d18a1bf262fadc379d7528c6dd0e3d5613e322fa..18bbcb36105d581053c2e6a2730777263c50eb08 100755 GIT binary patch delta 12695 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 HF#P^MijN%w delta 11593 zcmaiabyQSg_wG>A-AE{nlyrwkDJ|Uy$bfW99#Faj3F#E+?rxCo?#=<}8fNbJ-QRcD zy7!+uYn?S`uQ}^IJD$DYy`OjfJ|GoeAjL8Q7~WcXZnB?TEnIAz+-w{jK%g(_8OftD z%fdJVSS}C&>K=5gWvY{mQ&d~zfPymy5a?=X?~up5p4|MKgmTX zOEz~%K0RIZNdW$frs^NeTv$Az+aEhxLIm+ocW6tV96BfPy`FyXTDq~^zVr$s?#F)w zjGr?$#k1eGsG9X&UwV%9q-&5R5|1ED))ejpFcjeEqdjMK!*rEjwfR~yWcJne$*gDS zw(4_-El>BBYWb_v89OFf}^VsRm&_Hf+1Sk4lKGwt$t6N{VCWpuGHO`FFn=KvuNWZMki*!xX z?XNZ%)(2G-g%y_pyxqT3Jq5H90Xg^9iku*F5<5QBCtm4(Q5oJ5;n=D%<_n!RhF>*k zh0fm&dAIiT>b6jzBV#RA+O6Gj$qrlj_n@J; zbI|tDZjH&)G5IG2mHCDH^uTYrQ&Ju%!+}|3sV*L0l*u&P;FdzE&+PZnzyR|BcNbPq zbuZz9A|O|tiyJS1z8P{&AG3h|TlBm&=WKe}z5UhD)?K+51P$tSxj#AXPa9Fq8duaS{QTQN1%J68zTYb zBWH4Q=S4wRMjUv$TNrzlJY#w zJI;iRm^ABfXmu!RwQyJXTOu)M^8qF5GsH@1V~?ROqn#UO&T00lDCy;1HMG`Xq*dVlVJ*lExy%`RD9gNgd`7U9o9#K2{!T#lo_v0zm>L45v_~xInvEQw&D_~W#*>3YH;Pb9rHVE1K@!{a) zVCOsFA03fYO}I?qjOuhS-7~`%JzB?9{{FUx;8}|w=7Efx-WJD7CN0b^)cOXSpOR_5&GoxPQK>=hv6GmW?} zgmY{1XXfSoJ)Msi5Z-u?Ie%s-Bq;bnPfvIUrlFw$YK6ldegD2;K0Mr&WE+6iGMO*U zpw-saWzxH_00#--cTvXP@N{4k}P=I(gd7zkvq8hY#_0SCPi$G$tr>T{C3Z zay8`yh$}haI{RWLgf3#hvHk6Vj7;*6q&Kn&an?%We6D+cx37gBu2!C}>%IC7c!pkV zt~Dg!-?s1iuMH0mI}1~v&bRs8Hm?f_31x|NmfcITD<$v{)eNFagTdsSoMmnv9+PKo zM09j&mI;7!?*MfoN+Iz3`Nd{48xvB~B=V<@yQvPWS%1kuF}NAy0KX<q84e;OjUCJpBP;cI+&HzH|74A>}30lCa|&^---j8XTiJg8_gfHqg$`8-0*0{6+Juz(eY_5VbFVU8+u`RJC1|I z(-Dg3Nro^ro~T$$n6+@<3WGwpwXmF$5<5t~z!hPr2G#+>MtXR#&CHXA+R*iCIS_r% zwAB|6v%y4PlI)C_zG-StgA&1)@kyjoT;ecraq~(_h?y8s+a#j^vGYLFF|lRgw~W7k zPtC2!gpSIq>7m*jY9b+?>!YSofedO=xT`8pR*k$+ptjGVE{dhB+Q)2JRW;P$??=&W zblv9Mu>xN%t*qtKvsb;@)tFXHE1D|{LjZjX9N4=LJC;F;N{xz5N>h|_!& zG&-sor551BmnuV>M<96qlizoNx{&)c*{hs`9P8LDG3V;rUYhXV<6Gj^? zIrL!(;(_xFg)KUo1ZYm=Bqy6pObF}Ql;*jAiF|huvRzJgXLF$>Z|ACvW3_I|>8uTv zfS{v%XDlUfE_x@+q92CK^IAeA8d@r1m+GJL#q#LA%CWz}j51+Xg6w6Hyr`YvD;n*H zRjZyQhx{HZmVTn+HK1WiBY$DZkZ=`mbSS>TEJx2nBd(E^$&f=eoee7jtFMpTwEP`S z5O^mn4dzcMpBL8?ir>-)j~mEzJKJ7-;AZFCHuGXCNKJbe6?thxl0ARyb)RoKsiiqw z{Rz9UeCfTnJRvsLJaJZ1#2n$9g4Or4Re97>23sIAqUW<|qQs5z(xb*ZB|E$c+Q?kd4i;J2yU0vO*`z_#6=S8$U177I2y;`k$BRyGT z8DxYoSML!tD!H{C-AF9#z0MDMe__0J41R)#_{~3mq3yHGbl+)n?zwy$Z=bkqeku2L zEvmy{+fyG4khKe=R6^93l_bO=2G6fktR9wo6is9Q zL{ui`*5rNTZt&madz?hW^Vh#--fJg0UHO6??(8gn0W8Gt?CpNgF_1U5N9pi&;f9c* zurW3@pfL9L-4|21dA6M1FXbiv8vCx`;xpyYV8Kr%V)NR`WiP5m^0^A?>#dL3^Rr19;*SFFH{_%| zLSlp-VajmvAC)pAVM=Zt6}C3?f+FENjl%E0Ct5Tt-8X#?zN=sGot)lgWO)^%Zb1^h zXH8U)5BduOXSw))W)A23eQ`cF?&sjcYOYACArCMx*MzsPNj5h(A3zQ_wZ?f=hAIoq z!o#BL2uPpD)Qr6!IVnmeicVkf{PD!}iGxElE9emO1lAZtlLZ{s@csklK>>B``lpRS zpdCM8-eg$@;YlIC)-Y4ad*;0cioM6lQ_@64+pZetS{ZKbd%-I9ZG#t@Z>*^2-^6?HIO~{x3JZD>$7ggM z=blp|WYs!5m;G>P#d=0(>E)iey?sGJ%X3?wmKM6~+D-PXr0uUv!@*B_r2BnC(z_KZ0L9ZS{UGs2o`E0qca`2Jegu5VXx+`tF?29%&JN!T6_Aym zKvwh8vr?cm?}-Zqf$OD?*OiRsg6?&=M$Jd&R$y?mrko*u+h&dTL<2K+K-gcs4`55= z2}D`wSi8l}gx$9pHGA;*ya$Y8KECmP#ohiSmbKXKxO$Cj2AN&o?#zU^xi6$7HY7VJ zknbf6CM+ie`POzWDkf-Hfms-?IyCT4PX_d8?Ww6Zh5_o<8BSNZ$rU1D_BYa+fTGUcFy z%0*CeN=Mkx1%ux5@+zUU$<%%Kyy^?^jaP2l=$!p5>LEZh3h zhjeqcgedpB6O+V@Oua6%QtR@Kl3!aLM{iSB`-PIQ#wVqLqhFP-n9$C!u6d3jRszt+ zf;`%{L7Cr&V5eCroj*Ex^pwP9CkY8@YHqiw{T~^=cS_%a)$8>5gSSXTGP8V222x{t^1adJ3Wu7{WPD#IN3ZF&` z;2Zl>I|HCzomFv*9<2Mp}_JXS7EHTV_YDg22KNL@qOC-N%mTc1}%e~qN?n9k5G%j%j( z6dn=LO+XpW#zAf9h!254PHc*{cE?as*8`5DU3sR>#Rw zfW5cby)U4|;#SL*uc<(cMomDd#R|Ei{F{5D0t!-UL`Osc@!u%WoZmh=q76B}7=G?Y zh4keD(Sb(n>{wR2UcOU)r%*6GsczWUVh9`JUcbu<2!lIiMJxP5N$xBa8Y3i>!I$>7 z;QRC$OPe&&&CP8B;&eBQX+4Oe8K`b})8Tc427`3bo&T{=t9CHvsc5SYc0Z1| zpWWN9EH8IeKvu9{n!T0QVgbd9GQ|H*H86LX!h{?Y+*mW&Yna*^B$3m4$+#^5ONU35 z#N|Rx`_tcT{ZCOIQO)jZC%(vuf(DbD1ei@rlarJN!}GxI((7bt+#@-0;**WqHR$vq zT7&FI@d493J^EJ$=AZD4H_FX!nt3L|K(h_t?AJ&*rH(ZW&4L^R*}C%cedyXc~J( zvDvWo_UgY@P-p>{t6I${f{e_wDkXc`u&lcua6Yz6GMRnCW+p0MC|A}xN2f$mWJcmi z_akPH;4LzQzXJZfw1zevmtMd4U6r-l)%xki#xwy zMT7lN>)pBn!4l|Ou;*Xaeb(?9*uEQKE7GTArz@dCKaJA~vLJ8go5)+ZY7ur0wGQ`2 zD1igFF{rBL2ge*cYj!1>`oAw-H^ z%aq!u7w`2P}oHJmui6039|zaL%MD* zSLT-qjOj70yMUESPd)|E9h%vao? z_`&c(QN96P8*6(`!u)j=9tSb<6MmE2uRpxZ8tImrVl}HJ?2%RwO`&JwOfI}#4pTr{ zgm}D86NyoRekLZi=1a>dTXp2zK;Z+Y*Fic*DF0)-ZbqlHuRT!tGQ-7E&5ZK!;CmHD ze8t5`JSJ!8(zCA!r&dm=Q>hAktXr%~i>e(3(gRl=1`GhAl2z63d4?q}{?o7o#wdA< zjT7`c=qU4c%4Nf%p99c}w@rPtnWl{Yd#H044JvYDdZ98VfFd@rO9{DE5GVekf8&xf z%|;PjppfU*IEAPB^6q3}AXPV{wxZ3?G_0e7=FbhjnFmNtU zhxnc2F%bD?MnFliJZ0y64+4=ky_0>TRgFiGtfATEWGsGu zOQmH|$G`vzS3BRw*)pTV^De))f~f)_`*Z`EW~doB@?fowoZg9Y$4rp~{s2DPo3?Qz8LfLGL2IdPJeKY=rMG3Go^i;LfMI z^f~74M=Ah$U6Uq-%0V+@;!m^+#u7@xk8LxV0L+Q+h zAlt~)=cY^ENgF7IW$-}Rc5g3j@Mw#34`iRSqFj#+v=vPjlTnIn6l2zxq&uKR7te*P zj_DCNN9A~=&3;a&JR?zYYuUb6LPi$J&IKp4ijTwi7I;WWNy0V6GQ3qV^9@-;=C2SK z-v^MB(vXQI$Tb%GK>DPc>cKiL=%861Zn|~tWkTE`TL|P;(Ohoq37|BHOpkDm@w*PE z4b+2I5_Pn87pDM(w;NlgB2wK2bd>hB&#d%d^~GL8S-JvhkE^?*7U38s##JAnSAF>I zQhw)eSF7T+lcShnm)9B17Az$cwv4ZH02=9R8R+0bF*W8IRIs?>_|J2&q{#zQt-1da z5s&@nSDg0twYBw=Q*$As4(MoHt!7nwsvC6CuCk>8WT?+N1CHT(n-6v-vPo(XQ-s1e zcIO>awLR?n?JslGTc>K@YTVLA6I=V(Z5tlJqq*&)l^W-m?g}13Gm4!wgu>In2&dYt zU33e3S>b(oZEkUrV+XOW=k5N``SRLm@=eQdN&k{Q^!Tj86}EpY=C19|wFn!Z_l(i+ zV6nscqe%dL%EQScOdX_+zAHvM9j&8&=O&aw-^FUdXcdncFgC_Tjfej1Ti~BR7+c%h z;ZeNZ$wavOdnVIHlN0M|(DW3b*YcOsFl2uE@L(^0-!!MJIOcZ+zN@~q@T0HwW#Vs| zp8C7-T>^2MQ15ixt)Cc<)QThD(&h`d=X2p6=|=`gbM0^)Dssecb6JJMKojbZ6yI8a1UrQf;Szc>xt+R4`@> z#frMr7!J%7?ptVTbpiH*1}CY`*Nn-#jttV@p`>Kh%NjMhVLtnY6x!oF2S%7wM(5vM zzm&1Gv!&wNrxB7hatMHOCSeA)rl_mtg(Wc;b zpFb9p80pLM*3IoVsf4z{SF#3tT9*5eTNc~Z<$p|PkNz^C6`GwKmAdHH=ONwH$FF-O z`UtATWO<3<9ei8`l~V{FKYln2%_6dmbo^D{9ylgqJd!S$*tpI?+#z}0gv_3~@E?AJtMG>XmsQDC~WBmVjZm?oG`}hdn6W;qZCE)9FR=w!oPc z=wA|D16rdgV_ShufTP&Ah7)$z0#66U#@@vhJ+-+gMTf>aA{J?FnqDv;^LeQADM(xn zZdCTPDW7{6KbQ{C{!wRe^tG|r5Ol1#w>yCJ zz3I8a;M=VZI{6nvDeW2ohrzs(RCF;|Oz3*}_UYz$+m8{03sC_ ztzl-=3S)FCZXGl~%2n8C>K20ahtc!0>!1m|WZ^yP;#` zA{Hg_4x+ernoLF)s;F{d05O9BIxMWmVLYCe!hq%}6j{o=gPeG%g06sJy!86UuanK& zt!EJ(1>e-q>#yNoF8z1?ja)gj6gG(9j9by={yWS**qn0*HSM>(rAn)~6FzutXS4U; zZP8yZLAld8aq>tnUBgG5;=&sSQgBe|cLh^2j?@ty&XiLzX31#GqGc~&&2QeYT(xwf z2l4QxUiD`iNR3sFqo90~Kpw0a-{qpLUZx;F++}0Z$jyR0EixSw<3yUl!(XgEVnSjYaI z`}i52Krc@+&}S`9$nnIT^%KZ-a~H9;v-?$67oC|Y>GtxaKPg<`WlHy}7kneHp<@== zmy`NK+R+u4kNbcM;;hFt0@!YMiK}D$-aErsoiwr?&JE`;c7`AIR{X=4^Y0V{(<4<< zUcA}4FD9(-5mr&({=_%_B+)1JSWS9$b@L-mEE4bvE-{&!)tj%Cs6Wr?Vvdgv3F&`! z3oq{E{-c!JRF(N9FZjoWV143DRoSl?1l*o!GM>vvioF*m-xfsvE2rdGJAiScv-icS zaI@ng)n*(4pO0a@<~nBH$$?q?Hhd>DhLX_fb=fy>B!4;_?tLT9(8GC|4mDv6^`tYK zoCSVHH`~#cJqmQ1o3R9dkJlfbo|Er$wVkj~29r<3r@XQCewB1&u%$Lr36F=QH@eKG zadvqB#WGFb?_`y>Uj_dXE-IeZNY47&Gv_tuG5$10iWaquVOHpT{p~5^m?F=HGG@*u z>Pn0_(M(i#@Q#^*0XIPHbIZnnQq_$xCMJOSQk2t1c|cnM713ZgA};(C;1ON?5_YtY zg;gi!G0iKGxLU%U&m@sJw9SHni=7Y26oa9>*y|dd?$=75F4T}ljFPL(x_$nJ?`W8I z?R%edIuvZ+ZqFg%1gA!vL!aBBsk@s3iEMg7&Xr8bPxgjfNHi2U8en-UcPth_DpEu$ z`xaVNOa&U*6y;EZn0b9h1gEdB zcbO%)bC%7>(6gQxw4(Y#N-P8cxMfV7m3^bAWs(Uqoa^lGCOB5+c{C~X5u4V zf35iEzBF+&V@EQ$%A#TgKPUnZL1qeS%iBcoD zy~^-T3caY~;jZDHvDTkSi&@6xDC%_}_G#IeA=sRD#SW1Jd84`>XWzxte*KpI@RhxL zQFE#DYbzrH_WVL~En>m55TEzYR~RCmS;)wPwkgNSiopZtmWKH*W&jC67>0HA?4j(7 zcdS7NZcv|N+I;;h;#}<3Afsy7^3VCu;9+egE}h`vFH9tTDfD1jqipwQJ7WMjQM6J6B6}rm-!@g7cQC` z4s>Ogf(0aYCiQVDfrS(+|39w!n4FDLV**ky1p2Pq>rY3(MQq?T{Mm<4%pDNpcBE^5 z0Fv)=690i4SL_CcqqG3H?TfOA#Jj(buP8Z z95*khZO1L;m6=qJV9)@{coe-NZd&qV#nKt_$ny_mW#L?U?A3x2(#E?VPho{2&A?EP zEP3hd$qGE#em~3GZs>Rz=Mi2s@O!6D<$6g6v1|^^Mq4smme(6`bfI$;*{3a{i#~(- zZ@oSaa*-rz7Y-2)tNUN%RL7Zq{B5^{{iV#MFPC3i3B=VMB4vpN4y}}$qClm->C3Y8 z3uUdPe@IEItKi=Y($)0*DX0Pv=ku_TxC4i%j6co?l9Rr&+CztQcPR+julu@}?3o6t z!&-wbSC=n|#zOsu`&1<-ef^Nsy6oXwDjj9uSeG8F;>^VZ|19SLPRWKieVy}fi1%?R zA{X$TTFd_+D9@^kSx%#1FXt9&zLog-c7YZ!I$u$UMs0O}fryWfJV1?9Smt2ckl4c+ zTIFG=KjPBy%S>xoch_ii^wL2@399Xo=^1GiC+*f{Kxka4!}@TD{K9q`1%$Yfc~Zu1 zLAiHZ_7{Z0_{bc*e-?u?^IF=Gj%nAg$D4cUP$t%IKH;=|vRN3Oa<0E6&Y)O_Kk&Zw zv>Cx;&%MHZlQ8)_ZgfU$NU-Lv` zV5vH{YSKkzz5;EUh+uKol$x)Z4J0Di088kmJJ!L?j*slj5t?W~idap$&%!p@^1mAe z9o+-6%7FBSGs2D{pnJcpjamsW)DX|LakuiZ4UC$dB==;*{$9uQ?GSF-yTOrI~Pb{fRI#r3Z|J<7(Nled=nKIp5T>{zbVD*%=SyWk0`&4EVql1ksC7e?WEF_v7UaVNf z{^urQ0mj!YdRI5}V3Y29YJH=e?blB)c1*r!)e9FNA6__81LEG4!hX;6diDwm7dLSUiRQ<{O zDaZ!wwbY~uKT>+wmv3A@=Gdwxk>v#hIK6%2<9SxjAtAwuA@_!`D$GB)@av63m{fIJ z75(iM;(wDMZ;yez10n*6G72j}6j|LptMHL(tWSmQNQgQt+!_JWij%5t?506FL1?Bb zso^nu=Ar-sK9ghzgM9EHT857s@9ztN&-&=kX?ECoPaA`q$&Gqm+vlT$3VlB2>BvBF zk6z)|?8Vp$(4Zyg>*Szd7|twldgtXxC5+KN-z2YfLs8%ze&wQe=1oj6d#l}=i#;D$ zPT4o1qG&7#sf&Jzmu8$UnMneKTT=7>#xMg*_=kf4Esu+EnJ1T=8+1g#1oERzn;y|- z=GV`B@EYd|>a_#4ACYFnTOY8TF1QW(&rm9V!U9WG@c&-Cm3r|wlvT5No8>%uqE}uu zo`0jizBtHH@>*-pDlwQ`4~!htBIpw#C9QWxtAvq@mtcZ%{Ps#Vz?vmjF!b+C6771T zB7GciN5w?%e&^O^i>jU=W^nMOrRPv&3fwqeXT~!etncWdfc)ySWp1#FJ5*}J1G#M3 zBc18N;1;Q{h*fjV=oRe){;h|_TJ(%$%Up%m?a&H`!n!V|HyExV{U+Q+rht}&@9H_G z;ldR13?3=cpLNtEMdVOjynkz_8nD?zBY>{nCqz97+Q*;)M*6jf_wLtBJtQ&$=W?Yc z9QtV*vei_(6NJc}@^e*TpCV1cjNgWlu1;envGb{Bk;3q3BDiS1ae_E)&c-=PD0qhu z^dmhcwTTEwn4$J9W~tDlVt-5lG3cP&G5aWGA9@tlxeEe$dk!2-W>8Yf0yrOmNQ0KH z#P?K36#q8vz#d!l7nG)7#8v-ZX#wh~@5t9cJOIx2@im}GZSE&d6IB+GxEd@CA& zseBY76x?wM`<5e$G;ZHh2i5*}QiU9fIARJwFwO|r?Qnm6_aCYhA<@U7vi-L^_&*}U f|7KGEM~2f$T58ij{lY5-AwKWqRAtL$%)b6FE3WUu From 2a75083f80237f85fa2b57115c2e152cc021472f Mon Sep 17 00:00:00 2001 From: Joan Lung <3886584+ChangelingRain@users.noreply.github.com> Date: Thu, 5 Oct 2017 16:04:29 -0400 Subject: [PATCH 08/28] Makes angle2dir() much more accurate --- code/__HELPERS/type2type.dm | 470 ++++++++++++++++++++++++++++++++++++ 1 file changed, 470 insertions(+) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 46d6c2ce5c..ab06de1b8b 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -75,6 +75,7 @@ /world/proc/file2list(filename, seperator="\n", trim = TRUE) if (trim) return splittext(trim(file2text(filename)),seperator) +<<<<<<< HEAD return splittext(file2text(filename),seperator) //Turns a direction into text @@ -539,6 +540,475 @@ if(!istype(the_matrix) || the_matrix.len != 20) return "#ffffffff" return rgb(the_matrix[1]*255, the_matrix[6]*255, the_matrix[11]*255, the_matrix[16]*255) +======= + return splittext(file2text(filename),seperator) + +//Turns a direction into text +/proc/dir2text(direction) + switch(direction) + if(1) + return "north" + if(2) + return "south" + if(4) + return "east" + if(8) + return "west" + if(5) + return "northeast" + if(6) + return "southeast" + if(9) + return "northwest" + if(10) + return "southwest" + else + return + +//Turns text into proper directions +/proc/text2dir(direction) + switch(uppertext(direction)) + if("NORTH") + return 1 + if("SOUTH") + return 2 + if("EAST") + return 4 + if("WEST") + return 8 + if("NORTHEAST") + return 5 + if("NORTHWEST") + return 9 + if("SOUTHEAST") + return 6 + if("SOUTHWEST") + return 10 + else + return + +//Converts an angle (degrees) into an ss13 direction +/proc/angle2dir(degree) + + degree = SimplifyDegrees(degree) + switch(degree) + if(0 to 22.5) //north requires two angle ranges + return NORTH + if(22.5 to 67.5) //each range covers 45 degrees + return NORTHEAST + if(67.5 to 112.5) + return EAST + if(112.5 to 157.5) + return SOUTHEAST + if(157.5 to 202.5) + return SOUTH + if(202.5 to 247.5) + return SOUTHWEST + if(247.5 to 292.5) + return WEST + if(292.5 to 337.5) + return NORTHWEST + if(337.5 to 360) + return NORTH + +//returns the north-zero clockwise angle in degrees, given a direction + +/proc/dir2angle(D) + switch(D) + if(NORTH) + return 0 + if(SOUTH) + return 180 + if(EAST) + return 90 + if(WEST) + return 270 + if(NORTHEAST) + return 45 + if(SOUTHEAST) + return 135 + if(NORTHWEST) + return 315 + if(SOUTHWEST) + return 225 + else + return null + +//Returns the angle in english +/proc/angle2text(degree) + return dir2text(angle2dir(degree)) + +//Converts a blend_mode constant to one acceptable to icon.Blend() +/proc/blendMode2iconMode(blend_mode) + switch(blend_mode) + if(BLEND_MULTIPLY) + return ICON_MULTIPLY + if(BLEND_ADD) + return ICON_ADD + if(BLEND_SUBTRACT) + return ICON_SUBTRACT + else + return ICON_OVERLAY + +//Converts a rights bitfield into a string +/proc/rights2text(rights, seperator="", list/adds, list/subs) + if(rights & R_BUILDMODE) + . += "[seperator]+BUILDMODE" + if(rights & R_ADMIN) + . += "[seperator]+ADMIN" + if(rights & R_BAN) + . += "[seperator]+BAN" + if(rights & R_FUN) + . += "[seperator]+FUN" + if(rights & R_SERVER) + . += "[seperator]+SERVER" + if(rights & R_DEBUG) + . += "[seperator]+DEBUG" + if(rights & R_POSSESS) + . += "[seperator]+POSSESS" + if(rights & R_PERMISSIONS) + . += "[seperator]+PERMISSIONS" + if(rights & R_STEALTH) + . += "[seperator]+STEALTH" + if(rights & R_POLL) + . += "[seperator]+POLL" + if(rights & R_VAREDIT) + . += "[seperator]+VAREDIT" + if(rights & R_SOUNDS) + . += "[seperator]+SOUND" + if(rights & R_SPAWN) + . += "[seperator]+SPAWN" + + for(var/verbpath in adds) + . += "[seperator]+[verbpath]" + for(var/verbpath in subs) + . += "[seperator]-[verbpath]" + return . + +/proc/ui_style2icon(ui_style) + switch(ui_style) + if("Retro") + return 'icons/mob/screen_retro.dmi' + if("Plasmafire") + return 'icons/mob/screen_plasmafire.dmi' + if("Slimecore") + return 'icons/mob/screen_slimecore.dmi' + if("Operative") + return 'icons/mob/screen_operative.dmi' + if("Clockwork") + return 'icons/mob/screen_clockwork.dmi' + else + return 'icons/mob/screen_midnight.dmi' + +//colour formats +/proc/rgb2hsl(red, green, blue) + red /= 255;green /= 255;blue /= 255; + var/max = max(red,green,blue) + var/min = min(red,green,blue) + var/range = max-min + + var/hue=0;var/saturation=0;var/lightness=0; + lightness = (max + min)/2 + if(range != 0) + if(lightness < 0.5) + saturation = range/(max+min) + else + saturation = range/(2-max-min) + + var/dred = ((max-red)/(6*max)) + 0.5 + var/dgreen = ((max-green)/(6*max)) + 0.5 + var/dblue = ((max-blue)/(6*max)) + 0.5 + + if(max==red) + hue = dblue - dgreen + else if(max==green) + hue = dred - dblue + (1/3) + else + hue = dgreen - dred + (2/3) + if(hue < 0) + hue++ + else if(hue > 1) + hue-- + + return list(hue, saturation, lightness) + +/proc/hsl2rgb(hue, saturation, lightness) + var/red;var/green;var/blue; + if(saturation == 0) + red = lightness * 255 + green = red + blue = red + else + var/a;var/b; + if(lightness < 0.5) + b = lightness*(1+saturation) + else + b = (lightness+saturation) - (saturation*lightness) + a = 2*lightness - b + + red = round(255 * hue2rgb(a, b, hue+(1/3))) + green = round(255 * hue2rgb(a, b, hue)) + blue = round(255 * hue2rgb(a, b, hue-(1/3))) + + return list(red, green, blue) + +/proc/hue2rgb(a, b, hue) + if(hue < 0) + hue++ + else if(hue > 1) + hue-- + if(6*hue < 1) + return (a+(b-a)*6*hue) + if(2*hue < 1) + return b + if(3*hue < 2) + return (a+(b-a)*((2/3)-hue)*6) + return a + +// Very ugly, BYOND doesn't support unix time and rounding errors make it really hard to convert it to BYOND time. +// returns "YYYY-MM-DD" by default +/proc/unix2date(timestamp, seperator = "-") + + if(timestamp < 0) + return 0 //Do not accept negative values + + var/year = 1970 //Unix Epoc begins 1970-01-01 + var/dayInSeconds = 86400 //60secs*60mins*24hours + var/daysInYear = 365 //Non Leap Year + var/daysInLYear = daysInYear + 1//Leap year + var/days = round(timestamp / dayInSeconds) //Days passed since UNIX Epoc + var/tmpDays = days + 1 //If passed (timestamp < dayInSeconds), it will return 0, so add 1 + var/monthsInDays = list() //Months will be in here ***Taken from the PHP source code*** + var/month = 1 //This will be the returned MONTH NUMBER. + var/day //This will be the returned day number. + + while(tmpDays > daysInYear) //Start adding years to 1970 + year++ + if(isLeap(year)) + tmpDays -= daysInLYear + else + tmpDays -= daysInYear + + if(isLeap(year)) //The year is a leap year + monthsInDays = list(-1,30,59,90,120,151,181,212,243,273,304,334) + else + monthsInDays = list(0,31,59,90,120,151,181,212,243,273,304,334) + + var/mDays = 0; + var/monthIndex = 0; + + for(var/m in monthsInDays) + monthIndex++ + if(tmpDays > m) + mDays = m + month = monthIndex + + day = tmpDays - mDays //Setup the date + + return "[year][seperator][((month < 10) ? "0[month]" : month)][seperator][((day < 10) ? "0[day]" : day)]" + +/proc/isLeap(y) + return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) + + + +//Turns a Body_parts_covered bitfield into a list of organ/limb names. +//(I challenge you to find a use for this) +/proc/body_parts_covered2organ_names(bpc) + var/list/covered_parts = list() + + if(!bpc) + return 0 + + if(bpc & FULL_BODY) + covered_parts |= list("l_arm","r_arm","head","chest","l_leg","r_leg") + + else + if(bpc & HEAD) + covered_parts |= list("head") + if(bpc & CHEST) + covered_parts |= list("chest") + if(bpc & GROIN) + covered_parts |= list("chest") + + if(bpc & ARMS) + covered_parts |= list("l_arm","r_arm") + else + if(bpc & ARM_LEFT) + covered_parts |= list("l_arm") + if(bpc & ARM_RIGHT) + covered_parts |= list("r_arm") + + if(bpc & HANDS) + covered_parts |= list("l_arm","r_arm") + else + if(bpc & HAND_LEFT) + covered_parts |= list("l_arm") + if(bpc & HAND_RIGHT) + covered_parts |= list("r_arm") + + if(bpc & LEGS) + covered_parts |= list("l_leg","r_leg") + else + if(bpc & LEG_LEFT) + covered_parts |= list("l_leg") + if(bpc & LEG_RIGHT) + covered_parts |= list("r_leg") + + if(bpc & FEET) + covered_parts |= list("l_leg","r_leg") + else + if(bpc & FOOT_LEFT) + covered_parts |= list("l_leg") + if(bpc & FOOT_RIGHT) + covered_parts |= list("r_leg") + + return covered_parts + + + +//adapted from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ +/proc/heat2colour(temp) + return rgb(heat2colour_r(temp), heat2colour_g(temp), heat2colour_b(temp)) + + +/proc/heat2colour_r(temp) + temp /= 100 + if(temp <= 66) + . = 255 + else + . = max(0, min(255, 329.698727446 * (temp - 60) ** -0.1332047592)) + + +/proc/heat2colour_g(temp) + temp /= 100 + if(temp <= 66) + . = max(0, min(255, 99.4708025861 * log(temp) - 161.1195681661)) + else + . = max(0, min(255, 288.1221685293 * ((temp - 60) ** -0.075148492))) + + +/proc/heat2colour_b(temp) + temp /= 100 + if(temp >= 66) + . = 255 + else + if(temp <= 16) + . = 0 + else + . = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307)) + +/proc/color2hex(color) //web colors + if(!color) + return "#000000" + + switch(color) + if("white") + return "#FFFFFF" + if("black") + return "#000000" + if("gray") + return "#808080" + if("brown") + return "#A52A2A" + if("red") + return "#FF0000" + if("darkred") + return "#8B0000" + if("crimson") + return "#DC143C" + if("orange") + return "#FFA500" + if("yellow") + return "#FFFF00" + if("green") + return "#008000" + if("lime") + return "#00FF00" + if("darkgreen") + return "#006400" + if("cyan") + return "#00FFFF" + if("blue") + return "#0000FF" + if("navy") + return "#000080" + if("teal") + return "#008080" + if("purple") + return "#800080" + if("indigo") + return "#4B0082" + else + return "#FFFFFF" + + +//This is a weird one: +//It returns a list of all var names found in the string +//These vars must be in the [var_name] format +//It's only a proc because it's used in more than one place + +//Takes a string and a datum +//The string is well, obviously the string being checked +//The datum is used as a source for var names, to check validity +//Otherwise every single word could technically be a variable! +/proc/string2listofvars(var/t_string, var/datum/var_source) + if(!t_string || !var_source) + return list() + + . = list() + + var/var_found = findtext(t_string,"\[") //Not the actual variables, just a generic "should we even bother" check + if(var_found) + //Find var names + + // "A dog said hi [name]!" + // splittext() --> list("A dog said hi ","name]!" + // jointext() --> "A dog said hi name]!" + // splittext() --> list("A","dog","said","hi","name]!") + + t_string = replacetext(t_string,"\[","\[ ")//Necessary to resolve "word[var_name]" scenarios + var/list/list_value = splittext(t_string,"\[") + var/intermediate_stage = jointext(list_value, null) + + list_value = splittext(intermediate_stage," ") + for(var/value in list_value) + if(findtext(value,"]")) + value = splittext(value,"]") //"name]!" --> list("name","!") + for(var/A in value) + if(var_source.vars.Find(A)) + . += A + +//assumes format #RRGGBB #rrggbb +/proc/color_hex2num(A) + if(!A) + return 0 + var/R = hex2num(copytext(A,2,4)) + var/G = hex2num(copytext(A,4,6)) + var/B = hex2num(copytext(A,6,0)) + return R+G+B + +//word of warning: using a matrix like this as a color value will simplify it back to a string after being set +/proc/color_hex2color_matrix(string) + var/length = length(string) + if(length != 7 && length != 9) + return color_matrix_identity() + var/r = hex2num(copytext(string, 2, 4))/255 + var/g = hex2num(copytext(string, 4, 6))/255 + var/b = hex2num(copytext(string, 6, 8))/255 + var/a = 1 + if(length == 9) + a = hex2num(copytext(string, 8, 10))/255 + if(!isnum(r) || !isnum(g) || !isnum(b) || !isnum(a)) + return color_matrix_identity() + return list(r,0,0,0, 0,g,0,0, 0,0,b,0, 0,0,0,a, 0,0,0,0) + +//will drop all values not on the diagonal +/proc/color_matrix2color_hex(list/the_matrix) + if(!istype(the_matrix) || the_matrix.len != 20) + return "#ffffffff" + return rgb(the_matrix[1]*255, the_matrix[6]*255, the_matrix[11]*255, the_matrix[16]*255) +>>>>>>> 6b8775f... Makes angle2dir() much more accurate (#30989) /proc/type2parent(child) var/string_type = "[child]" From c8e5928517e6d6e67b90ebe4bf138d94230d1aa3 Mon Sep 17 00:00:00 2001 From: Robustin Date: Thu, 5 Oct 2017 16:10:47 -0400 Subject: [PATCH 09/28] Emotes now shatter 80% less immersions (#31240) * Emote Checks by Default * Removes emote argument * More emote fixes * Overhauled emote check * Closed Spans --- code/datums/emotes.dm | 11 ++++++----- code/modules/mob/living/emote.dm | 30 ++++++++++++++++++------------ 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm index 455ec0f62a..88e6148c5f 100644 --- a/code/datums/emotes.dm +++ b/code/datums/emotes.dm @@ -42,7 +42,7 @@ I.trigger(key, L) if(!msg) - return FALSE + return user.log_message(msg, INDIVIDUAL_EMOTE_LOG) msg = "[user] " + msg @@ -91,21 +91,22 @@ /datum/emote/proc/select_param(mob/user, params) return replacetext(message_param, "%t", params) -/datum/emote/proc/can_run_emote(mob/user, help_check) +/datum/emote/proc/can_run_emote(mob/user, status_check = TRUE) . = TRUE if(!is_type_in_typecache(user, mob_type_allowed_typecache)) return FALSE if(is_type_in_typecache(user, mob_type_blacklist_typecache)) return FALSE - if(!help_check) + if(status_check) if(user.stat > stat_allowed || (user.status_flags & FAKEDEATH)) + to_chat(user, "You cannot [key] while unconscious.") return FALSE - if(restraint_check && user.restrained()) + if(restraint_check && (user.restrained() || user.buckled)) + to_chat(user, "You cannot [key] while restrained.") return FALSE if(user.reagents && user.reagents.has_reagent("mimesbane")) return FALSE - /datum/emote/sound var/sound //Sound to play when emote is called var/vary = FALSE //used for the honk borg emote diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 9f31c5b055..bbe02a3f8e 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -29,6 +29,7 @@ key_third_person = "bows" message = "bows." message_param = "bows to %t." + restraint_check = TRUE /datum/emote/living/burp key = "burp" @@ -119,6 +120,7 @@ key = "flap" key_third_person = "flaps" message = "flaps their wings." + restraint_check = TRUE var/wing_time = 20 /datum/emote/living/flap/run_emote(mob/user, params) @@ -138,6 +140,7 @@ key = "aflap" key_third_person = "aflaps" message = "flaps their wings ANGRILY!" + restraint_check = TRUE wing_time = 10 /datum/emote/living/flip @@ -147,7 +150,7 @@ /datum/emote/living/flip/run_emote(mob/user, params) . = ..() - if(!.) + if(.) user.SpinAnimation(7,1) /datum/emote/living/frown @@ -454,7 +457,7 @@ if(e in keys) continue E = emote_list[e] - if(E.can_run_emote(user, TRUE)) + if(E.can_run_emote(user, status_check = FALSE)) keys += E.key keys = sortList(keys) @@ -481,18 +484,21 @@ /datum/emote/living/spin key = "spin" key_third_person = "spins" + restraint_check = TRUE /datum/emote/living/spin/run_emote(mob/user) - user.spin(20, 1) - if(iscyborg(user)) - var/mob/living/silicon/robot/R = user - if(R.buckled_mobs) - for(var/mob/M in R.buckled_mobs) - if(R.riding_datum) - R.riding_datum.force_dismount(M) - else - R.unbuckle_all_mobs() - ..() + . = ..() + if(.) + user.spin(20, 1) + if(iscyborg(user)) + var/mob/living/silicon/robot/R = user + if(R.buckled_mobs) + for(var/mob/M in R.buckled_mobs) + if(R.riding_datum) + R.riding_datum.force_dismount(M) + else + R.unbuckle_all_mobs() + /datum/emote/living/circle key = "circle" From b3243d59004945760137471caba66b4711a24a00 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 5 Oct 2017 16:31:34 -0400 Subject: [PATCH 11/28] Removes old ass belt.dm (#31317) --- .../objects/items/weapons/storage/belt.dm | 531 ------------------ 1 file changed, 531 deletions(-) delete mode 100644 code/game/objects/items/weapons/storage/belt.dm diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm deleted file mode 100644 index f8a020b677..0000000000 --- a/code/game/objects/items/weapons/storage/belt.dm +++ /dev/null @@ -1,531 +0,0 @@ -/obj/item/weapon/storage/belt - name = "belt" - desc = "Can hold various things." - icon = 'icons/obj/clothing/belts.dmi' - icon_state = "utilitybelt" - item_state = "utility" - slot_flags = SLOT_BELT - attack_verb = list("whipped", "lashed", "disciplined") - max_integrity = 300 - var/content_overlays = FALSE //If this is true, the belt will gain overlays based on what it's holding - -/obj/item/weapon/storage/belt/update_icon() - cut_overlays() - if(content_overlays) - for(var/obj/item/I in contents) - var/mutable_appearance/M = I.get_belt_overlay() - add_overlay(M) - ..() - -/obj/item/weapon/storage/belt/Initialize() - . = ..() - update_icon() - -/obj/item/weapon/storage/belt/utility - name = "toolbelt" //Carn: utility belt is nicer, but it bamboozles the text parsing. - desc = "Holds tools." - icon_state = "utilitybelt" - item_state = "utility" - can_hold = list( - /obj/item/weapon/crowbar, - /obj/item/weapon/screwdriver, - /obj/item/weapon/weldingtool, - /obj/item/weapon/wirecutters, - /obj/item/weapon/wrench, - /obj/item/device/multitool, - /obj/item/device/flashlight, - /obj/item/stack/cable_coil, - /obj/item/device/t_scanner, - /obj/item/device/analyzer, - /obj/item/weapon/extinguisher/mini, - /obj/item/device/radio, - /obj/item/clothing/gloves - ) - content_overlays = TRUE - -/obj/item/weapon/storage/belt/utility/chief - name = "\improper Chief Engineer's toolbelt" //"the Chief Engineer's toolbelt", because "Chief Engineer's toolbelt" is not a proper noun - desc = "Holds tools, looks snazzy." - icon_state = "utilitybelt_ce" - item_state = "utility_ce" - -/obj/item/weapon/storage/belt/utility/chief/full/PopulateContents() - new /obj/item/weapon/screwdriver/power(src) - new /obj/item/weapon/crowbar/power(src) - new /obj/item/weapon/weldingtool/experimental(src)//This can be changed if this is too much - new /obj/item/device/multitool(src) - new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange")) - new /obj/item/weapon/extinguisher/mini(src) - new /obj/item/device/analyzer(src) - //much roomier now that we've managed to remove two tools - - -/obj/item/weapon/storage/belt/utility/full/PopulateContents() - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wrench(src) - new /obj/item/weapon/weldingtool(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/wirecutters(src) - new /obj/item/device/multitool(src) - new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange")) - -/obj/item/weapon/storage/belt/utility/full/engi/PopulateContents() - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wrench(src) - new /obj/item/weapon/weldingtool/largetank(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/wirecutters(src) - new /obj/item/device/multitool(src) - new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange")) - - -/obj/item/weapon/storage/belt/utility/atmostech/PopulateContents() - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wrench(src) - new /obj/item/weapon/weldingtool(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/wirecutters(src) - new /obj/item/device/t_scanner(src) - new /obj/item/weapon/extinguisher/mini(src) - - -/obj/item/weapon/storage/belt/utility/servant/PopulateContents() - new /obj/item/weapon/screwdriver/brass(src) - new /obj/item/weapon/wirecutters/brass(src) - new /obj/item/weapon/wrench/brass(src) - new /obj/item/weapon/crowbar/brass(src) - new /obj/item/weapon/weldingtool/experimental/brass(src) - new /obj/item/device/multitool(src) - new /obj/item/stack/cable_coil(src, 30, "yellow") - - -/obj/item/weapon/storage/belt/medical - name = "medical belt" - desc = "Can hold various medical equipment." - icon_state = "medicalbelt" - item_state = "medical" - max_w_class = WEIGHT_CLASS_BULKY - can_hold = list( - /obj/item/device/healthanalyzer, - /obj/item/weapon/dnainjector, - /obj/item/weapon/reagent_containers/dropper, - /obj/item/weapon/reagent_containers/glass/beaker, - /obj/item/weapon/reagent_containers/glass/bottle, - /obj/item/weapon/reagent_containers/pill, - /obj/item/weapon/reagent_containers/syringe, - /obj/item/weapon/lighter, - /obj/item/weapon/storage/fancy/cigarettes, - /obj/item/weapon/storage/pill_bottle, - /obj/item/stack/medical, - /obj/item/device/flashlight/pen, - /obj/item/weapon/extinguisher/mini, - /obj/item/weapon/reagent_containers/hypospray, - /obj/item/device/sensor_device, - /obj/item/device/radio, - /obj/item/clothing/gloves/, - /obj/item/weapon/lazarus_injector, - /obj/item/weapon/bikehorn/rubberducky, - /obj/item/clothing/mask/surgical, - /obj/item/clothing/mask/breath, - /obj/item/clothing/mask/breath/medical, - /obj/item/weapon/surgical_drapes, //for true paramedics - /obj/item/weapon/scalpel, - /obj/item/weapon/circular_saw, - /obj/item/weapon/surgicaldrill, - /obj/item/weapon/retractor, - /obj/item/weapon/cautery, - /obj/item/weapon/hemostat, - /obj/item/device/geiger_counter, - /obj/item/clothing/neck/stethoscope, - /obj/item/weapon/stamp, - /obj/item/clothing/glasses, - /obj/item/weapon/wrench/medical, - /obj/item/clothing/mask/muzzle, - /obj/item/weapon/storage/bag/chemistry, - /obj/item/weapon/storage/bag/bio, - /obj/item/weapon/reagent_containers/blood, - /obj/item/weapon/tank/internals/emergency_oxygen - ) - - -/obj/item/weapon/storage/belt/security - name = "security belt" - desc = "Can hold security gear like handcuffs and flashes." - icon_state = "securitybelt" - item_state = "security"//Could likely use a better one. - storage_slots = 5 - max_w_class = WEIGHT_CLASS_NORMAL //Because the baton wouldn't fit otherwise. - Neerti - can_hold = list( - /obj/item/weapon/melee/baton, - /obj/item/weapon/melee/classic_baton, - /obj/item/weapon/grenade, - /obj/item/weapon/reagent_containers/spray/pepper, - /obj/item/weapon/restraints/handcuffs, - /obj/item/device/assembly/flash/handheld, - /obj/item/clothing/glasses, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_box, - /obj/item/weapon/reagent_containers/food/snacks/donut, - /obj/item/weapon/reagent_containers/food/snacks/donut/jelly, - /obj/item/weapon/kitchen/knife/combat, - /obj/item/device/flashlight/seclite, - /obj/item/weapon/melee/classic_baton/telescopic, - /obj/item/device/radio, - /obj/item/clothing/gloves/, - /obj/item/weapon/restraints/legcuffs/bola - ) - content_overlays = TRUE - -/obj/item/weapon/storage/belt/security/full/PopulateContents() - new /obj/item/weapon/reagent_containers/spray/pepper(src) - new /obj/item/weapon/restraints/handcuffs(src) - new /obj/item/weapon/grenade/flashbang(src) - new /obj/item/device/assembly/flash/handheld(src) - new /obj/item/weapon/melee/baton/loaded(src) - update_icon() - - -/obj/item/weapon/storage/belt/mining - name = "explorer's webbing" - desc = "A versatile chest rig, cherished by miners and hunters alike." - icon_state = "explorer1" - item_state = "explorer1" - storage_slots = 6 - w_class = WEIGHT_CLASS_BULKY - max_w_class = WEIGHT_CLASS_BULKY //Pickaxes are big. - max_combined_w_class = 20 //Not an issue with this whitelist, probably. - can_hold = list( - /obj/item/weapon/crowbar, - /obj/item/weapon/screwdriver, - /obj/item/weapon/weldingtool, - /obj/item/weapon/wirecutters, - /obj/item/weapon/wrench, - /obj/item/device/flashlight, - /obj/item/stack/cable_coil, - /obj/item/device/analyzer, - /obj/item/weapon/extinguisher/mini, - /obj/item/device/radio, - /obj/item/clothing/gloves, - /obj/item/weapon/resonator, - /obj/item/device/mining_scanner, - /obj/item/weapon/pickaxe, - /obj/item/stack/sheet/animalhide, - /obj/item/stack/sheet/sinew, - /obj/item/stack/sheet/bone, - /obj/item/weapon/lighter, - /obj/item/weapon/storage/fancy/cigarettes, - /obj/item/weapon/reagent_containers/food/drinks/bottle, - /obj/item/stack/medical, - /obj/item/weapon/kitchen/knife, - /obj/item/weapon/reagent_containers/hypospray, - /obj/item/device/gps, - /obj/item/weapon/storage/bag/ore, - /obj/item/weapon/survivalcapsule, - /obj/item/device/t_scanner/adv_mining_scanner, - /obj/item/weapon/reagent_containers/pill, - /obj/item/weapon/storage/pill_bottle, - /obj/item/weapon/ore, - /obj/item/weapon/reagent_containers/food/drinks, - /obj/item/organ/regenerative_core, - /obj/item/device/wormhole_jaunter, - /obj/item/weapon/storage/bag/plants, - /obj/item/stack/marker_beacon - ) - - -/obj/item/weapon/storage/belt/mining/vendor - contents = newlist(/obj/item/weapon/survivalcapsule) - -/obj/item/weapon/storage/belt/mining/alt - icon_state = "explorer2" - item_state = "explorer2" - -/obj/item/weapon/storage/belt/mining/primitive - name = "hunter's belt" - desc = "A versatile belt, woven from sinew." - storage_slots = 5 - icon_state = "ebelt" - item_state = "ebelt" - -/obj/item/weapon/storage/belt/soulstone - name = "soul stone belt" - desc = "Designed for ease of access to the shards during a fight, as to not let a single enemy spirit slip away" - icon_state = "soulstonebelt" - item_state = "soulstonebelt" - storage_slots = 6 - can_hold = list( - /obj/item/device/soulstone - ) - -/obj/item/weapon/storage/belt/soulstone/full/PopulateContents() - for(var/i in 1 to 6) - new /obj/item/device/soulstone(src) - -/obj/item/weapon/storage/belt/champion - name = "championship belt" - desc = "Proves to the world that you are the strongest!" - icon_state = "championbelt" - item_state = "champion" - materials = list(MAT_GOLD=400) - storage_slots = 1 - can_hold = list( - /obj/item/clothing/mask/luchador - ) - -/obj/item/weapon/storage/belt/military - name = "chest rig" - desc = "A set of tactical webbing worn by Syndicate boarding parties." - icon_state = "militarywebbing" - item_state = "militarywebbing" - max_w_class = WEIGHT_CLASS_SMALL - -/obj/item/weapon/storage/belt/military/abductor - name = "agent belt" - desc = "A belt used by abductor agents." - icon = 'icons/obj/abductor.dmi' - icon_state = "belt" - item_state = "security" - -/obj/item/weapon/storage/belt/military/abductor/full/PopulateContents() - new /obj/item/weapon/screwdriver/abductor(src) - new /obj/item/weapon/wrench/abductor(src) - new /obj/item/weapon/weldingtool/abductor(src) - new /obj/item/weapon/crowbar/abductor(src) - new /obj/item/weapon/wirecutters/abductor(src) - new /obj/item/device/multitool/abductor(src) - new /obj/item/stack/cable_coil(src,30,"white") - - -/obj/item/weapon/storage/belt/military/army - name = "army belt" - desc = "A belt used by military forces." - icon_state = "grenadebeltold" - item_state = "security" - -/obj/item/weapon/storage/belt/military/assault - name = "assault belt" - desc = "A tactical assault belt." - icon_state = "assaultbelt" - item_state = "security" - storage_slots = 6 - -/obj/item/weapon/storage/belt/grenade - name = "grenadier belt" - desc = "A belt for holding grenades." - icon_state = "grenadebeltnew" - item_state = "security" - max_w_class = WEIGHT_CLASS_BULKY - display_contents_with_number = TRUE - storage_slots = 30 - max_combined_w_class = 60 //needs to be this high - can_hold = list( - /obj/item/weapon/grenade, - /obj/item/weapon/screwdriver, - /obj/item/weapon/lighter, - /obj/item/device/multitool, - /obj/item/weapon/reagent_containers/food/drinks/bottle/molotov, - /obj/item/weapon/grenade/plastic/c4, - ) -/obj/item/weapon/storage/belt/grenade/full/PopulateContents() - new /obj/item/weapon/grenade/flashbang(src) - new /obj/item/weapon/grenade/smokebomb(src) - new /obj/item/weapon/grenade/smokebomb(src) - new /obj/item/weapon/grenade/smokebomb(src) - new /obj/item/weapon/grenade/smokebomb(src) - new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/syndieminibomb/concussion/frag(src) - new /obj/item/weapon/grenade/gluon(src) - new /obj/item/weapon/grenade/gluon(src) - new /obj/item/weapon/grenade/gluon(src) - new /obj/item/weapon/grenade/gluon(src) - new /obj/item/weapon/grenade/chem_grenade/incendiary(src) - new /obj/item/weapon/grenade/chem_grenade/incendiary(src) - new /obj/item/weapon/grenade/chem_grenade/facid(src) - new /obj/item/weapon/grenade/syndieminibomb(src) - new /obj/item/weapon/grenade/syndieminibomb(src) - new /obj/item/weapon/screwdriver(src) - new /obj/item/device/multitool(src) - -/obj/item/weapon/storage/belt/wands - name = "wand belt" - desc = "A belt designed to hold various rods of power. A veritable fanny pack of exotic magic." - icon_state = "soulstonebelt" - item_state = "soulstonebelt" - storage_slots = 6 - can_hold = list( - /obj/item/weapon/gun/magic/wand - ) - -/obj/item/weapon/storage/belt/wands/full/PopulateContents() - new /obj/item/weapon/gun/magic/wand/death(src) - new /obj/item/weapon/gun/magic/wand/resurrection(src) - new /obj/item/weapon/gun/magic/wand/polymorph(src) - new /obj/item/weapon/gun/magic/wand/teleport(src) - new /obj/item/weapon/gun/magic/wand/door(src) - new /obj/item/weapon/gun/magic/wand/fireball(src) - - for(var/obj/item/weapon/gun/magic/wand/W in contents) //All wands in this pack come in the best possible condition - W.max_charges = initial(W.max_charges) - W.charges = W.max_charges - -/obj/item/weapon/storage/belt/janitor - name = "janibelt" - desc = "A belt used to hold most janitorial supplies." - icon_state = "janibelt" - item_state = "janibelt" - storage_slots = 6 - max_w_class = WEIGHT_CLASS_BULKY // Set to this so the light replacer can fit. - can_hold = list( - /obj/item/weapon/grenade/chem_grenade, - /obj/item/device/lightreplacer, - /obj/item/device/flashlight, - /obj/item/weapon/reagent_containers/spray, - /obj/item/weapon/soap, - /obj/item/weapon/holosign_creator, - /obj/item/key/janitor, - /obj/item/clothing/gloves - ) - -/obj/item/weapon/storage/belt/bandolier - name = "bandolier" - desc = "A bandolier for holding shotgun ammunition." - icon_state = "bandolier" - item_state = "bandolier" - storage_slots = 18 - display_contents_with_number = TRUE - can_hold = list( - /obj/item/ammo_casing/shotgun - ) - -/obj/item/weapon/storage/belt/holster - name = "shoulder holster" - desc = "A holster to carry a handgun and ammo. WARNING: Badasses only." - icon_state = "holster" - item_state = "holster" - storage_slots = 3 - max_w_class = WEIGHT_CLASS_NORMAL - can_hold = list( - /obj/item/weapon/gun/ballistic/automatic/pistol, - /obj/item/weapon/gun/ballistic/revolver, - /obj/item/ammo_box, - ) - alternate_worn_layer = UNDER_SUIT_LAYER - -/obj/item/weapon/storage/belt/holster/full/PopulateContents() - new /obj/item/weapon/gun/ballistic/revolver/detective(src) - new /obj/item/ammo_box/c38(src) - new /obj/item/ammo_box/c38(src) - -/obj/item/weapon/storage/belt/fannypack - name = "fannypack" - desc = "A dorky fannypack for keeping small items in." - icon_state = "fannypack_leather" - item_state = "fannypack_leather" - storage_slots = 3 - max_w_class = WEIGHT_CLASS_SMALL - -/obj/item/weapon/storage/belt/fannypack/black - name = "black fannypack" - icon_state = "fannypack_black" - item_state = "fannypack_black" - -/obj/item/weapon/storage/belt/fannypack/red - name = "red fannypack" - icon_state = "fannypack_red" - item_state = "fannypack_red" - -/obj/item/weapon/storage/belt/fannypack/purple - name = "purple fannypack" - icon_state = "fannypack_purple" - item_state = "fannypack_purple" - -/obj/item/weapon/storage/belt/fannypack/blue - name = "blue fannypack" - icon_state = "fannypack_blue" - item_state = "fannypack_blue" - -/obj/item/weapon/storage/belt/fannypack/orange - name = "orange fannypack" - icon_state = "fannypack_orange" - item_state = "fannypack_orange" - -/obj/item/weapon/storage/belt/fannypack/white - name = "white fannypack" - icon_state = "fannypack_white" - item_state = "fannypack_white" - -/obj/item/weapon/storage/belt/fannypack/green - name = "green fannypack" - icon_state = "fannypack_green" - item_state = "fannypack_green" - -/obj/item/weapon/storage/belt/fannypack/pink - name = "pink fannypack" - icon_state = "fannypack_pink" - item_state = "fannypack_pink" - -/obj/item/weapon/storage/belt/fannypack/cyan - name = "cyan fannypack" - icon_state = "fannypack_cyan" - item_state = "fannypack_cyan" - -/obj/item/weapon/storage/belt/fannypack/yellow - name = "yellow fannypack" - icon_state = "fannypack_yellow" - item_state = "fannypack_yellow" - -/obj/item/weapon/storage/belt/sabre - name = "sabre sheath" - desc = "An ornate sheath designed to hold an officer's blade." - icon_state = "sheath" - item_state = "sheath" - storage_slots = 1 - rustle_jimmies = FALSE - w_class = WEIGHT_CLASS_BULKY - max_w_class = WEIGHT_CLASS_BULKY - can_hold = list( - /obj/item/weapon/melee/sabre - ) - -/obj/item/weapon/storage/belt/sabre/examine(mob/user) - ..() - if(contents.len) - to_chat(user, "Alt-click it to quickly draw the blade.") - -/obj/item/weapon/storage/belt/sabre/AltClick(mob/user) - if(!ishuman(user) || !user.canUseTopic(src, be_close=TRUE)) - return - if(contents.len) - var/obj/item/I = contents[1] - user.visible_message("[user] takes [I] out of [src].", "You take [I] out of [src].",\ - ) - user.put_in_hands(I) - update_icon() - else - to_chat(user, "[src] is empty.") - -/obj/item/weapon/storage/belt/sabre/update_icon() - icon_state = "sheath" - item_state = "sheath" - if(contents.len) - icon_state += "-sabre" - item_state += "-sabre" - if(loc && isliving(loc)) - var/mob/living/L = loc - L.regenerate_icons() - ..() - - -/obj/item/weapon/storage/belt/sabre/PopulateContents() - new /obj/item/weapon/melee/sabre(src) - update_icon() From 645d8fdc7cf1d691addd8c67ede26c8923430a45 Mon Sep 17 00:00:00 2001 From: oranges Date: Fri, 6 Oct 2017 11:42:44 +1300 Subject: [PATCH 13/28] Merge pull request #31315 from tgstation/Cyberboss-patch-3 Removes shitty sleep from area/Entered --- code/game/area/areas.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index b062b8f054..222ce73f92 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -449,10 +449,11 @@ GLOBAL_LIST_EMPTY(teleportlocs) if(!L.client.played) SEND_SOUND(L, sound(sound, repeat = 0, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE)) - L.client.played = 1 - sleep(600) //ewww - this is very very bad - if(L.&& L.client) - L.client.played = 0 + L.client.played = TRUE + addtimer(CALLBACK(L.client, /client/proc/ResetAmbiencePlayed), 600) + +/client/proc/ResetAmbiencePlayed() + played = FALSE /atom/proc/has_gravity(turf/T) if(!T || !isturf(T)) From 13eedff76702d3729517eca6a23132c4ad9fd1b6 Mon Sep 17 00:00:00 2001 From: The-clown-known-as-Pepe Date: Fri, 6 Oct 2017 00:47:49 +0200 Subject: [PATCH 15/28] Fixes rubber shot after unintended nerf. (#31316) * Update bullets.dm * fix * refactor * Update ammo_casings.dm --- code/modules/projectiles/projectile/bullets.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 8395ef4d83..cf38d5bfff 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -8,7 +8,7 @@ hitsound_wall = "ricochet" impact_effect_type = /obj/effect/temp_visual/impact_effect -/obj/item/projectile/bullet/pellet/Range() +/obj/item/projectile/bullet/pellet/shotgun_buckshot/Range() ..() damage -= 0.75 if(damage < 0) From 648040de9c1866f582847569c9f92d27c067da05 Mon Sep 17 00:00:00 2001 From: vuonojenmustaturska Date: Fri, 6 Oct 2017 01:58:25 +0300 Subject: [PATCH 17/28] Makes a couple of atmos procs a tiny bit faster, removes /datum/gas_mixture/thermal_energy() (#31321) * Atmos stuff * moved the define --- code/__DEFINES/atmospherics.dm | 2 ++ code/modules/atmospherics/gasmixtures/gas_mixture.dm | 5 +---- code/modules/atmospherics/gasmixtures/reactions.dm | 4 ++-- code/modules/atmospherics/machinery/datum_pipeline.dm | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index a79850b04f..c6ca2cf0ec 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -174,3 +174,5 @@ #define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland #define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300" + +#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity()) \ No newline at end of file diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index ad1ba46d86..ac8349f5f7 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -119,9 +119,6 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) /datum/gas_mixture/proc/return_volume() //liters return max(0, volume) -/datum/gas_mixture/proc/thermal_energy() //joules - return temperature * heat_capacity() - /datum/gas_mixture/proc/archive() //Update archived versions of variables //Returns: 1 in all cases @@ -424,7 +421,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) var/list/cached_gases = gases var/temp = temperature - var/ener = thermal_energy() + var/ener = THERMAL_ENERGY(src) reaction_loop: for(var/r in SSair.gas_reactions) diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index a37e4d61c4..abbfcf8924 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -199,13 +199,13 @@ var/old_heat_capacity = air.heat_capacity() var/carbon_efficency = min(cached_gases["plasma"][MOLES]/cached_gases["co2"][MOLES],MAX_CARBON_EFFICENCY) - var/reaction_energy = air.thermal_energy() + var/reaction_energy = THERMAL_ENERGY(air) var/moles_impurities = air.total_moles()-(cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES]) var/plasma_fused = (PLASMA_FUSED_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY) var/carbon_catalyzed = (CARBON_CATALYST_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY) var/oxygen_added = carbon_catalyzed - var/nitrogen_added = (plasma_fused-oxygen_added)-(air.thermal_energy()/PLASMA_BINDING_ENERGY) + var/nitrogen_added = (plasma_fused-oxygen_added)-(THERMAL_ENERGY(air)/PLASMA_BINDING_ENERGY) reaction_energy = max(reaction_energy+((carbon_efficency*cached_gases["plasma"][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0) diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm index 11a7881a98..ad7fdb921a 100644 --- a/code/modules/atmospherics/machinery/datum_pipeline.dm +++ b/code/modules/atmospherics/machinery/datum_pipeline.dm @@ -232,7 +232,7 @@ total_gas_mixture.merge(G) - total_thermal_energy += G.thermal_energy() + total_thermal_energy += THERMAL_ENERGY(G) total_heat_capacity += G.heat_capacity() total_gas_mixture.temperature = total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0 From 4d06415a4bef979ff3fa462a64df5b84556220ba Mon Sep 17 00:00:00 2001 From: Joan Lung <3886584+ChangelingRain@users.noreply.github.com> Date: Thu, 5 Oct 2017 20:21:33 -0400 Subject: [PATCH 19/28] Makes Ocular Wardens effective again (#31325) * Makes Ocular Wardens effective again * get that, too --- .../clock_cult/clock_structures/ocular_warden.dm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm index cdff486eea..364c967ae9 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm @@ -11,7 +11,7 @@ break_message = "The warden's eye gives a glare of utter hate before falling dark!" debris = list(/obj/item/clockwork/component/belligerent_eye/blind_eye = 1) resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - var/damage_per_tick = 2.5 + var/damage_per_tick = 3 var/sight_range = 3 var/atom/movable/target var/list/idle_messages = list(" sulkily glares around.", " lazily drifts from side to side.", " looks around for something to burn.", " slowly turns in circles.") @@ -141,8 +141,12 @@ . = 1 if(target) for(var/turf/T in getline(src, target)) + if(T.density) + . -= 0.1 + continue for(var/obj/structure/O in T) - if(O.density) - . -= 0.15 + if(O != src && O.density) + . -= 0.1 + break . -= (get_dist(src, target) * 0.05) . = max(., 0.1) //The lowest damage a warden can do is 10% of its normal amount (0.25 by default) From 52c57543cba0b903184ebee03c267b279ed5bb7a Mon Sep 17 00:00:00 2001 From: LetterJay Date: Thu, 5 Oct 2017 22:43:08 -0500 Subject: [PATCH 21/28] Update misc_special.dm --- code/modules/clothing/head/misc_special.dm | 182 --------------------- 1 file changed, 182 deletions(-) diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index d14ef81806..4a86008ad2 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -1,184 +1,3 @@ -<<<<<<< HEAD -/* - * Contents: - * Welding mask - * Cakehat - * Ushanka - * Pumpkin head - * Kitty ears - * Cardborg disguise - */ - -/* - * Welding mask - */ -/obj/item/clothing/head/welding - name = "welding helmet" - desc = "A head-mounted face cover designed to protect the wearer completely from space-arc eye." - icon_state = "welding" - flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH - item_state = "welding" - materials = list(MAT_METAL=1750, MAT_GLASS=400) -// var/up = 0 - flash_protect = 2 - tint = 2 - armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 60) - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE - actions_types = list(/datum/action/item_action/toggle) - visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE - visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH - resistance_flags = FIRE_PROOF - -/obj/item/clothing/head/welding/attack_self(mob/user) - weldingvisortoggle(user) - - -/* - * Cakehat - */ -/obj/item/clothing/head/hardhat/cakehat - name = "cakehat" - desc = "You put the cake on your head. Brilliant." - icon_state = "hardhat0_cakehat" - item_state = "hardhat0_cakehat" - item_color = "cakehat" - hitsound = 'sound/weapons/tap.ogg' - flags_inv = HIDEEARS|HIDEHAIR - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) - brightness_on = 2 //luminosity when on - flags_cover = HEADCOVERSEYES - heat = 100 - -/obj/item/clothing/head/hardhat/cakehat/process() - var/turf/location = src.loc - if(ishuman(location)) - var/mob/living/carbon/human/M = location - if(M.is_holding(src) || M.head == src) - location = M.loc - - if(isturf(location)) - location.hotspot_expose(700, 1) - -/obj/item/clothing/head/hardhat/cakehat/turn_on() - ..() - force = 2 - throwforce = 2 - damtype = BURN - hitsound = 'sound/items/welder.ogg' - START_PROCESSING(SSobj, src) - -/obj/item/clothing/head/hardhat/cakehat/turn_off() - ..() - force = 0 - throwforce = 0 - damtype = BRUTE - hitsound = 'sound/weapons/tap.ogg' - STOP_PROCESSING(SSobj, src) - -/obj/item/clothing/head/hardhat/cakehat/is_hot() - return on * heat -/* - * Ushanka - */ -/obj/item/clothing/head/ushanka - name = "ushanka" - desc = "Perfect for winter in Siberia, da?" - icon_state = "ushankadown" - item_state = "ushankadown" - flags_inv = HIDEEARS|HIDEHAIR - var/earflaps = 1 - cold_protection = HEAD - min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT - - dog_fashion = /datum/dog_fashion/head/ushanka - -/obj/item/clothing/head/ushanka/attack_self(mob/user) - if(earflaps) - src.icon_state = "ushankaup" - src.item_state = "ushankaup" - earflaps = 0 - to_chat(user, "You raise the ear flaps on the ushanka.") - else - src.icon_state = "ushankadown" - src.item_state = "ushankadown" - earflaps = 1 - to_chat(user, "You lower the ear flaps on the ushanka.") - -/* - * Pumpkin head - */ -/obj/item/clothing/head/hardhat/pumpkinhead - name = "carved pumpkin" - desc = "A jack o' lantern! Believed to ward off evil spirits." - icon_state = "hardhat0_pumpkin" - item_state = "hardhat0_pumpkin" - item_color = "pumpkin" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) - brightness_on = 2 //luminosity when on - flags_cover = HEADCOVERSEYES - -/* - * Kitty ears - */ -/obj/item/clothing/head/kitty - name = "kitty ears" - desc = "A pair of kitty ears. Meow!" - icon_state = "kitty" - color = "#999999" - dynamic_hair_suffix = "" - - dog_fashion = /datum/dog_fashion/head/kitty - -/obj/item/clothing/head/kitty/equipped(mob/living/carbon/human/user, slot) - if(ishuman(user) && slot == slot_head) - update_icon(user) - user.update_inv_head() //Color might have been changed by update_icon. - ..() - -/obj/item/clothing/head/kitty/update_icon(mob/living/carbon/human/user) - if(ishuman(user)) - add_atom_colour("#[user.hair_color]", FIXED_COLOUR_PRIORITY) - -/obj/item/clothing/head/kitty/genuine - desc = "A pair of kitty ears. A tag on the inside says \"Hand made from real cats.\"" - - -/obj/item/clothing/head/hardhat/reindeer - name = "novelty reindeer hat" - desc = "Some fake antlers and a very fake red nose." - icon_state = "hardhat0_reindeer" - item_state = "hardhat0_reindeer" - item_color = "reindeer" - flags_inv = 0 - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) - brightness_on = 1 //luminosity when on - dynamic_hair_suffix = "" - - dog_fashion = /datum/dog_fashion/head/reindeer - -/obj/item/clothing/head/cardborg - name = "cardborg helmet" - desc = "A helmet made out of a box." - icon_state = "cardborg_h" - item_state = "cardborg_h" - flags_cover = HEADCOVERSEYES - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR - - dog_fashion = /datum/dog_fashion/head/cardborg - -/obj/item/clothing/head/cardborg/equipped(mob/living/user, slot) - ..() - if(ishuman(user) && slot == slot_head) - var/mob/living/carbon/human/H = user - if(istype(H.wear_suit, /obj/item/clothing/suit/cardborg)) - var/obj/item/clothing/suit/cardborg/CB = H.wear_suit - CB.disguise(user, src) - -/obj/item/clothing/head/cardborg/dropped(mob/living/user) - ..() - user.remove_alt_appearance("standard_borg_disguise") -======= /* * Contents: * Welding mask @@ -400,4 +219,3 @@ hair_style = pick(GLOB.hair_styles_list - "Bald") //Don't want invisible wig hair_color = "#[random_short_color()]" . = ..() ->>>>>>> d17d66f... Adds wigs (#31304) From d50c1034b92bc1525694c7be178b93b1b6b763ae Mon Sep 17 00:00:00 2001 From: LetterJay Date: Thu, 5 Oct 2017 22:44:50 -0500 Subject: [PATCH 22/28] Update type2type.dm --- code/__HELPERS/type2type.dm | 615 +++++------------------------------- 1 file changed, 74 insertions(+), 541 deletions(-) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index ab06de1b8b..75985f9c2e 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -1,546 +1,80 @@ -/* - * Holds procs designed to change one type of value, into another. - * Contains: - * hex2num & num2hex - * file2list - * angle2dir - * angle2text - * worldtime2text - * text2dir_extended & dir2text_short - */ - -//Returns an integer given a hex input, supports negative values "-ff" -//skips preceding invalid characters -//breaks when hittin invalid characters thereafter -/proc/hex2num(hex) - . = 0 - if(istext(hex)) - var/negative = 0 - var/len = length(hex) - for(var/i=1, i<=len, i++) - var/num = text2ascii(hex,i) - switch(num) - if(48 to 57) - num -= 48 //0-9 - if(97 to 102) - num -= 87 //a-f - if(65 to 70) - num -= 55 //A-F - if(45) - negative = 1//- - else - if(num) - break - else - continue - . *= 16 - . += num - if(negative) - . *= -1 - return . - -//Returns the hex value of a decimal number -//len == length of returned string -//if len < 0 then the returned string will be as long as it needs to be to contain the data -//Only supports positive numbers -//if an invalid number is provided, it assumes num==0 -//Note, unlike previous versions, this one works from low to high <-- that way -/proc/num2hex(num, len=2) - if(!isnum(num)) - num = 0 - num = round(abs(num)) - . = "" - var/i=0 - while(1) - if(len<=0) - if(!num) - break - else - if(i>=len) - break - var/remainder = num/16 - num = round(remainder) - remainder = (remainder - num) * 16 - switch(remainder) - if(9,8,7,6,5,4,3,2,1) - . = "[remainder]" + . - if(10,11,12,13,14,15) - . = ascii2text(remainder+87) + . - else - . = "0" + . - i++ - return . - -//Splits the text of a file at seperator and returns them in a list. +/* + * Holds procs designed to change one type of value, into another. + * Contains: + * hex2num & num2hex + * file2list + * angle2dir + * angle2text + * worldtime2text + * text2dir_extended & dir2text_short + */ + +//Returns an integer given a hex input, supports negative values "-ff" +//skips preceding invalid characters +//breaks when hittin invalid characters thereafter +/proc/hex2num(hex) + . = 0 + if(istext(hex)) + var/negative = 0 + var/len = length(hex) + for(var/i=1, i<=len, i++) + var/num = text2ascii(hex,i) + switch(num) + if(48 to 57) + num -= 48 //0-9 + if(97 to 102) + num -= 87 //a-f + if(65 to 70) + num -= 55 //A-F + if(45) + negative = 1//- + else + if(num) + break + else + continue + . *= 16 + . += num + if(negative) + . *= -1 + return . + +//Returns the hex value of a decimal number +//len == length of returned string +//if len < 0 then the returned string will be as long as it needs to be to contain the data +//Only supports positive numbers +//if an invalid number is provided, it assumes num==0 +//Note, unlike previous versions, this one works from low to high <-- that way +/proc/num2hex(num, len=2) + if(!isnum(num)) + num = 0 + num = round(abs(num)) + . = "" + var/i=0 + while(1) + if(len<=0) + if(!num) + break + else + if(i>=len) + break + var/remainder = num/16 + num = round(remainder) + remainder = (remainder - num) * 16 + switch(remainder) + if(9,8,7,6,5,4,3,2,1) + . = "[remainder]" + . + if(10,11,12,13,14,15) + . = ascii2text(remainder+87) + . + else + . = "0" + . + i++ + return . + +//Splits the text of a file at seperator and returns them in a list. /world/proc/file2list(filename, seperator="\n", trim = TRUE) if (trim) return splittext(trim(file2text(filename)),seperator) -<<<<<<< HEAD - return splittext(file2text(filename),seperator) - -//Turns a direction into text -/proc/dir2text(direction) - switch(direction) - if(1) - return "north" - if(2) - return "south" - if(4) - return "east" - if(8) - return "west" - if(5) - return "northeast" - if(6) - return "southeast" - if(9) - return "northwest" - if(10) - return "southwest" - else - return - -//Turns text into proper directions -/proc/text2dir(direction) - switch(uppertext(direction)) - if("NORTH") - return 1 - if("SOUTH") - return 2 - if("EAST") - return 4 - if("WEST") - return 8 - if("NORTHEAST") - return 5 - if("NORTHWEST") - return 9 - if("SOUTHEAST") - return 6 - if("SOUTHWEST") - return 10 - else - return - -//Converts an angle (degrees) into an ss13 direction -/proc/angle2dir(degree) - - degree = SimplifyDegrees(degree) - - if(degree < 45) - return NORTH - if(degree < 90) - return NORTHEAST - if(degree < 135) - return EAST - if(degree < 180) - return SOUTHEAST - if(degree < 225) - return SOUTH - if(degree < 270) - return SOUTHWEST - if(degree < 315) - return WEST - return NORTH|WEST - -//returns the north-zero clockwise angle in degrees, given a direction - -/proc/dir2angle(D) - switch(D) - if(NORTH) - return 0 - if(SOUTH) - return 180 - if(EAST) - return 90 - if(WEST) - return 270 - if(NORTHEAST) - return 45 - if(SOUTHEAST) - return 135 - if(NORTHWEST) - return 315 - if(SOUTHWEST) - return 225 - else - return null - -//Returns the angle in english -/proc/angle2text(degree) - return dir2text(angle2dir(degree)) - -//Converts a blend_mode constant to one acceptable to icon.Blend() -/proc/blendMode2iconMode(blend_mode) - switch(blend_mode) - if(BLEND_MULTIPLY) - return ICON_MULTIPLY - if(BLEND_ADD) - return ICON_ADD - if(BLEND_SUBTRACT) - return ICON_SUBTRACT - else - return ICON_OVERLAY - -//Converts a rights bitfield into a string -/proc/rights2text(rights, seperator="", list/adds, list/subs) - if(rights & R_BUILDMODE) - . += "[seperator]+BUILDMODE" - if(rights & R_ADMIN) - . += "[seperator]+ADMIN" - if(rights & R_BAN) - . += "[seperator]+BAN" - if(rights & R_FUN) - . += "[seperator]+FUN" - if(rights & R_SERVER) - . += "[seperator]+SERVER" - if(rights & R_DEBUG) - . += "[seperator]+DEBUG" - if(rights & R_POSSESS) - . += "[seperator]+POSSESS" - if(rights & R_PERMISSIONS) - . += "[seperator]+PERMISSIONS" - if(rights & R_STEALTH) - . += "[seperator]+STEALTH" - if(rights & R_POLL) - . += "[seperator]+POLL" - if(rights & R_VAREDIT) - . += "[seperator]+VAREDIT" - if(rights & R_SOUNDS) - . += "[seperator]+SOUND" - if(rights & R_SPAWN) - . += "[seperator]+SPAWN" - - for(var/verbpath in adds) - . += "[seperator]+[verbpath]" - for(var/verbpath in subs) - . += "[seperator]-[verbpath]" - return . - -/proc/ui_style2icon(ui_style) - switch(ui_style) - if("Retro") - return 'icons/mob/screen_retro.dmi' - if("Plasmafire") - return 'icons/mob/screen_plasmafire.dmi' - if("Slimecore") - return 'icons/mob/screen_slimecore.dmi' - if("Operative") - return 'icons/mob/screen_operative.dmi' - if("Clockwork") - return 'icons/mob/screen_clockwork.dmi' - else - return 'icons/mob/screen_midnight.dmi' - -//colour formats -/proc/rgb2hsl(red, green, blue) - red /= 255;green /= 255;blue /= 255; - var/max = max(red,green,blue) - var/min = min(red,green,blue) - var/range = max-min - - var/hue=0;var/saturation=0;var/lightness=0; - lightness = (max + min)/2 - if(range != 0) - if(lightness < 0.5) - saturation = range/(max+min) - else - saturation = range/(2-max-min) - - var/dred = ((max-red)/(6*max)) + 0.5 - var/dgreen = ((max-green)/(6*max)) + 0.5 - var/dblue = ((max-blue)/(6*max)) + 0.5 - - if(max==red) - hue = dblue - dgreen - else if(max==green) - hue = dred - dblue + (1/3) - else - hue = dgreen - dred + (2/3) - if(hue < 0) - hue++ - else if(hue > 1) - hue-- - - return list(hue, saturation, lightness) - -/proc/hsl2rgb(hue, saturation, lightness) - var/red;var/green;var/blue; - if(saturation == 0) - red = lightness * 255 - green = red - blue = red - else - var/a;var/b; - if(lightness < 0.5) - b = lightness*(1+saturation) - else - b = (lightness+saturation) - (saturation*lightness) - a = 2*lightness - b - - red = round(255 * hue2rgb(a, b, hue+(1/3))) - green = round(255 * hue2rgb(a, b, hue)) - blue = round(255 * hue2rgb(a, b, hue-(1/3))) - - return list(red, green, blue) - -/proc/hue2rgb(a, b, hue) - if(hue < 0) - hue++ - else if(hue > 1) - hue-- - if(6*hue < 1) - return (a+(b-a)*6*hue) - if(2*hue < 1) - return b - if(3*hue < 2) - return (a+(b-a)*((2/3)-hue)*6) - return a - -// Very ugly, BYOND doesn't support unix time and rounding errors make it really hard to convert it to BYOND time. -// returns "YYYY-MM-DD" by default -/proc/unix2date(timestamp, seperator = "-") - - if(timestamp < 0) - return 0 //Do not accept negative values - - var/year = 1970 //Unix Epoc begins 1970-01-01 - var/dayInSeconds = 86400 //60secs*60mins*24hours - var/daysInYear = 365 //Non Leap Year - var/daysInLYear = daysInYear + 1//Leap year - var/days = round(timestamp / dayInSeconds) //Days passed since UNIX Epoc - var/tmpDays = days + 1 //If passed (timestamp < dayInSeconds), it will return 0, so add 1 - var/monthsInDays = list() //Months will be in here ***Taken from the PHP source code*** - var/month = 1 //This will be the returned MONTH NUMBER. - var/day //This will be the returned day number. - - while(tmpDays > daysInYear) //Start adding years to 1970 - year++ - if(isLeap(year)) - tmpDays -= daysInLYear - else - tmpDays -= daysInYear - - if(isLeap(year)) //The year is a leap year - monthsInDays = list(-1,30,59,90,120,151,181,212,243,273,304,334) - else - monthsInDays = list(0,31,59,90,120,151,181,212,243,273,304,334) - - var/mDays = 0; - var/monthIndex = 0; - - for(var/m in monthsInDays) - monthIndex++ - if(tmpDays > m) - mDays = m - month = monthIndex - - day = tmpDays - mDays //Setup the date - - return "[year][seperator][((month < 10) ? "0[month]" : month)][seperator][((day < 10) ? "0[day]" : day)]" - -/proc/isLeap(y) - return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) - - - -//Turns a Body_parts_covered bitfield into a list of organ/limb names. -//(I challenge you to find a use for this) -/proc/body_parts_covered2organ_names(bpc) - var/list/covered_parts = list() - - if(!bpc) - return 0 - - if(bpc & FULL_BODY) - covered_parts |= list("l_arm","r_arm","head","chest","l_leg","r_leg") - - else - if(bpc & HEAD) - covered_parts |= list("head") - if(bpc & CHEST) - covered_parts |= list("chest") - if(bpc & GROIN) - covered_parts |= list("chest") - - if(bpc & ARMS) - covered_parts |= list("l_arm","r_arm") - else - if(bpc & ARM_LEFT) - covered_parts |= list("l_arm") - if(bpc & ARM_RIGHT) - covered_parts |= list("r_arm") - - if(bpc & HANDS) - covered_parts |= list("l_arm","r_arm") - else - if(bpc & HAND_LEFT) - covered_parts |= list("l_arm") - if(bpc & HAND_RIGHT) - covered_parts |= list("r_arm") - - if(bpc & LEGS) - covered_parts |= list("l_leg","r_leg") - else - if(bpc & LEG_LEFT) - covered_parts |= list("l_leg") - if(bpc & LEG_RIGHT) - covered_parts |= list("r_leg") - - if(bpc & FEET) - covered_parts |= list("l_leg","r_leg") - else - if(bpc & FOOT_LEFT) - covered_parts |= list("l_leg") - if(bpc & FOOT_RIGHT) - covered_parts |= list("r_leg") - - return covered_parts - - - -//adapted from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ -/proc/heat2colour(temp) - return rgb(heat2colour_r(temp), heat2colour_g(temp), heat2colour_b(temp)) - - -/proc/heat2colour_r(temp) - temp /= 100 - if(temp <= 66) - . = 255 - else - . = max(0, min(255, 329.698727446 * (temp - 60) ** -0.1332047592)) - - -/proc/heat2colour_g(temp) - temp /= 100 - if(temp <= 66) - . = max(0, min(255, 99.4708025861 * log(temp) - 161.1195681661)) - else - . = max(0, min(255, 288.1221685293 * ((temp - 60) ** -0.075148492))) - - -/proc/heat2colour_b(temp) - temp /= 100 - if(temp >= 66) - . = 255 - else - if(temp <= 16) - . = 0 - else - . = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307)) - -/proc/color2hex(color) //web colors - if(!color) - return "#000000" - - switch(color) - if("white") - return "#FFFFFF" - if("black") - return "#000000" - if("gray") - return "#808080" - if("brown") - return "#A52A2A" - if("red") - return "#FF0000" - if("darkred") - return "#8B0000" - if("crimson") - return "#DC143C" - if("orange") - return "#FFA500" - if("yellow") - return "#FFFF00" - if("green") - return "#008000" - if("lime") - return "#00FF00" - if("darkgreen") - return "#006400" - if("cyan") - return "#00FFFF" - if("blue") - return "#0000FF" - if("navy") - return "#000080" - if("teal") - return "#008080" - if("purple") - return "#800080" - if("indigo") - return "#4B0082" - else - return "#FFFFFF" - - -//This is a weird one: -//It returns a list of all var names found in the string -//These vars must be in the [var_name] format -//It's only a proc because it's used in more than one place - -//Takes a string and a datum -//The string is well, obviously the string being checked -//The datum is used as a source for var names, to check validity -//Otherwise every single word could technically be a variable! -/proc/string2listofvars(var/t_string, var/datum/var_source) - if(!t_string || !var_source) - return list() - - . = list() - - var/var_found = findtext(t_string,"\[") //Not the actual variables, just a generic "should we even bother" check - if(var_found) - //Find var names - - // "A dog said hi [name]!" - // splittext() --> list("A dog said hi ","name]!" - // jointext() --> "A dog said hi name]!" - // splittext() --> list("A","dog","said","hi","name]!") - - t_string = replacetext(t_string,"\[","\[ ")//Necessary to resolve "word[var_name]" scenarios - var/list/list_value = splittext(t_string,"\[") - var/intermediate_stage = jointext(list_value, null) - - list_value = splittext(intermediate_stage," ") - for(var/value in list_value) - if(findtext(value,"]")) - value = splittext(value,"]") //"name]!" --> list("name","!") - for(var/A in value) - if(var_source.vars.Find(A)) - . += A - -//assumes format #RRGGBB #rrggbb -/proc/color_hex2num(A) - if(!A) - return 0 - var/R = hex2num(copytext(A,2,4)) - var/G = hex2num(copytext(A,4,6)) - var/B = hex2num(copytext(A,6,0)) - return R+G+B - -//word of warning: using a matrix like this as a color value will simplify it back to a string after being set -/proc/color_hex2color_matrix(string) - var/length = length(string) - if(length != 7 && length != 9) - return color_matrix_identity() - var/r = hex2num(copytext(string, 2, 4))/255 - var/g = hex2num(copytext(string, 4, 6))/255 - var/b = hex2num(copytext(string, 6, 8))/255 - var/a = 1 - if(length == 9) - a = hex2num(copytext(string, 8, 10))/255 - if(!isnum(r) || !isnum(g) || !isnum(b) || !isnum(a)) - return color_matrix_identity() - return list(r,0,0,0, 0,g,0,0, 0,0,b,0, 0,0,0,a, 0,0,0,0) - -//will drop all values not on the diagonal -/proc/color_matrix2color_hex(list/the_matrix) - if(!istype(the_matrix) || the_matrix.len != 20) - return "#ffffffff" - return rgb(the_matrix[1]*255, the_matrix[6]*255, the_matrix[11]*255, the_matrix[16]*255) -======= return splittext(file2text(filename),seperator) //Turns a direction into text @@ -1008,7 +542,6 @@ if(!istype(the_matrix) || the_matrix.len != 20) return "#ffffffff" return rgb(the_matrix[1]*255, the_matrix[6]*255, the_matrix[11]*255, the_matrix[16]*255) ->>>>>>> 6b8775f... Makes angle2dir() much more accurate (#30989) /proc/type2parent(child) var/string_type = "[child]" From 4fc286289e2deb870c729aa2ede06fdc216e3ff3 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 6 Oct 2017 01:11:34 -0500 Subject: [PATCH 23/28] Automatic changelog generation for PR #3157 [ci skip] --- html/changelogs/AutoChangeLog-pr-3157.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3157.yml diff --git a/html/changelogs/AutoChangeLog-pr-3157.yml b/html/changelogs/AutoChangeLog-pr-3157.yml new file mode 100644 index 0000000000..69e7b10920 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3157.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Wigs are now available in AutoDrobe" From e1a72d16abfe9dedf1441896006f43a4c98ea846 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 6 Oct 2017 01:12:08 -0500 Subject: [PATCH 24/28] Automatic changelog generation for PR #3159 [ci skip] --- html/changelogs/AutoChangeLog-pr-3159.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3159.yml diff --git a/html/changelogs/AutoChangeLog-pr-3159.yml b/html/changelogs/AutoChangeLog-pr-3159.yml new file mode 100644 index 0000000000..d835ae4122 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3159.yml @@ -0,0 +1,7 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "Added the H.E.C.K. suit, a guaranteed loot frop from Bubblegum." + - rscadd: "The H.E.C.K. suit is fully fire (and ash) proof, and has very good melee armor." + - rscadd: "H.E.C.K. suits can also be painted with spraycans, to fully customize your experience." + - rscadd: "Despite spending centuries inside a demon king, H.E.C.K. suits are most definitely safe." From 6c77fa5cb684430af31faac81eea799ec26f0067 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 6 Oct 2017 01:12:23 -0500 Subject: [PATCH 25/28] Automatic changelog generation for PR #3160 [ci skip] --- html/changelogs/AutoChangeLog-pr-3160.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3160.yml diff --git a/html/changelogs/AutoChangeLog-pr-3160.yml b/html/changelogs/AutoChangeLog-pr-3160.yml new file mode 100644 index 0000000000..c9d48dc583 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3160.yml @@ -0,0 +1,5 @@ +author: "Kevak/Neri" +delete-after: True +changes: + - bugfix: "Fixed plasmaman organsprites being missing" + - imageadd: "Plasmaman organ sprites added. Credit to Toriate for the sprites" From 31febed84950555aed0e57f20d81bb4b3e59e0eb Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 6 Oct 2017 01:12:44 -0500 Subject: [PATCH 26/28] Automatic changelog generation for PR #3163 [ci skip] --- html/changelogs/AutoChangeLog-pr-3163.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3163.yml diff --git a/html/changelogs/AutoChangeLog-pr-3163.yml b/html/changelogs/AutoChangeLog-pr-3163.yml new file mode 100644 index 0000000000..3c82b42146 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3163.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - bugfix: "Emotes (e.g. spinning and flipping) will now properly check for consciousness, restraints, etc. when appropriate." From 3f761e3403014b77d066827bb5e87a107e08dc65 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 6 Oct 2017 01:14:04 -0500 Subject: [PATCH 27/28] Automatic changelog generation for PR #3168 [ci skip] --- html/changelogs/AutoChangeLog-pr-3168.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3168.yml diff --git a/html/changelogs/AutoChangeLog-pr-3168.yml b/html/changelogs/AutoChangeLog-pr-3168.yml new file mode 100644 index 0000000000..ee61a58860 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3168.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - tweak: "Made atmos tiny bit faster" From 446c075fa18630b87b57d1c6722d562732c52d51 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 6 Oct 2017 01:14:17 -0500 Subject: [PATCH 28/28] Automatic changelog generation for PR #3170 [ci skip] --- html/changelogs/AutoChangeLog-pr-3170.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3170.yml diff --git a/html/changelogs/AutoChangeLog-pr-3170.yml b/html/changelogs/AutoChangeLog-pr-3170.yml new file mode 100644 index 0000000000..eeb9a06f55 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3170.yml @@ -0,0 +1,6 @@ +author: "Joan" +delete-after: True +changes: + - balance: "Ocular Warden base damage per second changed from 12.5 to 15." + - bugfix: "Ocular Wardens no longer count themselves when checking for dense objects, which decreased their overall damage by 15%." + - balance: "Ocular Wardens now only reduce their damage by 10% per dense object, and only do so once per turf. However, dense turfs now reduce their damage with the same 10% penalty."