diff --git a/.travis.yml b/.travis.yml index 0eccf6708e..56fa54f58d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,6 @@ matrix: addons: apt: packages: - - libc6-i386 - libstdc++6:i386 cache: directories: @@ -39,7 +38,6 @@ matrix: mariadb: '10.2' apt: packages: - - libc6-i386 - libstdc++6:i386 - libssl-dev:i386 - gcc-multilib diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 13fcc94b4b..a0051c3b1e 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -203,21 +203,20 @@ //Print a list of antagonists to the server log var/list/total_antagonists = list() //Look into all mobs in world, dead or alive - for(var/datum/mind/Mind in minds) - var/temprole = Mind.special_role - if(temprole) //if they are an antagonist of some sort. - if(temprole in total_antagonists) //If the role exists already, add the name to it - total_antagonists[temprole] += ", [Mind.name]([Mind.key])" - else - total_antagonists.Add(temprole) //If the role doesnt exist in the list, create it and add the mob - total_antagonists[temprole] += ": [Mind.name]([Mind.key])" + for(var/datum/antagonist/A in GLOB.antagonists) + if(!A.owner) + continue + if(!(A.name in total_antagonists)) + total_antagonists[A.name] = list() + total_antagonists[A.name] += "[key_name(A.owner)]" CHECK_TICK //Now print them all into the log! log_game("Antagonists at round end were...") - for(var/i in total_antagonists) - log_game("[i]s[total_antagonists[i]].") + for(var/antag_name in total_antagonists) + var/list/L = total_antagonists[antag_name] + log_game("[antag_name]s :[L.Join(", ")].") CHECK_TICK SSdbcore.SetRoundEnd() diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index bb2cb98cd2..5b9bb8c184 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -375,6 +375,7 @@ Turf and target are separate in case you want to teleport some distance from a t var/client/C var/key var/ckey + var/fallback_name if(!whom) return "*null*" @@ -394,6 +395,16 @@ Turf and target are separate in case you want to teleport some distance from a t C = GLOB.directory[ckey] if(C) M = C.mob + else if(istype(whom,/datum/mind)) + var/datum/mind/mind = whom + key = mind.key + ckey = ckey(key) + if(mind.current) + M = mind.current + if(M.client) + C = M.client + else + fallback_name = mind.name else return "*invalid*" @@ -419,11 +430,14 @@ Turf and target are separate in case you want to teleport some distance from a t else . += "*no key*" - if(include_name && M) - if(M.real_name) - . += "/([M.real_name])" - else if(M.name) - . += "/([M.name])" + if(include_name) + if(M) + if(M.real_name) + . += "/([M.real_name])" + else if(M.name) + . += "/([M.name])" + else if(fallback_name) + . += "/([fallback_name])" return . diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm index 0e1f1fb8fd..88423e8b6d 100644 --- a/code/controllers/subsystem/dbcore.dm +++ b/code/controllers/subsystem/dbcore.dm @@ -237,11 +237,29 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table item = list() _db_query = _dm_db_new_query() +/datum/DBQuery/Destroy() + Close() + SSdbcore.active_queries -= src + return ..() + +/datum/DBQuery/CanProcCall(proc_name) + //fuck off kevinz + return FALSE + +/datum/DBQuery/proc/Activity(activity) + last_activity = activity + last_activity_time = world.time + /datum/DBQuery/proc/warn_execute() . = Execute() if(!.) to_chat(usr, "A SQL error occurred during this operation, check the server logs.") +/datum/DBQuery/proc/SetQuery(new_sql) + Activity("SetQuery") + Close() + sql = new_sql + /datum/DBQuery/proc/Execute(sql_query = sql, cursor_handler = default_cursor, log_error = TRUE) var/start_time var/timeout = CONFIG_GET(number/query_debug_log_timeout) diff --git a/code/controllers/subsystem/processing/circuit.dm b/code/controllers/subsystem/processing/circuit.dm index db1bf1ff5f..dad71a005a 100644 --- a/code/controllers/subsystem/processing/circuit.dm +++ b/code/controllers/subsystem/processing/circuit.dm @@ -78,5 +78,8 @@ PROCESSING_SUBSYSTEM_DEF(circuit) /obj/item/integrated_electronics/wirer, /obj/item/integrated_electronics/debugger, /obj/item/integrated_electronics/analyzer, - /obj/item/integrated_electronics/detailer + /obj/item/integrated_electronics/detailer, + /obj/item/card/data, + /obj/item/card/data/full_color, + /obj/item/card/data/disk ) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 445ed389b7..d1e3de1248 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -45,8 +45,9 @@ /obj/machinery/computer/communications/process() if(..()) - if(state != STATE_STATUSDISPLAY && state != STATE_CALLSHUTTLE && state != STATE_PURCHASE && state != STATE_VIEWMESSAGE) - updateDialog() + var/ai_autoupdate = aistate != STATE_STATUSDISPLAY && aistate != STATE_CALLSHUTTLE && aistate != STATE_PURCHASE && aistate != STATE_VIEWMESSAGE + var/machine_user_autoupdate = state != STATE_STATUSDISPLAY && state != STATE_CALLSHUTTLE && state != STATE_PURCHASE && state != STATE_VIEWMESSAGE + updateDialog(machine_user_autoupdate,ai_autoupdate) /obj/machinery/computer/communications/Topic(href, href_list) if(..()) diff --git a/code/game/objects/effects/bump_teleporter.dm b/code/game/objects/effects/bump_teleporter.dm index 42f59cc535..307a912fe3 100644 --- a/code/game/objects/effects/bump_teleporter.dm +++ b/code/game/objects/effects/bump_teleporter.dm @@ -11,8 +11,8 @@ var/static/list/AllTeleporters -/obj/effect/bump_teleporter/New() - ..() +/obj/effect/bump_teleporter/Initialize() + . = ..() LAZYADD(AllTeleporters, src) /obj/effect/bump_teleporter/Destroy() diff --git a/code/game/objects/effects/countdown.dm b/code/game/objects/effects/countdown.dm index d62146be5e..1165ee50a0 100644 --- a/code/game/objects/effects/countdown.dm +++ b/code/game/objects/effects/countdown.dm @@ -14,9 +14,9 @@ anchored = TRUE layer = GHOST_LAYER -/obj/effect/countdown/New(atom/A) +/obj/effect/countdown/Initialize() . = ..() - attach(A) + attach(loc) /obj/effect/countdown/examine(mob/user) . = ..() diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm index 8c31847f78..eb4c562c36 100644 --- a/code/game/objects/effects/effect_system/effect_system.dm +++ b/code/game/objects/effects/effect_system/effect_system.dm @@ -12,13 +12,13 @@ would spawn and follow the beaker, even if it is carried or thrown. pass_flags = PASSTABLE | PASSGRILLE anchored = TRUE -/obj/effect/particle_effect/New() - ..() +/obj/effect/particle_effect/Initialize() + . = ..() GLOB.cameranet.updateVisibility(src) /obj/effect/particle_effect/Destroy() GLOB.cameranet.updateVisibility(src) - . = ..() + return ..() /datum/effect_system var/number = 3 diff --git a/code/game/objects/effects/effect_system/effects_explosion.dm b/code/game/objects/effects/effect_system/effects_explosion.dm index 33ecd308d1..d208510e86 100644 --- a/code/game/objects/effects/effect_system/effects_explosion.dm +++ b/code/game/objects/effects/effect_system/effects_explosion.dm @@ -4,8 +4,8 @@ opacity = 1 anchored = TRUE -/obj/effect/particle_effect/expl_particles/New() - ..() +/obj/effect/particle_effect/expl_particles/Initialize() + . = ..() QDEL_IN(src, 15) /datum/effect_system/expl_particles @@ -29,8 +29,8 @@ pixel_x = -32 pixel_y = -32 -/obj/effect/explosion/New() - ..() +/obj/effect/explosion/Initialize() + . = ..() QDEL_IN(src, 10) /datum/effect_system/explosion diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index d9a7d6fb7b..e7b7472e86 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -270,8 +270,8 @@ max_integrity = 20 CanAtmosPass = ATMOS_PASS_DENSITY -/obj/structure/foamedmetal/New() - ..() +/obj/structure/foamedmetal/Initialize() + . = ..() air_update_turf(1) diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index 5618ca9a91..472261003f 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -30,8 +30,8 @@ set_opacity(0) //if we were blocking view, we aren't now because we're fading out stoplag() -/obj/effect/particle_effect/smoke/New() - ..() +/obj/effect/particle_effect/smoke/Initialize() + . = ..() create_reagents(500) START_PROCESSING(SSobj, src) diff --git a/code/game/objects/effects/effect_system/effects_sparks.dm b/code/game/objects/effects/effect_system/effects_sparks.dm index 695c835a89..8453b6438d 100644 --- a/code/game/objects/effects/effect_system/effects_sparks.dm +++ b/code/game/objects/effects/effect_system/effects_sparks.dm @@ -22,8 +22,8 @@ anchored = TRUE light_range = 1 -/obj/effect/particle_effect/sparks/New() - ..() +/obj/effect/particle_effect/sparks/Initialize() + . = ..() flick("sparks", src) // replay the animation playsound(src.loc, "sparks", 100, 1) var/turf/T = loc diff --git a/code/game/objects/effects/effect_system/effects_water.dm b/code/game/objects/effects/effect_system/effects_water.dm index 4c84c97650..469b05176a 100644 --- a/code/game/objects/effects/effect_system/effects_water.dm +++ b/code/game/objects/effects/effect_system/effects_water.dm @@ -7,8 +7,8 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT -/obj/effect/particle_effect/water/New() - ..() +/obj/effect/particle_effect/water/Initialize() + . = ..() QDEL_IN(src, 70) /obj/effect/particle_effect/water/Move(turf/newloc) @@ -45,8 +45,8 @@ steam.start() -- spawns the effect icon_state = "extinguish" density = FALSE -/obj/effect/particle_effect/steam/New() - ..() +/obj/effect/particle_effect/steam/Initialize() + . = ..() QDEL_IN(src, 20) /datum/effect_system/steam_spread diff --git a/code/game/objects/effects/forcefields.dm b/code/game/objects/effects/forcefields.dm index ef074f4cec..6aab4f386a 100644 --- a/code/game/objects/effects/forcefields.dm +++ b/code/game/objects/effects/forcefields.dm @@ -8,8 +8,8 @@ CanAtmosPass = ATMOS_PASS_DENSITY var/timeleft = 300 //Set to 0 for permanent forcefields (ugh) -/obj/effect/forcefield/New() - ..() +/obj/effect/forcefield/Initialize() + . = ..() if(timeleft) QDEL_IN(src, timeleft) diff --git a/code/game/objects/effects/manifest.dm b/code/game/objects/effects/manifest.dm index 2082f2b495..fbf403a765 100644 --- a/code/game/objects/effects/manifest.dm +++ b/code/game/objects/effects/manifest.dm @@ -3,8 +3,9 @@ icon = 'icons/mob/screen_gen.dmi' icon_state = "x" -/obj/effect/manifest/New() - src.invisibility = INVISIBILITY_ABSTRACT +/obj/effect/manifest/Initialize() + . = ..() + invisibility = INVISIBILITY_ABSTRACT /obj/effect/manifest/proc/manifest() var/dat = "Crew Manifest:
" diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 8f256f1102..2ae4f5e5c5 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -98,8 +98,8 @@ density = FALSE var/duration = 0 -/obj/effect/mine/pickup/New() - ..() +/obj/effect/mine/pickup/Initialize() + . = ..() animate(src, pixel_y = 4, time = 20, loop = -1) /obj/effect/mine/pickup/triggermine(mob/victim) diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index c1abc2c02e..a0634928ce 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -13,8 +13,8 @@ icon_state="b_beam" var/atom/BeamSource -/obj/effect/overlay/beam/New() - ..() +/obj/effect/overlay/beam/Initialize() + . = ..() QDEL_IN(src, 10) /obj/effect/overlay/palmtree_r diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm index be9cb0b89a..82c272e7f9 100644 --- a/code/game/objects/items/airlock_painter.dm +++ b/code/game/objects/items/airlock_painter.dm @@ -15,8 +15,8 @@ var/obj/item/toner/ink = null -/obj/item/airlock_painter/New() - ..() +/obj/item/airlock_painter/Initialize() + . = ..() ink = new /obj/item/toner(src) //This proc doesn't just check if the painter can be used, but also uses it. diff --git a/code/game/objects/items/candle.dm b/code/game/objects/items/candle.dm index a0ec648a1a..b660801f90 100644 --- a/code/game/objects/items/candle.dm +++ b/code/game/objects/items/candle.dm @@ -14,8 +14,8 @@ var/start_lit = FALSE heat = 1000 -/obj/item/candle/New() - ..() +/obj/item/candle/Initialize() + . = ..() if(start_lit) // No visible message light(show_message = FALSE) diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 4c96bf3b84..2d30a015e2 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -9,7 +9,7 @@ /* - * DATA CARDS - Used for the teleporter + * DATA CARDS - Used for the IC data card reader */ /obj/item/card name = "card" @@ -24,30 +24,49 @@ return BRUTELOSS /obj/item/card/data - name = "data disk" - desc = "A disk of data." - icon_state = "data" + name = "data card" + desc = "A plastic magstripe card for simple and speedy data storage and transfer. This one has a stripe running down the middle." + icon_state = "data_1" + obj_flags = UNIQUE_RENAME var/function = "storage" var/data = "null" var/special = null item_state = "card-id" lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' + var/detail_color = COLOR_ASSEMBLY_ORANGE -/obj/item/card/data/verb/label(t as text) - set name = "Label Disk" - set category = "Object" - set src in usr +/obj/item/card/data/Initialize() + .=..() + update_icon() - if(usr.stat || !usr.canmove || usr.restrained()) +/obj/item/card/data/update_icon() + cut_overlays() + if(detail_color == COLOR_FLOORTILE_GRAY) return + var/mutable_appearance/detail_overlay = mutable_appearance('icons/obj/card.dmi', "[icon_state]-color") + detail_overlay.color = detail_color + add_overlay(detail_overlay) - if (t) - src.name = "data disk- '[t]'" - else - src.name = "data disk" - src.add_fingerprint(usr) - return +/obj/item/card/data/attackby(obj/item/I, mob/living/user) + if(istype(I, /obj/item/integrated_electronics/detailer)) + var/obj/item/integrated_electronics/detailer/D = I + detail_color = D.detail_color + update_icon() + return ..() + +/obj/item/proc/GetCard() + +/obj/item/card/data/GetCard() + return src + +/obj/item/card/data/full_color + desc = "A plastic magstripe card for simple and speedy data storage and transfer. This one has the entire card colored." + icon_state = "data_2" + +/obj/item/card/data/disk + desc = "A plastic magstripe card for simple and speedy data storage and transfer. This one inexplicibly looks like a floppy disk." + icon_state = "data_3" /* * ID CARDS diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 5ab8000402..6731caffd7 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -92,8 +92,12 @@ GLOBAL_LIST_EMPTY(PDAs) ..() if(!id && !inserted_item) return - else - to_chat(user, "Alt-click to remove contents.") + + if(id) + to_chat(user, "Alt-click to remove the id.") + + if(inserted_item && (!isturf(loc))) + to_chat(user, "Ctrl-click to remove [inserted_item].") /obj/item/pda/Initialize() . = ..() @@ -712,6 +716,15 @@ GLOBAL_LIST_EMPTY(PDAs) else remove_pen() +/obj/item/pda/CtrlClick() + ..() + + if(issilicon(usr)) + return + + if(usr.canUseTopic(src) && !isturf(loc)) + remove_pen() + /obj/item/pda/verb/verb_remove_id() set category = "Object" set name = "Eject ID" diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 0ef20dea19..fca7f9bc6d 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -160,11 +160,22 @@ if(sensor.on && sensor.visible) add_overlay("proxy_beam") -/obj/item/transfer_valve/proc/merge_gases() - tank_two.air_contents.volume += tank_one.air_contents.volume +/obj/item/transfer_valve/proc/merge_gases(datum/gas_mixture/target, change_volume = TRUE) + var/target_self = FALSE + if(!target || (target == tank_one.air_contents)) + target = tank_two.air_contents + if(target == tank_two.air_contents) + target_self = TRUE + if(change_volume) + if(!target_self) + target.volume += tank_two.volume + target.volume += tank_one.air_contents.volume var/datum/gas_mixture/temp temp = tank_one.air_contents.remove_ratio(1) - tank_two.air_contents.merge(temp) + target.merge(temp) + if(!target_self) + temp = tank_two.air_contents.remove_ratio(1) + target.merge(temp) /obj/item/transfer_valve/proc/split_gases() if (!valve_open || !tank_one || !tank_two) diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index 936accce39..4da0fd8a44 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -67,6 +67,7 @@ attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed") novariants = TRUE grind_results = list("bluespace" = 20) + point_value = 30 var/crystal_type = /obj/item/stack/ore/bluespace_crystal/refined /obj/item/stack/sheet/bluespace_crystal/attack_self(mob/user)// to prevent the construction menu from ever happening diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 3264deae88..996576d8e5 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -24,6 +24,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/glass grind_results = list("silicon" = 20) + point_value = 1 /obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins to slice [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -138,6 +139,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/rglass grind_results = list("silicon" = 20, "iron" = 10) + point_value = 4 /obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) add_fingerprint(user) @@ -180,6 +182,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmarglass grind_results = list("silicon" = 20, "plasma" = 10, "iron" = 10) + point_value = 23 /obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.prglass_recipes diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 300f18cbeb..87d1985b18 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -104,6 +104,7 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \ materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT) novariants = TRUE grind_results = list("carbon" = 20) + point_value = 25 GLOBAL_LIST_INIT(diamond_recipes, list ( \ new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \ @@ -129,6 +130,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \ materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE grind_results = list("uranium" = 20) + point_value = 20 GLOBAL_LIST_INIT(uranium_recipes, list ( \ new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \ @@ -154,6 +156,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \ max_integrity = 100 materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT) grind_results = list("plasma" = 20) + point_value = 20 /obj/item/stack/sheet/mineral/plasma/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins licking \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -193,6 +196,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \ sheettype = "gold" materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT) grind_results = list("gold" = 20) + point_value = 20 GLOBAL_LIST_INIT(gold_recipes, list ( \ new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \ @@ -220,6 +224,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \ sheettype = "silver" materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT) grind_results = list("silver" = 20) + point_value = 20 GLOBAL_LIST_INIT(silver_recipes, list ( \ new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \ @@ -247,6 +252,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \ materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE grind_results = list("banana" = 20) + point_value = 50 GLOBAL_LIST_INIT(bananium_recipes, list ( \ new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \ @@ -272,6 +278,7 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \ throw_range = 3 sheettype = "titanium" materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT) + point_value = 20 GLOBAL_LIST_INIT(titanium_recipes, list ( \ new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20), \ @@ -300,6 +307,7 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \ throw_range = 3 sheettype = "plastitanium" materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT, MAT_PLASMA=MINERAL_MATERIAL_AMOUNT) + point_value = 45 GLOBAL_LIST_INIT(plastitanium_recipes, list ( \ new/datum/stack_recipe("plas-titanium tile", /obj/item/stack/tile/mineral/plastitanium, 1, 4, 20), \ diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 52fdf558ee..014e4738b0 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -106,6 +106,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/metal grind_results = list("iron" = 20) + point_value = 2 /obj/item/stack/sheet/metal/ratvar_act() new /obj/item/stack/tile/brass(loc, amount) @@ -166,6 +167,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/plasteel grind_results = list("iron" = 20, "plasma" = 20) + point_value = 23 /obj/item/stack/sheet/plasteel/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.plasteel_recipes diff --git a/code/game/objects/items/stacks/sheets/sheets.dm b/code/game/objects/items/stacks/sheets/sheets.dm index 315cc94b66..21b43eba20 100644 --- a/code/game/objects/items/stacks/sheets/sheets.dm +++ b/code/game/objects/items/stacks/sheets/sheets.dm @@ -11,4 +11,5 @@ attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed") novariants = FALSE var/perunit = MINERAL_MATERIAL_AMOUNT - var/sheettype = null //this is used for girders in the creation of walls/false walls \ No newline at end of file + var/sheettype = null //this is used for girders in the creation of walls/false walls + var/point_value = 0 //turn-in value for the gulag stacker - loosely relative to its rarity. \ No newline at end of file diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index fe46141614..c338f24d26 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -231,3 +231,35 @@ new /obj/item/reagent_containers/pill/patch/silver_sulf(src) for(var/i in 1 to 3) new /obj/item/reagent_containers/pill/patch/styptic(src) + +/obj/item/storage/pill_bottle/zoom + name = "suspicious pill bottle" + desc = "The label is pretty old and almost unreadable, you recognize some chemical compounds." + +/obj/item/storage/pill_bottle/zoom/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/reagent_containers/pill/zoom(src) + +/obj/item/storage/pill_bottle/happy + name = "suspicious pill bottle" + desc = "There is a smiley on the top." + +/obj/item/storage/pill_bottle/happy/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/reagent_containers/pill/happy(src) + +/obj/item/storage/pill_bottle/lsd + name = "suspicious pill bottle" + desc = "There is a badly drawn thing with the shape of a mushroom." + +/obj/item/storage/pill_bottle/lsd/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/reagent_containers/pill/lsd(src) + +/obj/item/storage/pill_bottle/aranesp + name = "suspicious pill bottle" + desc = "The label says 'gotta go fast'." + +/obj/item/storage/pill_bottle/aranesp/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/reagent_containers/pill/aranesp(src) diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 447a83422b..74aea29768 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -226,7 +226,6 @@ air_contents.react() check_status() - /obj/item/tank/proc/check_status() //Handle exploding, leaking, and rupturing of the tank diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 02e1cc9bd0..664cdbf383 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -138,19 +138,22 @@ else obj_flags &= ~IN_USE -/obj/proc/updateDialog() +/obj/proc/updateDialog(update_viewers = TRUE,update_ais = TRUE) // Check that people are actually using the machine. If not, don't update anymore. if(obj_flags & IN_USE) - var/list/nearby = viewers(1, src) - var/is_in_use = 0 - for(var/mob/M in nearby) - if ((M.client && M.machine == src)) - is_in_use = 1 - src.interact(M) - var/ai_in_use = AutoUpdateAI(src) + var/is_in_use = FALSE + if(update_viewers) + for(var/mob/M in viewers(1, src)) + if ((M.client && M.machine == src)) + is_in_use = TRUE + src.interact(M) + var/ai_in_use = FALSE + if(update_ais) + ai_in_use = AutoUpdateAI(src) - if(!ai_in_use && !is_in_use) - obj_flags &= ~IN_USE + if(update_viewers && update_ais) //State change is sure only if we check both + if(!ai_in_use && !is_in_use) + obj_flags &= ~IN_USE /obj/attack_ghost(mob/user) diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm index b5dfbf7817..85feb3026c 100644 --- a/code/modules/admin/fun_balloon.dm +++ b/code/modules/admin/fun_balloon.dm @@ -6,7 +6,7 @@ anchored = TRUE var/popped = FALSE -/obj/effect/fun_balloon/New() +/obj/effect/fun_balloon/Initialize() . = ..() SSobj.processing |= src diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 410e976b85..daa1ce473a 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -57,7 +57,7 @@ var/mob/living/carbon/human/H = null for(var/mob/living/carbon/human/applicant in GLOB.player_list) - if(isReadytoRumble(applicant, ROLE_TRAITOR, FALSE)) + if(isReadytoRumble(applicant, ROLE_TRAITOR)) if(temp.age_check(applicant.client)) if(!(applicant.job in temp.restricted_jobs)) candidates += applicant diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index 2bfe1cec71..5bd8c548f7 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -496,10 +496,4 @@ #undef STIMULUM_SECOND_RISE #undef STIMULUM_ABSOLUTE_DROP #undef REACTION_OPPRESSION_THRESHOLD -#undef PLASMA_BINDING_ENERGY -#undef MAX_CATALYST_EFFICENCY -#undef PLASMA_FUSED_COEFFICENT -#undef CATALYST_COEFFICENT -#undef FUSION_PURITY_THRESHOLD -#undef FUSION_HEAT_DROPOFF #undef NOBLIUM_FORMATION_ENERGY diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index e6b4a29502..cffd954b0e 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -1746,14 +1746,26 @@ /datum/supply_pack/costumes_toys/randomised/contraband name = "Contraband Crate" - desc = "Psst.. bud... want some contraband? I can get you a poster, some nice cigs, bling, even some ambrosia deus...you know, the good stuff. Just keep it away from the cops, kay?" + desc = "Psst.. bud... want some contraband? I can get you a poster, some nice cigs, dank, even some sponsored items...you know, the good stuff. Just keep it away from the cops, kay?" contraband = TRUE cost = 3000 - num_contained = 5 + num_contained = 7 contains = list(/obj/item/poster/random_contraband, + /obj/item/poster/random_contraband, + /obj/item/reagent_containers/food/snacks/grown/cannabis, + /obj/item/reagent_containers/food/snacks/grown/cannabis/rainbow, + /obj/item/reagent_containers/food/snacks/grown/cannabis/white, + /obj/item/storage/pill_bottle/zoom, + /obj/item/storage/pill_bottle/happy, + /obj/item/storage/pill_bottle/lsd, + /obj/item/storage/pill_bottle/aranesp, + /obj/item/storage/pill_bottle/stimulant, + /obj/item/toy/cards/deck/syndicate, + /obj/item/reagent_containers/food/drinks/bottle/absinthe, + /obj/item/clothing/under/syndicate/tacticool, + /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/storage/fancy/cigarettes/cigpack_shadyjims, - /obj/item/storage/fancy/cigarettes/cigpack_midori, - /obj/item/seeds/ambrosia/deus, + /obj/item/clothing/mask/gas/syndicate, /obj/item/clothing/neck/necklace/dope) crate_name = "crate" diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index cb797c34d4..8245148096 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -100,6 +100,11 @@ icon_state = "scarf" color = "#4A4A4B" //Grey but it looks black +/obj/item/clothing/neck/scarf/pink + name = "pink scarf" + icon_state = "scarf" + color = "#F699CD" //Pink + /obj/item/clothing/neck/scarf/red name = "red scarf" icon_state = "scarf" @@ -118,7 +123,7 @@ /obj/item/clothing/neck/scarf/purple name = "purple scarf" icon_state = "scarf" - color = "#9557C5" //purple + color = "#9557C5" //Purple /obj/item/clothing/neck/scarf/yellow name = "yellow scarf" @@ -128,7 +133,7 @@ /obj/item/clothing/neck/scarf/orange name = "orange scarf" icon_state = "scarf" - color = "#C67A4B" //orange + color = "#C67A4B" //Orange /obj/item/clothing/neck/scarf/cyan name = "cyan scarf" diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 29be63a2bb..dc903dce85 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -59,7 +59,7 @@ if(!proximity) return - if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it. + if(target.is_refillable() && is_drainable()) //Something like a glass. Player probably wants to transfer TO it. if(!reagents.total_volume) to_chat(user, "[src] is empty.") return diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index e9ffb9e450..7e541f2471 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -427,7 +427,7 @@ /obj/item/disk/plantgene/proc/update_name() if(gene) - name = "[gene.get_name()] (Plant Data Disk)" + name = "[gene.get_name()] (plant data disk)" else name = "plant data disk" @@ -437,4 +437,6 @@ /obj/item/disk/plantgene/examine(mob/user) ..() + if(gene && (istype(gene, /datum/plant_gene/core/potency))) + to_chat(user,"Percent is relative to potency, not maximum volume of the plant.") to_chat(user, "The write-protect tab is set to [src.read_only ? "protected" : "unprotected"].") diff --git a/code/modules/integrated_electronics/subtypes/access.dm b/code/modules/integrated_electronics/subtypes/access.dm index bf710be0e2..9012cd1089 100644 --- a/code/modules/integrated_electronics/subtypes/access.dm +++ b/code/modules/integrated_electronics/subtypes/access.dm @@ -1,5 +1,5 @@ /obj/item/integrated_circuit/input/card_reader - name = "card reader" + name = "ID card reader" //To differentiate it from the data card reader desc = "A circuit that can read the registred name, assignment, and PassKey string from an ID card." icon_state = "card_reader" @@ -14,6 +14,10 @@ "on read" = IC_PINTYPE_PULSE_OUT ) +/obj/item/integrated_circuit/input/card_reader/old + name = "card reader" + spawn_flags = 0 + /obj/item/integrated_circuit/input/card_reader/attackby_react(obj/item/I, mob/living/user, intent) var/obj/item/card/id/card = I.GetID() var/list/access = I.GetAccess() diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index b780762cd4..02500e5ed6 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -1104,3 +1104,43 @@ else activate_pin(3) +/obj/item/integrated_circuit/input/data_card_reader + name = "data card reader" + desc = "A circuit that can read from and write to data cards." + extended_desc = "Setting the \"write mode\" boolean to true will cause any data cards that are used on the assembly to replace\ + their existing function and data strings with the given strings, if it is set to false then using a data card on the assembly will cause\ + the function and data strings stored on the card to be written to the output pins." + icon_state = "card_reader" + complexity = 4 + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + inputs = list( + "function" = IC_PINTYPE_STRING, + "data to store" = IC_PINTYPE_STRING, + "write mode" = IC_PINTYPE_BOOLEAN + ) + outputs = list( + "function" = IC_PINTYPE_STRING, + "stored data" = IC_PINTYPE_STRING + ) + activators = list( + "on write" = IC_PINTYPE_PULSE_OUT, + "on read" = IC_PINTYPE_PULSE_OUT + ) + +/obj/item/integrated_circuit/input/data_card_reader/attackby_react(obj/item/I, mob/living/user, intent) + var/obj/item/card/data/card = I.GetCard() + var/write_mode = get_pin_data(IC_INPUT, 3) + if(card) + if(write_mode == TRUE) + card.function = get_pin_data(IC_INPUT, 1) + card.data = get_pin_data(IC_INPUT, 2) + push_data() + activate_pin(1) + else + set_pin_data(IC_OUTPUT, 1, card.function) + set_pin_data(IC_OUTPUT, 2, card.data) + push_data() + activate_pin(2) + else + return FALSE + return TRUE diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm index a6c28b4146..59ce11baeb 100644 --- a/code/modules/lighting/lighting_source.dm +++ b/code/modules/lighting/lighting_source.dm @@ -56,10 +56,10 @@ if (top_atom) LAZYREMOVE(top_atom.light_sources, src) - + if (needs_update) GLOB.lighting_update_lights -= src - + . = ..() // Yes this doesn't align correctly on anything other than 4 width tabs. @@ -116,7 +116,6 @@ . = LUM_FALLOFF(C, pixel_turf); \ . *= light_power; \ var/OLD = effect_str[C]; \ - \ effect_str[C] = .; \ \ C.update_lumcount \ @@ -126,7 +125,6 @@ (. * lum_b) - (OLD * applied_lum_b) \ ); - #define REMOVE_CORNER(C) \ . = -effect_str[C]; \ C.update_lumcount \ @@ -167,8 +165,9 @@ /datum/light_source/proc/update_corners() var/update = FALSE + var/atom/source_atom = src.source_atom - if (!source_atom || QDELETED(source_atom)) + if (QDELETED(source_atom)) qdel(src) return diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index a8d94e9ce4..765f9d92e0 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -1,3 +1,5 @@ +GLOBAL_LIST(labor_sheet_values) + /**********************Prisoners' Console**************************/ /obj/machinery/mineral/labor_claim_console @@ -20,6 +22,18 @@ Radio.listening = FALSE locate_stacking_machine() + if(!GLOB.labor_sheet_values) + var/sheet_list = list() + for(var/sheet_type in subtypesof(/obj/item/stack/sheet)) + var/obj/item/stack/sheet/sheet = sheet_type + if(!initial(sheet.point_value) || (initial(sheet.merge_type) && initial(sheet.merge_type) != sheet_type)) //ignore no-value sheets and x/fifty subtypes + continue + sheet_list += list(list("ore" = initial(sheet.name), "value" = initial(sheet.point_value))) + GLOB.labor_sheet_values = sortList(sheet_list, /proc/cmp_sheet_list) + +/proc/cmp_sheet_list(list/a, list/b) + return a["value"] - b["value"] + /obj/machinery/mineral/labor_claim_console/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/card/id/prisoner)) if(!inserted_id) @@ -52,16 +66,10 @@ if(check_auth()) can_go_home = TRUE - var/list/ores = list() if(stacking_machine) data["unclaimed_points"] = stacking_machine.points - for(var/ore in stacking_machine.ore_values) - var/list/O = list() - O["ore"] = ore - O["value"] = stacking_machine.ore_values[ore] - ores += list(O) - data["ores"] = ores + data["ores"] = GLOB.labor_sheet_values data["can_go_home"] = can_go_home return data @@ -127,15 +135,10 @@ /obj/machinery/mineral/stacking_machine/laborstacker - var/points = 0 //The unclaimed value of ore stacked. Value for each ore loosely relative to its rarity. - var/list/ore_values = list("glass" = 1, "metal" = 2, "reinforced glass" = 4, "gold" = 20, "silver" = 20, "uranium" = 20, "titanium" = 20, "solid plasma" = 20, "plasteel" = 23, "plasma glass" = 23, "diamond" = 25, "bluespace polycrystal" = 30, "plastitanium" = 45, "bananium" = 50) + var/points = 0 //The unclaimed value of ore stacked. /obj/machinery/mineral/stacking_machine/laborstacker/process_sheet(obj/item/stack/sheet/inp) - if(istype(inp)) - var/n = inp.name - var/a = inp.amount - if(n in ore_values) - points += ore_values[n] * a + points += inp.point_value * inp.amount ..() diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm index f0a06429c5..dcc9034e2d 100644 --- a/code/modules/mining/machine_stacking.dm +++ b/code/modules/mining/machine_stacking.dm @@ -105,8 +105,8 @@ stack_list[inp.type] = s var/obj/item/stack/sheet/storage = stack_list[inp.type] storage.amount += inp.amount //Stack the sheets - qdel(inp) //Let the old sheet garbage collect while(storage.amount > stack_amt) //Get rid of excessive stackage var/obj/item/stack/sheet/out = new inp.type(null, stack_amt) unload_mineral(out) storage.amount -= stack_amt + qdel(inp) //Let the old sheet garbage collect diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index e13a8e5c39..03a93a6a52 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -171,8 +171,6 @@ if("Survival Capsule and Explorer's Webbing") new /obj/item/storage/belt/mining/vendor(drop_location) if("Resonator Kit") - new /obj/item/storage/belt/mining/alt(drop_location) - new /obj/item/t_scanner/adv_mining_scanner(drop_location) new /obj/item/extinguisher/mini(drop_location) new /obj/item/resonator(drop_location) if("Minebot Kit") @@ -185,8 +183,6 @@ new /obj/item/fulton_core(drop_location) new /obj/item/stack/marker_beacon/thirty(drop_location) if("Crusher Kit") - new /obj/item/storage/belt/mining/alt(drop_location) - new /obj/item/t_scanner/adv_mining_scanner(drop_location) new /obj/item/extinguisher/mini(drop_location) new /obj/item/twohanded/required/kinetic_crusher(drop_location) if("Mining Conscription Kit") diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 40ec50d67e..a469bf5258 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -164,8 +164,8 @@ //If there's an MMI in the robot, have it ejected when the mob goes away. --NEO /mob/living/silicon/robot/Destroy() + var/atom/T = drop_location()//To hopefully prevent run time errors. if(mmi && mind)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside. - var/turf/T = get_turf(loc)//To hopefully prevent run time errors. if(T) mmi.forceMove(T) if(mmi.brainmob) @@ -184,6 +184,10 @@ connected_ai.connected_robots -= src if(shell) GLOB.available_ai_shells -= src + else + if(T && istype(radio) && istype(radio.keyslot)) + radio.keyslot.forceMove(T) + radio.keyslot = null qdel(wires) qdel(module) qdel(eye_lights) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 6d3a9f9631..7d03ad4b9e 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -1,3 +1,5 @@ +#define MEDAL_PREFIX "Bubblegum" + /* BUBBLEGUM @@ -7,22 +9,15 @@ Bubblegum's footsteps are heralded by shaking booms, proving its tremendous size It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage. -It tries to strike at its target through any bloodpools under them; if it fails to do that, it will spray blood and then attempt to warp to a bloodpool near the target. -If it fails to warp to a target, it may summon up to 6 slaughterlings from the blood around it. -If it does not summon all 6 slaughterlings, it will instead charge at its target, dealing massive damage to anything it hits and spraying a stream of blood. -At half health, it will either charge three times or warp, then charge, instead of doing a single charge. +It often charges, dealing massive damage to anything unfortunate enough to be standing where it's aiming. +Whenever it isn't chasing something down, it will sink into nearby blood pools (if possible) and springs out of the closest one to its target. +To make this possible, it sprays streams of blood at random. +From these blood pools Bubblegum may summon slaughterlings - weak, low-damage minions designed to impede the target's progress. -<<<<<<< HEAD -When Bubblegum dies, it leaves behind a H.E.C.K. mining suit as well as a chest that can contain three things: - 1. A bottle that, when activated, drives everyone nearby into a frenzy - 2. A contract that marks for death the chosen target - 3. A spellblade that can slice off limbs at range -======= When Bubblegum dies, it leaves behind a H.E.C.K. suit+helmet as well as a chest that can contain three things: 1. A spellblade that can slice off limbs at range 2. A bottle that, when activated, drives everyone nearby into a frenzy 3. A contract that marks for death the chosen target ->>>>>>> c6ca01f... Merge pull request #38661 from 81Denton/fug Difficulty: Hard @@ -51,8 +46,7 @@ Difficulty: Hard del_on_death = 1 crusher_loot = list(/obj/structure/closet/crate/necropolis/bubblegum/crusher) loot = list(/obj/structure/closet/crate/necropolis/bubblegum) - blood_volume = BLOOD_VOLUME_MAXIMUM //BLEED FOR ME - var/charging = FALSE + var/charging = 0 medal_type = BOSS_MEDAL_BUBBLEGUM score_type = BUBBLEGUM_SCORE deathmessage = "sinks into a pool of blood, fleeing the battle. You've won, for now... " @@ -64,54 +58,33 @@ Difficulty: Hard desc = "You're not quite sure how a signal can be bloody." invisibility = 100 -/mob/living/simple_animal/hostile/megafauna/bubblegum/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE) - . = ..() - if(. > 0 && prob(25)) - var/obj/effect/decal/cleanable/blood/gibs/bubblegum/B = new /obj/effect/decal/cleanable/blood/gibs/bubblegum(loc) - if(prob(40)) - step(B, pick(GLOB.cardinals)) - else - B.setDir(pick(GLOB.cardinals)) - -/obj/effect/decal/cleanable/blood/gibs/bubblegum - name = "thick blood" - desc = "Thick, splattered blood." - random_icon_states = list("gib3", "gib5", "gib6") - bloodiness = 20 - -/obj/effect/decal/cleanable/blood/gibs/bubblegum/can_bloodcrawl_in() - return TRUE - /mob/living/simple_animal/hostile/megafauna/bubblegum/Life() ..() - move_to_delay = CLAMP((health/maxHealth) * 10, 5, 10) + move_to_delay = CLAMP(round((health/maxHealth) * 10), 5, 10) /mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire() - anger_modifier = CLAMP(((maxHealth - health)/60),0,20) + anger_modifier = CLAMP(((maxHealth - health)/50),0,20) if(charging) return ranged_cooldown = world.time + ranged_cooldown_time - var/warped = FALSE - if(!try_bloodattack()) - INVOKE_ASYNC(src, .proc/blood_spray) - warped = blood_warp() - if(warped && prob(100 - anger_modifier)) - return + blood_warp() - if(prob(90 - anger_modifier) || slaughterlings()) - if(health > maxHealth * 0.5) + if(prob(25)) + INVOKE_ASYNC(src, .proc/blood_spray) + + else if(prob(5+anger_modifier/2)) + slaughterlings() + else + if(health > maxHealth/2 && !client) INVOKE_ASYNC(src, .proc/charge) else - if(prob(70) || warped) - INVOKE_ASYNC(src, .proc/charge, 2) - else - INVOKE_ASYNC(src, .proc/warp_charge) + INVOKE_ASYNC(src, .proc/triple_charge) /mob/living/simple_animal/hostile/megafauna/bubblegum/Initialize() . = ..() - for(var/mob/living/simple_animal/hostile/megafauna/bubblegum/B in GLOB.mob_living_list) + for(var/mob/living/simple_animal/hostile/megafauna/bubblegum/B in GLOB.mob_list) if(B != src) return INITIALIZE_HINT_QDEL //There can be only one var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new @@ -125,56 +98,53 @@ Difficulty: Hard if(.) SSshuttle.shuttle_purchase_requirements_met |= "bubblegum" -/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon) - if(!charging) - ..() +/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A) + if(charging) + return + ..() /mob/living/simple_animal/hostile/megafauna/bubblegum/AttackingTarget() - if(!charging) - return ..() + if(charging) + return + ..() /mob/living/simple_animal/hostile/megafauna/bubblegum/Goto(target, delay, minimum_distance) - if(!charging) - ..() + if(charging) + return + ..() /mob/living/simple_animal/hostile/megafauna/bubblegum/Move() + if(!stat) + playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1) if(charging) - new /obj/effect/temp_visual/decoy/fading(loc,src) + new/obj/effect/temp_visual/decoy/fading(loc,src) DestroySurroundings() . = ..() - if(!stat && .) - playsound(src, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1) if(charging) DestroySurroundings() -/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/warp_charge() - blood_warp() +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/triple_charge() + charge() + sleep(10) + charge() + sleep(10) charge() -/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge(bonus_charges) +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge() var/turf/T = get_turf(target) if(!T || T == loc) return - new /obj/effect/temp_visual/dragon_swoop/bubblegum(T) - charging = TRUE + new /obj/effect/temp_visual/dragon_swoop(T) + charging = 1 DestroySurroundings() walk(src, 0) setDir(get_dir(src, T)) var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(loc,src) - animate(D, alpha = 0, color = "#FF0000", transform = matrix()*2, time = 3) - sleep(3) - throw_at(T, get_dist(src, T), 1, src, 0, callback = CALLBACK(src, .charge_end, bonus_charges)) - -/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge_end(bonus_charges, list/effects_to_destroy) - charging = FALSE - try_bloodattack() - if(target) - if(bonus_charges) - bonus_charges-- - charge(bonus_charges) - else - Goto(target, move_to_delay, minimum_distance) - SetRecoveryTime(MEGAFAUNA_DEFAULT_RECOVERY_TIME) + animate(D, alpha = 0, color = "#FF0000", transform = matrix()*2, time = 5) + sleep(5) + throw_at(T, get_dist(src, T), 1, src, 0) + charging = 0 + Goto(target, move_to_delay, minimum_distance) /mob/living/simple_animal/hostile/megafauna/bubblegum/Collide(atom/A) @@ -198,142 +168,20 @@ Difficulty: Hard var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src))) L.throw_at(throwtarget, 3) - charging = FALSE + charging = 0 -/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_mobs_on_blood() - var/list/targets = ListTargets() - . = list() - for(var/mob/living/L in targets) - var/list/bloodpool = get_pools(get_turf(L), 0) - if(bloodpool.len && (!faction_check_mob(L) || L.stat == DEAD)) - . += L - -/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/try_bloodattack() - var/list/targets = get_mobs_on_blood() - if(targets.len) - INVOKE_ASYNC(src, .proc/bloodattack, targets, prob(50)) - - return TRUE - return FALSE - -/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodattack(list/targets, handedness) - var/mob/living/target_one = pick_n_take(targets) - var/turf/target_one_turf = get_turf(target_one) - var/mob/living/target_two - if(targets.len) - target_two = pick_n_take(targets) - var/turf/target_two_turf = get_turf(target_two) - if(target_two.stat != CONSCIOUS || prob(10)) - bloodgrab(target_two_turf, handedness) - else - bloodsmack(target_two_turf, handedness) - - if(target_one) - var/list/pools = get_pools(get_turf(target_one), 0) - if(pools.len) - target_one_turf = get_turf(target_one) - if(target_one_turf) - if(target_one.stat != CONSCIOUS || prob(10)) - bloodgrab(target_one_turf, !handedness) - else - bloodsmack(target_one_turf, !handedness) - - if(!target_two && target_one) - var/list/poolstwo = get_pools(get_turf(target_one), 0) - if(poolstwo.len) - target_one_turf = get_turf(target_one) - if(target_one_turf) - if(target_one.stat != CONSCIOUS || prob(10)) - bloodgrab(target_one_turf, handedness) - else - bloodsmack(target_one_turf, handedness) - -/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodsmack(turf/T, handedness) - if(handedness) - new /obj/effect/temp_visual/bubblegum_hands/rightsmack(T) - else - new /obj/effect/temp_visual/bubblegum_hands/leftsmack(T) - sleep(2.5) - for(var/mob/living/L in T) - if(!faction_check_mob(L)) - to_chat(L, "[src] rends you!") - playsound(T, attack_sound, 100, 1, -1) - var/limb_to_hit = L.get_bodypart(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)) - L.apply_damage(25, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, "melee", null, null, armour_penetration)) - sleep(3) - -/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodgrab(turf/T, handedness) - if(handedness) - new /obj/effect/temp_visual/bubblegum_hands/rightpaw(T) - new /obj/effect/temp_visual/bubblegum_hands/rightthumb(T) - else - new /obj/effect/temp_visual/bubblegum_hands/leftpaw(T) - new /obj/effect/temp_visual/bubblegum_hands/leftthumb(T) - sleep(6) - for(var/mob/living/L in T) - if(!faction_check_mob(L)) - to_chat(L, "[src] drags you through the blood!") - playsound(T, 'sound/magic/enter_blood.ogg', 100, 1, -1) - var/turf/targetturf = get_step(src, dir) - L.forceMove(targetturf) - playsound(targetturf, 'sound/magic/exit_blood.ogg', 100, 1, -1) - if(L.stat != CONSCIOUS) - addtimer(CALLBACK(src, .proc/devour, L), 2) - sleep(1) - -/obj/effect/temp_visual/dragon_swoop/bubblegum - duration = 10 - -/obj/effect/temp_visual/bubblegum_hands - icon = 'icons/effects/bubblegum.dmi' - duration = 9 - -/obj/effect/temp_visual/bubblegum_hands/rightthumb - icon_state = "rightthumbgrab" - -/obj/effect/temp_visual/bubblegum_hands/leftthumb - icon_state = "leftthumbgrab" - -/obj/effect/temp_visual/bubblegum_hands/rightpaw - icon_state = "rightpawgrab" - layer = BELOW_MOB_LAYER - -/obj/effect/temp_visual/bubblegum_hands/leftpaw - icon_state = "leftpawgrab" - layer = BELOW_MOB_LAYER - -/obj/effect/temp_visual/bubblegum_hands/rightsmack - icon_state = "rightsmack" - -/obj/effect/temp_visual/bubblegum_hands/leftsmack - icon_state = "leftsmack" - /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_warp() - if(Adjacent(target)) - return FALSE - var/list/can_jaunt = get_pools(get_turf(src), 1) - if(!can_jaunt.len) - return FALSE - - var/list/pools = get_pools(get_turf(target), 2) - var/list/pools_to_remove = get_pools(get_turf(target), 1) - pools -= pools_to_remove - if(!pools.len) - return FALSE - - var/obj/effect/temp_visual/decoy/DA = new /obj/effect/temp_visual/decoy(loc,src) - DA.color = "#FF0000" - var/oldtransform = DA.transform - DA.transform = matrix()*2 - animate(DA, alpha = 255, color = initial(DA.color), transform = oldtransform, time = 3) - sleep(3) - qdel(DA) - var/obj/effect/decal/cleanable/blood/found_bloodpool - pools = get_pools(get_turf(target), 2) - pools_to_remove = get_pools(get_turf(target), 1) - pools -= pools_to_remove + var/list/pools = list() + var/can_jaunt = FALSE + for(var/obj/effect/decal/cleanable/blood/nearby in view(src,2)) + can_jaunt = TRUE + break + if(!can_jaunt) + return + for(var/obj/effect/decal/cleanable/blood/nearby in view(get_turf(target),2)) + pools += nearby if(pools.len) shuffle_inplace(pools) found_bloodpool = pick(pools) @@ -343,51 +191,30 @@ Difficulty: Hard forceMove(get_turf(found_bloodpool)) playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1) visible_message("And springs back out!") - return TRUE - return FALSE -/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_pools(turf/T, range) - . = list() - for(var/obj/effect/decal/cleanable/nearby in view(T, range)) - if(nearby.can_bloodcrawl_in()) - . += nearby /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_spray() visible_message("[src] sprays a stream of gore!") - var/range = 6 + round(anger_modifier * 0.4) + var/turf/E = get_edge_target_turf(src, src.dir) + var/range = 10 var/turf/previousturf = get_turf(src) - var/turf/J = previousturf - var/targetdir = get_dir(src, target) - if(target.loc == loc) - targetdir = dir - face_atom(target) - new /obj/effect/decal/cleanable/blood/bubblegum(J) - for(var/i in 1 to range) - J = get_step(previousturf, targetdir) - new /obj/effect/temp_visual/dir_setting/bloodsplatter(previousturf, get_dir(previousturf, J)) - playsound(previousturf,'sound/effects/splat.ogg', 100, 1, -1) - if(!J || !previousturf.atmos_adjacent_turfs || !previousturf.atmos_adjacent_turfs[J]) + for(var/turf/J in getline(src,E)) + if(!range) break - new /obj/effect/decal/cleanable/blood/bubblegum(J) + new /obj/effect/temp_visual/dir_setting/bloodsplatter(previousturf, get_dir(previousturf, J)) + if(!previousturf.CanAtmosPass(J)) + break + playsound(J,'sound/effects/splat.ogg', 100, 1, -1) + new /obj/effect/decal/cleanable/blood(J) + range-- previousturf = J sleep(1) -/obj/effect/decal/cleanable/blood/bubblegum - bloodiness = 0 - -/obj/effect/decal/cleanable/blood/bubblegum/can_bloodcrawl_in() - return TRUE - /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/slaughterlings() visible_message("[src] summons a shoal of slaughterlings!") - var/max_amount = 6 - for(var/H in get_pools(get_turf(src), 1)) - if(!max_amount) - break - max_amount-- - var/obj/effect/decal/cleanable/blood/B = H - new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/slaughter(B.loc) - return max_amount + for(var/obj/effect/decal/cleanable/blood/H in range(src, 10)) + if(prob(25)) + new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/slaughter(H.loc) /mob/living/simple_animal/hostile/asteroid/hivelordbrood/slaughter name = "slaughterling" @@ -405,3 +232,5 @@ Difficulty: Hard if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum)) return 1 return 0 + +#undef MEDAL_PREFIX \ No newline at end of file diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm index e7b628653f..df1f9fdfbd 100644 --- a/code/modules/projectiles/guns/misc/blastcannon.dm +++ b/code/modules/projectiles/guns/misc/blastcannon.dm @@ -11,8 +11,21 @@ clumsy_check = FALSE randomspread = FALSE + var/hugbox = TRUE + var/max_power = INFINITY + var/reaction_volume_mod = 0 + var/reaction_cycles = 3 //How many times gases react() before calculation. Very finnicky value, do not mess with without good reason. + var/prereaction = TRUE + + var/bombcheck = TRUE + var/debug_power = 0 + var/obj/item/transfer_valve/bomb +/obj/item/gun/blastcannon/debug + debug_power = 80 + bombcheck = FALSE + /obj/item/gun/blastcannon/Initialize() . = ..() if(!pin) @@ -56,27 +69,33 @@ return TRUE return ..() +//returns the third value of a bomb blast /obj/item/gun/blastcannon/proc/calculate_bomb() if(!istype(bomb) || !istype(bomb.tank_one) || !istype(bomb.tank_two)) return 0 - var/datum/gas_mixture/temp = new(60) //directional buff. - temp.merge(bomb.tank_one.air_contents.remove_ratio(1)) - temp.merge(bomb.tank_two.air_contents.remove_ratio(2)) - for(var/i in 1 to 6) + var/datum/gas_mixture/temp = new(max(reaction_volume_mod, 0)) + bomb.merge_gases(temp) + if(prereaction) + temp.react(src) + var/prereaction_pressure = temp.return_pressure() + if(prereaction_pressure < TANK_FRAGMENT_PRESSURE) + return 0 + for(var/i in 1 to reaction_cycles) temp.react(src) var/pressure = temp.return_pressure() qdel(temp) if(pressure < TANK_FRAGMENT_PRESSURE) return 0 - return (pressure / TANK_FRAGMENT_SCALE) + return ((pressure - TANK_FRAGMENT_PRESSURE) / TANK_FRAGMENT_SCALE) /obj/item/gun/blastcannon/afterattack(atom/target, mob/user, flag, params) - if((!bomb) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2)) + if((!bomb && bombcheck) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2)) return ..() - var/power = calculate_bomb() + var/power = bomb? calculate_bomb() : debug_power + power = min(power, max_power) QDEL_NULL(bomb) update_icon() - var/heavy = power * 0.2 + var/heavy = power * 0.25 var/medium = power * 0.5 var/light = power user.visible_message("[user] opens [bomb] on [user.p_their()] [name] and fires a blast wave at [target]!","You open [bomb] on your [name] and fire a blast wave at [target]!") @@ -87,7 +106,8 @@ message_admins(log_str) log_game(log_str) var/obj/item/projectile/blastwave/BW = new(loc, heavy, medium, light) - BW.preparePixelProjectile(target, get_turf(target), user, params, 0) + BW.hugbox = hugbox + BW.preparePixelProjectile(target, get_turf(src), params, 0) BW.fire() /obj/item/projectile/blastwave @@ -99,6 +119,7 @@ var/heavyr = 0 var/mediumr = 0 var/lightr = 0 + var/hugbox = TRUE range = 150 /obj/item/projectile/blastwave/Initialize(mapload, _h, _m, _l) @@ -110,14 +131,25 @@ /obj/item/projectile/blastwave/Range() ..() var/amount_destruction = EXPLODE_NONE + var/wallbreak_chance = 0 if(heavyr) amount_destruction = EXPLODE_DEVASTATE + wallbreak_chance = 99 else if(mediumr) amount_destruction = EXPLODE_HEAVY + wallbreak_chance = 66 else if(lightr) amount_destruction = EXPLODE_LIGHT + wallbreak_chance = 33 if(amount_destruction) - loc.ex_act(amount_destruction) + if(hugbox) + loc.contents_explosion(EXPLODE_HEAVY, loc) + if(istype(loc, /turf/closed/wall)) + var/turf/closed/wall/W = loc + if(prob(wallbreak_chance)) + W.dismantle_wall(TRUE, TRUE) + else + loc.ex_act(amount_destruction) else qdel(src) diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index f5d46a240e..d2f840cda3 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -151,10 +151,32 @@ icon_state = "pill18" list_reagents = list("insulin" = 50) roundstart = 1 - +///////////////////////////////////////// this pill is used only in a legion mob drop /obj/item/reagent_containers/pill/shadowtoxin name = "black pill" desc = "I wouldn't eat this if I were you." icon_state = "pill9" color = "#454545" - list_reagents = list("shadowmutationtoxin" = 1) \ No newline at end of file + list_reagents = list("shadowmutationtoxin" = 1) +//////////////////////////////////////// drugs +/obj/item/reagent_containers/pill/zoom + name = "zoom pill" + list_reagents = list("synaptizine" = 10, "nicotine" = 10, "methamphetamine" = 1) + + +/obj/item/reagent_containers/pill/happy + name = "happy pill" + list_reagents = list("sugar" = 10, "space_drugs" = 10) + + +/obj/item/reagent_containers/pill/lsd + name = "hallucinogen pill" + list_reagents = list("mushroomhallucinogen" = 15, "mindbreaker" = 15) + + +/obj/item/reagent_containers/pill/aranesp + name = "speedy pill" + list_reagents = list("aranesp" = 10) + + + diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index aa0b714cc8..c806a68867 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -199,7 +199,7 @@ /obj/item/bodypart/r_leg/drop_limb(special) if(owner && !special) if(owner.legcuffed) - owner.legcuffed.forceMove(drop_location()) + owner.legcuffed.forceMove(owner.drop_location()) //At this point bodypart is still in nullspace owner.legcuffed.dropped(owner) owner.legcuffed = null owner.update_inv_legcuffed() @@ -210,7 +210,7 @@ /obj/item/bodypart/l_leg/drop_limb(special) //copypasta if(owner && !special) if(owner.legcuffed) - owner.legcuffed.forceMove(drop_location()) + owner.legcuffed.forceMove(owner.drop_location()) owner.legcuffed.dropped(owner) owner.legcuffed = null owner.update_inv_legcuffed() diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index 89197a7f07..619e2c8193 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -1412,6 +1412,16 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) limited_stock = 2 //you can't use more than two! restricted_roles = list("Shaft Miner") +/datum/uplink_item/role_restricted/blastcannon + name = "Blast Cannon" + desc = "A highly specialized weapon, the Blast Cannon is actually relatively simple. It contains an attachment for a tank transfer valve mounted to an angled pipe specially constructed \ + withstand extreme pressure and temperatures, and has a mechanical trigger for triggering the transfer valve. Essentially, it turns the explosive force of a bomb into a narrow-angle \ + blast wave \"projectile\". Aspiring scientists may find this highly useful, as forcing the pressure shockwave into a narrow angle seems to be able to bypass whatever quirk of physics \ + disallows explosive ranges above a certain distance, allowing for the device to use the theoretical yield of a transfer valve bomb, instead of the factual yield." + item = /obj/item/gun/blastcannon + cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled scientist. + restricted_roles = list("Research Director", "Scientist") + /datum/uplink_item/device_tools/clown_bomb name = "Clown Bomb" desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index f3ab636fb0..ad5b38575c 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -35,6 +35,7 @@ /obj/item/clothing/neck/tie/red = 1, /obj/item/clothing/neck/tie/black = 1, /obj/item/clothing/neck/tie/horrible = 1, + /obj/item/clothing/neck/scarf/pink = 1, /obj/item/clothing/neck/scarf/red = 1, /obj/item/clothing/neck/scarf/green = 1, /obj/item/clothing/neck/scarf/darkblue = 1, @@ -118,5 +119,5 @@ /obj/item/vending_refill/clothing machine_name = "ClothesMate" icon_state = "refill_clothes" - charges = list(37, 4, 4)// of 111 standard, 12 contraband, 10 premium(?) - init_charges = list(37, 4, 4) + charges = list(38, 4, 4)// of 112 standard, 12 contraband, 10 premium(?) + init_charges = list(38, 4, 4) diff --git a/html/changelogs/AutoChangeLog-pr-7188.yml b/html/changelogs/AutoChangeLog-pr-7188.yml new file mode 100644 index 0000000000..d27aee5b1b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7188.yml @@ -0,0 +1,8 @@ +author: "JStheguy" +delete-after: True +changes: + - rscadd: "Added the data card reader circuit, a circuit that is able to read data cards, as well as write to them." + - tweak: "Data cards are now longer inexplicably called data disks despite clearly being cards, and can be printed from the \"tools\" section of the integrated circuit printer." + - tweak: "Data cards no longer have a special \"label card\" verb and instead can have their names and descriptions changed with a pen." + - rscadd: "Also, some aesthetically different variants of the data cards, because why not." + - imageadd: "Data cards have new sprites, with support for coloring them via the assembly detailer." diff --git a/html/changelogs/AutoChangeLog-pr-7189.yml b/html/changelogs/AutoChangeLog-pr-7189.yml new file mode 100644 index 0000000000..f0718609b9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7189.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Added a pink scarf to vendomats" diff --git a/html/changelogs/AutoChangeLog-pr-7190.yml b/html/changelogs/AutoChangeLog-pr-7190.yml new file mode 100644 index 0000000000..ac2f2cf485 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7190.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Players can now ctrl-click the PDA to remove the item in its pen slot" diff --git a/html/changelogs/AutoChangeLog-pr-7201.yml b/html/changelogs/AutoChangeLog-pr-7201.yml new file mode 100644 index 0000000000..562c8e4190 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7201.yml @@ -0,0 +1,5 @@ +author: "Cobby" +delete-after: True +changes: + - rscdel: "Removed Advanced Mining Scanner from roundstart voucher kits." + - rscdel: "Removed Explorer Webbing from all voucher kits besides the shelter capsule pack." diff --git a/html/changelogs/AutoChangeLog-pr-7218.yml b/html/changelogs/AutoChangeLog-pr-7218.yml new file mode 100644 index 0000000000..6bb568d088 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7218.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - spellcheck: "Plant disks with potency genes clarify the percent is for potency scaling and not relative to max volume on examine." diff --git a/html/changelogs/AutoChangeLog-pr-7219.yml b/html/changelogs/AutoChangeLog-pr-7219.yml new file mode 100644 index 0000000000..b50be06a75 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7219.yml @@ -0,0 +1,4 @@ +author: "Dax Dupont" +delete-after: True +changes: + - admin: "Create antags now checks for people being on station before applying." diff --git a/html/changelogs/AutoChangeLog-pr-7220.yml b/html/changelogs/AutoChangeLog-pr-7220.yml new file mode 100644 index 0000000000..ba87335d1e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7220.yml @@ -0,0 +1,6 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Blast cannons have been fixed and are now available for purchase by traitorous scientists for a low low price of 14TC." + - rscadd: "Blast cannons take the explosive power of a TTV bomb and ejects a linear projectile that will apply what the bomb would do to a certain tile at that distance to that tile. However, this will not cause breaches, or gib mobs, unless the gods (admins) so will it. +experimental: Blast cannons do not respect maxcap. (Unless the admins so will it.)" diff --git a/html/changelogs/AutoChangeLog-pr-7222.yml b/html/changelogs/AutoChangeLog-pr-7222.yml new file mode 100644 index 0000000000..1fb99a2d63 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7222.yml @@ -0,0 +1,4 @@ +author: "Kor" +delete-after: True +changes: + - rscadd: "Bubblegum has regained his original (deadlier) move set." diff --git a/html/changelogs/AutoChangeLog-pr-7230.yml b/html/changelogs/AutoChangeLog-pr-7230.yml new file mode 100644 index 0000000000..b1674293b5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7230.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Cyborgs now drop keys on deconstruction/detonation" diff --git a/html/changelogs/AutoChangeLog-pr-7231.yml b/html/changelogs/AutoChangeLog-pr-7231.yml new file mode 100644 index 0000000000..4bd894c04e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7231.yml @@ -0,0 +1,4 @@ +author: "Time-Green" +delete-after: True +changes: + - bugfix: "Soda is no longer intangible to the laws of physics" diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi index e6778c51af..507801844c 100644 Binary files a/icons/obj/card.dmi and b/icons/obj/card.dmi differ diff --git a/sound/effects/comfyfire.ogg b/sound/effects/comfyfire.ogg index 9b796219b3..1bc7fc02d0 100644 Binary files a/sound/effects/comfyfire.ogg and b/sound/effects/comfyfire.ogg differ