diff --git a/_maps/festivestation.json b/_maps/festivestation.json index 0803c1b566..b8884371a3 100644 --- a/_maps/festivestation.json +++ b/_maps/festivestation.json @@ -7,5 +7,8 @@ "ferry": "ferry_fancy", "whiteship": "whiteship_box", "emergency": "emergency_box" - } + }, + "traits": [ + { "Weather_Icestorm":true } + ] } diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 791e6d1368..4078c690d4 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -29637,6 +29637,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/item/cautery, /turf/open/floor/plasteel/white, /area/science/robotics/lab) "btb" = ( diff --git a/_maps/spookystation.json b/_maps/spookystation.json index ec2db6e950..c880aacff7 100644 --- a/_maps/spookystation.json +++ b/_maps/spookystation.json @@ -7,5 +7,8 @@ "whiteship": "whiteship_pubby", "ferry": "ferry_fancy", "cargo": "cargo_box" - } + }, + "traits": [ + { "Weather_Longrain":true } + ] } diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm index 5e3f571cb7..70bb338b7b 100644 --- a/code/__DEFINES/maps.dm +++ b/code/__DEFINES/maps.dm @@ -43,6 +43,8 @@ require only minor tweaks. #define ZTRAIT_ASHSTORM "Weather_Ashstorm" #define ZTRAIT_ACIDRAIN "Weather_Acidrain" #define ZTRAIT_VOIDSTORM "Weather_Voidstorm" +#define ZTRAIT_ICESTORM "Weather_Icestorm" +#define ZTRAIT_LONGRAIN "Weather_Longrain" // number - bombcap is multiplied by this before being applied to bombs #define ZTRAIT_BOMBCAP_MULTIPLIER "Bombcap Multiplier" diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index 410e21d419..46fb232d6d 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -343,10 +343,15 @@ SUBSYSTEM_DEF(research) break //Just need one to work. if (!isnull(last_income)) var/income_time_difference = world.time - last_income - science_tech.last_bitcoins = bitcoins // Doesn't take tick drift into account for(var/i in bitcoins) bitcoins[i] *= income_time_difference / 10 science_tech.add_point_list(bitcoins) + if(!length(science_tech.last_bitcoins)) + science_tech.last_bitcoins = science_tech.research_points + for(var/i in science_tech.last_bitcoins) + var/old_weighted = science_tech.last_bitcoins[i] * (1 MINUTES - income_time_difference) + var/new_weighted = science_tech.research_points[i] * income_time_difference + science_tech.last_bitcoins[i] = round((old_weighted + new_weighted) / (1 MINUTES)) last_income = world.time /datum/controller/subsystem/research/proc/calculate_server_coefficient() //Diminishing returns. diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index 03c23e11f6..eb49323464 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -178,7 +178,7 @@ var/mob/living/silicon/robot/R = target if(iscyborg(R)) - if(R.module.dogborg == TRUE || R.dogborg == TRUE) //I hate whoever that thought that putting two types of dogborg that don't even sync up properly was good + if((R.module.dogborg == TRUE || R.dogborg == TRUE) && isturf(R.loc)) //I hate whoever that thought that putting two types of dogborg that don't even sync up properly was good message.pixel_x = 16 /** diff --git a/code/datums/weather/weather_types/ice_storm.dm b/code/datums/weather/weather_types/ice_storm.dm index f7be622770..451b0bdad6 100644 --- a/code/datums/weather/weather_types/ice_storm.dm +++ b/code/datums/weather/weather_types/ice_storm.dm @@ -19,7 +19,7 @@ area_type = /area/edina protected_areas = list(/area/edina/protected) - target_trait = ZTRAIT_STATION + target_trait = ZTRAIT_ICESTORM immunity_type = "rad" diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index b62befc88c..0052306949 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -382,6 +382,70 @@ else return ..() +////////////////////////////////////////////// +// // +// Clock Cult (MID) // +// // +////////////////////////////////////////////// + + +//changes two people midround into clockwork cultists +/datum/dynamic_ruleset/midround/ratvar_awakening + name = "Ratvar Awakening" + antag_datum = /datum/antagonist/clockcult + antag_flag = "clock mid" + antag_flag_override = ROLE_SERVANT_OF_RATVAR + protected_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + restricted_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + enemy_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + required_enemies = list(1,1,1,1,1,1,0,0,0,0) + required_candidates = 2 + weight = 3 + cost = 20 + requirements = list(101,101,101,101,50,40,30,20,10,10) + var/list/clock_cap = list(1,1,1,1,2,3,4,5,5,5) + flags = HIGH_IMPACT_RULESET + +/datum/dynamic_ruleset/midround/ratvar_awakening/acceptable(population=0, threat=0) + if (locate(/datum/dynamic_ruleset/roundstart/clockcult) in mode.executed_rules) + return FALSE // Unavailable if clockies exist at round start + indice_pop = min(clock_cap.len, round(living_players.len/5)+1) + required_candidates = clock_cap[indice_pop] + return ..() + +/datum/dynamic_ruleset/midround/ratvar_awakening/trim_candidates() + ..() + candidates = living_players + for(var/mob/living/player as anything in candidates) + var/turf/player_turf = get_turf(player) + if(!player_turf || !is_station_level(player_turf.z)) + candidates -= player //no ghost roles + continue + + if(!is_eligible_servant(player)) + candidates -= player + continue + + if(player.mind && (player.mind.special_role || length(player.mind.antag_datums) > 0)) + candidates -= player //no double dipping + +/datum/dynamic_ruleset/midround/ratvar_awakening/execute() + if(!candidates || !candidates.len) + return FALSE + for(var/i = 0; i < required_candidates; i++) + if(!candidates.len) + break + var/mob/living/clock_antag = pick_n_take(candidates) + assigned += clock_antag.mind + for(var/datum/mind/M in assigned) //add them to the clockwork team + add_servant_of_ratvar(M.current) + SSticker.mode.equip_servant(M.current) + SSticker.mode.greet_servant(M.current) + message_admins("[ADMIN_LOOKUPFLW(M.current)] was selected by the [name] ruleset and has been made into a midround clock cultist.") + log_game("DYNAMIC: [key_name(M.current)] was selected by the [name] ruleset and has been made into a midround clock cultist.") + load_reebe() + return ..() + ////////////////////////////////////////////// // // // BLOB (GHOST) // diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index ad9c8edf8f..fffcd6dada 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -271,18 +271,7 @@ if(resin_cooldown) to_chat(user, "Resin launcher is still recharging...") return - resin_cooldown = TRUE - R.remove_any(100) - var/obj/effect/resin_container/A = new (get_turf(src)) - log_game("[key_name(user)] used Resin Launcher at [AREACOORD(user)].") - playsound(src,'sound/items/syringeproj.ogg',40,1) - for(var/a=0, a<5, a++) - step_towards(A, target) - sleep(2) - A.Smoke() - spawn(100) - if(src) - resin_cooldown = FALSE + launch_resin(target, user) return if(nozzle_mode == RESIN_FOAM) if(!Adj|| !isturf(target)) @@ -301,6 +290,21 @@ to_chat(user, "Resin foam mix is still being synthesized...") return +/obj/item/extinguisher/mini/nozzle/proc/launch_resin(atom/target, mob/user) + set waitfor = FALSE + resin_cooldown = TRUE + reagents.remove_any(100) + var/obj/effect/resin_container/A = new (get_turf(src)) + log_game("[key_name(user)] used Resin Launcher at [AREACOORD(user)].") + playsound(src,'sound/items/syringeproj.ogg',40,1) + for(var/a=0, a<5, a++) + step_towards(A, target) + sleep(2) + A.Smoke() + spawn(100) + if(src) + resin_cooldown = FALSE + /obj/effect/resin_container name = "resin container" desc = "A compacted ball of expansive resin, used to repair the atmosphere in a room, or seal off breaches." diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index 9bd1030685..521c32fe3d 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -387,8 +387,7 @@ log_combat(user, M, "used a cult spell on", source.name, "") M.set_last_attacker(user) -/obj/item/melee/blood_magic/afterattack(atom/target, mob/living/carbon/user, proximity) - . = ..() +/obj/item/melee/blood_magic/proc/post_cast(atom/target, mob/living/carbon/user, proximity) if(invocation) user.whisper(invocation, language = /datum/language/common) if(health_cost) @@ -467,6 +466,7 @@ to_chat(user, "In an brilliant flash of red, [L] [is_servant_of_ratvar(L) ? "writhes in pain!" : "falls to the ground!"]") uses-- ..() + post_cast(target, user, proximity) //Teleportation /obj/item/melee/blood_magic/teleport @@ -480,40 +480,45 @@ to_chat(user, "You can only teleport adjacent cultists with this spell!") return if(iscultist(user)) - var/list/potential_runes = list() - var/list/teleportnames = list() - for(var/R in GLOB.teleport_runes) - var/obj/effect/rune/teleport/T = R - potential_runes[avoid_assoc_duplicate_keys(T.listkey, teleportnames)] = T - - if(!potential_runes.len) - to_chat(user, "There are no valid runes to teleport to!") - log_game("Teleport talisman failed - no other teleport runes") - return - - var/turf/T = get_turf(src) - if(is_away_level(T.z)) - to_chat(user, "You are not in the right dimension!") - log_game("Teleport spell failed - user in away mission") - return - - var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked - var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to? - if(QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !actual_selected_rune || !proximity) - return - var/turf/dest = get_turf(actual_selected_rune) - if(is_blocked_turf(dest, TRUE)) - to_chat(user, "The target rune is blocked. Attempting to teleport to it would be massively unwise.") - return - uses-- - var/turf/origin = get_turf(user) - var/mob/living/L = target - if(do_teleport(L, dest, channel = TELEPORT_CHANNEL_CULT)) - origin.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] with a sharp crack!", \ - "You speak the words of the talisman and find yourself somewhere else!", "You hear a sharp crack.") - dest.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") + try_teleport(target, user, proximity) ..() +/obj/item/melee/blood_magic/teleport/proc/try_teleport(atom/target, mob/living/carbon/user, proximity) + set waitfor = FALSE + var/list/potential_runes = list() + var/list/teleportnames = list() + for(var/R in GLOB.teleport_runes) + var/obj/effect/rune/teleport/T = R + potential_runes[avoid_assoc_duplicate_keys(T.listkey, teleportnames)] = T + + if(!potential_runes.len) + to_chat(user, "There are no valid runes to teleport to!") + log_game("Teleport talisman failed - no other teleport runes") + return + + var/turf/T = get_turf(src) + if(is_away_level(T.z)) + to_chat(user, "You are not in the right dimension!") + log_game("Teleport spell failed - user in away mission") + return + + var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked + var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to? + if(QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !actual_selected_rune || !proximity) + return + var/turf/dest = get_turf(actual_selected_rune) + if(is_blocked_turf(dest, TRUE)) + to_chat(user, "The target rune is blocked. Attempting to teleport to it would be massively unwise.") + return + uses-- + var/turf/origin = get_turf(user) + var/mob/living/L = target + if(do_teleport(L, dest, channel = TELEPORT_CHANNEL_CULT)) + origin.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] with a sharp crack!", \ + "You speak the words of the talisman and find yourself somewhere else!", "You hear a sharp crack.") + dest.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") + post_cast(target, user, proximity) + //Shackles /obj/item/melee/blood_magic/shackles name = "Binding Aura" @@ -530,6 +535,7 @@ user.visible_message("This victim doesn't have enough arms to complete the restraint!") return ..() + post_cast(target, user, proximity) /obj/item/melee/blood_magic/shackles/proc/CuffAttack(mob/living/carbon/C, mob/living/user) if(!C.handcuffed) @@ -583,6 +589,7 @@ to_chat(user, "A dark cloud emanates from your hand and swirls around the metal, twisting it into a construct shell!") new /obj/structure/constructshell(T) SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + post_cast(target, proximity_flag, user) else to_chat(user, "You need 50 metal to produce a construct shell!") else if(istype(target, /obj/item/stack/sheet/plasteel)) @@ -593,56 +600,73 @@ new /obj/item/stack/sheet/runed_metal(T,quantity) to_chat(user, "A dark cloud emanates from you hand and swirls around the plasteel, transforming it into runed metal!") SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + post_cast(target, user, proximity_flag) if(istype(target, /obj/item/clothing/suit/hooded/wintercoat) && target.type != /obj/item/clothing/suit/hooded/wintercoat/narsie) - if (do_after(user,30,target=target)) - new /obj/item/clothing/suit/hooded/wintercoat/narsie(T) - qdel(target) - to_chat(user, "A dark cloud emanates from you hand and swirls around [target], transforming it into a narsian winter coat!") - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + convert_coat(target, user, proximity_flag, T) else if(istype(target,/mob/living/silicon/robot)) - var/mob/living/silicon/robot/candidate = target - if(!iscultist(user, TRUE)) - to_chat(user, "You are not strongly connected enough to Nar'sie to use make constructs...") - else if(candidate.mmi) - user.visible_message("A dark cloud emanates from [user]'s hand and swirls around [candidate]!") - playsound(T, 'sound/machines/airlock_alien_prying.ogg', 80, 1) - var/prev_color = candidate.color - candidate.color = "black" - if(do_after(user, 90, target = candidate)) - candidate.emp_act(80) - var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer") - user.visible_message("The dark cloud receedes from what was formerly [candidate], revealing a\n [construct_class]!") - switch(construct_class) - if("Juggernaut") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/armored, candidate, user, 0, T) - if("Wraith") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, candidate, user, 0, T) - if("Artificer") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, candidate, user, 0, T) - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) - uses-- - candidate.mmi = null - qdel(candidate) - else - candidate.color = prev_color - else - uses-- - to_chat(user, "A dark cloud emanates from you hand and swirls around [candidate] - twisting it into a construct shell!") - new /obj/structure/constructshell(T) - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + convert_borg(target, user, proximity_flag, T) else if(istype(target,/obj/machinery/door/airlock)) - playsound(T, 'sound/machines/airlockforced.ogg', 50, 1) - do_sparks(5, TRUE, target) - if(do_after(user, 50, target = user)) - target.narsie_act() - uses-- - user.visible_message("Black ribbons suddenly emanate from [user]'s hand and cling to the airlock - twisting and corrupting it!") - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + convert_door(target, user, proximity_flag, T) else to_chat(user, "The spell will not work on [target]!") return ..() +/obj/item/melee/blood_magic/construction/proc/convert_coat(atom/target, mob/user, proximity_flag, turf/T) + set waitfor = FALSE + if(do_after(user,30,target=target)) + new /obj/item/clothing/suit/hooded/wintercoat/narsie(T) + qdel(target) + to_chat(user, "A dark cloud emanates from you hand and swirls around [target], transforming it into a narsian winter coat!") + SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + post_cast(target, user, proximity_flag) + +/obj/item/melee/blood_magic/construction/proc/convert_door(atom/target, mob/user, proximity_flag, turf/T) + set waitfor = FALSE + playsound(T, 'sound/machines/airlockforced.ogg', 50, 1) + do_sparks(5, TRUE, target) + if(do_after(user, 50, target = user)) + target.narsie_act() + uses-- + user.visible_message("Black ribbons suddenly emanate from [user]'s hand and cling to the airlock - twisting and corrupting it!") + SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + post_cast(target, user, proximity_flag) + +/obj/item/melee/blood_magic/construction/proc/convert_borg(atom/target, mob/user, proximity_flag, turf/T) + set waitfor = FALSE + var/mob/living/silicon/robot/candidate = target + if(!iscultist(user, TRUE)) + to_chat(user, "You are not strongly connected enough to Nar'sie to use make constructs...") + return + else if(candidate.mmi) + user.visible_message("A dark cloud emanates from [user]'s hand and swirls around [candidate]!") + playsound(T, 'sound/machines/airlock_alien_prying.ogg', 80, 1) + var/prev_color = candidate.color + candidate.color = "black" + if(do_after(user, 90, target = candidate)) + candidate.emp_act(80) + var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer") + user.visible_message("The dark cloud receedes from what was formerly [candidate], revealing a\n [construct_class]!") + switch(construct_class) + if("Juggernaut") + makeNewConstruct(/mob/living/simple_animal/hostile/construct/armored, candidate, user, 0, T) + if("Wraith") + makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, candidate, user, 0, T) + if("Artificer") + makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, candidate, user, 0, T) + SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + uses-- + candidate.mmi = null + qdel(candidate) + else + candidate.color = prev_color + else + uses-- + to_chat(user, "A dark cloud emanates from you hand and swirls around [candidate] - twisting it into a construct shell!") + new /obj/structure/constructshell(T) + SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + post_cast(target, user, proximity_flag) + //Armor: Gives the target a basic cultist combat loadout /obj/item/melee/blood_magic/armor name = "Bladed Aura" @@ -665,6 +689,7 @@ C.put_in_hands(new /obj/item/melee/cultblade(user)) C.put_in_hands(new /obj/item/restraints/legcuffs/bola/cult(user)) ..() + post_cast(target, user, proximity) /obj/item/melee/blood_magic/manipulator name = "Ritual Aura" @@ -693,7 +718,9 @@ H.adjust_integration_blood(uses * 2) to_chat(user,"You use the last of your blood rites to restore what blood you could!") uses = 0 - return ..() + ..() + post_cast(target, user, proximity) + return else H.blood_volume = (BLOOD_VOLUME_SAFE*H.blood_ratio) uses -= round(restore_blood/2) @@ -758,6 +785,7 @@ if(istype(target, /obj/effect/decal/cleanable/blood)) blood_draw(target, user) ..() + post_cast() /obj/item/melee/blood_magic/manipulator/proc/blood_draw(atom/target, mob/living/carbon/human/user) var/temp = 0 diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 35151953a0..20e41828d4 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -660,40 +660,42 @@ return if(istype(A, /obj/item)) - - var/list/cultists = list() - for(var/datum/mind/M in SSticker.mode.cult) - if(M.current && M.current.stat != DEAD) - cultists |= M.current - var/mob/living/cultist_to_receive = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in (cultists - user) - if(!Adjacent(user) || !src || QDELETED(src) || user.incapacitated()) - return - if(!cultist_to_receive) - to_chat(user, "You require a destination!") - log_game("Void torch failed - no target") - return - if(cultist_to_receive.stat == DEAD) - to_chat(user, "[cultist_to_receive] has died!") - log_game("Void torch failed - target died") - return - if(!iscultist(cultist_to_receive)) - to_chat(user, "[cultist_to_receive] is not a follower of the Geometer!") - log_game("Void torch failed - target was deconverted") - return - if(A in user.GetAllContents()) - to_chat(user, "[A] must be on a surface in order to teleport it!") - return - to_chat(user, "You ignite [A] with \the [src], turning it to ash, but through the torch's flames you see that [A] has reached [cultist_to_receive]!") - cultist_to_receive.put_in_hands(A) - charges-- - to_chat(user, "\The [src] now has [charges] charge\s.") - if(charges == 0) - qdel(src) + transmit_item(A, user, proximity) else ..() to_chat(user, "\The [src] can only transport items!") +/obj/item/flashlight/flare/culttorch/proc/transmit_item(atom/movable/A, mob/user, proximity) + set waitfor = FALSE + var/list/cultists = list() + for(var/datum/mind/M in SSticker.mode.cult) + if(M.current && M.current.stat != DEAD) + cultists |= M.current + var/mob/living/cultist_to_receive = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in (cultists - user) + if(!Adjacent(user) || !src || QDELETED(src) || user.incapacitated()) + return + if(!cultist_to_receive) + to_chat(user, "You require a destination!") + log_game("Void torch failed - no target") + return + if(cultist_to_receive.stat == DEAD) + to_chat(user, "[cultist_to_receive] has died!") + log_game("Void torch failed - target died") + return + if(!iscultist(cultist_to_receive)) + to_chat(user, "[cultist_to_receive] is not a follower of the Geometer!") + log_game("Void torch failed - target was deconverted") + return + if(A in user.GetAllContents()) + to_chat(user, "[A] must be on a surface in order to teleport it!") + return + to_chat(user, "You ignite [A] with \the [src], turning it to ash, but through the torch's flames you see that [A] has reached [cultist_to_receive]!") + cultist_to_receive.put_in_hands(A) + charges-- + to_chat(user, "\The [src] now has [charges] charge\s.") + if(charges == 0) + qdel(src) /obj/item/cult_spear name = "blood halberd" diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index 5044a73c10..adee8b66ce 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -60,83 +60,86 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) return if(A.anchored || (A.move_resist > max_force_fulton)) return - to_chat(user, "You start attaching the pack to [A]...") - if(do_after(user,50,target=A)) - to_chat(user, "You attach the pack to [A] and activate it.") - if(loc == user && istype(user.back, /obj/item/storage/backpack)) - var/obj/item/storage/backpack/B = user.back - SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, src, user, FALSE, FALSE) - uses_left-- - if(uses_left <= 0) - user.transferItemToLoc(src, A, TRUE) - var/mutable_appearance/balloon - var/mutable_appearance/balloon2 - var/mutable_appearance/balloon3 - if(isliving(A)) - var/mob/living/M = A - M.DefaultCombatKnockdown(320) // Keep them from moving during the duration of the extraction - M.buckled = 0 // Unbuckle them to prevent anchoring problems - else - A.anchored = TRUE - A.density = FALSE - var/obj/effect/extraction_holder/holder_obj = new(A.loc) - holder_obj.appearance = A.appearance - A.forceMove(holder_obj) - balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand") - balloon2.pixel_y = 10 - balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM - holder_obj.add_overlay(balloon2) - sleep(4) - balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon") - balloon.pixel_y = 10 - balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM - holder_obj.cut_overlay(balloon2) - holder_obj.add_overlay(balloon) - playsound(holder_obj.loc, 'sound/items/fulext_deploy.wav', 50, 1, -3) - animate(holder_obj, pixel_z = 10, time = 20) - sleep(20) - animate(holder_obj, pixel_z = 15, time = 10) - sleep(10) - animate(holder_obj, pixel_z = 10, time = 10) - sleep(10) - animate(holder_obj, pixel_z = 15, time = 10) - sleep(10) - animate(holder_obj, pixel_z = 10, time = 10) - sleep(10) - playsound(holder_obj.loc, 'sound/items/fultext_launch.wav', 50, 1, -3) - animate(holder_obj, pixel_z = 1000, time = 30) - if(ishuman(A)) - var/mob/living/carbon/human/L = A - L.SetUnconscious(0) - L.drowsyness = 0 - L.SetSleeping(0) - sleep(30) - var/list/flooring_near_beacon = list() - for(var/turf/open/floor in orange(1, beacon)) - flooring_near_beacon += floor - holder_obj.forceMove(pick(flooring_near_beacon)) - animate(holder_obj, pixel_z = 10, time = 50) - sleep(50) - animate(holder_obj, pixel_z = 15, time = 10) - sleep(10) - animate(holder_obj, pixel_z = 10, time = 10) - sleep(10) - balloon3 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract") - balloon3.pixel_y = 10 - balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM - holder_obj.cut_overlay(balloon) - holder_obj.add_overlay(balloon3) - sleep(4) - holder_obj.cut_overlay(balloon3) - A.anchored = FALSE // An item has to be unanchored to be extracted in the first place. - A.density = initial(A.density) - animate(holder_obj, pixel_z = 0, time = 5) - sleep(5) - A.forceMove(holder_obj.loc) - qdel(holder_obj) - if(uses_left <= 0) - qdel(src) + attach_fulton(A, user, flag, params) +/obj/item/extraction_pack/proc/attach_fulton(atom/movable/A, mob/living/carbon/human/user, flag, params) + set waitfor = FALSE + to_chat(user, "You start attaching the pack to [A]...") + if(do_after(user,50,target=A)) + to_chat(user, "You attach the pack to [A] and activate it.") + if(loc == user && istype(user.back, /obj/item/storage/backpack)) + var/obj/item/storage/backpack/B = user.back + SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, src, user, FALSE, FALSE) + uses_left-- + if(uses_left <= 0) + user.transferItemToLoc(src, A, TRUE) + var/mutable_appearance/balloon + var/mutable_appearance/balloon2 + var/mutable_appearance/balloon3 + if(isliving(A)) + var/mob/living/M = A + M.DefaultCombatKnockdown(320) // Keep them from moving during the duration of the extraction + M.buckled = 0 // Unbuckle them to prevent anchoring problems + else + A.anchored = TRUE + A.density = FALSE + var/obj/effect/extraction_holder/holder_obj = new(A.loc) + holder_obj.appearance = A.appearance + A.forceMove(holder_obj) + balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand") + balloon2.pixel_y = 10 + balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.add_overlay(balloon2) + sleep(4) + balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon") + balloon.pixel_y = 10 + balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.cut_overlay(balloon2) + holder_obj.add_overlay(balloon) + playsound(holder_obj.loc, 'sound/items/fulext_deploy.wav', 50, 1, -3) + animate(holder_obj, pixel_z = 10, time = 20) + sleep(20) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + playsound(holder_obj.loc, 'sound/items/fultext_launch.wav', 50, 1, -3) + animate(holder_obj, pixel_z = 1000, time = 30) + if(ishuman(A)) + var/mob/living/carbon/human/L = A + L.SetUnconscious(0) + L.drowsyness = 0 + L.SetSleeping(0) + sleep(30) + var/list/flooring_near_beacon = list() + for(var/turf/open/floor in orange(1, beacon)) + flooring_near_beacon += floor + holder_obj.forceMove(pick(flooring_near_beacon)) + animate(holder_obj, pixel_z = 10, time = 50) + sleep(50) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + balloon3 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract") + balloon3.pixel_y = 10 + balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.cut_overlay(balloon) + holder_obj.add_overlay(balloon3) + sleep(4) + holder_obj.cut_overlay(balloon3) + A.anchored = FALSE // An item has to be unanchored to be extracted in the first place. + A.density = initial(A.density) + animate(holder_obj, pixel_z = 0, time = 5) + sleep(5) + A.forceMove(holder_obj.loc) + qdel(holder_obj) + if(uses_left <= 0) + qdel(src) /obj/item/fulton_core name = "extraction beacon signaller" diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 9a6cd477ad..7aa085f41b 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -2217,9 +2217,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.throw_alert("tempfeel", /atom/movable/screen/alert/cold, 2) if(-35 to -20) H.throw_alert("tempfeel", /atom/movable/screen/alert/cold, 1) - if(-20 to 0) //This is the sweet spot where air is considered normal + if(-20 to 1) //This is the sweet spot where air is considered normal H.clear_alert("tempfeel") - if(0 to 15) //When the air around you matches your body's temperature, you'll start to feel warm. + if(1 to 15) //When the air around you matches your body's temperature, you'll start to feel warm. H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 1) if(15 to 30) H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 2) diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm index ddeef393ac..71bc1020e2 100644 --- a/code/modules/movespeed/modifiers/mobs.dm +++ b/code/modules/movespeed/modifiers/mobs.dm @@ -15,6 +15,7 @@ /datum/movespeed_modifier/hunger variable = TRUE + blacklisted_movetypes = FLOATING|FLYING /datum/movespeed_modifier/slaughter multiplicative_slowdown = -1 diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index b4f1acbed4..41e22de9e6 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -148,6 +148,10 @@ /obj/item/pen/afterattack(obj/O, mob/living/user, proximity) . = ..() //Changing name/description of items. Only works if they have the UNIQUE_RENAME object flag set + try_modify_object(O, user, proximity) + +/obj/item/pen/proc/try_modify_object(obj/O, mob/living/user, proximity) + set waitfor = FALSE if(isobj(O) && proximity && (O.obj_flags & UNIQUE_RENAME)) var/penchoice = input(user, "What would you like to edit?", "Rename, change description or reset both?") as null|anything in list("Rename","Change description","Reset") if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) diff --git a/code/modules/pool/pool_controller.dm b/code/modules/pool/pool_controller.dm index 142690566b..ff52fb9fef 100644 --- a/code/modules/pool/pool_controller.dm +++ b/code/modules/pool/pool_controller.dm @@ -235,10 +235,10 @@ if(POOL_SCALDING) //Scalding M.adjust_bodytemperature(50,0,500) if(POOL_WARM) //Warm - M.adjust_bodytemperature(20,0,360) //Heats up mobs till the thermometer shows up + M.adjust_bodytemperature(20,0,323.15) //Heats up mobs till the thermometer shows up //Normal temp does nothing, because it's just room temperature water. if(POOL_COOL) - M.adjust_bodytemperature(-20,250) //Cools mobs till the thermometer shows up + M.adjust_bodytemperature(-20,274.15) //Cools mobs till the thermometer shows up if(POOL_FRIGID) //Freezing M.adjust_bodytemperature(-60) //cool mob at -35k per cycle, less would not affect the mob enough. if(M.bodytemperature <= 50 && !M.stat) diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 70cd28718c..9bf794a0a2 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -735,7 +735,10 @@ if(jb) to_chat(user, "Your mind goes blank as you attempt to use the potion.") return + try_transfer_mind(SM, user) +/obj/item/slimepotion/transference/proc/try_transfer_mind(mob/living/simple_animal/SM, mob/user) + set waitfor = FALSE prompted = 1 if(alert("This will permanently transfer your consciousness to [SM]. Are you sure you want to do this?",,"Yes","No")=="No") prompted = 0 diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 553cc2d043..2b212bd224 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -223,7 +223,6 @@ var/alert_type = null if(ispath(breathing_class)) breathing_class = breathing_classes[breathing_class] - var/list/gases = breathing_class.gases alert_category = breathing_class.high_alert_category alert_type = breathing_class.high_alert_datum danger_reagent = breathing_class.danger_reagent diff --git a/html/changelog.html b/html/changelog.html index f1834a647e..b1f30d9e83 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,40 @@ -->
+

11 December 2021

+

SandPoot updated:

+
    +
  • Borg speech is now centralized even inside lockers or something like that.
  • +
+

bunny232 updated:

+
    +
  • Cold blooded critters won't worry too much about the air around them being too hot even though their body temperature is the same as it.
  • +
  • The warm pool is no longer nearly boiling and the cool pool no longer goes below 0C.
  • +
+ +

09 December 2021

+

DeltaFire15 updated:

+
    +
  • Linters should no longer scream.
  • +
+

Linzolle updated:

+
    +
  • it now only snows on festivestation instead of every map
  • +
  • rain now triggers properly on spookystation
  • +
+

TripleShades updated:

+
    +
  • (Pubby) Gives Robotic's Lab Surgery a cautery
  • +
+

keronshb updated:

+
    +
  • Lets dynamic pick clock cultists midround
  • +
+

timothyteakettle updated:

+
    +
  • being fat no longer makes you slower when floating
  • +
+

05 December 2021

Arturlang updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 7be04803a8..fd720bcc02 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -30372,3 +30372,23 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. DeltaFire15: - bugfix: Fireman carry no longer drops the carried person if passing over a prone individual. +2021-12-09: + DeltaFire15: + - bugfix: Linters should no longer scream. + Linzolle: + - bugfix: it now only snows on festivestation instead of every map + - bugfix: rain now triggers properly on spookystation + TripleShades: + - rscadd: (Pubby) Gives Robotic's Lab Surgery a cautery + keronshb: + - rscadd: Lets dynamic pick clock cultists midround + timothyteakettle: + - bugfix: being fat no longer makes you slower when floating +2021-12-11: + SandPoot: + - bugfix: Borg speech is now centralized even inside lockers or something like that. + bunny232: + - bugfix: Cold blooded critters won't worry too much about the air around them being + too hot even though their body temperature is the same as it. + - balance: The warm pool is no longer nearly boiling and the cool pool no longer + goes below 0C. diff --git a/html/changelogs/AutoChangeLog-pr-15417.yml b/html/changelogs/AutoChangeLog-pr-15417.yml deleted file mode 100644 index 2008aeafa8..0000000000 --- a/html/changelogs/AutoChangeLog-pr-15417.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "DeltaFire15" -delete-after: True -changes: - - bugfix: "Linters should no longer scream." diff --git a/html/changelogs/AutoChangeLog-pr-15421.yml b/html/changelogs/AutoChangeLog-pr-15421.yml new file mode 100644 index 0000000000..ffc347c20e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-15421.yml @@ -0,0 +1,4 @@ +author: "DeltaFire15" +delete-after: True +changes: + - bugfix: "Linters should no longer complain about afterattack sleeps." diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/JTGSZwork.dm b/modular_citadel/code/modules/eventmaps/Spookystation/JTGSZwork.dm index 98ca2005dc..8143380262 100644 --- a/modular_citadel/code/modules/eventmaps/Spookystation/JTGSZwork.dm +++ b/modular_citadel/code/modules/eventmaps/Spookystation/JTGSZwork.dm @@ -483,7 +483,8 @@ end_message = "The downpour gradually slows until it stops." area_type = /area/eventmap/outside - target_trait = ZTRAIT_STATION + target_trait = ZTRAIT_LONGRAIN + probability = 90 barometer_predictable = TRUE