diff --git a/_maps/map_files/stations/metastation.dmm b/_maps/map_files/stations/metastation.dmm index 905f487b264b..7a16de4bee22 100644 --- a/_maps/map_files/stations/metastation.dmm +++ b/_maps/map_files/stations/metastation.dmm @@ -41741,7 +41741,7 @@ }, /obj/effect/turf_decal/stripes/line, /obj/item/target/alien, -/turf/simulated/floor/plating/airless, +/turf/simulated/floor/indestructible/airless, /area/station/science/toxins/test) "cZc" = ( /obj/structure/cable, diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 810098e7d7c1..efc529ea251b 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1037,19 +1037,25 @@ Returns 1 if the chain up to the area contains the given typepath /proc/parse_zone(zone) - if(zone == "r_hand") return "right hand" - else if(zone == "l_hand") return "left hand" - else if(zone == "l_arm") return "left arm" - else if(zone == "r_arm") return "right arm" - else if(zone == "l_leg") return "left leg" - else if(zone == "r_leg") return "right leg" - else if(zone == "l_foot") return "left foot" - else if(zone == "r_foot") return "right foot" - else if(zone == "l_hand") return "left hand" - else if(zone == "r_hand") return "right hand" - else if(zone == "l_foot") return "left foot" - else if(zone == "r_foot") return "right foot" - else return zone + switch(zone) + if("r_hand") + return "right hand" + if("l_hand") + return "left hand" + if("r_arm") + return "right arm" + if("l_arm") + return "left arm" + if("r_foot") + return "right foot" + if("l_foot") + return "left foot" + if("r_leg") + return "right leg" + if("l_leg") + return "left leg" + else + return zone /* diff --git a/code/datums/components/defibrillator.dm b/code/datums/components/defibrillator.dm index e1c8011fe17e..83884d000978 100644 --- a/code/datums/components/defibrillator.dm +++ b/code/datums/components/defibrillator.dm @@ -183,8 +183,8 @@ ) busy = TRUE - var/mob/dead/observer/ghost = target.get_ghost(TRUE) - if(ghost?.can_reenter_corpse) + var/mob/dead/observer/ghost = target.get_ghost() + if(ghost) to_chat(ghost, "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)") window_flash(ghost.client) SEND_SOUND(ghost, sound('sound/effects/genetics.ogg')) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 35e07855e23e..736153710459 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1768,7 +1768,7 @@ /datum/mind/proc/get_ghost(even_if_they_cant_reenter) for(var/mob/dead/observer/G in GLOB.dead_mob_list) - if(G.mind == src) + if(G.mind == src && G.mind.key == G.key) if(G.can_reenter_corpse || even_if_they_cant_reenter) return G break diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 488ee658f168..7081814e916f 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -200,14 +200,8 @@ revivable_state = "flatline" else if(!mind) revivable_state = "dead" - else - var/foundghost = FALSE - for(var/mob/dead/observer/G in GLOB.player_list) - if(G.mind.current == src) - foundghost = (G.can_reenter_corpse && G.client) - break - if(foundghost || key) - revivable_state = "hassoul" + else if(get_ghost() || key) + revivable_state = "hassoul" holder.icon_state = "hud[revivable_state]" diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 0d3e96cc6c36..bad24ecf9249 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -20,7 +20,8 @@ var/feedback /// The desired outcome of the cloning process. var/datum/cloning_data/desired_data - + /// Is the scanner currently scanning someone? + var/currently_scanning = FALSE COOLDOWN_DECLARE(scancooldown) /obj/machinery/computer/cloning/Initialize(mapload) @@ -157,6 +158,7 @@ if(scanner) data["has_scanned"] = scanner.has_scanned + data["currently_scanning"] = currently_scanning else data["has_scanned"] = FALSE @@ -231,7 +233,6 @@ switch(text2num(params["tab"])) if(TAB_MAIN) tab = TAB_MAIN - scanner?.update_scan_status() return TRUE if(TAB_DAMAGES_BREAKDOWN) tab = TAB_DAMAGES_BREAKDOWN @@ -256,6 +257,7 @@ if(!scanner.occupant) return FALSE + currently_scanning = TRUE scanner.occupant.notify_ghost_cloning() feedback = list("text" = "Scanning occupant! Please wait...", "color" = "good", "scan_succeeded" = FALSE) COOLDOWN_START(src, scancooldown, 10 SECONDS) @@ -318,6 +320,7 @@ if("eject") if(scanner?.occupant) scanner.remove_mob(scanner.occupant) + currently_scanning = FALSE return TRUE @@ -352,5 +355,6 @@ feedback = list("text" = "Successfully scanned the patient.", "color" = "good", "scan_succeeded" = TRUE) desired_data = generate_healthy_data(scan) + currently_scanning = FALSE #undef TAB_MAIN #undef TAB_DAMAGES_BREAKDOWN diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 84ebb03663a3..071811f3137a 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -145,9 +145,11 @@ return !density /obj/machinery/door/get_superconductivity(direction) - if(density) - return superconductivity - return ..() + if(!density) + return ..() + if(heat_proof) + return ZERO_HEAT_TRANSFER_COEFFICIENT + return superconductivity /obj/machinery/door/proc/bumpopen(mob/user) if(operating) diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index b186a0981258..46c30b82a1a4 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -372,6 +372,8 @@ GLOBAL_LIST_EMPTY(turret_icons) /obj/machinery/porta_turret/crowbar_act(mob/living/user, obj/item/I) . = TRUE + if(!(stat & BROKEN) || syndicate) // No disasembling active turrets or syndicate ones + return to_chat(user, "You begin prying the metal coverings off.") if(!I.use_tool(src, user, 2 SECONDS, 0, 50)) return FALSE diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index fd747c6bdce3..d3ee336f86b6 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -98,6 +98,7 @@ icon_state = "shield2" density = FALSE appearance_flags = PIXEL_SCALE|LONG_GLIDE + layer = OBJ_LAYER // Mobs will appear above this var/boing = FALSE var/knockdown = FALSE aSignal = /obj/item/assembly/signaler/anomaly/grav diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 6cb40e0e3262..1938d86a1cd4 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -234,19 +234,15 @@ return if(!M.brainmob.key) - var/ghost_can_reenter = FALSE - if(M.brainmob.mind) - for(var/mob/dead/observer/G in GLOB.player_list) - if(G.can_reenter_corpse && G.mind == M.brainmob.mind) - ghost_can_reenter = TRUE - if(M.next_possible_ghost_ping < world.time) - G.notify_cloning("Somebody is trying to borg you! Re-enter your corpse if you want to be borged!", 'sound/voice/liveagain.ogg', src) - M.next_possible_ghost_ping = world.time + 30 SECONDS // Avoid spam - break - if(!ghost_can_reenter) - to_chat(user, "[M] is completely unresponsive; there's no point.") + var/mob/dead/observer/G = M.brainmob.get_ghost() + if(G) + if(M.next_possible_ghost_ping < world.time) + G.notify_cloning("Somebody is trying to borg you! Re-enter your corpse if you want to be borged!", 'sound/voice/liveagain.ogg', src) + M.next_possible_ghost_ping = world.time + 30 SECONDS // Avoid spam else - to_chat(user, "[M] is currently inactive. Try again later.") + to_chat(user, "[M] is completely unresponsive; there's no point.") + return + to_chat(user, "[M] is currently inactive. Try again later.") return if(M.brainmob.stat == DEAD) diff --git a/code/game/objects/items/stacks/medical_packs.dm b/code/game/objects/items/stacks/medical_packs.dm index ae50c811b8de..71fe2f71701c 100644 --- a/code/game/objects/items/stacks/medical_packs.dm +++ b/code/game/objects/items/stacks/medical_packs.dm @@ -212,6 +212,7 @@ healverb = "salve" heal_burn = 10 dynamic_icon_state = TRUE + merge_type = /obj/item/stack/medical/ointment /obj/item/stack/medical/ointment/apply(mob/living/M, mob/user) if(..()) @@ -258,6 +259,7 @@ belt_icon = "burnkit" heal_burn = 25 dynamic_icon_state = FALSE + merge_type = /obj/item/stack/medical/ointment/advanced /obj/item/stack/medical/ointment/advanced/cyborg energy_type = /datum/robot_storage/energy/medical/adv_burn_kit @@ -308,6 +310,7 @@ icon_state = "splint" unique_handling = TRUE self_delay = 100 + merge_type = /obj/item/stack/medical/splint var/other_delay = 0 /obj/item/stack/medical/splint/apply(mob/living/M, mob/user) diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm index 6c53d1398487..1035b0f70188 100644 --- a/code/game/objects/items/stacks/nanopaste.dm +++ b/code/game/objects/items/stacks/nanopaste.dm @@ -9,6 +9,7 @@ amount = 6 max_amount = 6 toolspeed = 1 + merge_type = /obj/item/stack/nanopaste /obj/item/stack/nanopaste/attack(mob/living/M as mob, mob/user as mob) if(!istype(M) || !istype(user)) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 5b9397d1a9ac..fbecc0325143 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -127,6 +127,8 @@ // We don't only use istype here, since that will match subtypes, and stack things that shouldn't stack if(!istype(check, merge_type) || check.merge_type != merge_type) return FALSE + if(amount <= 0 || check.amount <= 0) // no merging empty stacks that are in the process of being qdel'd + return FALSE if(is_cyborg) // No merging cyborg stacks into other stacks return FALSE if(ismob(loc) && !inhand) // no merging with items that are on the mob diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 47adcccace03..b92eab964a2a 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -230,6 +230,7 @@ mineralType = "metal" armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 70) resistance_flags = FIRE_PROOF + merge_type = /obj/item/stack/tile/plasteel /obj/item/stack/tile/plasteel/cyborg energy_type = /datum/robot_storage/energy/metal_tile diff --git a/code/game/objects/items/weapons/cigs.dm b/code/game/objects/items/weapons/cigs.dm index df1e190ab512..7905586a559e 100644 --- a/code/game/objects/items/weapons/cigs.dm +++ b/code/game/objects/items/weapons/cigs.dm @@ -582,6 +582,9 @@ LIGHTERS ARE IN LIGHTERS.DM qdel(O) else to_chat(user, "You need to dry this first!") + return + + return ..() /obj/item/clothing/mask/cigarette/pipe/cobpipe name = "corn cob pipe" diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 950f86d70416..d18ff165110b 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -245,8 +245,9 @@ hardened = TRUE // EMP-proof (on the component), but not emag-proof. resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF // Objective item, better not have it destroyed. heart_attack_probability = 10 + origin_tech = null /// To prevent spam from the emagging message on the advanced defibrillator. - var/next_emp_message + var/next_emp_message /obj/item/defibrillator/compact/advanced/examine(mob/user) . = ..() diff --git a/code/game/objects/items/weapons/grenades/syndieminibomb.dm b/code/game/objects/items/weapons/grenades/syndieminibomb.dm index 3525dfcc99df..cf3629985c3d 100644 --- a/code/game/objects/items/weapons/grenades/syndieminibomb.dm +++ b/code/game/objects/items/weapons/grenades/syndieminibomb.dm @@ -12,6 +12,7 @@ qdel(src) /obj/item/grenade/syndieminibomb/fake + origin_tech = "materials=3;magnets=4;syndicate=1" // no clown, this bomb not exactly the same /obj/item/grenade/syndieminibomb/fake/examine(mob/user) . = ..() diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm index 947332c96730..f51d1493347a 100644 --- a/code/game/objects/items/weapons/holy_weapons.dm +++ b/code/game/objects/items/weapons/holy_weapons.dm @@ -42,6 +42,11 @@ if(!V.get_ability(/datum/vampire_passive/full)) to_chat(M, "The nullrod's power interferes with your own!") V.adjust_nullification(30 + sanctify_force, 15 + sanctify_force) + if(!sanctify_force) + return + if(isliving(M)) + var/mob/living/L = M + L.adjustFireLoss(sanctify_force) // Bonus fire damage for sanctified (ERT) versions of nullrod /obj/item/nullrod/pickup(mob/living/user) . = ..() @@ -96,14 +101,6 @@ return FALSE return TRUE -/obj/item/nullrod/afterattack(atom/movable/AM, mob/user, proximity) - . = ..() - if(!sanctify_force) - return - if(isliving(AM)) - var/mob/living/L = AM - L.adjustFireLoss(sanctify_force) // Bonus fire damage for sanctified (ERT) versions of nullrod - /// fluff subtype to be used for all donator nullrods /obj/item/nullrod/fluff reskin_selectable = FALSE diff --git a/code/game/objects/items/weapons/knuckledusters.dm b/code/game/objects/items/weapons/knuckledusters.dm index 7d75c58660f2..e8981aa5e67e 100644 --- a/code/game/objects/items/weapons/knuckledusters.dm +++ b/code/game/objects/items/weapons/knuckledusters.dm @@ -65,7 +65,7 @@ icon_state = "knuckleduster_nt" force = 10 throwforce = 5 - origin_tech = "combat=3" + origin_tech = null resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF // Steal objectives shouldnt be easy to destroy. materials = list(MAT_GOLD = 500, MAT_TITANIUM = 200, MAT_PLASMA = 200) trauma = 10 diff --git a/code/game/objects/items/weapons/melee/energy_melee_weapons.dm b/code/game/objects/items/weapons/melee/energy_melee_weapons.dm index 5fef9bf2214e..96893ff65c9e 100644 --- a/code/game/objects/items/weapons/melee/energy_melee_weapons.dm +++ b/code/game/objects/items/weapons/melee/energy_melee_weapons.dm @@ -311,13 +311,14 @@ return if(isprojectile(hitby)) var/obj/item/projectile/P = hitby - if(P.reflectability == REFLECTABILITY_NEVER) //only 1 magic spell does this, but hey, needed - owner.visible_message("[owner] blocks [attack_text] with [src]!") - playsound(src, 'sound/weapons/effects/ric3.ogg', 100, TRUE) - return TRUE - owner.visible_message("[owner] parries [attack_text] with [src]!") - add_attack_logs(P.firer, src, "hit by [P.type] but got parried by [src]") - return -1 + if(P.reflectability == REFLECTABILITY_ENERGY) + owner.visible_message("[owner] parries [attack_text] with [src]!") + add_attack_logs(P.firer, src, "hit by [P.type] but got parried by [src]") + return -1 + owner.visible_message("[owner] blocks [attack_text] with [src]!") + playsound(src, 'sound/weapons/effects/ric3.ogg', 100, TRUE) + return TRUE + return TRUE ////////////////////////////// diff --git a/code/game/objects/items/weapons/melee/melee_misc.dm b/code/game/objects/items/weapons/melee/melee_misc.dm index ede849a3d35e..2db79162465f 100644 --- a/code/game/objects/items/weapons/melee/melee_misc.dm +++ b/code/game/objects/items/weapons/melee/melee_misc.dm @@ -34,7 +34,7 @@ w_class = WEIGHT_CLASS_BULKY armour_penetration_percentage = 75 sharp = TRUE - origin_tech = "combat=5" + origin_tech = null attack_verb = list("lunged at", "stabbed") hitsound = 'sound/weapons/rapierhit.ogg' materials = list(MAT_METAL = 1000) diff --git a/code/game/objects/items/weapons/storage/storage_base.dm b/code/game/objects/items/weapons/storage/storage_base.dm index 174364442eba..9ae621d46932 100644 --- a/code/game/objects/items/weapons/storage/storage_base.dm +++ b/code/game/objects/items/weapons/storage/storage_base.dm @@ -468,20 +468,18 @@ if(!prevent_warning) // all mobs with clients attached, sans the item's user - var/viewer_list = GLOB.player_list - user // the item's user will always get a notification to_chat(user, "You put [I] into [src].") // if the item less than normal sized, only people within 1 tile get the message, otherwise, everybody in view gets it if(I.w_class < WEIGHT_CLASS_NORMAL) - for(var/mob/M in viewer_list) + for(var/mob/M in range(1, user)) if(in_range(M, user)) M.show_message("[user] puts [I] into [src].") else // restrict player list to include only those in view - viewer_list = viewer_list & viewers(world.view, user) - for(var/mob/M in viewer_list) + for(var/mob/M in oviewers(7, user)) M.show_message("[user] puts [I] into [src].") orient2hud(user) diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index 6781a5ae7ec0..748c7a1d54f1 100644 --- a/code/game/objects/items/weapons/teleportation.dm +++ b/code/game/objects/items/weapons/teleportation.dm @@ -17,7 +17,7 @@ throw_speed = 3 throw_range = 5 materials = list(MAT_METAL=10000) - origin_tech = "magnets=3;bluespace=4" + origin_tech = null armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 30, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF var/icon_state_inactive = "hand_tele_inactive" diff --git a/code/game/turfs/simulated/floor/asteroid_floors.dm b/code/game/turfs/simulated/floor/asteroid_floors.dm index d4f98500c549..44021a067a0d 100644 --- a/code/game/turfs/simulated/floor/asteroid_floors.dm +++ b/code/game/turfs/simulated/floor/asteroid_floors.dm @@ -58,6 +58,15 @@ if(1) getDug() +/turf/simulated/floor/plating/asteroid/proc/attempt_ore_pickup(obj/item/storage/bag/ore/S, mob/user) + if(!istype(S)) + return + + if(S.pickup_all_on_tile) + for(var/obj/item/stack/ore/O in contents) + O.attackby(S, user) + return + /turf/simulated/floor/plating/asteroid/attackby(obj/item/I, mob/user, params) //note that this proc does not call ..() if(!I|| !user) @@ -82,11 +91,7 @@ return TRUE else if(istype(I, /obj/item/storage/bag/ore)) - var/obj/item/storage/bag/ore/S = I - if(S.pickup_all_on_tile) - for(var/obj/item/stack/ore/O in contents) - O.attackby(I, user) - return + attempt_ore_pickup(I, user) else if(istype(I, /obj/item/stack/tile)) var/obj/item/stack/tile/Z = I diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 47b1278de7ec..b00cbb4271b4 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -269,7 +269,7 @@ /client/New(TopicData) // TODO: Remove with 516 if(byond_version >= 516) // Enable 516 compat browser storage mechanisms - winset(src, "", "browser-options=byondstorage") + winset(src, "", "browser-options=byondstorage,find") var/tdata = TopicData //save this for later use // Instantiate stat panel diff --git a/code/modules/client/preference/link_processing.dm b/code/modules/client/preference/link_processing.dm index 99253e72309b..0656ec4750a8 100644 --- a/code/modules/client/preference/link_processing.dm +++ b/code/modules/client/preference/link_processing.dm @@ -476,6 +476,9 @@ valid_markings += markingstyle sortTim(valid_markings, GLOBAL_PROC_REF(cmp_text_asc)) + if(!length(valid_markings)) // Some IPC head models do have head markings, some don't; This is here to prevent us from attempting to open an empty TGUI list + tgui_alert(user, "No head markings available for this head!", "Character Preference") + return var/new_marking_style = tgui_input_list(user, "Choose the style of your character's head markings:", "Character Preference", valid_markings) if(new_marking_style) active_character.m_styles["head"] = new_marking_style diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index fd4b2a3885ea..f4f0ed7cae9b 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -51,7 +51,8 @@ OB = thing break if(OB && istype(F, /turf/simulated/floor/plating/asteroid)) - F.attackby(OB, AM) + var/turf/simulated/floor/plating/asteroid/FA = F + FA.attempt_ore_pickup(OB, AM) // Then, if the user is dragging an ore box, empty the satchel // into the box. var/mob/living/L = AM diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index 92ed05e83c2a..3ff5be8c1a18 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -19,7 +19,6 @@ S.hide_from(usr) for(var/obj/item/stack/ore/O in S.contents) S.remove_from_storage(O, src) //This will move the item to this item's contents - CHECK_TICK to_chat(user, "You empty the satchel into the box.") else return ..() diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index d0a880a90222..42511b04c461 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -221,13 +221,7 @@ if(!just_sleeping) msg += "[p_they(TRUE)] [p_are()] limp and unresponsive; there are no signs of life" if(get_int_organ(/obj/item/organ/internal/brain) && !key) - var/foundghost = FALSE - if(mind) - for(var/mob/dead/observer/G in GLOB.player_list) - if(G.mind == mind && G.can_reenter_corpse) - foundghost = TRUE - break - if(!foundghost) + if(!get_ghost()) msg += " and [p_their()] soul has departed" msg += "...\n" diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index bd6e91932d0e..18739b9e6ead 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -52,9 +52,11 @@ for(var/action_type in attack_action_types) var/datum/action/innate/megafauna_attack/attack_action = new action_type() attack_action.Grant(src) + RegisterSignal(src, COMSIG_HOSTILE_FOUND_TARGET, PROC_REF(hoverboard_deactivation)) /mob/living/simple_animal/hostile/megafauna/Destroy() QDEL_NULL(internal_gps) + UnregisterSignal(src, COMSIG_HOSTILE_FOUND_TARGET) return ..() /mob/living/simple_animal/hostile/megafauna/Moved() @@ -158,6 +160,21 @@ C.density = FALSE //I hate it. addtimer(VARSET_CALLBACK(C, density, TRUE), 2 SECONDS) // Needed to make them path. I hate it. +/mob/living/simple_animal/hostile/megafauna/proc/hoverboard_deactivation(source, target) + SIGNAL_HANDLER // COMSIG_HOSTILE_FOUND_TARGET + if(!isliving(target)) + return + var/mob/living/L = target + if(!L.buckled) + return + if(!istype(L.buckled, /obj/tgvehicle/scooter/skateboard/hoverboard)) + return + var/obj/tgvehicle/scooter/skateboard/hoverboard/cursed_board = L.buckled + // Not a visible message, as walls or such may be in the way + to_chat(L, "You hear a loud roar in the distance, and the lights on [cursed_board] begin to spark dangerously, as the board rumbles heavily!") + playsound(get_turf(src), 'sound/effects/tendril_destroyed.ogg', 200, FALSE, 50, TRUE, TRUE) + cursed_board.necropolis_curse() + /datum/action/innate/megafauna_attack name = "Megafauna Attack" button_overlay_icon = 'icons/mob/actions/actions_animal.dmi' diff --git a/code/modules/mob/mob_misc_procs.dm b/code/modules/mob/mob_misc_procs.dm index d9e460f5b960..e9c74f2b9c18 100644 --- a/code/modules/mob/mob_misc_procs.dm +++ b/code/modules/mob/mob_misc_procs.dm @@ -175,7 +175,8 @@ theghost = pick(candidates) to_chat(M, "Your mob has been taken over by a ghost!") message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)])") - M.ghostize() + var/mob/dead/observer/ghost = M.ghostize(TRUE) // Keep them respawnable + ghost.can_reenter_corpse = FALSE // but keep them out of their old body M.key = theghost.key dust_if_respawnable(theghost) else diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm index 39d6cada712a..b63adbe2b45f 100644 --- a/code/modules/projectiles/firing.dm +++ b/code/modules/projectiles/firing.dm @@ -38,10 +38,12 @@ /obj/item/ammo_casing/proc/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread, atom/firer_source_atom) var/turf/curloc = get_turf(firer_source_atom) - if(!istype(curloc)) // False-bottomed briefcase check. + if(!istype(curloc)) // False-bottomed briefcase check / shell launch system check. var/obj/item/holding = user.get_active_hand() if(istype(holding, /obj/item/storage/briefcase/false_bottomed)) curloc = get_turf(holding) + if(istype(firer_source_atom, /obj/item/gun/projectile/revolver/doublebarrel/shell_launcher)) + curloc = get_turf(user) if(!istype(targloc) || !istype(curloc) || !BB) return BB.ammo_casing = src diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index ef4e1989a945..895419b3f67b 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -17,6 +17,10 @@ /obj/item/organ/internal/cyberimp/emp_act() return // These shouldn't be hurt by EMPs in the standard way +/obj/item/organ/internal/cyberimp/examine(mob/user) + . = ..() + . += "It looks like it belongs in the [parse_zone(parent_organ)]." + //[[[[BRAIN]]]] /obj/item/organ/internal/cyberimp/brain diff --git a/code/modules/surgery/organs/brain.dm b/code/modules/surgery/organs/brain.dm index 45ccd25faafb..cd29e5c36ae6 100644 --- a/code/modules/surgery/organs/brain.dm +++ b/code/modules/surgery/organs/brain.dm @@ -59,14 +59,7 @@ . += "You can feel a bright spark of life in this one!" return if(brainmob?.mind) - var/foundghost = FALSE - for(var/mob/dead/observer/G in GLOB.player_list) - if(G.mind == brainmob.mind) - foundghost = TRUE - if(!G.can_reenter_corpse) - foundghost = FALSE - break - if(foundghost) + if(brainmob.get_ghost()) . += "You can feel the small spark of life still left in this one." return diff --git a/code/modules/tgui/tgui_panel/tgui_panel_external.dm b/code/modules/tgui/tgui_panel/tgui_panel_external.dm index f51c974ae4a2..74bdfa64b0a3 100644 --- a/code/modules/tgui/tgui_panel/tgui_panel_external.dm +++ b/code/modules/tgui/tgui_panel/tgui_panel_external.dm @@ -34,6 +34,8 @@ // Force show the panel to see if there are any errors winset(src, "output", "is-disabled=1&is-visible=0") winset(src, "chat_panel", "is-disabled=0;is-visible=1") + if(byond_version >= 516) + winset(src, null, "browser-options=byondstorage,find") /client/verb/refresh_tgui() set name = "Refresh TGUI" diff --git a/code/modules/vehicle/tg_vehicles/scooter.dm b/code/modules/vehicle/tg_vehicles/scooter.dm index ada9127fb35b..5b9d490601ad 100644 --- a/code/modules/vehicle/tg_vehicles/scooter.dm +++ b/code/modules/vehicle/tg_vehicles/scooter.dm @@ -33,6 +33,11 @@ buckled_mob.pixel_y = 5 else buckled_mob.pixel_y = -4 + if(istype(get_turf(src), /turf/simulated/floor/plating/asteroid)) //Rocks are bad for wheels mkay? + if(!HAS_TRAIT(src, TRAIT_NO_BREAK_GLASS_TABLES)) + buckled_mob.adjustStaminaLoss(2) + if(prob(7)) //Not to much spam. + to_chat(buckled_mob, "The rocky terrain you are riding on is tiring you out!") /obj/tgvehicle/scooter/skateboard name = "skateboard" @@ -51,6 +56,8 @@ var/instability = 10 ///If true, riding the skateboard with walk intent on will prevent crashing. var/can_slow_down = TRUE + ///Is this board cursed, preventing the cheeser from picking it up right away and using it again. Can not get on it while cursed either. + var/cursed = FALSE /obj/tgvehicle/scooter/skateboard/Initialize(mapload) . = ..() @@ -191,6 +198,9 @@ /obj/tgvehicle/scooter/skateboard/proc/pick_up_board(mob/living/carbon/skater) if(skater.incapacitated() || !Adjacent(skater)) return + if(cursed) + to_chat(skater, "Some magic burns your hands whenever you go to pick [src] up!") + return if(has_buckled_mobs()) to_chat(skater, "You can't lift this up when somebody's on it.") return @@ -214,6 +224,7 @@ instability = 3 icon_state = "hoverboard_red" resistance_flags = LAVA_PROOF | FIRE_PROOF + var/mutable_appearance/curse_overlay /obj/tgvehicle/scooter/skateboard/hoverboard/Initialize(mapload) . = ..() @@ -222,6 +233,27 @@ /obj/tgvehicle/scooter/skateboard/hoverboard/make_ridable() AddElement(/datum/element/ridable, /datum/component/riding/vehicle/scooter/skateboard/hover) +/obj/tgvehicle/scooter/skateboard/hoverboard/proc/necropolis_curse() + cursed = TRUE + can_buckle = FALSE + addtimer(CALLBACK(src, PROC_REF(remove_rider)), 5 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_DELETE_ME) + curse_overlay = mutable_appearance('icons/effects/cult_effects.dmi', "cult-mark", ABOVE_MOB_LAYER) + curse_overlay.pixel_y = -10 + + add_overlay(curse_overlay) + +/obj/tgvehicle/scooter/skateboard/hoverboard/proc/remove_rider() + visible_message("The boosters on [src] burn out as the magic extinguishes it!") + if(has_buckled_mobs()) + var/mob/living/carbon/skaterboy = buckled_mobs[1] + unbuckle_mob(skaterboy) + addtimer(CALLBACK(src, PROC_REF(clear_curse)), 30 SECONDS,TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_DELETE_ME) + +/obj/tgvehicle/scooter/skateboard/hoverboard/proc/clear_curse() + can_buckle = TRUE + cursed = FALSE + cut_overlay(curse_overlay) + /obj/tgvehicle/scooter/skateboard/hoverboard/admin name = "\improper Board Of Directors" desc = "The engineering complexity of a spaceship concentrated inside of a board. Just as expensive, too." diff --git a/html/statbrowser.css b/html/statbrowser.css index 802dadacf93a..d914168fa7ee 100644 --- a/html/statbrowser.css +++ b/html/statbrowser.css @@ -1,126 +1,178 @@ +/** + * MARK: Main styles + */ .light:root { --scrollbar-base: #f2f2f2; --scrollbar-thumb: #a7a7a7; } -html, -body { - scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-base); -} - -/* Light theme */ body { + display: flex; + flex-direction: column; + height: 100vh; + overflow: hidden; + box-sizing: border-box; font-family: Verdana, Geneva, Tahoma, sans-serif; - font-size: 12px !important; + font-size: 12px; margin: 0 !important; padding: 0 !important; - overflow-x: hidden; - overflow-y: scroll; + scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-base); } -#menu { - background-color: #efeeee; - position: fixed; - width: 100%; - z-index: 100; +a { + cursor: pointer; + color: #003399; + text-decoration: none; } -#statcontent { - padding: 7px; +a:hover { + color: #007fff; } -a { - color: black; - text-decoration: none; +h3 { + margin: 0 -0.5em 0.5em; + padding: 1em 0.66em 0.5em; + border-bottom: 0.1667em solid; } -a:hover, -.dark a:hover, -.ntos a:hover, -.paradise a:hover, -.syndicate a:hover { - text-decoration: underline; +img { + -ms-interpolation-mode: nearest-neighbor; + image-rendering: pixelated; } -ul { - list-style-type: none; - margin: 0; - padding: 0; - background-color: #333; +table { + margin-top: -0.25em; } -li { - float: left; +*, +*:before, +*:after { + box-sizing: inherit; } -li a { - display: block; - color: white; - text-align: center; - padding: 14px 16px; - text-decoration: none; +#menu { + display: flex; + overflow-x: auto; + overflow-y: hidden; + padding: 0.25em 0.25em 0; + background-color: #ffffff; } -li a:hover:not(.active) { - background-color: #111; +.menu-wrap { + flex-wrap: wrap-reverse; } -td { - padding-right: 15px; +#menu.tabs-classic { + padding: 0.15em; } -.button-container { - display: inline-flex; - flex-wrap: wrap-reverse; - flex-direction: row; - align-items: flex-start; - overflow-x: hidden; - white-space: pre-wrap; +#menu.tabs-classic .button { + min-width: 3em; + min-height: auto; + line-height: 1.667em; + margin: 0.1em; + border: 0; + border-radius: 0.16em; +} + +#menu.tabs-classic .button.active { + background-color: #0668b8; + color: white; +} + +#menu.tabs-classic ~ #under-menu { + height: 0; } .button { - background-color: #ffffff; - border-style: none; - border-bottom-style: solid; - border: 1px solid transparent; - border-bottom-width: 2px; - color: rgba(0, 0, 0, 0.7); - padding: 7px 8px 5px 8px; - text-align: center; - text-decoration: none; - font-size: 12px; - margin: 0; + display: inline-flex; + align-items: center; + flex-shrink: 0; cursor: pointer; - transition-duration: 100ms; - order: 3; - min-width: 40px; + user-select: none; + -ms-user-select: none; /* Remove after Byond 516 */ + text-align: center; + white-space: nowrap; + min-width: 4em; + min-height: 2.25em; + color: rgba(0, 0, 0, 0.5); + border-top: 0.1667em solid transparent; + border-bottom: 0.1667em solid transparent; + border-radius: 0.25em 0.25em 0 0; +} + +.button-text { + flex-grow: 1; + margin: 0 0.5em; } .button:hover { background-color: #ececec; - transition-duration: 0; } -.button:active, .button.active { + cursor: default; background-color: #dfdfdf; color: black; border-bottom-color: #000000; } +#under-menu { + height: 0.5em; + background-color: #eeeeee; +} + +#under-content { + height: calc(0.5em - 4px); + background-color: #eeeeee; +} + +#statcontent { + flex: 1; + padding: 0.5em; + overflow-y: scroll; + overflow-x: hidden; +} + .grid-container { - margin: -2px; - margin-right: -15px; + margin: -0.25em; } .grid-item { + display: inline-flex; position: relative; + user-select: none; + -ms-user-select: none; /* Remove after Byond 516 */ + width: 100%; + max-height: 1.85em; + text-decoration: none; + background-color: transparent; + color: black; +} + +.grid-item:hover, +.grid-item:active { + color: #003399; + z-index: 1; +} + +.grid-item-text { display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + pointer-events: none; width: 100%; - box-sizing: border-box; + padding: 0.33em 0.5em; + border-radius: 0.25em; +} + +.grid-item:hover .grid-item-text, +.grid-item:active .grid-item-text { + height: 100%; overflow: visible; - padding: 3px 2px; - text-decoration: none; + white-space: normal; + background-color: #ececec; } @media only screen and (min-width: 300px) { @@ -147,59 +199,20 @@ td { } } -.grid-item:hover { - z-index: 1; -} - -.grid-item:hover .grid-item-text { - width: auto; - text-decoration: underline; -} - -.grid-item-text { - display: inline-block; - width: 100%; - background-color: #ffffff; - margin: 0 -6px; - padding: 0 6px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - pointer-events: none; -} - -.link, .listedturf_link { - background: none; - border: none; - color: black; - text-decoration: none; + display: flex; + align-items: center; cursor: pointer; - font-size: 13px; + border-radius: 0.25em; } -.link { - display: inline; - padding: 7px 14px; - margin: 2px 2px; -} - -.link:hover, .listedturf_link:hover { - text-decoration: underline; -} - -img { - -ms-interpolation-mode: nearest-neighbor; - image-rendering: pixelated; -} - -.interview_panel_controls, -.interview_panel_stats { - margin-bottom: 10px; + background-color: #ececec; } -/* Dark Theme */ +/** + * MARK: Dark + */ .dark:root { --scrollbar-base: #181818; --scrollbar-thumb: #363636; @@ -217,40 +230,60 @@ body.dark { scrollbar-shadow-color: #3b3b3b; } -.dark #menu { - background-color: #212020; +.dark a { + color: #6699ff; +} + +.dark a:hover, +.dark .grid-item:hover, +.dark .grid-item:active { + color: #80bfff; } -.dark button { +.dark #menu { background-color: #131313; +} + +.dark #menu.tabs-classic .button.active { + background-color: #20b142; +} + +.dark .button { color: rgba(255, 255, 255, 0.5); } -.dark button:hover { +.dark .button:hover { background-color: #252525; } -.dark .button:active, .dark .button.active { background-color: #313131; - color: white; - border-bottom-color: #ffffff; + color: #d4dfec; + border-bottom-color: #d4dfec; } -.dark .grid-item-text { - background-color: #131313; +.dark #under-menu, +.dark #under-content { + background-color: #202020; } -.dark a { +.dark .grid-item .grid-item-text { color: #b2c4dd; } -.dark .link, -.dark .listedturf_link { - color: #abc6ec; +.dark .grid-item:hover .grid-item-text, +.dark .grid-item:active .grid-item-text { + background-color: #252525; + color: #80bfff; } -/* NTOS theme */ +.dark .listedturf_link:hover { + background-color: #252525; +} + +/** + * MARK: NTOS + */ .ntos:root { --scrollbar-base: #141d26; --scrollbar-thumb: #2a3b4f; @@ -266,133 +299,191 @@ body.ntos { scrollbar-shadow-color: #2a3b4f; } -.ntos #menu { - background-color: #1b2633; +.ntos a { + color: #6699ff; +} + +.ntos a:hover, +.ntos .grid-item:hover, +.ntos .grid-item:active { + color: #80bfff; } -.ntos button { +.ntos #menu { background-color: #121922; +} + +.ntos #menu.tabs-classic .button.active { + background-color: #20b142; +} + +.ntos .button { color: rgba(255, 255, 255, 0.5); } -.ntos button:hover { +.ntos .button:hover { background-color: #242a32; } -.ntos .button:active, .ntos .button.active { background-color: #30363e; - color: white; - border-bottom-color: #ffffff; + color: #d4dfec; + border-bottom-color: #d4dfec; } -.ntos .grid-item-text { - background-color: #121922; +.ntos #under-menu, +.ntos #under-content { + background-color: #1b2633; } -.ntos a { +.ntos .grid-item .grid-item-text { color: #b2c4dd; } -.ntos .link, -.ntos .listedturf_link { - color: #abc6ec; +.ntos .grid-item:hover .grid-item-text, +.ntos .grid-item:active .grid-item-text { + background-color: #242a32; + color: #80bfff; } -/* Paradise theme */ -.paradise:root { - --scrollbar-base: #680b29; - --scrollbar-thumb: #cb1551; +.ntos .listedturf_link:hover { + background-color: #242a32; } -body.paradise { - background-color: #400125; - color: #dec5bd; - scrollbar-base-color: #680b29; - scrollbar-face-color: #99103d; - scrollbar-track-color: #680b29; - scrollbar-arrow-color: #ea2e6c; - scrollbar-shadow-color: #99103d; +/** + * MARK: Syndicate + */ +.syndicate:root { + --scrollbar-base: #3a0202; + --scrollbar-thumb: #770303; } -.paradise #menu { - background-color: #800448; +body.syndicate { + background-color: #2b0101; + color: #debdbd; + scrollbar-base-color: #3a0202; + scrollbar-face-color: #770303; + scrollbar-track-color: #3a0202; + scrollbar-arrow-color: #fa2d2d; + scrollbar-shadow-color: #770303; } -.paradise button { - background-color: #400125; +.syndicate a { + color: #6699ff; +} + +.syndicate a:hover, +.syndicate .grid-item:hover, +.syndicate .grid-item:active { + color: #80bfff; +} + +.syndicate #menu { + background-color: #2b0101; +} + +.syndicate #menu.tabs-classic .button.active { + background-color: #9d0808; +} + +.syndicate .button { color: rgba(255, 255, 255, 0.5); } -.paradise button:hover { - background-color: #4e1435; +.syndicate .button:hover { + background-color: #3b1414; } -.paradise .button:active, -.paradise .button.active { - background-color: #582140; - color: white; - border-bottom-color: #ffffff; +.syndicate .button.active { + background-color: #462121; + color: #d4dfec; + border-bottom-color: #d4dfec; } -.paradise .grid-item-text { - background-color: #400125; +.syndicate #under-menu, +.syndicate #under-content { + background-color: #4d0202; } -.paradise a { +.syndicate .grid-item .grid-item-text { + color: #e4cdcd; +} + +.syndicate .grid-item:hover .grid-item-text, +.syndicate .grid-item:active .grid-item-text { + background-color: #3b1414; + color: #f5bcbc; +} + +.syndicate .listedturf_link:hover { + background-color: #3b1414; +} + +/** + * MARK: Paradise + */ +.paradise:root { + --scrollbar-base: #680b29; + --scrollbar-thumb: #cb1551; +} + +body.paradise { + background-color: #400125; color: #dec5bd; + scrollbar-base-color: #680b29; + scrollbar-face-color: #99103d; + scrollbar-track-color: #680b29; + scrollbar-arrow-color: #ea2e6c; + scrollbar-shadow-color: #99103d; } -.paradise .link, -.paradise .listedturf_link { - color: #edc1b2; +.paradise a { + color: #6699ff; } -/* Syndicate theme */ -.syndicate:root { - --scrollbar-base: #3a0202; - --scrollbar-thumb: #770303; +.paradise a:hover, +.paradise .grid-item:hover, +.paradise .grid-item:active { + color: #80bfff; } -body.syndicate { - background-color: #2b0101; - color: #debdbd; - scrollbar-base-color: #3a0202; - scrollbar-face-color: #770303; - scrollbar-track-color: #3a0202; - scrollbar-arrow-color: #fa2d2d; - scrollbar-shadow-color: #770303; +.paradise #menu { + background-color: #400025; } -.syndicate #menu { - background-color: #4d0202; +.paradise #menu.tabs-classic .button.active { + background-color: #bf6030; } -.syndicate button { - background-color: #2b0101; +.paradise .button { color: rgba(255, 255, 255, 0.5); } -.syndicate button:hover { - background-color: #3b1414; +.paradise .button:hover { + background-color: #4e1435; } -.syndicate .button:active, -.syndicate .button.active { - background-color: #462121; - color: white; - border-bottom-color: #ffffff; +.paradise .button.active { + background-color: #582140; + color: #d4dfec; + border-bottom-color: #d4dfec; } -.syndicate .grid-item-text { - background-color: #2b0101; +.paradise #under-menu, +.paradise #under-content { + background-color: #800448; } -.syndicate a { - color: #debdbd; +.paradise .grid-item .grid-item-text { + color: #e4d7cd; } -.syndicate .link, -.syndicate .listedturf_link { - color: #edb2b2; +.paradise .grid-item:hover .grid-item-text, +.paradise .grid-item:active .grid-item-text { + background-color: #4e1435; + color: #f5d5bc; +} + +.paradise .listedturf_link:hover { + background-color: #4e1435; } diff --git a/html/statbrowser.html b/html/statbrowser.html index 1aea8811d58a..0dcef13897d7 100644 --- a/html/statbrowser.html +++ b/html/statbrowser.html @@ -1,3 +1,6 @@ -
- +1024,I&&(t.dump&&Xw===t.dump.charCodeAt(0)?v+="?":v+="? "),v+=t.dump,I&&(v+=CT(t,e)),ed(t,e+1,E,!0,I)&&(t.dump&&Xw===t.dump.charCodeAt(0)?v+=":":v+=": ",v+=t.dump,a+=v));t.tag=n,t.dump=a||"{}"}function kK(t,e,r){var o,a,n,u,A,p;for(a=r?t.explicitTypes:t.implicitTypes,n=0,u=a.length;n tag resolver accepts not "'+p+'" style');t.dump=o}return!0}return!1}function ed(t,e,r,o,a,n){t.tag=null,t.dump=r,kK(t,r,!1)||kK(t,r,!0);var u=QK.call(t.dump);o&&(o=t.flowLevel<0||t.flowLevel>e);var A=u==="[object Object]"||u==="[object Array]",p,h;if(A&&(p=t.duplicates.indexOf(r),h=p!==-1),(t.tag!==null&&t.tag!=="?"||h||t.indent!==2&&e>0)&&(a=!1),h&&t.usedDuplicates[p])t.dump="*ref_"+p;else{if(A&&h&&!t.usedDuplicates[p]&&(t.usedDuplicates[p]=!0),u==="[object Object]")o&&Object.keys(t.dump).length!==0?(q6e(t,e,t.dump,a),h&&(t.dump="&ref_"+p+t.dump)):(H6e(t,e,t.dump),h&&(t.dump="&ref_"+p+" "+t.dump));else if(u==="[object Array]"){var E=t.noArrayIndent&&e>0?e-1:e;o&&t.dump.length!==0?(_6e(t,E,t.dump,a),h&&(t.dump="&ref_"+p+t.dump)):(U6e(t,E,t.dump),h&&(t.dump="&ref_"+p+" "+t.dump))}else if(u==="[object String]")t.tag!=="?"&&N6e(t,t.dump,e,n);else{if(t.skipInvalid)return!1;throw new $w("unacceptable kind of an object to dump "+u)}t.tag!==null&&t.tag!=="?"&&(t.dump="!<"+t.tag+"> "+t.dump)}return!0}function G6e(t,e){var r=[],o=[],a,n;for(wT(t,r,o),a=0,n=o.length;a {var n,u;if(Object.getPrototypeOf(o).toString()==="[object Set]")if(typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return pr(a,"Unbound coercion result");let A=[...o],p=[...o];if(!r(p,Object.assign(Object.assign({},a),{coercion:void 0})))return!1;let h=()=>p.some((E,I)=>E!==A[I])?new Set(p):o;return a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",nI(a.coercion,o,h)]),!0}else{let A=!0;for(let p of o)if(A=t(p,Object.assign({},a))&&A,!A&&a?.errors==null)break;return A}if(typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return pr(a,"Unbound coercion result");let A={value:o};return r(o,Object.assign(Object.assign({},a),{coercion:Wu(A,"value")}))?(a.coercions.push([(u=a.p)!==null&&u!==void 0?u:".",nI(a.coercion,o,()=>new Set(A.value))]),!0):!1}return pr(a,`Expected a set (got ${qn(o)})`)}})}function fqe(t,e){let r=iD(sD([t,e])),o=oD(e,{keys:t});return Hr({test:(a,n)=>{var u,A,p;if(Object.getPrototypeOf(a).toString()==="[object Map]")if(typeof n?.coercions<"u"){if(typeof n?.coercion>"u")return pr(n,"Unbound coercion result");let h=[...a],E=[...a];if(!r(E,Object.assign(Object.assign({},n),{coercion:void 0})))return!1;let I=()=>E.some((v,x)=>v[0]!==h[x][0]||v[1]!==h[x][1])?new Map(E):a;return n.coercions.push([(u=n.p)!==null&&u!==void 0?u:".",nI(n.coercion,a,I)]),!0}else{let h=!0;for(let[E,I]of a)if(h=t(E,Object.assign({},n))&&h,!h&&n?.errors==null||(h=e(I,Object.assign(Object.assign({},n),{p:Kp(n,E)}))&&h,!h&&n?.errors==null))break;return h}if(typeof n?.coercions<"u"){if(typeof n?.coercion>"u")return pr(n,"Unbound coercion result");let h={value:a};return Array.isArray(a)?r(a,Object.assign(Object.assign({},n),{coercion:void 0}))?(n.coercions.push([(A=n.p)!==null&&A!==void 0?A:".",nI(n.coercion,a,()=>new Map(h.value))]),!0):!1:o(a,Object.assign(Object.assign({},n),{coercion:Wu(h,"value")}))?(n.coercions.push([(p=n.p)!==null&&p!==void 0?p:".",nI(n.coercion,a,()=>new Map(Object.entries(h.value)))]),!0):!1}return pr(n,`Expected a map (got ${qn(a)})`)}})}function sD(t,{delimiter:e}={}){let r=dz(t.length);return Hr({test:(o,a)=>{var n;if(typeof o=="string"&&typeof e<"u"&&typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return pr(a,"Unbound coercion result");o=o.split(e),a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",a.coercion.bind(null,o)])}if(!Array.isArray(o))return pr(a,`Expected a tuple (got ${qn(o)})`);let u=r(o,Object.assign({},a));for(let A=0,p=o.length;A {var n;if(Array.isArray(o)&&typeof a?.coercions<"u")return typeof a?.coercion>"u"?pr(a,"Unbound coercion result"):r(o,Object.assign(Object.assign({},a),{coercion:void 0}))?(o=Object.fromEntries(o),a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",a.coercion.bind(null,o)]),!0):!1;if(typeof o!="object"||o===null)return pr(a,`Expected an object (got ${qn(o)})`);let u=Object.keys(o),A=!0;for(let p=0,h=u.length;p `:`[${x}]`)}o.push(...this.arity.leading.map(u=>`<${u}>`)),this.arity.extra===tl?o.push("..."):o.push(...this.arity.extra.map(u=>`[${u}]`)),o.push(...this.arity.trailing.map(u=>`<${u}>`))}return{usage:o.join(" "),options:a}}compile(){if(typeof this.context>"u")throw new Error("Assertion failed: No context attached");let e=yz(),r=un.InitialNode,o=this.usage().usage,a=this.options.filter(A=>A.required).map(A=>A.nameSet);r=Mc(e,el()),zo(e,un.InitialNode,Hn.StartOfInput,r,["setCandidateState",{candidateUsage:o,requiredOptions:a}]);let n=this.arity.proxy?"always":"isNotOptionLike",u=this.paths.length>0?this.paths:[[]];for(let A of u){let p=r;if(A.length>0){let v=Mc(e,el());Cy(e,p,v),this.registerOptions(e,v),p=v}for(let v=0;v {var XJe=Xp(),ZJe=Hl(),$Je=XJe(ZJe,"DataView");Cte.exports=$Je});var Bte=_((kFt,Ite)=>{var eVe=Xp(),tVe=Hl(),rVe=eVe(tVe,"Promise");Ite.exports=rVe});var Pte=_((QFt,vte)=>{var nVe=Xp(),iVe=Hl(),sVe=nVe(iVe,"Set");vte.exports=sVe});var Ste=_((RFt,Dte)=>{var oVe=Xp(),aVe=Hl(),lVe=oVe(aVe,"WeakMap");Dte.exports=lVe});var qI=_((FFt,Tte)=>{var $L=wte(),eN=UD(),tN=Bte(),rN=Pte(),nN=Ste(),Fte=gd(),Hy=qL(),bte="[object Map]",cVe="[object Object]",xte="[object Promise]",kte="[object Set]",Qte="[object WeakMap]",Rte="[object DataView]",uVe=Hy($L),AVe=Hy(eN),fVe=Hy(tN),pVe=Hy(rN),hVe=Hy(nN),dd=Fte;($L&&dd(new $L(new ArrayBuffer(1)))!=Rte||eN&&dd(new eN)!=bte||tN&&dd(tN.resolve())!=xte||rN&&dd(new rN)!=kte||nN&&dd(new nN)!=Qte)&&(dd=function(t){var e=Fte(t),r=e==cVe?t.constructor:void 0,o=r?Hy(r):"";if(o)switch(o){case uVe:return Rte;case AVe:return bte;case fVe:return xte;case pVe:return kte;case hVe:return Qte}return e});Tte.exports=dd});var qte=_((TFt,Hte)=>{var iN=HD(),gVe=jL(),dVe=kee(),mVe=Ete(),Lte=qI(),Nte=ql(),Ote=OI(),yVe=zD(),EVe=1,Mte="[object Arguments]",Ute="[object Array]",XD="[object Object]",CVe=Object.prototype,_te=CVe.hasOwnProperty;function wVe(t,e,r,o,a,n){var u=Nte(t),A=Nte(e),p=u?Ute:Lte(t),h=A?Ute:Lte(e);p=p==Mte?XD:p,h=h==Mte?XD:h;var E=p==XD,I=h==XD,v=p==h;if(v&&Ote(t)){if(!Ote(e))return!1;u=!0,E=!1}if(v&&!E)return n||(n=new iN),u||yVe(t)?gVe(t,e,r,o,a,n):dVe(t,e,p,r,o,a,n);if(!(r&EVe)){var x=E&&_te.call(t,"__wrapped__"),C=I&&_te.call(e,"__wrapped__");if(x||C){var F=x?t.value():t,N=C?e.value():e;return n||(n=new iN),a(F,N,r,o,n)}}return v?(n||(n=new iN),mVe(t,e,r,o,a,n)):!1}Hte.exports=wVe});var Wte=_((LFt,Yte)=>{var IVe=qte(),Gte=Vu();function jte(t,e,r,o,a){return t===e?!0:t==null||e==null||!Gte(t)&&!Gte(e)?t!==t&&e!==e:IVe(t,e,r,o,jte,a)}Yte.exports=jte});var zte=_((NFt,Kte)=>{var BVe=Wte();function vVe(t,e){return BVe(t,e)}Kte.exports=vVe});var sN=_((OFt,Jte)=>{var PVe=Xp(),DVe=function(){try{var t=PVe(Object,"defineProperty");return t({},"",{}),t}catch{}}();Jte.exports=DVe});var ZD=_((MFt,Xte)=>{var Vte=sN();function SVe(t,e,r){e=="__proto__"&&Vte?Vte(t,e,{configurable:!0,enumerable:!0,value:r,writable:!0}):t[e]=r}Xte.exports=SVe});var oN=_((UFt,Zte)=>{var bVe=ZD(),xVe=Ty();function kVe(t,e,r){(r!==void 0&&!xVe(t[e],r)||r===void 0&&!(e in t))&&bVe(t,e,r)}Zte.exports=kVe});var ere=_((_Ft,$te)=>{function QVe(t){return function(e,r,o){for(var a=-1,n=Object(e),u=o(e),A=u.length;A--;){var p=u[t?A:++a];if(r(n[p],p,n)===!1)break}return e}}$te.exports=QVe});var rre=_((HFt,tre)=>{var RVe=ere(),FVe=RVe();tre.exports=FVe});var aN=_((GI,qy)=>{var TVe=Hl(),ore=typeof GI=="object"&&GI&&!GI.nodeType&&GI,nre=ore&&typeof qy=="object"&&qy&&!qy.nodeType&&qy,LVe=nre&&nre.exports===ore,ire=LVe?TVe.Buffer:void 0,sre=ire?ire.allocUnsafe:void 0;function NVe(t,e){if(e)return t.slice();var r=t.length,o=sre?sre(r):new t.constructor(r);return t.copy(o),o}qy.exports=NVe});var $D=_((qFt,lre)=>{var are=YL();function OVe(t){var e=new t.constructor(t.byteLength);return new are(e).set(new are(t)),e}lre.exports=OVe});var lN=_((GFt,cre)=>{var MVe=$D();function UVe(t,e){var r=e?MVe(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.length)}cre.exports=UVe});var eS=_((jFt,ure)=>{function _Ve(t,e){var r=-1,o=t.length;for(e||(e=Array(o));++r>/2":{type_args:!1,type_result:!1,fn:function(w,S,y){return w>>S}},"/\\/2":{type_args:!1,type_result:!1,fn:function(w,S,y){return w&S}},"\\//2":{type_args:!1,type_result:!1,fn:function(w,S,y){return w|S}},"xor/2":{type_args:!1,type_result:!1,fn:function(w,S,y){return w^S}},"rem/2":{type_args:!1,type_result:!1,fn:function(w,S,y){return S?w%S:b.error.evaluation("zero_division",y.__call_indicator)}},"mod/2":{type_args:!1,type_result:!1,fn:function(w,S,y){return S?w-parseInt(w/S)*S:b.error.evaluation("zero_division",y.__call_indicator)}},"max/2":{type_args:null,type_result:null,fn:function(w,S,y){return Math.max(w,S)}},"min/2":{type_args:null,type_result:null,fn:function(w,S,y){return Math.min(w,S)}}}},directive:{"dynamic/1":function(w,S){var y=S.args[0];if(b.type.is_variable(y))w.throw_error(b.error.instantiation(S.indicator));else if(!b.type.is_compound(y)||y.indicator!=="//2")w.throw_error(b.error.type("predicate_indicator",y,S.indicator));else if(b.type.is_variable(y.args[0])||b.type.is_variable(y.args[1]))w.throw_error(b.error.instantiation(S.indicator));else if(!b.type.is_atom(y.args[0]))w.throw_error(b.error.type("atom",y.args[0],S.indicator));else if(!b.type.is_integer(y.args[1]))w.throw_error(b.error.type("integer",y.args[1],S.indicator));else{var R=S.args[0].args[0].id+"/"+S.args[0].args[1].value;w.session.public_predicates[R]=!0,w.session.rules[R]||(w.session.rules[R]=[])}},"multifile/1":function(w,S){var y=S.args[0];b.type.is_variable(y)?w.throw_error(b.error.instantiation(S.indicator)):!b.type.is_compound(y)||y.indicator!=="//2"?w.throw_error(b.error.type("predicate_indicator",y,S.indicator)):b.type.is_variable(y.args[0])||b.type.is_variable(y.args[1])?w.throw_error(b.error.instantiation(S.indicator)):b.type.is_atom(y.args[0])?b.type.is_integer(y.args[1])?w.session.multifile_predicates[S.args[0].args[0].id+"/"+S.args[0].args[1].value]=!0:w.throw_error(b.error.type("integer",y.args[1],S.indicator)):w.throw_error(b.error.type("atom",y.args[0],S.indicator))},"set_prolog_flag/2":function(w,S){var y=S.args[0],R=S.args[1];b.type.is_variable(y)||b.type.is_variable(R)?w.throw_error(b.error.instantiation(S.indicator)):b.type.is_atom(y)?b.type.is_flag(y)?b.type.is_value_flag(y,R)?b.type.is_modifiable_flag(y)?w.session.flag[y.id]=R:w.throw_error(b.error.permission("modify","flag",y)):w.throw_error(b.error.domain("flag_value",new H("+",[y,R]),S.indicator)):w.throw_error(b.error.domain("prolog_flag",y,S.indicator)):w.throw_error(b.error.type("atom",y,S.indicator))},"use_module/1":function(w,S){var y=S.args[0];if(b.type.is_variable(y))w.throw_error(b.error.instantiation(S.indicator));else if(!b.type.is_term(y))w.throw_error(b.error.type("term",y,S.indicator));else if(b.type.is_module(y)){var R=y.args[0].id;e(w.session.modules,R)===-1&&w.session.modules.push(R)}},"char_conversion/2":function(w,S){var y=S.args[0],R=S.args[1];b.type.is_variable(y)||b.type.is_variable(R)?w.throw_error(b.error.instantiation(S.indicator)):b.type.is_character(y)?b.type.is_character(R)?y.id===R.id?delete w.session.__char_conversion[y.id]:w.session.__char_conversion[y.id]=R.id:w.throw_error(b.error.type("character",R,S.indicator)):w.throw_error(b.error.type("character",y,S.indicator))},"op/3":function(w,S){var y=S.args[0],R=S.args[1],V=S.args[2];if(b.type.is_variable(y)||b.type.is_variable(R)||b.type.is_variable(V))w.throw_error(b.error.instantiation(S.indicator));else if(!b.type.is_integer(y))w.throw_error(b.error.type("integer",y,S.indicator));else if(!b.type.is_atom(R))w.throw_error(b.error.type("atom",R,S.indicator));else if(!b.type.is_atom(V))w.throw_error(b.error.type("atom",V,S.indicator));else if(y.value<0||y.value>1200)w.throw_error(b.error.domain("operator_priority",y,S.indicator));else if(V.id===",")w.throw_error(b.error.permission("modify","operator",V,S.indicator));else if(V.id==="|"&&(y.value<1001||R.id.length!==3))w.throw_error(b.error.permission("modify","operator",V,S.indicator));else if(["fy","fx","yf","xf","xfx","yfx","xfy"].indexOf(R.id)===-1)w.throw_error(b.error.domain("operator_specifier",R,S.indicator));else{var X={prefix:null,infix:null,postfix:null};for(var $ in w.session.__operators)if(!!w.session.__operators.hasOwnProperty($)){var ie=w.session.__operators[$][V.id];ie&&(e(ie,"fx")!==-1&&(X.prefix={priority:$,type:"fx"}),e(ie,"fy")!==-1&&(X.prefix={priority:$,type:"fy"}),e(ie,"xf")!==-1&&(X.postfix={priority:$,type:"xf"}),e(ie,"yf")!==-1&&(X.postfix={priority:$,type:"yf"}),e(ie,"xfx")!==-1&&(X.infix={priority:$,type:"xfx"}),e(ie,"xfy")!==-1&&(X.infix={priority:$,type:"xfy"}),e(ie,"yfx")!==-1&&(X.infix={priority:$,type:"yfx"}))}var be;switch(R.id){case"fy":case"fx":be="prefix";break;case"yf":case"xf":be="postfix";break;default:be="infix";break}if(((X.prefix&&be==="prefix"||X.postfix&&be==="postfix"||X.infix&&be==="infix")&&X[be].type!==R.id||X.infix&&be==="postfix"||X.postfix&&be==="infix")&&y.value!==0)w.throw_error(b.error.permission("create","operator",V,S.indicator));else return X[be]&&(me(w.session.__operators[X[be].priority][V.id],R.id),w.session.__operators[X[be].priority][V.id].length===0&&delete w.session.__operators[X[be].priority][V.id]),y.value>0&&(w.session.__operators[y.value]||(w.session.__operators[y.value.toString()]={}),w.session.__operators[y.value][V.id]||(w.session.__operators[y.value][V.id]=[]),w.session.__operators[y.value][V.id].push(R.id)),!0}}},predicate:{"op/3":function(w,S,y){b.directive["op/3"](w,y)&&w.success(S)},"current_op/3":function(w,S,y){var R=y.args[0],V=y.args[1],X=y.args[2],$=[];for(var ie in w.session.__operators)for(var be in w.session.__operators[ie])for(var Fe=0;Fe