diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index c157be159a4e..c1472d132ff8 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -9908,8 +9908,9 @@ "doR" = ( /obj/machinery/power/apc/auto_name/directional/south, /obj/structure/cable, -/obj/effect/mapping_helpers/apc/cell_5k, /obj/machinery/plumbing/ooze_compressor, +/obj/effect/mapping_helpers/apc/cell_10k, +/obj/effect/mapping_helpers/apc/full_charge, /turf/open/floor/iron/white, /area/station/science/xenobiology) "doW" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 29a07339b6ba..43768adc6127 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -42678,6 +42678,8 @@ /obj/effect/turf_decal/siding/purple{ dir = 9 }, +/obj/effect/mapping_helpers/apc/cell_10k, +/obj/effect/mapping_helpers/apc/full_charge, /turf/open/floor/iron, /area/station/science/xenobiology) "kpy" = ( @@ -89711,6 +89713,11 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/engineering/atmos) +"vUy" = ( +/obj/machinery/duct, +/obj/machinery/light/floor/has_bulb, +/turf/open/floor/engine, +/area/station/science/xenobiology) "vUz" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, @@ -121069,7 +121076,7 @@ feF gcr pTC iLv -gvX +vUy duq fMl fMl @@ -121079,7 +121086,7 @@ taA fMl fMl xsN -gvX +vUy iLv mAt aAx @@ -122868,7 +122875,7 @@ woj rrU pTC iLv -gvX +vUy pQz fMl fMl @@ -122878,7 +122885,7 @@ taA fMl fMl esm -gvX +vUy iLv mAt cZl diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 6cae56e2d386..10dc68395186 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -1194,6 +1194,8 @@ }, /obj/machinery/power/apc/auto_name/directional/south, /obj/structure/cable, +/obj/effect/mapping_helpers/apc/cell_10k, +/obj/effect/mapping_helpers/apc/full_charge, /turf/open/floor/iron/white, /area/station/science/xenobiology) "aut" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index bcc8844dcc25..b477ff8f1011 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -13278,6 +13278,8 @@ /obj/effect/turf_decal/tile/purple/half/contrasted{ dir = 8 }, +/obj/effect/mapping_helpers/apc/cell_10k, +/obj/effect/mapping_helpers/apc/full_charge, /turf/open/floor/iron/white, /area/station/science/cytology) "eYw" = ( @@ -32577,8 +32579,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/duct, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/cable, /turf/open/floor/stone, /area/station/science/xenobiology) "lJh" = ( @@ -49930,6 +49930,10 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/effect/mapping_helpers/apc/cell_10k, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/effect/mapping_helpers/apc/full_charge, +/obj/structure/cable, /turf/open/floor/stone, /area/station/science/xenobiology) "rMz" = ( diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 096c0677e899..cef5e292f535 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -44309,6 +44309,16 @@ /obj/structure/cable, /turf/open/floor/carpet, /area/station/command/heads_quarters/hos) +"nme" = ( +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 1 + }, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/obj/effect/mapping_helpers/apc/cell_10k, +/obj/effect/mapping_helpers/apc/full_charge, +/turf/open/floor/stone, +/area/station/science/xenobiology) "nmf" = ( /obj/structure/table/wood, /obj/machinery/computer/security/wooden_tv, @@ -54558,14 +54568,6 @@ /obj/structure/cable, /turf/open/space/basic, /area/space/nearstation) -"qCW" = ( -/obj/effect/turf_decal/trimline/purple/filled/line{ - dir = 1 - }, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/turf/open/floor/stone, -/area/station/science/xenobiology) "qCX" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -67170,6 +67172,16 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron, /area/station/cargo/drone_bay) +"uAW" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/starboard/central) "uAZ" = ( /obj/effect/turf_decal/trimline/white/warning{ dir = 8 @@ -124257,7 +124269,7 @@ xPQ vud tml qVr -qCW +nme pbt xcM dtN @@ -126540,8 +126552,8 @@ hFC bwz xks qxm -icR -icR +uAW +lLW iix tuN tuN @@ -127825,7 +127837,7 @@ oys oys gDw gDw -nop +bay nop hPn eyE @@ -128080,8 +128092,8 @@ kHX gDw gDw gDw -nop -nop +bay +uJu nop oys oys diff --git a/_maps/~monkestation/RandomBars/Icebox/BarSM.dmm b/_maps/~monkestation/RandomBars/Icebox/BarSM.dmm index a283cdc68cd6..3b341440cb3c 100644 --- a/_maps/~monkestation/RandomBars/Icebox/BarSM.dmm +++ b/_maps/~monkestation/RandomBars/Icebox/BarSM.dmm @@ -1385,6 +1385,7 @@ /obj/effect/turf_decal/trimline/yellow/warning{ dir = 5 }, +/obj/effect/mapping_helpers/mail_sorting/service/bar, /turf/open/floor/pod/dark, /area/station/commons/lounge) "Vg" = ( diff --git a/_maps/~monkestation/RandomBars/Icebox/clockwork_icebox.dmm b/_maps/~monkestation/RandomBars/Icebox/clockwork_icebox.dmm index e2dfb4976558..a8890927c179 100644 --- a/_maps/~monkestation/RandomBars/Icebox/clockwork_icebox.dmm +++ b/_maps/~monkestation/RandomBars/Icebox/clockwork_icebox.dmm @@ -304,10 +304,11 @@ "oS" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/junction/flip{ +/obj/structure/cable, +/obj/structure/disposalpipe/sorting/mail/flip{ dir = 4 }, -/obj/structure/cable, +/obj/effect/mapping_helpers/mail_sorting/service/bar, /turf/open/floor/bronze, /area/station/commons/lounge) "qk" = ( @@ -412,16 +413,6 @@ }, /turf/open/floor/bronze/filled, /area/station/service/bar) -"va" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/mapping_helpers/mail_sorting/service/bar, -/obj/structure/cable, -/turf/open/floor/bronze, -/area/station/commons/lounge) "vh" = ( /obj/structure/chair/bronze{ dir = 1 @@ -993,7 +984,7 @@ Pz Xo cx vh -va +Xp TP EK EK diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm index 18a07c0d0197..b86931a592a5 100644 --- a/code/__DEFINES/maths.dm +++ b/code/__DEFINES/maths.dm @@ -7,6 +7,9 @@ #define IS_FINITE__UNSAFE(a) (a-a == a-a) #define IS_FINITE(a) (isnum(a) && IS_FINITE__UNSAFE(a)) + +#define IS_SAFE_NUM(a) (isnum(a) && !IS_INF__UNSAFE(a) && IS_FINITE__UNSAFE(a)) + // ------------------------------------ // Aight dont remove the rest diff --git a/code/__DEFINES/~monkestation/clock_cult.dm b/code/__DEFINES/~monkestation/clock_cult.dm index 8a1bb92a7446..e9c9424b50dd 100644 --- a/code/__DEFINES/~monkestation/clock_cult.dm +++ b/code/__DEFINES/~monkestation/clock_cult.dm @@ -5,5 +5,16 @@ #define SIGIL_TRANSMISSION_RANGE 4 +///base state the ark is created in, any state besides this will be a hostile environment +#define ARK_STATE_BASE 0 +///state for the grace period after the cult has reached its member count max and have enough activing anchoring crystals to summon +#define ARK_STATE_CHARGING 1 +///state for after the cult has been annouced as well as the first half of the assault +#define ARK_STATE_ACTIVE 2 +///state for the halfway point of ark activation +#define ARK_STATE_SUMMONING 3 +///the ark has either finished opening or been destroyed in this state +#define ARK_STATE_FINAL 4 + ///max damage taken per hit by "important" clock structures #define MAX_IMPORTANT_CLOCK_DAMAGE 30 diff --git a/code/__DEFINES/~monkestation/traits.dm b/code/__DEFINES/~monkestation/traits.dm index 0ab61cb18a9a..91ef22414513 100644 --- a/code/__DEFINES/~monkestation/traits.dm +++ b/code/__DEFINES/~monkestation/traits.dm @@ -14,6 +14,8 @@ #define TRAIT_ALL_SURGERIES "all_surgeries" /// Prevents the user from ever (unintentionally) failing a surgery step, and ensures they always have the maximum surgery speed. #define TRAIT_PERFECT_SURGEON "perfect_surgeon" +/// Prevents the user from casting spells using sign language. Works on both /datum/mind and /mob/living. +#define TRAIT_CANT_SIGN_SPELLS "cant_sign_spells" /// Station trait for when the clown has bridge access *shudders* #define STATION_TRAIT_CLOWN_BRIDGE "clown_bridge" diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 6d294a153cdc..2b2ee17563d0 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -201,6 +201,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_EXPANDED_FOV" = TRAIT_EXPANDED_FOV, "TRAIT_ANALGESIA" = TRAIT_ANALGESIA, "TRAIT_ON_ELEVATED_SURFACE" = TRAIT_ON_ELEVATED_SURFACE, + "TRAIT_CANT_SIGN_SPELLS" = TRAIT_CANT_SIGN_SPELLS, // monke edit ), /obj/item/bodypart = list( "TRAIT_PARALYSIS" = TRAIT_PARALYSIS, diff --git a/code/controllers/subsystem/polling.dm b/code/controllers/subsystem/polling.dm index 2bed96ac7d40..6d9821ca85be 100644 --- a/code/controllers/subsystem/polling.dm +++ b/code/controllers/subsystem/polling.dm @@ -181,6 +181,9 @@ SUBSYSTEM_DEF(polling) /datum/controller/subsystem/polling/proc/poll_ghost_candidates_for_mob(question, role, check_jobban, poll_time = 30 SECONDS, mob/target_mob, ignore_category = null, flashwindow = TRUE, pic_source, role_name_text) var/static/list/mob/currently_polling_mobs = list() + if(!isnull(target_mob) && !ismob(target_mob)) + stack_trace("attempted to use a non-mob as the target mob ([target_mob] | [target_mob.type])") + if(currently_polling_mobs.Find(target_mob)) return list() diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 2ef99e3dc5f2..99d5fd4e91c9 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -508,6 +508,7 @@ /obj/item/reagent_containers/syringe, /obj/item/slime_extract, /obj/item/swab, + /obj/item/stack/biomass // monke: make science bags able to hold biomass cubes )) /* diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index 736e438ab6c1..b1c08db0e731 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -1227,8 +1227,8 @@ var/particle_chance = ((PARTICLE_CHANCE_CONSTANT)/(reaction_energy-PARTICLE_CHANCE_CONSTANT)) + 1//Asymptopically approaches 100% as the energy of the reaction goes up. if(prob(PERCENT(particle_chance))) location.fire_nuclear_particle() - var/rad_power = max((FUSION_RAD_COEFFICIENT/instability) + 5000, 0) - radiation_pulse(location,rad_power) + var/rad_power = max((FUSION_RAD_COEFFICIENT/instability) + 250, 15000) //Wow! + radiation_pulse(location, rand(1,30), 9, 60, 2 SECONDS, rad_power, 1) // Nonmodular. Fixes fusion going wacko mode - makes it significantly harder to irradiate people through walls, and fixes the range issue. var/new_heat_capacity = air.heat_capacity() if(new_heat_capacity > MINIMUM_HEAT_CAPACITY && (air.temperature <= FUSION_MAXIMUM_TEMPERATURE || reaction_energy <= 0)) //If above FUSION_MAXIMUM_TEMPERATURE, will only adjust temperature for endothermic reactions. air.temperature = clamp(((air.temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY) diff --git a/code/modules/mob/living/basic/guardian/guardian_verbs.dm b/code/modules/mob/living/basic/guardian/guardian_verbs.dm index abf536503b2a..f2e81306c515 100644 --- a/code/modules/mob/living/basic/guardian/guardian_verbs.dm +++ b/code/modules/mob/living/basic/guardian/guardian_verbs.dm @@ -170,9 +170,8 @@ "Do you want to play as [owner.real_name]'s [chosen_guardian.theme.name]?", check_jobban = ROLE_PAI, poll_time = 10 SECONDS, - target_mob = src, + target_mob = owner, ignore_category = POLL_IGNORE_HOLOPARASITE, - pic_source = src, role_name_text = chosen_guardian.theme.name ) if (!LAZYLEN(ghost_candidates)) diff --git a/code/modules/mob/living/basic/pets/parrot/parrot_ai/parroting_action.dm b/code/modules/mob/living/basic/pets/parrot/parrot_ai/parroting_action.dm index 52f516ee4060..d1488a60b3bb 100644 --- a/code/modules/mob/living/basic/pets/parrot/parrot_ai/parroting_action.dm +++ b/code/modules/mob/living/basic/pets/parrot/parrot_ai/parroting_action.dm @@ -36,13 +36,6 @@ modified_speech = copytext_char(speech, 3) else - // monke start - stfu poly - var/speak_prob = speaking_pawn.ears.use_command ? 25 : 50 - for(var/channel in list(RADIO_KEY_COMMON, RADIO_TOKEN_COMMAND)) - if(channel in available_channels) - speak_prob = max(FLOOR(speak_prob * 0.4, 5), 5) - use_radio = prob(speak_prob) - // monke end if(HAS_CHANNEL_PREFIX) modified_speech = "[use_radio ? pick(available_channels) : ""][copytext_char(speech, 3)]" else diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index a7c6c3baed07..366e4d2e692a 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -470,8 +470,8 @@ colour = "grey" /datum/status_effect/stabilized/grey/tick() - for(var/mob/living/basic/slime/S in range(1, get_turf(owner))) - SEND_SIGNAL(S, COMSIG_FRIENDSHIP_CHANGE, owner, 1) + for(var/mob/living/basic/slime/new_friend in range(3, get_turf(owner))) + SEND_SIGNAL(new_friend, COMSIG_FRIENDSHIP_CHANGE, owner, 1) return ..() /datum/status_effect/stabilized/orange diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm index b72a363faaf9..77d567b78186 100644 --- a/code/modules/spells/spell.dm +++ b/code/modules/spells/spell.dm @@ -378,6 +378,8 @@ return FALSE if((invocation_type == INVOCATION_WHISPER || invocation_type == INVOCATION_SHOUT) && !living_owner.can_speak()) + if(HAS_TRAIT(living_owner, TRAIT_SIGN_LANG) && !HAS_MIND_TRAIT(living_owner, TRAIT_CANT_SIGN_SPELLS)) // monkestation edit: allow sign language users to cast spells + return TRUE if(feedback) to_chat(owner, span_warning("You can't get the words out to invoke [src]!")) return FALSE diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm index deae8acc20fe..6a8f4fa52bb8 100644 --- a/code/modules/vending/autodrobe.dm +++ b/code/modules/vending/autodrobe.dm @@ -14,6 +14,8 @@ "products" = list( /obj/item/clothing/under/costume/gladiator = 1, /obj/item/clothing/head/helmet/gladiator = 1, + /obj/item/clothing/head/viking/fake_helmet = 1, //monkestation edit + /obj/item/clothing/under/viking/fake_tunic = 1, //monkestation edit /obj/item/clothing/suit/toggle/labcoat/mad = 1, /obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1, /obj/item/clothing/head/bio_hood/plague = 1, diff --git a/html/changelogs/AutoChangeLog-pr-1638.yml b/html/changelogs/AutoChangeLog-pr-1638.yml new file mode 100644 index 000000000000..f4143ee6fb7c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1638.yml @@ -0,0 +1,16 @@ +author: "Absolucy" +delete-after: True +changes: + - rscadd: "Added a HUD that appears when hovering your mouse over ooze compressors, showing the current extract it is making, and the progress on making said extract." + - bugfix: "Fixed the normal slime extract menu coming up on ooze compressors after selecting a crossbreed." + - bugfix: "Fixed xenobiology machinery taking up absurd amounts of power while doing nothing." + - balance: "Increased range of stabilized grey extract from 1 to 3." + - qol: "Increased biomass cube stack size (5 -> 15)." + - qol: "Biocubes now fit in science bags." + - qol: "You can dump biocubes from a science bag into the biomass recycler." + - qol: "You can right click the slime market with a science bag to sell all the extracts without the confirmation prompt." + - rscadd: "Added balloon alerts to lots of xenobio-related actions." + - qol: "You can toggle ooze suckers directly via right click." + - qol: "You can now right click an active ooze compressor to cancel the current recipe." + - qol: "Slime mutation syringes now show whether they've been used or not in the examine text." + - bugfix: "Removing accessories from slimes now works properly." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1658.yml b/html/changelogs/AutoChangeLog-pr-1658.yml new file mode 100644 index 000000000000..6e6f666425ed --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1658.yml @@ -0,0 +1,5 @@ +author: "Absolucy" +delete-after: True +changes: + - bugfix: "Fix holoparasite resetting not working." + - code_imp: "Added a safety check that'll emit a (harmless) runtime if something tries to pass an invalid target mob to `SSpolling.poll_ghost_candidates_for_mob`." \ No newline at end of file diff --git a/html/changelogs/archive/2024-04.yml b/html/changelogs/archive/2024-04.yml index 00d92a7b69be..b77717544386 100644 --- a/html/changelogs/archive/2024-04.yml +++ b/html/changelogs/archive/2024-04.yml @@ -172,3 +172,33 @@ 2024-04-14: KnigTheThrasher: - rscadd: Added composters into every perma botany +2024-04-15: + Absolucy: + - qol: People who can't taste things also can't smell things. + - qol: Mute people who can still use sign language are now capable of using sign + language to invoke spells. Wizards are still too egotistical to even consider + doing so, tho. +2024-04-16: + KnigTheThrasher: + - bugfix: Fixed Icebox tests +2024-04-17: + Absolucy: + - qol: Heavily increases and randomizes the speech cooldown of parrots. + DimWhat: + - rscadd: Added two new tails to the anime quirk + KittyNoodle: + - balance: Hardlight spears can no longer be used with scarp. + - balance: Hardlight spear damage and wounding reduced. + - balance: Hardlight spear homing removed. + - balance: Hardlight spear embed chance halved + - balance: Hardlight spears now have cooldown after firing before you can use another + spear. + KnigTheThrasher: + - bugfix: Tram disposals should work now + TTNT789: + - rscadd: adds a viking costume to the autodrobe + Yawet330: + - bugfix: Fusion, why? + wraith-54321: + - balance: Clockwork airlocks lose their damage deflection when placed on reebe + - balance: Clockwork walls take half as long to deconstruct on reebe diff --git a/monkestation/code/__HELPERS/reagents.dm b/monkestation/code/__HELPERS/reagents.dm index 4803b2044356..5400bdedafed 100644 --- a/monkestation/code/__HELPERS/reagents.dm +++ b/monkestation/code/__HELPERS/reagents.dm @@ -1,7 +1,8 @@ ///Returns a random reagent object minus ethanol reagents /proc/get_random_reagent_id_unrestricted_non_ethanol() - var/static/list/random_reagents = list() - if(!random_reagents.len) + var/static/list/random_reagents + if(!random_reagents) + random_reagents = list() for(var/datum/reagent/reagent_path as anything in subtypesof(/datum/reagent)) if(istype(reagent_path, /datum/reagent/consumable) && !initial(reagent_path.bypass_restriction)) continue diff --git a/monkestation/code/game/objects/items/implants/hardlight.dm b/monkestation/code/game/objects/items/implants/hardlight.dm index 5d7518b40a53..c77e5885472c 100644 --- a/monkestation/code/game/objects/items/implants/hardlight.dm +++ b/monkestation/code/game/objects/items/implants/hardlight.dm @@ -234,12 +234,6 @@ back_spear_overlay.pixel_x = -32 . += back_spear_overlay - -/obj/item/gun/magic/hardlight_spear/can_trigger_gun(mob/living/user, akimbo_usage) // This isn't really a gun, so it shouldn't be checking for TRAIT_NOGUNS, a firing pin (pinless), or a trigger guard (guardless) - if(akimbo_usage) - return FALSE //this would be kinda weird while shooting someone down. - return TRUE - /obj/item/gun/magic/hardlight_spear/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) . = ..() if(!.) @@ -247,11 +241,16 @@ if(spears_left) var/obj/item/gun/magic/hardlight_spear/spear = new type spear.spears_left = spears_left - 1 + spear.apply_cooldown() qdel(src) user.put_in_hands(spear) else user.dropItemToGround(src, TRUE) +/obj/item/gun/magic/hardlight_spear/proc/apply_cooldown() + semicd = TRUE + addtimer(CALLBACK(src, PROC_REF(reset_semicd)), 1.5 SECONDS) + /obj/item/ammo_casing/magic/hardlight_spear name = "please god report this" desc = "Why god why" @@ -259,34 +258,23 @@ projectile_type = /obj/projectile/bullet/hardlight_spear heavy_metal = FALSE -/obj/item/ammo_casing/magic/hardlight_spear/ready_proj(atom/target, mob/living/user, quiet, zone_override, atom/fired_from) - if(!loaded_projectile) - return - - if(isliving(target)) - loaded_projectile.homing = TRUE - loaded_projectile.homing_turn_speed = 40 - loaded_projectile.set_homing_target(target) - - return ..() - /obj/projectile/bullet/hardlight_spear name = "hardlight spear" icon = 'monkestation/icons/obj/guns/projectiles.dmi' icon_state = "lightspear" - damage = 45 - armour_penetration = 10 - wound_bonus = 5 - bare_wound_bonus = 60 - wound_falloff_tile = 0 - embed_falloff_tile = 0 - speed = 0.4 //lower = faster + damage = 40 + armour_penetration = 5 + wound_bonus = -5 + bare_wound_bonus = 50 + wound_falloff_tile = -1 + embed_falloff_tile = -1 + speed = 0.7 //lower = faster shrapnel_type = /obj/item/shrapnel/bullet/spear light_outer_range = 1 light_power = 1 hitsound = 'sound/weapons/bladeslice.ogg' hitsound_wall = 'sound/weapons/parry.ogg' - embedding = list(embed_chance=100, fall_chance=2, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.5, pain_mult=5, jostle_pain_mult=6, rip_time=10) + embedding = list(embed_chance=70, fall_chance=6, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.5, pain_mult=2, jostle_pain_mult=3, rip_time=10) /obj/item/shrapnel/bullet/spear name = "hardlight spear" diff --git a/monkestation/code/modules/antagonists/clock_cult/machines/observation_console.dm b/monkestation/code/modules/antagonists/clock_cult/machines/observation_console.dm index be7c8c793de2..42b7795e2773 100644 --- a/monkestation/code/modules/antagonists/clock_cult/machines/observation_console.dm +++ b/monkestation/code/modules/antagonists/clock_cult/machines/observation_console.dm @@ -4,18 +4,23 @@ icon_screen = "ratvar1" icon_keyboard = "ratvar_key1" icon_state = "ratvarcomputer" + resistance_flags = INDESTRUCTIBLE clockwork = TRUE lock_override = TRUE circuit = /obj/item/circuitboard/machine/camera_console_ratvar + ///List of areas we are allowed to warp to + var/static/list/allowed_areas = list() /obj/machinery/computer/camera_advanced/ratvar/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) actions += new /datum/action/innate/clockcult/warp(src) + actions += new /datum/action/innate/clockcult/console_info(src) + actions += new /datum/action/innate/clockcult/add_warp_area(src, src) /obj/machinery/computer/camera_advanced/ratvar/Destroy() STOP_PROCESSING(SSobj, src) - . = ..() + return ..() /obj/machinery/computer/camera_advanced/ratvar/process(seconds_per_tick) if(SPT_PROB(3, seconds_per_tick)) @@ -52,7 +57,7 @@ /datum/action/innate/clockcult/warp/Activate() if(!isliving(owner)) return - if(GLOB.clock_ark && GLOB.clock_ark.current_state >= 2) //equal to ARK_STATE_ACTIVE, not using the defines so we can #undef them + if(GLOB.clock_ark && GLOB.clock_ark.current_state >= ARK_STATE_ACTIVE) to_chat(owner, span_brass("You cannot warp while the gateway is opening!")) return if(warping) @@ -76,14 +81,34 @@ warping = TRUE button_icon_state = "warp_cancel" build_all_button_icons(UPDATE_BUTTON_ICON) - if(do_after(cam_user, 5 SECONDS, target = target_loc, extra_checks = CALLBACK(src, PROC_REF(special_check)))) + if(do_after(cam_user, 5 SECONDS, target = target_loc, extra_checks = CALLBACK(src, PROC_REF(warping_check)))) try_servant_warp(cam_user, target_loc) button_icon_state = "warp_down" build_all_button_icons(UPDATE_BUTTON_ICON) warping = FALSE -/datum/action/innate/clockcult/warp/proc/special_check() +/datum/action/innate/clockcult/warp/proc/warping_check() return warping +/datum/action/innate/clockcult/console_info + name = "Console info" + desc = "Get info on this console." + button_icon_state = "console_info" + +/datum/action/innate/clockcult/add_warp_area + name = "Add Warp Area" + desc = "Add an additional area you can warp to." + button_icon_state = "Spatial Warp" + ///Ref to the console we are linked to + var/obj/machinery/computer/camera_advanced/ratvar/linked_console + +/datum/action/innate/clockcult/add_warp_area/New(Target, console) + . = ..() + linked_console = console + +/datum/action/innate/clockcult/add_warp_area/Destroy() + linked_console = null + return ..() + /obj/item/circuitboard/machine/camera_console_ratvar build_path = /obj/machinery/computer/camera_advanced/ratvar diff --git a/monkestation/code/modules/antagonists/clock_cult/structures/airlock.dm b/monkestation/code/modules/antagonists/clock_cult/structures/airlock.dm index 0b678db0a8e0..c14bf31356c6 100644 --- a/monkestation/code/modules/antagonists/clock_cult/structures/airlock.dm +++ b/monkestation/code/modules/antagonists/clock_cult/structures/airlock.dm @@ -11,6 +11,11 @@ req_access = list(ACCESS_CLOCKCULT) damage_deflection = 10 +/obj/machinery/door/airlock/bronze/clock/Initialize(mapload) + . = ..() + if(on_reebe(src)) + damage_deflection = 0 + /obj/machinery/door/airlock/bronze/clock/canAIControl(mob/user) return (IS_CLOCK(user) && !isAllPowerCut()) diff --git a/monkestation/code/modules/antagonists/clock_cult/structures/the_ark.dm b/monkestation/code/modules/antagonists/clock_cult/structures/the_ark.dm index 48fb92ad8923..a10d48c3f560 100644 --- a/monkestation/code/modules/antagonists/clock_cult/structures/the_ark.dm +++ b/monkestation/code/modules/antagonists/clock_cult/structures/the_ark.dm @@ -1,11 +1,6 @@ GLOBAL_DATUM(clock_ark, /obj/structure/destructible/clockwork/the_ark) //set to be equal to the ark on creation if none GLOBAL_VAR_INIT(ratvar_risen, FALSE) -#define ARK_STATE_BASE 0 //base state the ark is created in, any state besides this will be a hostile environment -#define ARK_STATE_CHARGING 1 //state for the grace period after the cult has reached its member count max and have an active anchor crystal -#define ARK_STATE_ACTIVE 2 //state for after the cult has been annouced as well as the first half of the assault -#define ARK_STATE_SUMMONING 3 //state for the halfway point of ark activation -#define ARK_STATE_FINAL 4 //the ark has either finished opening or been destroyed in this state #define ARK_READY_PERIOD 300 SECONDS //how long until the cult is annouced after they reach max members, 5 minutes #define ARK_GRACE_PERIOD 210 SECONDS //how long until the portals open after the cult is annouced, 3 minutes 30 seconds #define ARK_ASSAULT_PERIOD 600 //how long the crew has to destroy the ark after the assault begins, 10 minutes @@ -239,11 +234,6 @@ GLOBAL_VAR_INIT(ratvar_risen, FALSE) explosion(pick(GLOB.abscond_markers), 50, 40, 30, 30, FALSE, TRUE) SSticker.force_ending = TRUE -#undef ARK_STATE_BASE -#undef ARK_STATE_CHARGING -#undef ARK_STATE_ACTIVE -#undef ARK_STATE_SUMMONING -#undef ARK_STATE_FINAL #undef ARK_READY_PERIOD #undef ARK_GRACE_PERIOD #undef ARK_ASSAULT_PERIOD diff --git a/monkestation/code/modules/antagonists/clock_cult/turf.dm b/monkestation/code/modules/antagonists/clock_cult/turf.dm index c8e33fe5e01d..8bd077ff4d42 100644 --- a/monkestation/code/modules/antagonists/clock_cult/turf.dm +++ b/monkestation/code/modules/antagonists/clock_cult/turf.dm @@ -195,6 +195,9 @@ //do the deconstruction stuff, this really should be a proc on Rwalls as well /turf/closed/wall/clockwork/proc/next_decon_state(obj/item/used_tool, mob/user, current_state, set_state, sent_message, use_time = 4 SECONDS) + if(on_reebe(src)) + use_time = round(use_time / 2, 0.1) //each stage takes half as long on reebe + if(used_tool.use_tool(src, user, use_time, volume=100)) if(!istype(src, /turf/closed/wall/clockwork) || d_state != current_state) return TRUE diff --git a/monkestation/code/modules/antagonists/wizard/wizard_antagonist.dm b/monkestation/code/modules/antagonists/wizard/wizard.dm similarity index 90% rename from monkestation/code/modules/antagonists/wizard/wizard_antagonist.dm rename to monkestation/code/modules/antagonists/wizard/wizard.dm index b644296388a7..ec0c23effe79 100644 --- a/monkestation/code/modules/antagonists/wizard/wizard_antagonist.dm +++ b/monkestation/code/modules/antagonists/wizard/wizard.dm @@ -1,3 +1,11 @@ +/datum/antagonist/wizard/on_gain() + . = ..() + ADD_TRAIT(owner, TRAIT_CANT_SIGN_SPELLS, REF(src)) + +/datum/antagonist/wizard/on_removal() + REMOVE_TRAITS_IN(owner, REF(src)) + return ..() + /datum/antagonist/wizard/traitor // traitors that complete a final objective to become a wizard, this subtype is mainly for wizard look things name = "\improper Syndicate Space Wizard" roundend_category = "syndicate wizards/witches" diff --git a/monkestation/code/modules/mob/dead/new_player/sprite_accessories/anime.dm b/monkestation/code/modules/mob/dead/new_player/sprite_accessories/anime.dm index 2ffaa4b5f2ef..6faea383a344 100644 --- a/monkestation/code/modules/mob/dead/new_player/sprite_accessories/anime.dm +++ b/monkestation/code/modules/mob/dead/new_player/sprite_accessories/anime.dm @@ -165,3 +165,13 @@ /datum/sprite_accessory/anime_bottom/bunny name = "Bunny Puff" icon_state = "playbunny" + +/datum/sprite_accessory/anime_bottom/mouse + name = "Mouse Tail" + icon_state = "mouse" + color_src = null + +/datum/sprite_accessory/anime_bottom/plug + name = "Plug" + icon_state = "plug" + hasinner = TRUE diff --git a/monkestation/code/modules/mob/living/basic/pets/parrot/parrot_ai/parroting_action.dm b/monkestation/code/modules/mob/living/basic/pets/parrot/parrot_ai/parroting_action.dm new file mode 100644 index 000000000000..96c6ed44340c --- /dev/null +++ b/monkestation/code/modules/mob/living/basic/pets/parrot/parrot_ai/parroting_action.dm @@ -0,0 +1,5 @@ +/datum/ai_behavior/perform_speech/parrot + action_cooldown = 45 SECONDS // SHUT UP + +/datum/ai_behavior/perform_speech/parrot/perform(seconds_per_tick, datum/ai_controller/controller, ...) + controller.behavior_cooldowns[src] = world.time + rand(45 SECONDS, 3 MINUTES) diff --git a/monkestation/code/modules/pollution/pollution.dm b/monkestation/code/modules/pollution/pollution.dm index 548a51c0e5fd..47c35eb04491 100644 --- a/monkestation/code/modules/pollution/pollution.dm +++ b/monkestation/code/modules/pollution/pollution.dm @@ -38,6 +38,8 @@ /// When a user smells this pollution /datum/pollution/proc/smell_act(mob/living/sniffer) + if(HAS_TRAIT(sniffer, TRAIT_AGEUSIA)) // can't taste, can't smell. + return var/list/singleton_cache = SSpollution.singletons var/datum/pollutant/dominant_pollutant var/dominiant_smell_power diff --git a/monkestation/code/modules/slimecore/items/mutation_syringe.dm b/monkestation/code/modules/slimecore/items/mutation_syringe.dm index fd3998c06be8..75883df8a3ff 100644 --- a/monkestation/code/modules/slimecore/items/mutation_syringe.dm +++ b/monkestation/code/modules/slimecore/items/mutation_syringe.dm @@ -5,25 +5,41 @@ icon = 'monkestation/code/modules/slimecore/icons/slimes.dmi' icon_state = "mutation_syringe" - ///the path we infuse + w_class = WEIGHT_CLASS_SMALL + + /// Type path of the slime trait to infuse. var/datum/slime_trait/infusing_trait_path - /// have we been used? - var/used = FALSE + /// Amount of uses remaining. + var/uses = 1 +/obj/item/slime_mutation_syringe/examine(mob/user) + . = ..() + if(uses) + . += span_notice("It has [uses] uses left.") + else + . += span_warning("It has been completely used up.") /obj/item/slime_mutation_syringe/afterattack(atom/target, mob/user, proximity_flag, click_parameters) . = ..() - if(!infusing_trait_path || used) + if(!ispath(infusing_trait_path)) + return + if(!uses) + user.balloon_alert(user, "used up") + to_chat(user, span_warning("[src] has been completely used up!")) return if(!istype(target, /mob/living/basic/slime)) return var/mob/living/basic/slime/slime = target if(slime.add_trait(infusing_trait_path)) - used = TRUE - icon_state = "mutation_syringe-empty" + uses-- + update_icon_state() + user.balloon_alert_to_viewers("injected mutator") to_chat(user, span_notice("You inject [target] with [src].")) +/obj/item/slime_mutation_syringe/update_icon_state() + . = ..() + icon_state = uses ? initial(icon_state) : "[initial(icon_state)]-empty" /obj/item/slime_mutation_syringe/cleaner name = "cleaner slime mutation syringe" @@ -64,19 +80,32 @@ icon = 'monkestation/code/modules/slimecore/icons/slimes.dmi' icon_state = "mutation_syringe" - /// have we been used? - var/used = FALSE + /// Amount of uses remaining. + var/uses = 1 +/obj/item/slime_mutation_syringe_random/examine(mob/user) + . = ..() + if(uses) + . += span_notice("It has [uses] uses left.") + else + . += span_warning("It has been completely used up.") /obj/item/slime_mutation_syringe_random/afterattack(atom/target, mob/user, proximity_flag, click_parameters) . = ..() - if(used) + if(!uses) + user.balloon_alert(user, "used up") + to_chat(user, span_warning("[src] has been completely used up!")) return if(!istype(target, /mob/living/basic/slime)) return var/mob/living/basic/slime/slime = target slime.start_mutating(TRUE) - used = TRUE - icon_state = "mutation_syringe-empty" + uses-- + update_icon_state() + user.balloon_alert_to_viewers("injected mutator") to_chat(user, span_notice("You inject [target] with [src].")) + +/obj/item/slime_mutation_syringe_random/update_icon_state() + . = ..() + icon_state = uses ? initial(icon_state) : "[initial(icon_state)]-empty" diff --git a/monkestation/code/modules/slimecore/machines/biomass_recycler.dm b/monkestation/code/modules/slimecore/machines/biomass_recycler.dm index be89b669ffe2..bdb0a50209e1 100644 --- a/monkestation/code/modules/slimecore/machines/biomass_recycler.dm +++ b/monkestation/code/modules/slimecore/machines/biomass_recycler.dm @@ -34,37 +34,38 @@ GLOBAL_LIST_INIT(biomass_unlocks, list()) power_change() return TOOL_ACT_TOOLTYPE_SUCCESS -/obj/machinery/biomass_recycler/attackby(obj/item/O, mob/user, params) - if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", O)) - return - - if(default_pry_open(O)) - return - - if(default_deconstruction_crowbar(O)) +/obj/machinery/biomass_recycler/attackby(obj/item/item, mob/user, params) + . = ..() + if(. || default_deconstruction_screwdriver(user, "grinder_open", "grinder", item) || default_pry_open(item) || default_deconstruction_crowbar(item) || machine_stat) return - - if(machine_stat) //NOPOWER etc + if(istype(item, /obj/item/storage/bag/xeno)) + var/total_biomass = 0 + for(var/obj/item/stack/biomass/biomass in item) + total_biomass += biomass.amount + stored_matter += biomass.amount + qdel(biomass) + if(total_biomass > 0) + to_chat(user, span_notice("You dump [total_biomass] cube\s of biomass from [item] into [src].")) + user.balloon_alert_to_viewers("inserted biomass") return - - if(HAS_TRAIT(O, TRAIT_NODROP)) + else if(HAS_TRAIT(item, TRAIT_NODROP)) return - - if(istype(O, /obj/item/stack/biomass)) - var/obj/item/stack/biomass/biomass = O + else if(istype(item, /obj/item/stack/biomass)) + var/obj/item/stack/biomass/biomass = item to_chat(user, span_notice("You insert [biomass.amount] cube\s of biomass into [src].")) + user.balloon_alert_to_viewers("inserted biomass") stored_matter += biomass.amount qdel(biomass) return var/can_recycle for(var/recycable_type in recyclable_types) - if(istype(O, recycable_type)) + if(istype(item, recycable_type)) can_recycle = recycable_type break if(can_recycle) - recycle(O, user, can_recycle) + recycle(item, user, can_recycle) /obj/machinery/biomass_recycler/MouseDrop_T(mob/living/target, mob/living/user) if(!istype(target)) @@ -125,6 +126,7 @@ GLOBAL_LIST_INIT(biomass_unlocks, list()) var/spawn_type = item_names[pick] if(stored_matter < printable_types[spawn_type]) to_chat(user, span_warning("[src] does not have enough stored biomass for that! It currently has [stored_matter] out of [printable_types[spawn_type]] unit\s required.")) + balloon_alert(user, "not enough biomass") return var/spawned = new spawn_type(user.loc) @@ -139,7 +141,7 @@ GLOBAL_LIST_INIT(biomass_unlocks, list()) icon = 'monkestation/code/modules/slimecore/icons/stack_objects.dmi' icon_state = "biomass" base_icon_state = "biomass" - max_amount = 5 + max_amount = 15 singular_name = "biomass cube" merge_type = /obj/item/stack/biomass flags_1 = CONDUCT_1 diff --git a/monkestation/code/modules/slimecore/machines/extract_requestor.dm b/monkestation/code/modules/slimecore/machines/extract_requestor.dm index 1e254d48b130..faed4fff0690 100644 --- a/monkestation/code/modules/slimecore/machines/extract_requestor.dm +++ b/monkestation/code/modules/slimecore/machines/extract_requestor.dm @@ -6,8 +6,8 @@ base_icon_state = "civilian_pad" density = TRUE use_power = IDLE_POWER_USE - idle_power_usage = 10 - active_power_usage = 2000 + idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION + active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION circuit = /obj/item/circuitboard/machine/slime_extract_requestor var/obj/machinery/computer/slime_market/console var/list/current_requests = list() diff --git a/monkestation/code/modules/slimecore/machines/ooze_compressor/ooze_compressor.dm b/monkestation/code/modules/slimecore/machines/ooze_compressor/ooze_compressor.dm index 8baef0b70d46..5ed9b18e56d8 100644 --- a/monkestation/code/modules/slimecore/machines/ooze_compressor/ooze_compressor.dm +++ b/monkestation/code/modules/slimecore/machines/ooze_compressor/ooze_compressor.dm @@ -18,12 +18,13 @@ icon = 'monkestation/code/modules/slimecore/icons/machinery.dmi' base_icon_state = "cross_compressor" icon_state = "cross_compressor" - category="Distribution" + category = "Distribution" anchored = TRUE - idle_power_usage = 10 - active_power_usage = 1000 + use_power = IDLE_POWER_USE + idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION + active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION buffer = 5000 reagent_flags = NO_REACT @@ -74,9 +75,12 @@ /obj/machinery/plumbing/ooze_compressor/add_context(atom/source, list/context, obj/item/held_item, mob/user) . = ..() - context[SCREENTIP_CONTEXT_ALT_LMB] = "Toggle Repeated Extract Compression" - context[SCREENTIP_CONTEXT_LMB] = "Select a normal extract to make" - context[SCREENTIP_CONTEXT_RMB] = "Select a crossbreed to make" + if(current_recipe) + context[SCREENTIP_CONTEXT_RMB] = "Cancel current recipe" + else + context[SCREENTIP_CONTEXT_LMB] = "Select a normal extract to make" + context[SCREENTIP_CONTEXT_RMB] = "Select a crossbreed to make" + context[SCREENTIP_CONTEXT_CTRL_LMB] = "[repeat_recipe ? "Disable" : "Enable"] repeated extract compression" return CONTEXTUAL_SCREENTIP_SET /obj/machinery/plumbing/ooze_compressor/create_reagents(max_vol, flags) @@ -86,10 +90,7 @@ /obj/machinery/plumbing/ooze_compressor/update_icon_state() . = ..() - if(compressing) - icon_state = "cross_compressor_running" - else - icon_state = base_icon_state + icon_state = compressing ? "cross_compressor_running" : base_icon_state /obj/machinery/plumbing/ooze_compressor/examine(mob/user) . = ..() @@ -152,44 +153,73 @@ update_appearance() if(holder.total_volume == 0 && !compressing) //we were emptying, but now we aren't holder.flags |= NO_REACT + manage_hud_as_needed() return NONE -/obj/machinery/plumbing/ooze_compressor/process(seconds_per_tick) - if(!compressing) - use_power(active_power_usage * seconds_per_tick) - /obj/machinery/plumbing/ooze_compressor/proc/compress_recipe() compressing = TRUE update_appearance() if(!repeat_recipe) reagents_for_recipe = list() + manage_hud_as_needed() + update_power_usage() addtimer(CALLBACK(src, PROC_REF(finish_compressing)), 3 SECONDS) /obj/machinery/plumbing/ooze_compressor/proc/finish_compressing() for(var/i in 1 to current_recipe.created_amount) - new current_recipe.output_item(loc) + new current_recipe.output_item(drop_location()) compressing = FALSE update_appearance() reagents.clear_reagents() if(!repeat_recipe) current_recipe = null + update_power_usage() + manage_hud_as_needed() + +/obj/machinery/plumbing/ooze_compressor/proc/update_power_usage() + if(compressing) + update_use_power(ACTIVE_POWER_USE) + else if(current_recipe) + update_use_power(IDLE_POWER_USE) + else + update_use_power(NO_POWER_USE) /obj/machinery/plumbing/ooze_compressor/attack_hand(mob/living/user, list/modifiers) . = ..() + if(. || !can_interact(user)) + return + if(!anchored) + balloon_alert(user, "unanchored!") + return TRUE if(change_recipe(user)) reagents.clear_reagents() + return TRUE /obj/machinery/plumbing/ooze_compressor/attack_hand_secondary(mob/living/user, list/modifiers) . = ..() - if(change_recipe(user, TRUE)) - reagents.clear_reagents() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN || !can_interact(user)) + return + . = SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + if(!anchored) + balloon_alert(user, "unanchored!") + return + if(current_recipe) + repeat_recipe = FALSE + if(!compressing) + current_recipe = null + reagents.clear_reagents() + update_power_usage() + balloon_alert_to_viewers("cancelled recipe") + else + if(change_recipe(user, TRUE)) + reagents.clear_reagents() -/obj/machinery/plumbing/ooze_compressor/AltClick(mob/user) - if(anchored) - visible_message(span_notice("[user] presses a button turning the repeat recipe system [repeat_recipe ? "Off" : "On"]")) +/obj/machinery/plumbing/ooze_compressor/CtrlClick(mob/user) + if(anchored && can_interact(user)) repeat_recipe = !repeat_recipe - return TRUE - . = ..() + balloon_alert_to_viewers("[repeat_recipe ? "enabled" : "disabled"] repeating") + visible_message(span_notice("[user] presses a button turning the repeat recipe system [repeat_recipe ? span_green("on") : span_red("off")]")) + return ..() /obj/machinery/plumbing/ooze_compressor/proc/change_recipe(mob/user, cross_breed = FALSE) var/choice @@ -201,14 +231,14 @@ else choice = show_radial_menu(user, src, recipe_choices, require_near = TRUE, tooltips = TRUE) - if(!(choice in choice_to_datum)) - return - - if(compressing) + if(compressing || !(choice in choice_to_datum)) return current_recipe = choice_to_datum[choice] reagents_for_recipe = list() reagents_for_recipe += current_recipe.required_oozes + balloon_alert_to_viewers("set extract recipe") + manage_hud_as_needed() + update_power_usage() #undef CROSSBREED_BASE_PATHS diff --git a/monkestation/code/modules/slimecore/machines/ooze_compressor/ooze_compressor_hud.dm b/monkestation/code/modules/slimecore/machines/ooze_compressor/ooze_compressor_hud.dm new file mode 100644 index 000000000000..bec098500afa --- /dev/null +++ b/monkestation/code/modules/slimecore/machines/ooze_compressor/ooze_compressor_hud.dm @@ -0,0 +1,127 @@ +/obj/machinery/plumbing/ooze_compressor + var/image/hover_appearance + var/datum/atom_hud/alternate_appearance/basic/ooze_compressor/hover_popup + +/obj/machinery/plumbing/ooze_compressor/Destroy() + QDEL_NULL(hover_popup) + return ..() + +/obj/machinery/plumbing/ooze_compressor/MouseEntered(location, control, params) + . = ..() + if(!QDELETED(usr) && anchored) + manage_hud_as_needed() + hover_popup?.show_to(usr) + +/obj/machinery/plumbing/ooze_compressor/MouseExited(location, control, params) + . = ..() + if(!QDELETED(usr) && !QDELETED(hover_popup)) + hover_popup.hide_from(usr) + manage_hud_as_needed(cleanup = TRUE) + +/obj/machinery/plumbing/ooze_compressor/set_anchored(anchorvalue) + . = ..() + if(!anchored) + manage_hud_as_needed() + +/obj/machinery/plumbing/ooze_compressor/proc/manage_hud_as_needed(cleanup = FALSE) + if(!anchored || (cleanup && !QDELETED(hover_popup) && !length(hover_popup.hud_users_all_z_levels))) + // don't bother keeping the hud around if it isn't needed + QDEL_NULL(hover_popup) + return + setup_hud() + +/obj/machinery/plumbing/ooze_compressor/proc/setup_hud() + // delete old hud if it exists and collect a list of its users + var/list/mob/old_users + if(!QDELETED(hover_popup)) + old_users = hover_popup.hud_users_all_z_levels.Copy() + QDEL_NULL(hover_popup) + + if(!length(GLOB.compressor_recipe_previews)) // we can't initialize this normally bc it will shit itself if initialized early + GLOB.compressor_recipe_previews = create_compressor_previews() + + // setup new hover appearance + if(current_recipe) + hover_appearance = image(GLOB.compressor_recipe_previews[current_recipe.type], loc = src, layer = CHAT_LAYER) + hover_appearance.add_filter("extract_outline", 1, outline_filter(size = 1, color = COLOR_WHITE)) + hover_appearance.pixel_y = 10 + else + hover_appearance = image(loc = src, layer = CHAT_LAYER) + hover_appearance.pixel_y = 18 + SET_PLANE_EXPLICIT(hover_appearance, HUD_PLANE, src) + hover_appearance.plane = HUD_PLANE + hover_appearance.appearance_flags = RESET_COLOR + + // now setup the actual hud + hover_popup = add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/ooze_compressor, "ooze_compressor", hover_appearance) + // and the cooldown maptext + refresh_info_maptext() + + for(var/mob/old_user as anything in old_users) + if(QDELETED(old_user)) + continue + hover_popup.show_to(old_user) + +/obj/machinery/plumbing/ooze_compressor/proc/refresh_info_maptext() + if(!hover_popup) + return + if(!hover_popup.info_maptext) + hover_popup.info_maptext = image(loc = src, layer = CHAT_LAYER + 0.1) + SET_PLANE_EXPLICIT(hover_popup.info_maptext, HUD_PLANE, src) + hover_popup.info_maptext.plane = HUD_PLANE + hover_popup.info_maptext.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA | KEEP_APART + hover_popup.info_maptext.maptext_height = world.icon_size / 2 + hover_popup.info_maptext.maptext_y = 4 + var/maptext + if(compressing) + hover_popup.info_maptext.maptext_width = world.icon_size * 2 + hover_popup.info_maptext.maptext_x = -(world.icon_size / 2) + maptext = "compressing..." + else + hover_popup.info_maptext.maptext_width = world.icon_size + hover_popup.info_maptext.maptext_x = 0 + maptext = current_recipe ? "[get_progress()]%" : "inactive" + hover_popup.info_maptext.maptext = MAPTEXT_TINY_UNICODE("[maptext]") + hover_popup.give_info() + +/obj/machinery/plumbing/ooze_compressor/proc/get_progress() + if(!current_recipe || compressing) + return 0 + var/current = 0 + var/needed = 0 + for(var/datum/reagent/reagent as anything in current_recipe.required_oozes) + needed += current_recipe.required_oozes[reagent] || 0 + for(var/datum/reagent/listed_reagent as anything in reagents.reagent_list) + if(listed_reagent.type != reagent) + continue + current += listed_reagent.volume + return clamp(round((current / needed) * 100, 1), 0, 100) + +/datum/atom_hud/alternate_appearance/basic/ooze_compressor + var/image/info_maptext + +/datum/atom_hud/alternate_appearance/basic/ooze_compressor/show_to(mob/new_viewer) + . = ..() + if(info_maptext && !QDELETED(new_viewer) && !QDELETED(new_viewer.client)) + new_viewer.client.images |= info_maptext + +/datum/atom_hud/alternate_appearance/basic/ooze_compressor/hide_from(mob/former_viewer, absolute) + . = ..() + if(info_maptext && !QDELETED(former_viewer) && !QDELETED(former_viewer.client)) + former_viewer.client.images -= info_maptext + +/datum/atom_hud/alternate_appearance/basic/ooze_compressor/proc/give_info() + if(!info_maptext) + return + for(var/mob/user as anything in hud_users_all_z_levels) + if(QDELETED(user) || QDELETED(user.client)) + continue + user.client.images |= info_maptext + +/datum/atom_hud/alternate_appearance/basic/ooze_compressor/proc/take_cooldowns() + if(!info_maptext) + return + for(var/mob/user as anything in hud_users_all_z_levels) + if(QDELETED(user) || QDELETED(user.client)) + continue + user.client.images -= info_maptext diff --git a/monkestation/code/modules/slimecore/machines/ooze_compressor/recipes/_base_recipe.dm b/monkestation/code/modules/slimecore/machines/ooze_compressor/recipes/_base_recipe.dm index a60288732cb3..dbc827f25b35 100644 --- a/monkestation/code/modules/slimecore/machines/ooze_compressor/recipes/_base_recipe.dm +++ b/monkestation/code/modules/slimecore/machines/ooze_compressor/recipes/_base_recipe.dm @@ -1,6 +1,18 @@ +GLOBAL_LIST_EMPTY_TYPED(compressor_recipe_previews, /image) + /datum/compressor_recipe var/list/required_oozes = list() var/obj/item/output_item var/created_amount = 1 /datum/compressor_recipe/crossbreed + +/proc/create_compressor_previews() + . = list() + for(var/datum/compressor_recipe/recipe as anything in subtypesof(/datum/compressor_recipe)) + var/output_type = recipe::output_item + if(!ispath(output_type, /obj/item)) + continue + var/obj/item/preview = new output_type(null) + .[recipe] = image(getFlatIcon(preview)) + qdel(preview) diff --git a/monkestation/code/modules/slimecore/machines/ooze_sucker.dm b/monkestation/code/modules/slimecore/machines/ooze_sucker.dm index 216edb7dfdbe..69f2f497ee76 100644 --- a/monkestation/code/modules/slimecore/machines/ooze_sucker.dm +++ b/monkestation/code/modules/slimecore/machines/ooze_sucker.dm @@ -7,10 +7,13 @@ icon_state = "ooze_sucker" anchored = FALSE density = FALSE - idle_power_usage = 10 - active_power_usage = 1000 + + use_power = IDLE_POWER_USE + idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.1 + active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.15 + buffer = 3000 - category="Distribution" + category = "Distribution" reagent_flags = NO_REACT /// Pump is turned on by engineer, etc. @@ -31,6 +34,9 @@ /// Additional ratio of liquid volume to drain var/drain_percent = 1 + /// Whether draining was performed last process or not. + var/drained_last_process = FALSE + /obj/machinery/plumbing/ooze_sucker/Initialize(mapload, bolt, layer) . = ..() AddComponent(/datum/component/plumbing/simple_supply, bolt, layer) @@ -68,6 +74,22 @@ turned_on = FALSE update_icon_state() +/obj/machinery/plumbing/ooze_sucker/create_reagents(max_vol, flags) + . = ..() + RegisterSignals(reagents, list(COMSIG_REAGENTS_REM_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_CLEAR_REAGENTS, COMSIG_REAGENTS_REACTED), PROC_REF(on_reagent_change)) + RegisterSignal(reagents, COMSIG_QDELETING, PROC_REF(on_reagents_del)) + +/// Handles properly detaching signal hooks. +/obj/machinery/plumbing/ooze_sucker/proc/on_reagents_del(datum/reagents/reagents) + SIGNAL_HANDLER + UnregisterSignal(reagents, list(COMSIG_REAGENTS_REM_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_CLEAR_REAGENTS, COMSIG_REAGENTS_REACTED, COMSIG_QDELETING)) + return NONE + +/// Handles ensuring power usage becomes idle when reagents are full. +/obj/machinery/plumbing/ooze_sucker/proc/on_reagent_change(datum/reagents/holder, ...) + SIGNAL_HANDLER + update_power_usage() + return NONE /obj/machinery/plumbing/ooze_sucker/proc/toggle_state() turned_on = !turned_on @@ -109,12 +131,25 @@ // We're good, actually pump. for(var/turf/affected_turf as anything in affected_turfs) pump_turf(affected_turf, seconds_per_tick, multiplier) + update_power_usage() + +/obj/machinery/plumbing/ooze_sucker/proc/update_power_usage() + if(!turned_on) + update_use_power(NO_POWER_USE) + else if(reagents && reagents.total_volume >= reagents.maximum_volume) + update_use_power(IDLE_POWER_USE) + else if(drained_last_process) + update_use_power(ACTIVE_POWER_USE) + else + update_use_power(IDLE_POWER_USE) /obj/machinery/plumbing/ooze_sucker/proc/pump_turf(turf/affected_turf, seconds_per_tick, multiplier) if(processes < processes_required) processes++ return processes = 0 + drained_last_process = FALSE + if(!affected_turf.liquids || !affected_turf.liquids.liquid_group) return @@ -128,3 +163,12 @@ if(!targeted_group.reagents_per_turf) return targeted_group.transfer_specific_reagents(reagents, target_value, reagents_to_check = typesof(/datum/reagent/slime_ooze), merge = TRUE) + drained_last_process = TRUE + +/obj/machinery/plumbing/ooze_sucker/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + toggle_state() + balloon_alert_to_viewers("[turned_on ? "enabled" : "disabled"] ooze sucker") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN diff --git a/monkestation/code/modules/slimecore/machines/slime_grinder.dm b/monkestation/code/modules/slimecore/machines/slime_grinder.dm index 4cb79b472b19..b5ef7280e7c1 100644 --- a/monkestation/code/modules/slimecore/machines/slime_grinder.dm +++ b/monkestation/code/modules/slimecore/machines/slime_grinder.dm @@ -7,8 +7,11 @@ icon = 'monkestation/code/modules/slimecore/icons/slime_grinder.dmi' icon_state = "slime_grinder_backdrop" base_icon_state = "slime_grinder_backdrop" - idle_power_usage = 10 - active_power_usage = 1000 + + use_power = IDLE_POWER_USE + idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION + active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION + buffer = 3000 category="Distribution" diff --git a/monkestation/code/modules/slimecore/machines/slime_market.dm b/monkestation/code/modules/slimecore/machines/slime_market.dm index 8e299bec9cda..57cd96c8397b 100644 --- a/monkestation/code/modules/slimecore/machines/slime_market.dm +++ b/monkestation/code/modules/slimecore/machines/slime_market.dm @@ -6,25 +6,11 @@ base_icon_state = "market_pad" density = TRUE use_power = IDLE_POWER_USE - idle_power_usage = 10 - active_power_usage = 2000 + idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION + active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION circuit = /obj/item/circuitboard/machine/slime_market_pad var/obj/machinery/computer/slime_market/console -/obj/machinery/slime_market_pad/attackby(obj/item/I, mob/user, params) - if(default_deconstruction_screwdriver(user, icon_state, icon_state, I)) - user.visible_message(span_notice("\The [user] [panel_open ? "opens" : "closes"] the hatch on \the [src]."), span_notice("You [panel_open ? "open" : "close"] the hatch on \the [src].")) - update_appearance() - return TRUE - - if(default_unfasten_wrench(user, I)) - return TRUE - - if(default_deconstruction_crowbar(I)) - return TRUE - - . = ..() - /obj/machinery/slime_market_pad/examine(mob/user) . = ..() if(!panel_open) @@ -41,6 +27,8 @@ /obj/machinery/slime_market_pad/AltClick(mob/user) . = ..() + if(!.) + return link_console() /obj/machinery/slime_market_pad/proc/link_console() @@ -53,30 +41,39 @@ console.link_market_pad() break -/obj/machinery/slime_market_pad/attackby(obj/item/I, mob/living/user, params) +/obj/machinery/slime_market_pad/attackby(obj/item/item, mob/living/user, params) . = ..() - if(!console) + if(. || !can_interact(user)) + return + if(default_deconstruction_screwdriver(user, icon_state, icon_state, item)) + user.visible_message(span_notice("\The [user] [panel_open ? "opens" : "closes"] the hatch on \the [src]."), span_notice("You [panel_open ? "open" : "close"] the hatch on \the [src].")) + update_appearance() + return TRUE + if(default_unfasten_wrench(user, item) || default_deconstruction_crowbar(item)) + return TRUE + if(QDELETED(console)) to_chat(user, span_warning("[src] does not have a console linked to it!")) return - - if(istype(I, /obj/item/slime_extract)) - var/obj/item/slime_extract/extract = I + if(istype(item, /obj/item/slime_extract)) + var/obj/item/slime_extract/extract = item if(extract.tier == 0) to_chat(user, span_warning("[src] doesn't seem to accept this extract!")) return flick("[base_icon_state]_vend", src) sell_extract(extract) return - - else if(istype(I, /obj/item/storage/bag/xeno)) - if(tgui_alert(user, "Are you sure you want to sell all extracts from [I]?", "<3?", list("Yes", "No")) != "Yes") + else if(istype(item, /obj/item/storage/bag/xeno)) + if(tgui_alert(user, "Are you sure you want to sell all extracts from [item]?", "<3?", list("Yes", "No")) != "Yes") return - flick("[base_icon_state]_vend", src) - for(var/obj/item/slime_extract/extract in I) + var/sold_extracts = 0 + for(var/obj/item/slime_extract/extract in item) if(extract.tier == 0) continue sell_extract(extract) + sold_extracts++ + if(sold_extracts > 0) + user.balloon_alert_to_viewers("sold [sold_extracts] extracts") return /obj/machinery/slime_market_pad/proc/sell_extract(obj/item/slime_extract/extract) @@ -97,23 +94,38 @@ SSresearch.slime_core_prices[core_type] = (1 + price_mod * price_limiter) * SSresearch.slime_core_prices[core_type] qdel(extract) -/obj/machinery/slime_market_pad/attackby_secondary(obj/item/weapon, mob/user, params) - if(!console) - to_chat(user, span_warning("[src] does not have a console linked to it!")) +/obj/machinery/slime_market_pad/attackby_secondary(obj/item/item, mob/user, params) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN || !can_interact(user)) return + if(QDELETED(console)) + to_chat(user, span_warning("[src] does not have a console linked to it!")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - if(!console.request_pad) + if(istype(item, /obj/item/storage/bag/xeno)) + flick("[base_icon_state]_vend", src) + var/sold_extracts = 0 + for(var/obj/item/slime_extract/extract in item) + if(extract.tier == 0) + continue + sell_extract(extract) + sold_extracts++ + if(sold_extracts > 0) + user.balloon_alert_to_viewers("sold [sold_extracts] extracts") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + if(QDELETED(console.request_pad)) to_chat(user, span_warning("[console] does not have a request_pad linked to it!")) - return + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN if(!length(console.request_pad.current_requests)) to_chat(user, span_warning("There are no current extract requests!")) - return + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - if(istype(weapon, /obj/item/slime_extract)) + if(istype(item, /obj/item/slime_extract)) var/list/radial_choices = list() var/list/choice_to_request = list() - var/obj/item/slime_extract/extract = weapon + var/obj/item/slime_extract/extract = item for(var/datum/extract_request_data/current as anything in console.request_pad.current_requests) if((current.extract_path != extract.type) || current.ready_for_pickup) continue @@ -134,4 +146,4 @@ flick("[base_icon_state]_vend", src) qdel(extract) - return + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN diff --git a/monkestation/code/modules/slimecore/machines/slime_market_computer.dm b/monkestation/code/modules/slimecore/machines/slime_market_computer.dm index 3c86eb44af7a..a3394c7a0105 100644 --- a/monkestation/code/modules/slimecore/machines/slime_market_computer.dm +++ b/monkestation/code/modules/slimecore/machines/slime_market_computer.dm @@ -66,7 +66,7 @@ GLOBAL_DATUM(default_slime_market, /obj/machinery/computer/slime_market) /obj/machinery/computer/slime_market/ui_assets(mob/user) return list( - get_asset_datum(/datum/asset/spritesheet/xenobio_market), + get_asset_datum(/datum/asset/spritesheet/xenobio_market) ) /obj/machinery/computer/slime_market/ui_interact(mob/user, datum/tgui/ui) @@ -110,19 +110,21 @@ GLOBAL_DATUM(default_slime_market, /obj/machinery/computer/slime_market) iter += 1 var/obj/item/slime_extract/core = core_type - var/list/core_data = list("icon" = "[initial(core.icon_state)]", - "price" = SSresearch.slime_core_prices[core_type], - "key" = iter % 4, - ) + var/list/core_data = list( + "icon" = "[initial(core.icon_state)]", + "price" = SSresearch.slime_core_prices[core_type], + "key" = iter % 4 + ) price_row.Add(list(core_data)) iter += 1 if(core_type == /obj/item/slime_extract/grey) core = /obj/item/slime_extract/rainbow - var/list/rainbow_core_data = list("icon" = "[initial(core.icon_state)]", - "price" = SSresearch.slime_core_prices[/obj/item/slime_extract/rainbow], - "key" = iter % 4, - ) + var/list/rainbow_core_data = list( + "icon" = "[initial(core.icon_state)]", + "price" = SSresearch.slime_core_prices[/obj/item/slime_extract/rainbow], + "key" = iter % 4 + ) price_row.Add(list(rainbow_core_data)) iter += 1 price_row.Add(list(list("key" = iter % 4))) diff --git a/monkestation/code/modules/slimecore/machines/slime_pen_controller.dm b/monkestation/code/modules/slimecore/machines/slime_pen_controller.dm index e071ac929ecb..862b41467872 100644 --- a/monkestation/code/modules/slimecore/machines/slime_pen_controller.dm +++ b/monkestation/code/modules/slimecore/machines/slime_pen_controller.dm @@ -28,7 +28,6 @@ . = ..() locate_machinery() - /obj/machinery/slime_pen_controller/add_context(atom/source, list/context, obj/item/held_item, mob/user) . = ..() @@ -69,13 +68,13 @@ var/list/mutation_info = list() var/mob_string for(var/mob/living/mob as anything in mutation_data.latch_needed) - mob_string += "[mutation_data.latch_needed[mob]] units of genetic data from [initial(mob.name)]. \n" + mob_string += "[mutation_data.latch_needed[mob]] units of genetic data from [mob::name]. \n" var/item_string for(var/obj/item/item as anything in mutation_data.needed_items) - item_string += "[initial(item.name)]. \n" + item_string += "[item:name]. \n" mutation_info += list( - "color" = capitalize(initial(mutation_data.output.name)), + "color" = capitalize(mutation_data.output::name), "weight" = mutation_data.weight, "mutate_chance" = mutation_data.mutate_probability, "mobs_needed" = mob_string, @@ -135,7 +134,6 @@ . = ..() if(.) return - switch(action) if("buy") for(var/datum/corral_upgrade/item as anything in subtypesof(/datum/corral_upgrade)) @@ -146,7 +144,7 @@ /obj/machinery/slime_pen_controller/proc/try_buy(datum/corral_upgrade/item) if(!linked_data) return - if(SSresearch.xenobio_points < initial(item.cost)) + if(SSresearch.xenobio_points < item::cost) return var/datum/corral_upgrade/new_upgrade = new item @@ -165,25 +163,23 @@ return /obj/machinery/slime_pen_controller/attack_hand_secondary(mob/user, list/modifiers) - if(linked_sucker) - visible_message(span_notice("[user] fiddles with the [src] toggling the pens ooze sucker.")) - linked_sucker.toggle_state() - return TRUE . = ..() - -/obj/machinery/slime_pen_controller/attackby(obj/item/weapon, mob/user, params) - if(weapon.tool_behaviour == TOOL_MULTITOOL) - if(!multitool_check_buffer(user, weapon)) - return - var/obj/item/multitool/M = weapon - if(!M.buffer) - return - var/obj/machinery/corral_corner/pad = M.buffer - if(!istype(pad)) - return - if(!pad.connected_data) - return - linked_data = pad.connected_data - to_chat(user, span_notice("You link the [pad] to the [src].")) + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) return + if(!QDELETED(linked_sucker)) + linked_sucker.toggle_state() + balloon_alert_to_viewers("[linked_sucker.turned_on ? "enabled" : "disabled"] ooze sucker") + visible_message(span_notice("[user] fiddles with the [src], [linked_sucker.turned_on ? "enabling" : "disabling"] the pens ooze sucker.")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/machinery/slime_pen_controller/multitool_act(mob/living/user, obj/item/multitool/multitool) . = ..() + if(!multitool_check_buffer(user, multitool) || QDELETED(multitool.buffer)) + return + var/obj/machinery/corral_corner/pad = multitool.buffer + if(!istype(pad) || !pad.connected_data) + return + linked_data = pad.connected_data + balloon_alert_to_viewers("linked pad") + pad.balloon_alert_to_viewers("linked to controller") + to_chat(user, span_notice("You link the [pad] to the [src].")) diff --git a/monkestation/code/modules/slimecore/mobs/_base_slime.dm b/monkestation/code/modules/slimecore/mobs/_base_slime.dm index dfbe5d102b8a..5b21399ca0ba 100644 --- a/monkestation/code/modules/slimecore/mobs/_base_slime.dm +++ b/monkestation/code/modules/slimecore/mobs/_base_slime.dm @@ -162,6 +162,7 @@ /mob/living/basic/slime/mob_try_pickup(mob/living/user, instant) if(!SEND_SIGNAL(src, COMSIG_FRIENDSHIP_CHECK_LEVEL, user, FRIENDSHIP_FRIEND)) to_chat(user, span_notice("[src] doesn't trust you enough to let you pick them up")) + balloon_alert(user, "not enough trust!") return FALSE . = ..() @@ -188,10 +189,9 @@ /mob/living/basic/slime/proc/recompile_ai_tree() var/list/new_planning_subtree = list() + RemoveElement(/datum/element/basic_eating, food_types = compiled_liked_foods) rebuild_foods() - RemoveElement(/datum/element/basic_eating) - new_planning_subtree |= add_or_replace_tree(/datum/ai_planning_subtree/pet_planning) if(!HAS_TRAIT(src, TRAIT_SLIME_RABID)) @@ -310,6 +310,7 @@ slime_flags |= SPLITTING_SLIME visible_message(span_notice("[name] starts to flatten, it looks to be splitting.")) + balloon_alert_to_viewers("splitting...") addtimer(CALLBACK(src, PROC_REF(finish_splitting)), 15 SECONDS) @@ -331,6 +332,7 @@ ai_controller.set_ai_status(AI_STATUS_OFF) visible_message(span_notice("[name] starts to undulate, it looks to be mutating.")) + balloon_alert_to_viewers("mutating...") slime_flags |= MUTATING_SLIME ungulate() @@ -414,8 +416,9 @@ . = ..() if(worn_accessory) visible_message("[user] takes the [worn_accessory] off the [src].") + balloon_alert_to_viewers("removed accessory") + worn_accessory.forceMove(user.drop_location()) worn_accessory = null - worn_accessory.forceMove(get_turf(user)) update_appearance() /mob/living/basic/slime/Life(seconds_per_tick, times_fired) diff --git a/monkestation/code/modules/trading/lootbox_odds.dm b/monkestation/code/modules/trading/lootbox_odds.dm index 33619926ab6c..18773422b2bb 100644 --- a/monkestation/code/modules/trading/lootbox_odds.dm +++ b/monkestation/code/modules/trading/lootbox_odds.dm @@ -32,8 +32,9 @@ user.client.client_token_holder.adjust_antag_tokens(LOW_THREAT, 1) if("Loadout Item") - var/static/list/viable_types = list() - if(!length(viable_types)) + var/static/list/viable_types + if(!viable_types) + viable_types = list() for(var/datum/loadout_item/type as anything in subtypesof(/datum/loadout_item)) var/datum/loadout_item/listed = new type() if(!istype(listed)) diff --git a/monkestation/code/modules/viking/viking_armour.dm b/monkestation/code/modules/viking/viking_armour.dm index 9c5bacd94e5e..046378082285 100644 --- a/monkestation/code/modules/viking/viking_armour.dm +++ b/monkestation/code/modules/viking/viking_armour.dm @@ -97,6 +97,18 @@ clothing_flags = STOPSPRESSUREDAMAGE female_sprite_flags = FEMALE_UNIFORM_TOP_ONLY +/obj/item/clothing/under/viking/fake_tunic + name = "viking pelt" + desc = "A faux wolf pelt made to cosplay with" + worn_icon_state = "pelts" + icon_state = "pelts" + w_class = WEIGHT_CLASS_NORMAL + +/obj/item/clothing/head/viking/fake_helmet + name = "foam helmet" + desc = "a foam helmet that looks like that of a vikings helmet" + worn_icon_state = "honeless_helm_worn" + icon_state = "hornless_helm_item" /datum/armor/viking melee = 45 bullet = 30 diff --git a/monkestation/icons/mob/anime/anime_bottom.dmi b/monkestation/icons/mob/anime/anime_bottom.dmi index bc6d43e412f0..03db82988211 100644 Binary files a/monkestation/icons/mob/anime/anime_bottom.dmi and b/monkestation/icons/mob/anime/anime_bottom.dmi differ diff --git a/monkestation/icons/mob/clock_cult/actions_clock.dmi b/monkestation/icons/mob/clock_cult/actions_clock.dmi index 76cda1eed569..a6b6f3832af3 100644 Binary files a/monkestation/icons/mob/clock_cult/actions_clock.dmi and b/monkestation/icons/mob/clock_cult/actions_clock.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 62dc515675d0..c31a3328ff04 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5942,7 +5942,7 @@ #include "monkestation\code\modules\antagonists\traitor\objectives\tide_bug_department.dm" #include "monkestation\code\modules\antagonists\traitor\objectives\final_objective\become_wizard.dm" #include "monkestation\code\modules\antagonists\traitor\objectives\final_objective\final_objective.dm" -#include "monkestation\code\modules\antagonists\wizard\wizard_antagonist.dm" +#include "monkestation\code\modules\antagonists\wizard\wizard.dm" #include "monkestation\code\modules\antagonists\wizard\equipment\artefact.dm" #include "monkestation\code\modules\antagonists\wizard\equipment\spellbook_entries\defensive.dm" #include "monkestation\code\modules\antagonists\wizard\equipment\spellbook_entries\mobility.dm" @@ -6412,6 +6412,7 @@ #include "monkestation\code\modules\mob\living\basic\animatronic.dm" #include "monkestation\code\modules\mob\living\basic\ggg\glerm.dm" #include "monkestation\code\modules\mob\living\basic\ggg\susflash.dm" +#include "monkestation\code\modules\mob\living\basic\pets\parrot\parrot_ai\parroting_action.dm" #include "monkestation\code\modules\mob\living\basic\space_fauna\fugu_gland.dm" #include "monkestation\code\modules\mob\living\basic\vermin\mouse.dm" #include "monkestation\code\modules\mob\living\carbon\carbon_death.dm" @@ -6758,6 +6759,7 @@ #include "monkestation\code\modules\slimecore\machines\slime_market_computer.dm" #include "monkestation\code\modules\slimecore\machines\slime_pen_controller.dm" #include "monkestation\code\modules\slimecore\machines\ooze_compressor\ooze_compressor.dm" +#include "monkestation\code\modules\slimecore\machines\ooze_compressor\ooze_compressor_hud.dm" #include "monkestation\code\modules\slimecore\machines\ooze_compressor\ooze_compressor_plumbing.dm" #include "monkestation\code\modules\slimecore\machines\ooze_compressor\shitcode.dm" #include "monkestation\code\modules\slimecore\machines\ooze_compressor\recipes\_base_recipe.dm"