diff --git a/code/__DEFINES/minimap.dm b/code/__DEFINES/minimap.dm index 9069ed323357..ca6d9718cd0c 100644 --- a/code/__DEFINES/minimap.dm +++ b/code/__DEFINES/minimap.dm @@ -4,7 +4,8 @@ #define MINIMAP_FLAG_PMC (1<<2) #define MINIMAP_FLAG_UPP (1<<3) #define MINIMAP_FLAG_CLF (1<<4) -#define MINIMAP_FLAG_ALL (1<<5) - 1 +#define MINIMAP_FLAG_YAUTJA (1<<5) +#define MINIMAP_FLAG_ALL (1<<6) - 1 ///Converts the overworld x and y to minimap x and y values #define MINIMAP_SCALE 2 diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm index 82237cd793b2..222222a09d54 100644 --- a/code/__DEFINES/xeno.dm +++ b/code/__DEFINES/xeno.dm @@ -8,6 +8,9 @@ #define TUNNEL_ENTER_BIG_XENO_DELAY 120 #define TUNNEL_ENTER_LARVA_DELAY 10 +/// The duration it takes a player controlled facehugger to leap or hug adjacently +#define FACEHUGGER_WINDUP_DURATION 1 SECONDS + // Defines for action types and click delays used by xenomorph/unarmedattack() and attack_alien(). /// Full attack delay. diff --git a/code/__HELPERS/logging.dm b/code/__HELPERS/logging.dm index 32da4c953188..5ecbff108725 100644 --- a/code/__HELPERS/logging.dm +++ b/code/__HELPERS/logging.dm @@ -108,8 +108,10 @@ if (CONFIG_GET(flag/log_interact)) WRITE_LOG(GLOB.world_game_log, "INTERACT: [msg]") LOG_REDIS("interact", "\[[time]\] [msg]") - origin.attack_log += "\[[time]\] [msg] " - target.attack_log += "\[[time]\] [msg] " + if(origin) + origin.attack_log += "\[[time]\] [msg] " + if(target) + target.attack_log += "\[[time]\] [msg] " GLOB.STUI.attack.Add("\[[time]]INTERACT: [msg]") GLOB.STUI.processing |= STUI_LOG_ATTACK diff --git a/code/_globalvars/lists/mapping_globals.dm b/code/_globalvars/lists/mapping_globals.dm index cf5b2ad435b8..47cc22dae5e1 100644 --- a/code/_globalvars/lists/mapping_globals.dm +++ b/code/_globalvars/lists/mapping_globals.dm @@ -27,6 +27,7 @@ GLOBAL_LIST_EMPTY(latewhiskey) GLOBAL_LIST_EMPTY(latejoin) GLOBAL_LIST_EMPTY(latejoin_by_squad) +GLOBAL_LIST_EMPTY(latejoin_by_job) GLOBAL_LIST_EMPTY(zombie_landmarks) diff --git a/code/datums/components/weed_food.dm b/code/datums/components/weed_food.dm index 0c578b661517..ce6c17e0af95 100644 --- a/code/datums/components/weed_food.dm +++ b/code/datums/components/weed_food.dm @@ -193,6 +193,8 @@ return FALSE if(!parent_turf?.weeds) return FALSE + if(SEND_SIGNAL(parent_mob, COMSIG_ATTEMPT_MOB_PULL) & COMPONENT_CANCEL_MOB_PULL) + return FALSE if(unmerged_time == world.time) return merge_with_weeds() // Weeds upgraded, re-merge now re-using the apperance @@ -245,6 +247,9 @@ UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE) parent_buckle = null + if(SEND_SIGNAL(parent_mob, COMSIG_ATTEMPT_MOB_PULL) & COMPONENT_CANCEL_MOB_PULL) + return FALSE + absorbing_weeds = parent_turf?.weeds if(!absorbing_weeds) return FALSE diff --git a/code/datums/emergency_calls/cryo_marines.dm b/code/datums/emergency_calls/cryo_marines.dm index eb914e198b37..fb4a0d94e177 100644 --- a/code/datums/emergency_calls/cryo_marines.dm +++ b/code/datums/emergency_calls/cryo_marines.dm @@ -36,30 +36,35 @@ if(leaders < cryo_squad.max_leaders && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_LEADER) && check_timelock(H.client, JOB_SQUAD_LEADER, time_required_for_job)) leader = H leaders++ - arm_equipment(H, /datum/equipment_preset/uscm/leader/cryo, TRUE, TRUE) + H.client.prefs.copy_all_to(H, JOB_SQUAD_LEADER, TRUE, TRUE) + arm_equipment(H, /datum/equipment_preset/uscm/leader/cryo, FALSE, TRUE) to_chat(H, SPAN_ROLE_HEADER("You are a Squad Leader in the USCM")) to_chat(H, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command.")) to_chat(H, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced.")) else if (heavies < max_heavies && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_HEAVY) && check_timelock(H.client, JOB_SQUAD_SPECIALIST, time_required_for_job)) heavies++ - arm_equipment(H, /datum/equipment_preset/uscm/spec/cryo, TRUE, TRUE) + H.client.prefs.copy_all_to(H, JOB_SQUAD_SPECIALIST, TRUE, TRUE) + arm_equipment(H, /datum/equipment_preset/uscm/spec/cryo, FALSE, TRUE) to_chat(H, SPAN_ROLE_HEADER("You are a Weapons Specialist in the USCM")) to_chat(H, SPAN_ROLE_BODY("Your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command.")) to_chat(H, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced.")) else if (medics < max_medics && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_MEDIC) && check_timelock(H.client, JOB_SQUAD_MEDIC, time_required_for_job)) medics++ - arm_equipment(H, /datum/equipment_preset/uscm/medic/cryo, TRUE, TRUE) + H.client.prefs.copy_all_to(H, JOB_SQUAD_MEDIC, TRUE, TRUE) + arm_equipment(H, /datum/equipment_preset/uscm/medic/cryo, FALSE, TRUE) to_chat(H, SPAN_ROLE_HEADER("You are a Hospital Corpsman in the USCM")) to_chat(H, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command.")) to_chat(H, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced.")) else if (engineers < max_engineers && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_ENGINEER) && check_timelock(H.client, JOB_SQUAD_ENGI, time_required_for_job)) engineers++ - arm_equipment(H, /datum/equipment_preset/uscm/engineer/cryo, TRUE, TRUE) + H.client.prefs.copy_all_to(H, JOB_SQUAD_ENGI, TRUE, TRUE) + arm_equipment(H, /datum/equipment_preset/uscm/engineer/cryo, FALSE, TRUE) to_chat(H, SPAN_ROLE_HEADER("You are an Engineer in the USCM")) to_chat(H, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command.")) to_chat(H, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced.")) else - arm_equipment(H, /datum/equipment_preset/uscm/pfc/cryo, TRUE, TRUE) + H.client.prefs.copy_all_to(H, JOB_SQUAD_MARINE, TRUE, TRUE) + arm_equipment(H, /datum/equipment_preset/uscm/pfc/cryo, FALSE, TRUE) to_chat(H, SPAN_ROLE_HEADER("You are a Rifleman in the USCM")) to_chat(H, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command.")) to_chat(H, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced.")) diff --git a/code/datums/statistics/entities/death_stats.dm b/code/datums/statistics/entities/death_stats.dm index 7e26e92ae135..4a01e4e9d72b 100644 --- a/code/datums/statistics/entities/death_stats.dm +++ b/code/datums/statistics/entities/death_stats.dm @@ -65,13 +65,25 @@ ) /mob/proc/track_mob_death(datum/cause_data/cause_data, turf/death_loc) - if(!mind || statistic_exempt) - return - if(cause_data && !istype(cause_data)) stack_trace("track_mob_death called with string cause ([cause_data]) instead of datum") cause_data = create_cause_data(cause_data) + var/log_message = "\[[time_stamp()]\] [key_name(src)] died to " + if(cause_data) + log_message += "[cause_data.cause_name]" + else + log_message += "unknown causes" + var/mob/cause_mob = cause_data?.resolve_mob() + if(cause_mob) + log_message += " from [key_name(cause_data.resolve_mob())]" + cause_mob.attack_log += "\[[time_stamp()]\] [key_name(cause_mob)] killed [key_name(src)] with [cause_data.cause_name]." + + attack_log += "[log_message]." + + if(!mind || statistic_exempt) + return + var/datum/entity/statistic/death/new_death = DB_ENTITY(/datum/entity/statistic/death) var/datum/entity/player/player_entity = get_player_from_key(mind.ckey) if(player_entity) @@ -96,7 +108,6 @@ new_death.cause_role_name = cause_data?.role new_death.cause_faction_name = cause_data?.faction - var/mob/cause_mob = cause_data?.resolve_mob() if(cause_mob) cause_mob.life_kills_total += life_value diff --git a/code/game/gamemodes/colonialmarines/colonialmarines.dm b/code/game/gamemodes/colonialmarines/colonialmarines.dm index 067201277e38..cf2b7819a596 100644 --- a/code/game/gamemodes/colonialmarines/colonialmarines.dm +++ b/code/game/gamemodes/colonialmarines/colonialmarines.dm @@ -372,11 +372,11 @@ var/headcount = count_per_faction() var/living = headcount["total_headcount"] if ((headcount["WY_headcount"] / living) > MAJORITY) - musical_track = pick('sound/theme/LastManStanding_WY.ogg') + musical_track = pick('sound/theme/lastmanstanding_wy.ogg') else if ((headcount["UPP_headcount"] / living) > MAJORITY) - musical_track = pick('sound/theme/LastManStanding_UPP.ogg') + musical_track = pick('sound/theme/lastmanstanding_upp.ogg') else if ((headcount["CLF_headcount"] / living) > MAJORITY) - musical_track = pick('sound/theme/LastManStanding_CLF.ogg') + musical_track = pick('sound/theme/lastmanstanding_clf.ogg') else if ((headcount["marine_headcount"] / living) > MAJORITY) musical_track = pick('sound/theme/neutral_melancholy2.ogg') //This is the theme song for Colonial Marines the game, fitting else diff --git a/code/game/gamemodes/colonialmarines/whiskey_outpost.dm b/code/game/gamemodes/colonialmarines/whiskey_outpost.dm index 64d8795be3d2..e172939c847f 100644 --- a/code/game/gamemodes/colonialmarines/whiskey_outpost.dm +++ b/code/game/gamemodes/colonialmarines/whiskey_outpost.dm @@ -664,8 +664,8 @@ /obj/item/ammo_magazine/rocket/wp) if(2) //Smartgun supplies spawnitems = list( - /obj/item/cell/high, - /obj/item/cell/high, + /obj/item/smartgun_battery, + /obj/item/smartgun_battery, /obj/item/ammo_magazine/smartgun, /obj/item/ammo_magazine/smartgun, /obj/item/ammo_magazine/smartgun, diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index b860667486be..234902e11d22 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -288,6 +288,8 @@ join_turf = get_turf(pick(GLOB.spawns_by_job[type])) else if(assigned_squad && GLOB.latejoin_by_squad[assigned_squad]) join_turf = get_turf(pick(GLOB.latejoin_by_squad[assigned_squad])) + else if(GLOB.latejoin_by_job[title]) + join_turf = get_turf(pick(GLOB.latejoin_by_job[title])) else join_turf = get_turf(pick(GLOB.latejoin)) human.forceMove(join_turf) diff --git a/code/game/jobs/role_authority.dm b/code/game/jobs/role_authority.dm index e7697d54f0de..d1934c597da7 100644 --- a/code/game/jobs/role_authority.dm +++ b/code/game/jobs/role_authority.dm @@ -553,6 +553,8 @@ I hope it's easier to tell what the heck this proc is even doing, unlike previou var/turf/late_join_turf if(GLOB.latejoin_by_squad[assigned_squad]) late_join_turf = get_turf(pick(GLOB.latejoin_by_squad[assigned_squad])) + else if(GLOB.latejoin_by_job[J.title]) + late_join_turf = get_turf(pick(GLOB.latejoin_by_job[J.title])) else late_join_turf = get_turf(pick(GLOB.latejoin)) H.forceMove(late_join_turf) diff --git a/code/game/machinery/computer/almayer_control.dm b/code/game/machinery/computer/almayer_control.dm index b2a931224464..7d63a2e8c3af 100644 --- a/code/game/machinery/computer/almayer_control.dm +++ b/code/game/machinery/computer/almayer_control.dm @@ -1,16 +1,3 @@ -#define STATE_DEFAULT 1 -#define STATE_EVACUATION 2 -#define STATE_EVACUATION_CANCEL 3 -#define STATE_DISTRESS 4 -#define STATE_DESTROY 5 -#define STATE_DEFCONLIST 6 - -#define STATE_MESSAGELIST 7 -#define STATE_VIEWMESSAGE 8 -#define STATE_DELMESSAGE 9 - - - #define COMMAND_SHIP_ANNOUNCE "Command Ship Announcement" /obj/structure/machinery/computer/almayer_control @@ -21,273 +8,149 @@ unslashable = TRUE unacidable = TRUE - var/state = STATE_DEFAULT - - var/is_announcement_active = TRUE - - var/cooldown_request = 0 - var/cooldown_destruct = 0 - var/cooldown_central = 0 + /// requesting a distress beacon + COOLDOWN_DECLARE(cooldown_request) + /// requesting evac + COOLDOWN_DECLARE(cooldown_destruct) + /// messaging HC (admins) + COOLDOWN_DECLARE(cooldown_central) + /// making a ship announcement + COOLDOWN_DECLARE(cooldown_message) var/list/messagetitle = list() var/list/messagetext = list() - var/currmsg = 0 - var/aicurrmsg = 0 /obj/structure/machinery/computer/almayer_control/attack_remote(mob/user as mob) return attack_hand(user) /obj/structure/machinery/computer/almayer_control/attack_hand(mob/user as mob) - if(..() || !allowed(user) || inoperable()) + if(..() || inoperable()) return + if(!allowed(user)) + to_chat(usr, SPAN_WARNING("Access denied.")) + return FALSE + if(!istype(loc.loc, /area/almayer/command/cic)) //Has to be in the CIC. Can also be a generic CIC area to communicate, if wanted. to_chat(usr, SPAN_WARNING("Unable to establish a connection.")) return FALSE - ui_interact(user) - -/obj/structure/machinery/computer/almayer_control/ui_interact(mob/user as mob) - user.set_interaction(src) + tgui_interact(user) - var/dat = "Almayer Control Console" +// tgui boilerplate \\ - if(EvacuationAuthority.evac_status == EVACUATION_STATUS_INITIATING) - dat += "Evacuation in Progress\n
\nETA: [EvacuationAuthority.get_status_panel_eta()]
" - - switch(state) - if(STATE_DEFAULT) - dat += "Alert Level: [get_security_level()]
" - dat += "
[is_announcement_active ? "Make a ship announcement" : "*Unavailable*"]" - dat += GLOB.admins.len > 0 ? "
Send a message to USCM" : "
USCM communication offline" - dat += "
Award a medal" - dat += "

" - dat += "

" - - - dat += "
Message list" - dat += "
Send Distress Beacon" - dat += "
Activate Self-Destruct" - switch(EvacuationAuthority.evac_status) - if(EVACUATION_STATUS_STANDING_BY) - dat += "
Initiate emergency evacuation" - if(EVACUATION_STATUS_INITIATING) - dat += "
Cancel emergency evacuation" - - if(STATE_EVACUATION) - dat += "Are you sure you want to evacuate the [MAIN_SHIP_NAME]? Confirm" - - if(STATE_EVACUATION_CANCEL) - dat += "Are you sure you want to cancel the evacuation of the [MAIN_SHIP_NAME]? Confirm" - - if(STATE_DISTRESS) - dat += "Are you sure you want to trigger a distress signal? The signal can be picked up by anyone listening, friendly or not. Confirm" - - if(STATE_DESTROY) - dat += "Are you sure you want to trigger the self-destruct? This would mean abandoning ship. Confirm" - - if(STATE_MESSAGELIST) - dat += "Messages:" - for(var/i = 1; i<=messagetitle.len; i++) - dat += "
[messagetitle[i]]" - - if(STATE_VIEWMESSAGE) - if (currmsg) - dat += "[messagetitle[currmsg]]

[messagetext[currmsg]]" - dat += "

Delete" - else - state = STATE_MESSAGELIST - attack_hand(user) - return FALSE +/obj/structure/machinery/computer/almayer_control/tgui_interact(mob/user, datum/tgui/ui, datum/ui_state/state) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AlmayerControl", "[name]") + ui.open() - if(STATE_DELMESSAGE) - if (currmsg) - dat += "Are you sure you want to delete this message? OK|Cancel" - else - state = STATE_MESSAGELIST - attack_hand(user) - return FALSE +/obj/structure/machinery/computer/almayer_control/ui_status(mob/user, datum/ui_state/state) + . = ..() + if(!allowed(user)) + return UI_CLOSE + if(!operable()) + return UI_CLOSE - dat += "
[(state != STATE_DEFAULT) ? "Main Menu|" : ""]Close" +/obj/structure/machinery/computer/almayer_control/ui_state(mob/user) + return GLOB.not_incapacitated_and_adjacent_strict_state - show_browser(user, dat, name, "almayer_control") - onclose(user, "almayer_control") +// tgui data \\ -/obj/structure/machinery/computer/almayer_control/Topic(href, href_list) - if(..()) - return FALSE - - usr.set_interaction(src) - var/datum/ares_link/link = GLOB.ares_link - switch(href_list["operation"]) - if("main") - state = STATE_DEFAULT - - if("ship_announce") - if(!is_announcement_active) - to_chat(usr, SPAN_WARNING("Please allow at least [COOLDOWN_COMM_MESSAGE*0.1] second\s to pass between announcements.")) - return FALSE - var/input = stripped_multiline_input(usr, "Please write a message to announce to the station crew.", "Priority Announcement", "") - if(!input || !is_announcement_active || !(usr in view(1,src))) - return FALSE - - is_announcement_active = FALSE - - var/signed = null - if(ishuman(usr)) - var/mob/living/carbon/human/H = usr - var/obj/item/card/id/id = H.wear_id - if(istype(id)) - var/paygrade = get_paygrades(id.paygrade, FALSE, H.gender) - signed = "[paygrade] [id.registered_name]" +/obj/structure/machinery/computer/almayer_control/ui_static_data(mob/user) + var/list/data = list() - shipwide_ai_announcement(input, COMMAND_SHIP_ANNOUNCE, signature = signed) - addtimer(CALLBACK(src, PROC_REF(reactivate_announcement), usr), COOLDOWN_COMM_MESSAGE) - message_admins("[key_name(usr)] has made a shipwide annoucement.") - log_announcement("[key_name(usr)] has announced the following to the ship: [input]") + data["cooldown_request"] = COOLDOWN_COMM_REQUEST + data["cooldown_destruct"] = COOLDOWN_COMM_DESTRUCT + data["cooldown_central"] = COOLDOWN_COMM_CENTRAL + data["cooldown_message"] = COOLDOWN_COMM_MESSAGE + data["distresstimelock"] = DISTRESS_TIME_LOCK + return data - if("evacuation_start") - if(state == STATE_EVACUATION) - if(security_level < SEC_LEVEL_RED) - to_chat(usr, SPAN_WARNING("The ship must be under red alert in order to enact evacuation procedures.")) - return FALSE +/obj/structure/machinery/computer/almayer_control/ui_data(mob/user) + var/list/data = list() + var/list/messages = list() - if(EvacuationAuthority.flags_scuttle & FLAGS_EVACUATION_DENY) - to_chat(usr, SPAN_WARNING("The USCM has placed a lock on deploying the evacuation pods.")) - return FALSE + data["alert_level"] = security_level - if(!EvacuationAuthority.initiate_evacuation()) - to_chat(usr, SPAN_WARNING("You are unable to initiate an evacuation procedure right now!")) - return FALSE + data["time_request"] = cooldown_request + data["time_destruct"] = cooldown_destruct + data["time_central"] = cooldown_central + data["time_message"] = cooldown_message - log_game("[key_name(usr)] has called for an emergency evacuation.") - message_admins("[key_name_admin(usr)] has called for an emergency evacuation.") - link.log_ares_security("Initiate Evacuation", "[usr] has called for an emergency evacuation.") - return TRUE + data["worldtime"] = world.time - state = STATE_EVACUATION + data["evac_status"] = EvacuationAuthority.evac_status + if(EvacuationAuthority.evac_status == EVACUATION_STATUS_INITIATING) + data["evac_eta"] = EvacuationAuthority.get_status_panel_eta() - if("evacuation_cancel") - if(state == STATE_EVACUATION_CANCEL) - if(!EvacuationAuthority.cancel_evacuation()) - to_chat(usr, SPAN_WARNING("You are unable to cancel the evacuation right now!")) - return FALSE + if(!messagetitle.len) + data["messages"] = null + else + for(var/i in 1 to length(messagetitle)) + var/list/messagedata = list(list( + "title" = messagetitle[i], + "text" = messagetext[i], + "number" = i + )) + messages += messagedata - spawn(35)//some time between AI announcements for evac cancel and SD cancel. - if(EvacuationAuthority.evac_status == EVACUATION_STATUS_STANDING_BY)//nothing changed during the wait - //if the self_destruct is active we try to cancel it (which includes lowering alert level to red) - if(!EvacuationAuthority.cancel_self_destruct(1)) - //if SD wasn't active (likely canceled manually in the SD room), then we lower the alert level manually. - set_security_level(SEC_LEVEL_RED, TRUE) //both SD and evac are inactive, lowering the security level. + data["messages"] = messages - log_game("[key_name(usr)] has canceled the emergency evacuation.") - message_admins("[key_name_admin(usr)] has canceled the emergency evacuation.") - link.log_ares_security("Cancel Evacuation", "[usr] has cancelled the emergency evacuation.") - return TRUE + return data - state = STATE_EVACUATION_CANCEL +// end tgui data \\ - if("distress") - if(state == STATE_DISTRESS) - if(world.time < DISTRESS_TIME_LOCK) - to_chat(usr, SPAN_WARNING("The distress beacon cannot be launched this early in the operation. Please wait another [time_left_until(DISTRESS_TIME_LOCK, world.time, 1 MINUTES)] minutes before trying again.")) - return FALSE +// tgui interact \\ - if(!SSticker.mode) - return FALSE //Not a game mode? +/obj/structure/machinery/computer/almayer_control/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return - if(SSticker.mode.force_end_at == 0) - to_chat(usr, SPAN_WARNING("ARES has denied your request for operational security reasons.")) - return FALSE + switch(action) + if("award") + print_medal(usr, src) + . = TRUE - if(world.time < cooldown_request + COOLDOWN_COMM_REQUEST) - to_chat(usr, SPAN_WARNING("The distress beacon has recently broadcast a message. Please wait.")) - return FALSE + // evac stuff start \\ - if(security_level == SEC_LEVEL_DELTA) - to_chat(usr, SPAN_WARNING("The ship is already undergoing self-destruct procedures!")) - return FALSE + if("evacuation_start") + if(security_level < SEC_LEVEL_RED) + to_chat(usr, SPAN_WARNING("The ship must be under red alert in order to enact evacuation procedures.")) + return FALSE - for(var/client/C in GLOB.admins) - if((R_ADMIN|R_MOD) & C.admin_holder.rights) - C << 'sound/effects/sos-morse-code.ogg' - message_admins("[key_name(usr)] has requested a Distress Beacon! [CC_MARK(usr)] (SEND) (DENY) [ADMIN_JMP_USER(usr)] [CC_REPLY(usr)]") - to_chat(usr, SPAN_NOTICE("A distress beacon request has been sent to USCM Central Command.")) + if(EvacuationAuthority.flags_scuttle & FLAGS_EVACUATION_DENY) + to_chat(usr, SPAN_WARNING("The USCM has placed a lock on deploying the evacuation pods.")) + return FALSE - cooldown_request = world.time - return TRUE + if(!EvacuationAuthority.initiate_evacuation()) + to_chat(usr, SPAN_WARNING("You are unable to initiate an evacuation procedure right now!")) + return FALSE - state = STATE_DISTRESS + log_game("[key_name(usr)] has called for an emergency evacuation.") + message_admins("[key_name_admin(usr)] has called for an emergency evacuation.") + var/datum/ares_link/link = GLOB.ares_link + link.log_ares_security("Initiate Evacuation", "[usr] has called for an emergency evacuation.") + . = TRUE - if("destroy") - if(state == STATE_DESTROY) - //Comment to test - if(world.time < DISTRESS_TIME_LOCK) - to_chat(usr, SPAN_WARNING("The self-destruct cannot be activated this early in the operation. Please wait another [time_left_until(DISTRESS_TIME_LOCK, world.time, 1 MINUTES)] minutes before trying again.")) - return FALSE - - if(!SSticker.mode) - return FALSE //Not a game mode? - - if(SSticker.mode.force_end_at == 0) - to_chat(usr, SPAN_WARNING("ARES has denied your request for operational security reasons.")) - return FALSE - - if(world.time < cooldown_destruct + COOLDOWN_COMM_DESTRUCT) - to_chat(usr, SPAN_WARNING("A self-destruct request has already been sent to high command. Please wait.")) - return FALSE - - if(get_security_level() == "delta") - to_chat(usr, SPAN_WARNING("The [MAIN_SHIP_NAME]'s self-destruct is already activated.")) - return FALSE - - for(var/client/C in GLOB.admins) - if((R_ADMIN|R_MOD) & C.admin_holder.rights) - C << 'sound/effects/sos-morse-code.ogg' - message_admins("[key_name(usr)] has requested Self-Destruct! [CC_MARK(usr)] (GRANT) (DENY) [ADMIN_JMP_USER(usr)] [CC_REPLY(usr)]") - to_chat(usr, SPAN_NOTICE("A self-destruct request has been sent to USCM Central Command.")) - cooldown_destruct = world.time - return TRUE - - state = STATE_DESTROY - - if("messagelist") - currmsg = 0 - state = STATE_MESSAGELIST - - if("viewmessage") - state = STATE_VIEWMESSAGE - if (!currmsg) - if(href_list["message-num"]) currmsg = text2num(href_list["message-num"]) - else state = STATE_MESSAGELIST + if("evacuation_cancel") + if(!EvacuationAuthority.cancel_evacuation()) + to_chat(usr, SPAN_WARNING("You are unable to cancel the evacuation right now!")) + return FALSE - if("delmessage") - state = (currmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST - - if("delmessage2") - if(currmsg) - var/title = messagetitle[currmsg] - var/text = messagetext[currmsg] - messagetitle.Remove(title) - messagetext.Remove(text) - if(currmsg == aicurrmsg) aicurrmsg = 0 - currmsg = 0 - state = STATE_MESSAGELIST + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/structure/machinery/computer/almayer_control, cancel_evac)), 4 SECONDS) - if("messageUSCM") - if(world.time < cooldown_central + COOLDOWN_COMM_CENTRAL) - to_chat(usr, SPAN_WARNING("Arrays recycling. Please stand by.")) - return FALSE - var/input = stripped_input(usr, "Please choose a message to transmit to USCM. Please be aware that this process is very expensive, and abuse will lead to termination. Transmission does not guarantee a response. There is a small delay before you may send another message. Be clear and concise.", "To abort, send an empty message.", "") - if(!input || !(usr in view(1,src)) || world.time < cooldown_central + COOLDOWN_COMM_CENTRAL) return FALSE + log_game("[key_name(usr)] has canceled the emergency evacuation.") + message_admins("[key_name_admin(usr)] has canceled the emergency evacuation.") + var/datum/ares_link/link = GLOB.ares_link + link.log_ares_security("Cancel Evacuation", "[usr] has cancelled the emergency evacuation.") + . = TRUE - high_command_announce(input, usr) - to_chat(usr, SPAN_NOTICE("Message transmitted.")) - log_announcement("[key_name(usr)] has made an USCM announcement: [input]") - cooldown_central = world.time + // evac stuff end \\ - if("changeseclevel") + if("change_sec_level") var/list/alert_list = list(num2seclevel(SEC_LEVEL_GREEN), num2seclevel(SEC_LEVEL_BLUE)) switch(security_level) if(SEC_LEVEL_GREEN) @@ -302,27 +165,125 @@ return set_security_level(seclevel2num(level_selected)) - log_game("[key_name(usr)] has changed the security level to [get_security_level()].") message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].") + var/datum/ares_link/link = GLOB.ares_link + link.log_ares_security("Security Level Update", "[usr] has changed the security level to [get_security_level()].") + . = TRUE - if("award") - print_medal(usr, src) + if("messageUSCM") + if(!COOLDOWN_FINISHED(src, cooldown_central)) + to_chat(usr, SPAN_WARNING("Arrays are re-cycling. Please stand by.")) + return FALSE + var/input = stripped_input(usr, "Please choose a message to transmit to USCM. Please be aware that this process is very expensive, and abuse will lead to termination. Transmission does not guarantee a response. There is a small delay before you may send another message. Be clear and concise.", "To abort, send an empty message.", "") + if(!input || !(usr in view(1,src)) || !COOLDOWN_FINISHED(src, cooldown_central)) + return FALSE + + high_command_announce(input, usr) + to_chat(usr, SPAN_NOTICE("Message transmitted.")) + log_announcement("[key_name(usr)] has made an USCM announcement: [input]") + COOLDOWN_START(src, cooldown_central, COOLDOWN_COMM_CENTRAL) + . = TRUE + + if("ship_announce") + if(!COOLDOWN_FINISHED(src, cooldown_message)) + to_chat(usr, SPAN_WARNING("Please allow at least [COOLDOWN_TIMELEFT(src, cooldown_message)/10] second\s to pass between announcements.")) + return FALSE + var/input = stripped_multiline_input(usr, "Please write a message to announce to the station crew.", "Priority Announcement", "") + if(!input || !COOLDOWN_FINISHED(src, cooldown_message) || !(usr in view(1,src))) + return FALSE + + var/signed = null + if(ishuman(usr)) + var/mob/living/carbon/human/human_user = usr + var/obj/item/card/id/id = human_user.wear_id + if(istype(id)) + var/paygrade = get_paygrades(id.paygrade, FALSE, human_user.gender) + signed = "[paygrade] [id.registered_name]" + + COOLDOWN_START(src, cooldown_message, COOLDOWN_COMM_MESSAGE) + shipwide_ai_announcement(input, COMMAND_SHIP_ANNOUNCE, signature = signed) + message_admins("[key_name(usr)] has made a shipwide annoucement.") + log_announcement("[key_name(usr)] has announced the following to the ship: [input]") + . = TRUE + + if("distress") + if(world.time < DISTRESS_TIME_LOCK) + to_chat(usr, SPAN_WARNING("The distress beacon cannot be launched this early in the operation. Please wait another [time_left_until(DISTRESS_TIME_LOCK, world.time, 1 MINUTES)] minutes before trying again.")) + return FALSE + + if(!SSticker.mode) + return FALSE //Not a game mode? + + if(SSticker.mode.force_end_at == 0) + to_chat(usr, SPAN_WARNING("ARES has denied your request for operational security reasons.")) + return FALSE + + if(!COOLDOWN_FINISHED(src, cooldown_request)) + to_chat(usr, SPAN_WARNING("The distress beacon has recently broadcast a message. Please wait.")) + return FALSE - updateUsrDialog() + if(security_level == SEC_LEVEL_DELTA) + to_chat(usr, SPAN_WARNING("The ship is already undergoing self-destruct procedures!")) + return FALSE + + for(var/client/admin_client as anything in GLOB.admins) + if((R_ADMIN|R_MOD) & admin_client.admin_holder.rights) + admin_client << 'sound/effects/sos-morse-code.ogg' + message_admins("[key_name(usr)] has requested a Distress Beacon! [CC_MARK(usr)] (SEND) (DENY) [ADMIN_JMP_USER(usr)] [CC_REPLY(usr)]") + to_chat(usr, SPAN_NOTICE("A distress beacon request has been sent to USCM Central Command.")) + + COOLDOWN_START(src, cooldown_request, COOLDOWN_COMM_REQUEST) + . = TRUE + + // sd \\ + + if("destroy") + if(world.time < DISTRESS_TIME_LOCK) + to_chat(usr, SPAN_WARNING("The self-destruct cannot be activated this early in the operation. Please wait another [time_left_until(DISTRESS_TIME_LOCK, world.time, 1 MINUTES)] minutes before trying again.")) + return FALSE + + if(!SSticker.mode) + return FALSE //Not a game mode? + + if(SSticker.mode.force_end_at == 0) + to_chat(usr, SPAN_WARNING("ARES has denied your request for operational security reasons.")) + return FALSE + + if(!COOLDOWN_FINISHED(src, cooldown_destruct)) + to_chat(usr, SPAN_WARNING("A self-destruct request has already been sent to high command. Please wait.")) + return FALSE + + if(get_security_level() == "delta") + to_chat(usr, SPAN_WARNING("The [MAIN_SHIP_NAME]'s self-destruct is already activated.")) + return FALSE + + for(var/client/admin_client as anything in GLOB.admins) + if((R_ADMIN|R_MOD) & admin_client.admin_holder.rights) + admin_client << 'sound/effects/sos-morse-code.ogg' + message_admins("[key_name(usr)] has requested Self-Destruct! [CC_MARK(usr)] (GRANT) (DENY) [ADMIN_JMP_USER(usr)] [CC_REPLY(usr)]") + to_chat(usr, SPAN_NOTICE("A self-destruct request has been sent to USCM Central Command.")) + COOLDOWN_START(src, cooldown_destruct, COOLDOWN_COMM_DESTRUCT) + . = TRUE + + if("delmessage") + var/number_of_message = params["number"] + if(!number_of_message) + return FALSE + var/title = messagetitle[number_of_message] + var/text = messagetext[number_of_message] + messagetitle.Remove(title) + messagetext.Remove(text) + . = TRUE -/obj/structure/machinery/computer/almayer_control/proc/reactivate_announcement(mob/user) - is_announcement_active = TRUE - updateUsrDialog() +// end tgui interact \\ -#undef STATE_DEFAULT -#undef STATE_EVACUATION -#undef STATE_EVACUATION_CANCEL -#undef STATE_DISTRESS -#undef STATE_DESTROY -#undef STATE_DEFCONLIST +// end tgui \\ -#undef STATE_MESSAGELIST -#undef STATE_VIEWMESSAGE -#undef STATE_DELMESSAGE +/obj/structure/machinery/computer/almayer_control/proc/cancel_evac() + if(EvacuationAuthority.evac_status == EVACUATION_STATUS_STANDING_BY)//nothing changed during the wait + //if the self_destruct is active we try to cancel it (which includes lowering alert level to red) + if(!EvacuationAuthority.cancel_self_destruct(1)) + //if SD wasn't active (likely canceled manually in the SD room), then we lower the alert level manually. + set_security_level(SEC_LEVEL_RED, TRUE) //both SD and evac are inactive, lowering the security level. diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm index 05784ec3c161..445ae80d401c 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm @@ -110,6 +110,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_engi, list( list("Technician Satchel", 0, /obj/item/storage/backpack/marine/satchel/tech, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR), list("Technician Welderpack", 0, /obj/item/storage/backpack/marine/engineerpack, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY), list("Technician Welder-Satchel", 0, /obj/item/storage/backpack/marine/engineerpack/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR), + list("Technician Welder Chestrig", 0, /obj/item/storage/backpack/marine/engineerpack/welder_chestrig, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY), list("BELT (CHOOSE 1)", 0, null, null, null), list("G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm index 9775c20cac33..4fcd3d25237c 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm @@ -77,6 +77,7 @@ list("Shotgun Scabbard", 5, /obj/item/storage/large_holster/m37, VENDOR_ITEM_REGULAR), list("USCM Satchel", 10, /obj/item/storage/backpack/marine/satchel, VENDOR_ITEM_REGULAR), list("USCM Technical Satchel", 10, /obj/item/storage/backpack/marine/satchel/tech, VENDOR_ITEM_REGULAR), + list("USCM Technical Chestrig", 10, /obj/item/storage/backpack/marine/engineerpack/welder_chestrig, VENDOR_ITEM_REGULAR), list("USCM Uniform", 20, /obj/item/clothing/under/marine, VENDOR_ITEM_REGULAR), list("BELTS", -1, null, null), diff --git a/code/game/objects/effects/landmarks/landmarks.dm b/code/game/objects/effects/landmarks/landmarks.dm index 1cbe10c497f6..5f4a374ba31c 100644 --- a/code/game/objects/effects/landmarks/landmarks.dm +++ b/code/game/objects/effects/landmarks/landmarks.dm @@ -378,6 +378,8 @@ name = "late join" icon_state = "x2" var/squad + /// What job should latejoin on this landmark + var/job /obj/effect/landmark/late_join/alpha name = "alpha late join" @@ -396,16 +398,24 @@ squad = SQUAD_MARINE_4 +/obj/effect/landmark/late_join/working_joe + name = "working joe late join" + job = JOB_WORKING_JOE + /obj/effect/landmark/late_join/Initialize(mapload, ...) . = ..() if(squad) LAZYADD(GLOB.latejoin_by_squad[squad], src) + else if(job) + LAZYADD(GLOB.latejoin_by_job[job], src) else GLOB.latejoin += src /obj/effect/landmark/late_join/Destroy() if(squad) LAZYREMOVE(GLOB.latejoin_by_squad[squad], src) + else if(job) + LAZYREMOVE(GLOB.latejoin_by_job[job], src) else GLOB.latejoin -= src return ..() diff --git a/code/game/objects/items/devices/cictablet.dm b/code/game/objects/items/devices/cictablet.dm index 1a4aebe813cc..b2707a20aa90 100644 --- a/code/game/objects/items/devices/cictablet.dm +++ b/code/game/objects/items/devices/cictablet.dm @@ -53,6 +53,7 @@ data["faction"] = announcement_faction data["cooldown_message"] = cooldown_between_messages + data["distresstimelock"] = DISTRESS_TIME_LOCK return data @@ -63,7 +64,6 @@ data["evac_status"] = EvacuationAuthority.evac_status data["endtime"] = announcement_cooldown data["distresstime"] = distress_cooldown - data["distresstimelock"] = DISTRESS_TIME_LOCK data["worldtime"] = world.time return data diff --git a/code/game/objects/items/devices/motion_detector.dm b/code/game/objects/items/devices/motion_detector.dm index ade74531bc91..dd0c5d45eda4 100644 --- a/code/game/objects/items/devices/motion_detector.dm +++ b/code/game/objects/items/devices/motion_detector.dm @@ -229,11 +229,14 @@ if(human_user) show_blip(human_user, M) - for(var/mob/hologram/queen/Q in GLOB.hologram_list) - if(Q.z != cur_turf.z || !(range_bounds.contains_atom(Q))) continue + for(var/mob/hologram/holo as anything in GLOB.hologram_list) + if(!holo.motion_sensed) + continue + if(holo.z != cur_turf.z || !(range_bounds.contains_atom(holo))) + continue ping_count++ if(human_user) - show_blip(human_user, Q, "queen_eye") + show_blip(human_user, holo, "queen_eye") if(ping_count > 0) playsound(loc, pick('sound/items/detector_ping_1.ogg', 'sound/items/detector_ping_2.ogg', 'sound/items/detector_ping_3.ogg', 'sound/items/detector_ping_4.ogg'), 60, 0, 7, 2) diff --git a/code/game/objects/items/devices/portable_vendor.dm b/code/game/objects/items/devices/portable_vendor.dm index 0b96b859c4ac..875087efbff0 100644 --- a/code/game/objects/items/devices/portable_vendor.dm +++ b/code/game/objects/items/devices/portable_vendor.dm @@ -270,4 +270,7 @@ list("MISC", 0, null, null, null), list("Hollow Cane", 15, /obj/item/weapon/pole/fancy_cane/this_is_a_knife, "white", "A hollow cane that can store any commonplace sharp weaponry. Said weapon not included."), + + list("AMMO", 0, null, null, null), + list("ES-4 stun magazine", 10, /obj/item/ammo_magazine/pistol/es4, "white", "Holds 19 rounds of specialized Conductive 9mm."), ) diff --git a/code/game/objects/items/explosives/grenades/marines.dm b/code/game/objects/items/explosives/grenades/marines.dm index 1892c7543414..a8e0e1803a33 100644 --- a/code/game/objects/items/explosives/grenades/marines.dm +++ b/code/game/objects/items/explosives/grenades/marines.dm @@ -547,31 +547,32 @@ ram_distance -- //for max pinballing. icon_state = inactive_icon -/obj/item/explosive/grenade/slug/proc/impact_mob(mob/living/M) - var/direction = Get_Angle(src,M) - var/target_turf = get_angle_target_turf(src,direction,throw_max) - var/fling = rand(throw_min,throw_max) //WEEEEEEEEEEEEEEEEEEEE What is going to be put into throw_atom +/obj/item/explosive/grenade/slug/proc/impact_mob(mob/living/smacked) + var/direction = Get_Angle(src, smacked) + var/target_turf = get_angle_target_turf(src,direction, throw_max) + var/fling = rand(throw_min, throw_max) //WEEEEEEEEEEEEEEEEEEEE What is going to be put into throw_atom var/random_tile = 0 //random tile for bounce - playsound(M.loc, impact_sound, 75, 1) - M.apply_damage(impact_damage, BRUTE) + playsound(smacked.loc, impact_sound, 75, 1) + smacked.apply_damage(impact_damage, BRUTE) + smacked.attack_log += "\[[time_stamp()]\] [src], fired by [fingerprintslast], struck [key_name(smacked)]." random_tile = get_random_turf_in_range(src,ram_distance,ram_distance) //getting random tile for bounce src.throw_atom(random_tile,ram_distance,SPEED_FAST,src,TRUE,NORMAL_LAUNCH,NO_FLAGS) //time for a little trolling - if(isyautja(M)|| issynth(M)) - M.apply_effect(slowdown_time * 0.5, SLOW) - M.apply_effect(dazed_time * 0.5, DAZE) + if(isyautja(smacked)|| issynth(smacked)) + smacked.apply_effect(slowdown_time * 0.5, SLOW) + smacked.apply_effect(dazed_time * 0.5, DAZE) - if(M.mob_size >= MOB_SIZE_BIG)//big xenos not KO'ed - M.apply_effect(slowdown_time * 1.2, SLOW)//They are slowed more :trol: - M.apply_effect(dazed_time * 1.2, DAZE) + if(smacked.mob_size >= MOB_SIZE_BIG)//big xenos not KO'ed + smacked.apply_effect(slowdown_time * 1.2, SLOW)//They are slowed more :trol: + smacked.apply_effect(dazed_time * 1.2, DAZE) return - M.apply_effect(knockout_time, WEAKEN)//but little xenos and humans are - M.throw_atom(target_turf,fling,SPEED_AVERAGE,M,TRUE) - M.apply_effect(slowdown_time, SLOW) - M.apply_effect(dazed_time, DAZE) + smacked.apply_effect(knockout_time, WEAKEN)//but little xenos and humans are + smacked.throw_atom(target_turf, fling, SPEED_AVERAGE, smacked, TRUE) + smacked.apply_effect(slowdown_time, SLOW) + smacked.apply_effect(dazed_time, DAZE) return /obj/item/explosive/grenade/slug/baton diff --git a/code/game/objects/items/stacks/predator.dm b/code/game/objects/items/stacks/predator.dm index e500932b08f6..42874b907e02 100644 --- a/code/game/objects/items/stacks/predator.dm +++ b/code/game/objects/items/stacks/predator.dm @@ -51,6 +51,8 @@ SPAN_NOTICE("You start hanging [victim] up by the rope...")) if(!do_after(user, 3 SECONDS, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE, victim)) return + if(victim.anchored) + return // Just in case weed_food took them during this time user.visible_message(SPAN_WARNING("[user] hangs [victim] from the ceiling!"), SPAN_NOTICE("You finish hanging [victim].")) user.stop_pulling() victim.get_hung() @@ -106,4 +108,5 @@ apply_transform(A) pixel_x = 0 pixel_y = 0 + Moved(loc, NONE, TRUE) // Trigger any movement signals return COMPONENT_CANCEL_ATTACK diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index e36225177d91..40bd143fd074 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -914,6 +914,16 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r max_fuel = 100 worn_accessible = TRUE +/obj/item/storage/backpack/marine/engineerpack/welder_chestrig + name = "\improper Technician Welder Chestrig" + desc = "A specialized Chestrig worn by technicians and engineers. It carries one medium fuel tank for quick welder refueling and use." + icon_state = "welder_chestrig" + item_state = "welder_chestrig" + max_storage_space = 12 + has_gamemode_skin = FALSE + max_fuel = 100 + worn_accessible = TRUE + // Pyrotechnician Spec backpack fuel tank /obj/item/storage/backpack/marine/engineerpack/flamethrower name = "\improper USCM Pyrotechnician G6-2 fueltank" diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm index aa9d91921fae..30be2f6bc2e2 100644 --- a/code/game/objects/items/storage/lockbox.dm +++ b/code/game/objects/items/storage/lockbox.dm @@ -54,11 +54,9 @@ req_access = list(ACCESS_WY_CORPORATE) /obj/item/storage/lockbox/loyalty/fill_preset_inventory() - new /obj/item/ammo_magazine/pistol/mod88(src) - new /obj/item/ammo_magazine/pistol/mod88(src) - new /obj/item/ammo_magazine/pistol/mod88/rubber(src) - new /obj/item/ammo_magazine/pistol/mod88/rubber(src) - + new /obj/item/ammo_magazine/pistol/es4(src) + new /obj/item/ammo_magazine/pistol/es4(src) + new /obj/item/ammo_magazine/pistol/es4(src) /obj/item/storage/lockbox/cluster name = "lockbox of cluster flashbangs" diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index c9bfb9b9f757..be7571fa84a1 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -323,13 +323,25 @@ item_state = "syn_breacher" force_wielded = MELEE_FORCE_VERY_STRONG really_heavy = TRUE + var/move_delay_addition = 1.5 /obj/item/weapon/twohanded/breacher/synth/pickup(mob/user) if(!(HAS_TRAIT(user, TRAIT_SUPER_STRONG))) - to_chat(user, SPAN_WARNING("You barely manage to lift \the [src] above your knees. This thing will probably be useless to you.")) + to_chat(user, SPAN_HIGHDANGER("You barely manage to lift [src] above your knees. This thing will probably be useless to you.")) + user.apply_effect(3, EYE_BLUR) + RegisterSignal(user, COMSIG_HUMAN_POST_MOVE_DELAY, PROC_REF(handle_movedelay)) + return ..() +/obj/item/weapon/twohanded/breacher/synth/proc/handle_movedelay(mob/living/M, list/movedata) + SIGNAL_HANDLER + movedata["move_delay"] += move_delay_addition + +/obj/item/weapon/twohanded/breacher/synth/dropped(mob/user, silent) + . = ..() + UnregisterSignal(user, COMSIG_HUMAN_POST_MOVE_DELAY) + /obj/item/weapon/twohanded/breacher/synth/attack(target as mob, mob/living/user as mob) if(!HAS_TRAIT(user, TRAIT_SUPER_STRONG)) to_chat(user, SPAN_WARNING("\The [src] is too heavy for you to use as a weapon!")) diff --git a/code/game/objects/structures/props.dm b/code/game/objects/structures/props.dm index c71f9b227668..0df2cc345cb7 100644 --- a/code/game/objects/structures/props.dm +++ b/code/game/objects/structures/props.dm @@ -1152,3 +1152,91 @@ icon = 'icons/obj/structures/props/almayer_props.dmi' icon_state = "rope" density = FALSE + +/obj/structure/prop/pred_flight + name = "hunter flight console" + desc = "A console designed by the Hunters to assist in flight pathing and navigation." + icon = 'icons/obj/structures/machinery/computer.dmi' + icon_state = "overwatch" + density = TRUE + +/obj/structure/prop/invuln/joey + name = "Workin' Joey" + desc = "A defunct Seegson-brand Working Joe lifted from deep storage by a crew of marines after the last shore leave. Attempts have been made to modify the janitorial synthetic to serve as a crude bartender, but with little success." + icon = 'icons/obj/structures/props/props.dmi' + icon_state = "joey" + unslashable = FALSE + wrenchable = FALSE + /// converted into minutes when used to determine cooldown timer between quips + var/quip_delay_minimum = 5 + /// delay between Quips. Slightly randomized with quip_delay_minimum plus a random number + COOLDOWN_DECLARE(quip_delay) + /// delay between attack voicelines. Short but done for anti-spam + COOLDOWN_DECLARE(damage_delay) + /// list of quip emotes, taken from Working Joe + var/static/list/quips = list( + /datum/emote/living/carbon/human/synthetic/working_joe/quip/alwaysknow_damaged, + /datum/emote/living/carbon/human/synthetic/working_joe/quip/not_liking, + /datum/emote/living/carbon/human/synthetic/working_joe/greeting/how_can_i_help, + /datum/emote/living/carbon/human/synthetic/working_joe/task_update/day_never_done, + /datum/emote/living/carbon/human/synthetic/working_joe/task_update/required_by_apollo, + /datum/emote/living/carbon/human/synthetic/working_joe/warning/safety_breach + ) + /// list of voicelines to use when damaged + var/static/list/damaged = list( + /datum/emote/living/carbon/human/synthetic/working_joe/warning/damage, + /datum/emote/living/carbon/human/synthetic/working_joe/warning/that_stings, + /datum/emote/living/carbon/human/synthetic/working_joe/warning/irresponsible, + /datum/emote/living/carbon/human/synthetic/working_joe/warning/this_is_futile, + /datum/emote/living/carbon/human/synthetic/working_joe/warning/hysterical, + /datum/emote/living/carbon/human/synthetic/working_joe/warning/patience + ) + +/obj/structure/prop/invuln/joey/Initialize() + . = ..() + START_PROCESSING(SSobj, src) + +/obj/structure/prop/invuln/joey/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/structure/prop/invuln/joey/process() + //check if quip_delay cooldown finished. If so, random chance it says a line + if(COOLDOWN_FINISHED(src, quip_delay) && prob(10)) + emote(pick(quips)) + var/delay = rand(3) + quip_delay_minimum + COOLDOWN_START(src, quip_delay, delay MINUTES) + +// Advert your eyes. +/obj/structure/prop/invuln/joey/attackby(obj/item/W, mob/user) + attacked() + return ..() + +/obj/structure/prop/invuln/joey/bullet_act(obj/item/projectile/P) + attacked() + return ..() + +/// A terrible way of handling being hit. If signals would work it should be used. +/obj/structure/prop/invuln/joey/proc/attacked() + if(COOLDOWN_FINISHED(src, damage_delay) && prob(25)) + emote(pick(damaged)) + COOLDOWN_START(src, damage_delay, 8 SECONDS) + +/// SAY THE LINE JOE +/obj/structure/prop/invuln/joey/proc/emote(datum/emote/living/carbon/human/synthetic/working_joe/emote) + if (!emote) + return FALSE + + for(var/mob/mob in hearers(src, null)) + mob.show_message("[src] says, \"[initial(emote.say_message)]\"", SHOW_MESSAGE_AUDIBLE) + + var/list/viewers = get_mobs_in_view(7, src) + for(var/mob/current_mob in viewers) + if(!(current_mob.client?.prefs.toggles_langchat & LANGCHAT_SEE_EMOTES)) + viewers -= current_mob + langchat_speech(initial(emote.say_message), viewers, GLOB.all_languages, skip_language_check = TRUE) + + if(initial(emote.sound)) + playsound(loc, initial(emote.sound), 50, FALSE) + return TRUE + diff --git a/code/modules/admin/tabs/event_tab.dm b/code/modules/admin/tabs/event_tab.dm index b9eb4fd47ea1..fdf70d314c21 100644 --- a/code/modules/admin/tabs/event_tab.dm +++ b/code/modules/admin/tabs/event_tab.dm @@ -491,10 +491,10 @@ for(var/obj/structure/machinery/computer/almayer_control/C in machines) if(!(C.inoperable())) var/obj/item/paper/P = new /obj/item/paper( C.loc ) - P.name = "'[command_name] Update.'" + P.name = "'[customname].'" P.info = input P.update_icon() - C.messagetitle.Add("[command_name] Update") + C.messagetitle.Add("[customname]") C.messagetext.Add(P.info) if(alert("Press \"Yes\" if you want to announce it to ship crew and marines. Press \"No\" to keep it only as printed report on communication console.",,"Yes","No") == "Yes") diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 03d2ae517354..3d50b50e414c 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -519,6 +519,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) AddInteraction("Deferred to Mentors by [key_name_admin(usr)].", player_message = "Deferred to Mentors.") to_chat(initiator, SPAN_ADMINHELP("Your ticket has been deferred to Mentors.")) + log_admin_private("Ticket [TicketHref("#[id]")] deferred to mentors by [usr.key].") log_ahelp(id, "Defer", "Deferred to mentors by [usr.key]", null, usr.ckey) Close(silent = TRUE) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 16afa8d1b4f2..4f1161709657 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1955,11 +1955,17 @@ var/const/MAX_SAVE_SLOTS = 10 load_character(slot_for_job) /// Transfers both physical characteristics and character information to character -/datum/preferences/proc/copy_all_to(mob/living/carbon/human/character, job_title, is_late_join = FALSE) +/datum/preferences/proc/copy_all_to(mob/living/carbon/human/character, job_title, is_late_join = FALSE, check_datacore = FALSE) if(!istype(character)) return find_assigned_slot(job_title, is_late_join) + if(check_datacore && !(be_random_body && be_random_name)) + for(var/datum/data/record/record as anything in GLOB.data_core.locked) + if(record.fields["name"] == real_name) + be_random_body = TRUE + be_random_name = TRUE + break if(be_random_name) real_name = random_name(gender) @@ -1987,10 +1993,11 @@ var/const/MAX_SAVE_SLOTS = 10 character.flavor_texts["legs"] = flavor_texts["legs"] character.flavor_texts["feet"] = flavor_texts["feet"] - character.med_record = strip_html(med_record) - character.sec_record = strip_html(sec_record) - character.gen_record = strip_html(gen_record) - character.exploit_record = strip_html(exploit_record) + if(!be_random_name) + character.med_record = strip_html(med_record) + character.sec_record = strip_html(sec_record) + character.gen_record = strip_html(gen_record) + character.exploit_record = strip_html(exploit_record) character.age = age character.gender = gender diff --git a/code/modules/cm_marines/equipment/guncases.dm b/code/modules/cm_marines/equipment/guncases.dm index ff4d8397be26..8538af7ca90e 100644 --- a/code/modules/cm_marines/equipment/guncases.dm +++ b/code/modules/cm_marines/equipment/guncases.dm @@ -58,13 +58,15 @@ /obj/item/storage/box/guncase/lmg name = "\improper M41AE2 heavy pulse rifle case" desc = "A gun case containing the M41AE2 heavy pulse rifle. You can get additional ammunition at requisitions." - storage_slots = 3 + storage_slots = 5 can_hold = list(/obj/item/weapon/gun/rifle/lmg, /obj/item/ammo_magazine/rifle/lmg) /obj/item/storage/box/guncase/lmg/fill_preset_inventory() new /obj/item/weapon/gun/rifle/lmg(src) new /obj/item/ammo_magazine/rifle/lmg(src) new /obj/item/ammo_magazine/rifle/lmg/holo_target(src) + new /obj/item/attachable/flashlight + new /obj/item/attachable/bipod //------------ /obj/item/storage/box/guncase/m41aMK1 diff --git a/code/modules/cm_marines/marines_consoles.dm b/code/modules/cm_marines/marines_consoles.dm index 36535a0b5141..4743034a68f4 100644 --- a/code/modules/cm_marines/marines_consoles.dm +++ b/code/modules/cm_marines/marines_consoles.dm @@ -679,11 +679,13 @@ idle_power_usage = 250 active_power_usage = 500 var/faction = FACTION_MARINE + /// What type of /datum/crewmonitor this will create + var/crewmonitor_type = /datum/crewmonitor /obj/structure/machinery/computer/crew/Initialize() . = ..() if(!GLOB.crewmonitor[faction]) - GLOB.crewmonitor[faction] = new /datum/crewmonitor(faction) + GLOB.crewmonitor[faction] = new crewmonitor_type(faction) /obj/structure/machinery/computer/crew/attack_remote(mob/living/user) attack_hand(user) @@ -714,6 +716,12 @@ icon_state = "cmonitor" density = FALSE +/obj/structure/machinery/computer/crew/alt/yautja + name = "\improper Yautja health monitor" + desc = "Used to monitor active health sensors of all Yautja in the system. You can see that the console highlights the human's ship areas with BLUE and the hunting locations with RED." + faction = FACTION_YAUTJA + crewmonitor_type = /datum/crewmonitor/yautja + /obj/structure/machinery/computer/crew/upp faction = FACTION_UPP @@ -790,7 +798,7 @@ GLOBAL_LIST_EMPTY_TYPED(crewmonitor, /datum/crewmonitor) /datum/crewmonitor/ui_data(mob/user) . = list( "sensors" = update_data(), - "link_allowed" = isAI(user) + "link_allowed" = isAI(user), ) /datum/crewmonitor/proc/update_data() @@ -1102,6 +1110,51 @@ GLOBAL_LIST_EMPTY_TYPED(crewmonitor, /datum/crewmonitor) else jobs = list() +/datum/crewmonitor/yautja + faction = FACTION_YAUTJA + +/datum/crewmonitor/yautja/update_data() + var/list/results = list() + for(var/mob/living/carbon/human/human_mob as anything in GLOB.human_mob_list) + + if(!isyautja(human_mob)) + continue + + if(faction != human_mob.faction) + continue + + // Check if z-level is correct + var/turf/pos = get_turf(human_mob) + if(!pos) + continue + + // The entry for this human + var/list/entry = list( + "ref" = REF(human_mob), + "name" = human_mob.real_name, + "ijob" = UNKNOWN_JOB_ID, + "assignment" = "Hunter", + "oxydam" = round(human_mob.getOxyLoss(), 1), + "toxdam" = round(human_mob.getToxLoss(), 1), + "burndam" = round(human_mob.getFireLoss(), 1), + "brutedam" = round(human_mob.getBruteLoss(), 1), + "can_track" = TRUE, + ) + + if(is_mainship_level(pos.z)) + entry["side"] = "Almayer" + + var/area/mob_area = get_area(human_mob) + entry["area"] = sanitize_area(mob_area.name) + + results[++results.len] = entry + + // Cache result + data = results + last_update = world.time + + return results + #undef SENSOR_LIVING #undef SENSOR_VITALS #undef SENSOR_COORDS diff --git a/code/modules/cm_phone/phone.dm b/code/modules/cm_phone/phone.dm index ac00e717f79a..b3e0ecd87206 100644 --- a/code/modules/cm_phone/phone.dm +++ b/code/modules/cm_phone/phone.dm @@ -312,6 +312,7 @@ GLOBAL_LIST_EMPTY_TYPED(transmitters, /obj/structure/transmitter) P.handle_hear(message, L, speaking) attached_to.handle_hear(message, L, speaking) + log_say("TELEPHONE: [key_name(speaking)] on Phone '[phone_id]' to '[T.phone_id]' said '[message]'") /obj/structure/transmitter/attackby(obj/item/W, mob/user) if(W == attached_to) diff --git a/code/modules/cm_preds/falcon.dm b/code/modules/cm_preds/falcon.dm index 19977a7bd84a..4461f9b4f7e7 100644 --- a/code/modules/cm_preds/falcon.dm +++ b/code/modules/cm_preds/falcon.dm @@ -68,6 +68,7 @@ var/obj/item/falcon_drone/parent_drone var/obj/item/clothing/gloves/yautja/owned_bracers desc = "An agile drone used by Yautja to survey the hunting grounds." + motion_sensed = TRUE /mob/hologram/falcon/Initialize(mapload, mob/M, obj/item/falcon_drone/drone, obj/item/clothing/gloves/yautja/bracers) . = ..() diff --git a/code/modules/cm_preds/yaut_bracers.dm b/code/modules/cm_preds/yaut_bracers.dm index f33d5f9a5554..305badf6fceb 100644 --- a/code/modules/cm_preds/yaut_bracers.dm +++ b/code/modules/cm_preds/yaut_bracers.dm @@ -46,6 +46,8 @@ var/mob/living/carbon/human/owner //Pred spawned on, or thrall given to. var/obj/item/clothing/gloves/yautja/linked_bracer //Bracer linked to this one (thrall or mentor). COOLDOWN_DECLARE(bracer_recharge) + /// What minimap icon this bracer should have + var/minimap_icon = "predator" /obj/item/clothing/gloves/yautja/equipped(mob/user, slot) . = ..() @@ -54,6 +56,8 @@ if(!owner) owner = user toggle_lock_internal(user, TRUE) + RegisterSignal(user, list(COMSIG_MOB_STAT_SET_ALIVE, COMSIG_MOB_DEATH), PROC_REF(update_minimap_icon)) + INVOKE_NEXT_TICK(src, PROC_REF(update_minimap_icon), user) /obj/item/clothing/gloves/yautja/Destroy() STOP_PROCESSING(SSobj, src) @@ -65,6 +69,8 @@ /obj/item/clothing/gloves/yautja/dropped(mob/user) STOP_PROCESSING(SSobj, src) flags_item = initial(flags_item) + UnregisterSignal(user, list(COMSIG_MOB_STAT_SET_ALIVE, COMSIG_MOB_DEATH)) + SSminimaps.remove_marker(user) ..() /obj/item/clothing/gloves/yautja/pickup(mob/living/user) @@ -94,7 +100,7 @@ return if(human_holder.stat == DEAD) decloak(human_holder, TRUE) - if(!HAS_TRAIT(human_holder, TRAIT_YAUTJA_TECH) && !human_holder.hunter_data.thralled && prob(15)) + if(!HAS_TRAIT(human_holder, TRAIT_YAUTJA_TECH) && !human_holder.hunter_data.thralled && prob(2)) decloak(human_holder) shock_user(human_holder) @@ -102,6 +108,27 @@ /obj/item/clothing/gloves/yautja/proc/decloak() return +/// Called to update the minimap icon of the predator +/obj/item/clothing/gloves/yautja/proc/update_minimap_icon() + if(!ishuman(owner)) + return + + var/mob/living/carbon/human/human_owner = owner + var/turf/wearer_turf = get_turf(owner) + SSminimaps.remove_marker(owner) + if(!isyautja(owner)) + if(owner.stat >= DEAD) + if(human_owner.undefibbable) + SSminimaps.add_marker(owner, wearer_turf.z, MINIMAP_FLAG_YAUTJA, "bracer_stolen", 'icons/ui_icons/map_blips.dmi', overlay_iconstates = list("undefibbable")) + else + SSminimaps.add_marker(owner, wearer_turf.z, MINIMAP_FLAG_YAUTJA, "bracer_stolen", 'icons/ui_icons/map_blips.dmi', overlay_iconstates = list("defibbable")) + else + SSminimaps.add_marker(owner, wearer_turf.z, MINIMAP_FLAG_YAUTJA, "bracer_stolen", 'icons/ui_icons/map_blips.dmi') + else + if(owner?.stat >= DEAD) + SSminimaps.add_marker(owner, wearer_turf.z, MINIMAP_FLAG_YAUTJA, minimap_icon, 'icons/ui_icons/map_blips.dmi', overlay_iconstates = list("undefibbable")) //defib/undefib status doesn't really matter because they're gonna explode in the end regardless + else + SSminimaps.add_marker(owner, wearer_turf.z, MINIMAP_FLAG_YAUTJA, minimap_icon, 'icons/ui_icons/map_blips.dmi') /* *This is the main proc for checking AND draining the bracer energy. It must have human passed as an argument. *It can take a negative value in amount to restore energy. @@ -193,8 +220,23 @@ desc = "A pair of strange alien bracers, adapted for human biology." color = "#b85440" + minimap_icon = "thrall" +/obj/item/clothing/gloves/yautja/thrall/update_minimap_icon() + if(!ishuman(owner)) + return + + var/mob/living/carbon/human/human_owner = owner + var/turf/wearer_turf = get_turf(owner) + if(owner.stat >= DEAD) + if(human_owner.undefibbable) + SSminimaps.add_marker(owner, wearer_turf.z, MINIMAP_FLAG_YAUTJA, minimap_icon, overlay_iconstates = list("undefibbable")) + else + SSminimaps.add_marker(owner, wearer_turf.z, MINIMAP_FLAG_YAUTJA, minimap_icon, overlay_iconstates = list("defibbable")) + else + SSminimaps.add_marker(owner, wearer_turf.z, MINIMAP_FLAG_YAUTJA, minimap_icon) + /obj/item/clothing/gloves/yautja/hunter name = "clan bracers" desc = "An extremely complex, yet simple-to-operate set of armored bracers worn by the Yautja. It has many functions, activate them to use some." @@ -293,7 +335,7 @@ var/mob/living/carbon/human/human = loc //Non-Yautja have a chance to get stunned with each power drain - if((!HAS_TRAIT(human, TRAIT_YAUTJA_TECH) && !human.hunter_data.thralled) && prob(15)) + if((!HAS_TRAIT(human, TRAIT_YAUTJA_TECH) && !human.hunter_data.thralled) && prob(4)) if(cloaked) decloak(human, TRUE, DECLOAK_SPECIES) shock_user(human) diff --git a/code/modules/cm_tech/hologram.dm b/code/modules/cm_tech/hologram.dm index 83cc0937b46e..5c0e986f45b2 100644 --- a/code/modules/cm_tech/hologram.dm +++ b/code/modules/cm_tech/hologram.dm @@ -1,4 +1,4 @@ -GLOBAL_LIST_EMPTY(hologram_list) +GLOBAL_LIST_EMPTY_TYPED(hologram_list, /mob/hologram) /mob/hologram name = "Hologram" @@ -16,6 +16,8 @@ GLOBAL_LIST_EMPTY(hologram_list) var/mob/linked_mob var/datum/action/leave_hologram/leave_button + ///If can be detected on motion detectors. + var/motion_sensed = FALSE /mob/hologram/movement_delay() . = -2 // Very fast speed, so they can navigate through easily, they can't ever have movement delay whilst as a hologram diff --git a/code/modules/gear_presets/uscm_ship.dm b/code/modules/gear_presets/uscm_ship.dm index 75d661da503f..2714dd063786 100644 --- a/code/modules/gear_presets/uscm_ship.dm +++ b/code/modules/gear_presets/uscm_ship.dm @@ -261,6 +261,7 @@ new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/medium(new_human), WEAR_R_STORE) new_human.equip_to_slot_or_del(new /obj/item/device/demo_scanner(new_human), WEAR_L_STORE) new_human.equip_to_slot_or_del(new /obj/item/storage/bag/trash(new_human), WEAR_L_HAND) + new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/marine/engineerpack/welder_chestrig, (new_human), WEAR_R_HAND) /datum/equipment_preset/uscm_ship/maint/load_rank(mob/living/carbon/human/new_human) if(new_human.client) diff --git a/code/modules/mob/camera/imaginary_friend.dm b/code/modules/mob/camera/imaginary_friend.dm index 054dd6ea8ff4..a78de70a7e15 100644 --- a/code/modules/mob/camera/imaginary_friend.dm +++ b/code/modules/mob/camera/imaginary_friend.dm @@ -200,6 +200,7 @@ to_chat(owner, "[rendered]") to_chat(src, "[rendered]") + log_say("Imaginary Friend: [dead_rendered]") if(!hidden) var/list/send_to = list() if(!owner.client?.prefs.lang_chat_disabled) diff --git a/code/modules/mob/living/carbon/human/species/yautja/fake_sounds.dm b/code/modules/mob/living/carbon/human/species/yautja/fake_sounds.dm index f29a990b6254..80aa853c663f 100644 --- a/code/modules/mob/living/carbon/human/species/yautja/fake_sounds.dm +++ b/code/modules/mob/living/carbon/human/species/yautja/fake_sounds.dm @@ -2,21 +2,25 @@ category = YAUTJA_EMOTE_CATEGORY_FAKESOUND /datum/emote/living/carbon/human/yautja/fake_sound/aliengrowl + override_say = "Xenomorph growl" key = "aliengrowl" /datum/emote/living/carbon/human/yautja/fake_sound/aliengrowl/get_sound(mob/living/user) return pick('sound/voice/alien_growl1.ogg', 'sound/voice/alien_growl2.ogg') /datum/emote/living/carbon/human/yautja/fake_sound/alienhelp + override_say = "Xenomorph needs help" key = "alienhelp" /datum/emote/living/carbon/human/yautja/fake_sound/alienhelp/get_sound(mob/living/user) return pick('sound/voice/alien_help1.ogg', 'sound/voice/alien_help2.ogg') /datum/emote/living/carbon/human/yautja/fake_sound/malescream + override_say = "Human scream (male)" key = "malescream" sound = "male_scream" /datum/emote/living/carbon/human/yautja/fake_sound/femalescream + override_say = "Human scream (female)" key = "femalescream" sound = "female_scream" diff --git a/code/modules/mob/living/carbon/human/species/yautja/fake_voice.dm b/code/modules/mob/living/carbon/human/species/yautja/fake_voice.dm index 409fa83e7f1b..7e2c73fd41e4 100644 --- a/code/modules/mob/living/carbon/human/species/yautja/fake_voice.dm +++ b/code/modules/mob/living/carbon/human/species/yautja/fake_voice.dm @@ -2,49 +2,58 @@ category = YAUTJA_EMOTE_CATEGORY_VOICE /datum/emote/living/carbon/human/yautja/voice/anytime + override_say = "Anytime." key = "anytime" sound = 'sound/voice/pred_anytime.ogg' /datum/emote/living/carbon/human/yautja/voice/helpme + override_say = "Help me!" key = "helpme" sound = 'sound/voice/pred_helpme.ogg' volume = 25 /datum/emote/living/carbon/human/yautja/voice/iseeyou + override_say = "I see you." key = "iseeyou" sound = 'sound/hallucinations/i_see_you2.ogg' /datum/emote/living/carbon/human/yautja/voice/itsatrap + override_say = "It's a trap." key = "itsatrap" sound = 'sound/voice/pred_itsatrap.ogg' volume = 25 /datum/emote/living/carbon/human/yautja/voice/overhere + override_say = "Over here." key = "overhere" sound = 'sound/voice/pred_overhere.ogg' volume = 25 /datum/emote/living/carbon/human/yautja/voice/turnaround + override_say = "Turn around." key = "turnaround" sound = 'sound/voice/pred_turnaround.ogg' volume = 25 /datum/emote/living/carbon/human/yautja/voice/comeonout + override_say = "Come on out, motherfucker." key = "comeonout" sound = 'sound/voice/pred_come_on_out.ogg' /datum/emote/living/carbon/human/yautja/voice/overthere + override_say = "Over there." key = "overthere" sound = 'sound/voice/pred_over_there.ogg' /datum/emote/living/carbon/human/yautja/voice/uglyfreak + override_say = "Come on, you ugly freak." key = "uglyfreak" sound = 'sound/voice/pred_ugly_freak.ogg' diff --git a/code/modules/mob/living/carbon/xenomorph/Embryo.dm b/code/modules/mob/living/carbon/xenomorph/Embryo.dm index 54f5892ca93c..4ce266f70596 100644 --- a/code/modules/mob/living/carbon/xenomorph/Embryo.dm +++ b/code/modules/mob/living/carbon/xenomorph/Embryo.dm @@ -337,8 +337,8 @@ if(larva_embryo.client) larva_embryo.set_lighting_alpha_from_prefs(larva_embryo.client) - larva_embryo.attack_log += "\[[time_stamp()]\] chestbursted from [key_name(victim)]" - victim.attack_log += "\[[time_stamp()]\] Was chestbursted, larva was [key_name(larva_embryo)]" + larva_embryo.attack_log += "\[[time_stamp()]\] chestbursted from [key_name(victim)] in [get_area_name(larva_embryo)] at X[victim.x], Y[victim.y], Z[victim.z]" + victim.attack_log += "\[[time_stamp()]\] Was chestbursted in [get_area_name(larva_embryo)] at X[victim.x], Y[victim.y], Z[victim.z]. The larva was [key_name(larva_embryo)]." if(burstcount) step(larva_embryo, pick(cardinal)) @@ -359,7 +359,7 @@ if(!victim.first_xeno) to_chat(larva_embryo, SPAN_XENOHIGHDANGER("The Queen's will overwhelms your instincts...")) to_chat(larva_embryo, SPAN_XENOHIGHDANGER("\"[hive.hive_orders]\"")) - log_attack("[key_name(victim)] chestbursted, the larva was [key_name(larva_embryo)].") //this is so that admins are not spammed with los logs + log_attack("[key_name(victim)] chestbursted in [get_area_name(larva_embryo)] at X[victim.x], Y[victim.y], Z[victim.z]. The larva was [key_name(larva_embryo)].") //this is so that admins are not spammed with los logs for(var/obj/item/alien_embryo/AE in victim) qdel(AE) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/facehugger/facehugger_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/facehugger/facehugger_abilities.dm index 9f5de1c631cd..91bda707ec45 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/facehugger/facehugger_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/facehugger/facehugger_abilities.dm @@ -12,7 +12,7 @@ knockdown = TRUE knockdown_duration = 0.5 windup = TRUE - windup_duration = 10 + windup_duration = FACEHUGGER_WINDUP_DURATION freeze_self = TRUE freeze_time = 5 freeze_play_sound = FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/attack_alien.dm b/code/modules/mob/living/carbon/xenomorph/attack_alien.dm index 246e2d2809db..8e64afa3f733 100644 --- a/code/modules/mob/living/carbon/xenomorph/attack_alien.dm +++ b/code/modules/mob/living/carbon/xenomorph/attack_alien.dm @@ -982,3 +982,12 @@ var/matrix/A = matrix() apply_transform(A) stat &= ~BROKEN //Remove broken. MAGICAL REPAIRS + +//Misc +/obj/structure/prop/invuln/joey/attack_alien(mob/living/carbon/xenomorph/alien) + alien.animation_attack_on(src) + alien.visible_message(SPAN_DANGER("[alien] [alien.slashes_verb] [src]!"), \ + SPAN_DANGER("You [alien.slash_verb] [src]!"), null, 5) + playsound(loc, "alien_claw_metal", 25, 1) + attacked() + return XENO_ATTACK_ACTION diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm index 79a5f986ea10..ac03389994c9 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm @@ -133,7 +133,7 @@ to_chat(src, SPAN_WARNING("You can't infect \the [human]...")) return visible_message(SPAN_WARNING("\The [src] starts climbing onto \the [human]'s face..."), SPAN_XENONOTICE("You start climbing onto \the [human]'s face...")) - if(!do_after(src, 6 SECONDS, INTERRUPT_ALL, BUSY_ICON_HOSTILE, human, INTERRUPT_MOVED, BUSY_ICON_HOSTILE)) + if(!do_after(src, FACEHUGGER_WINDUP_DURATION, INTERRUPT_ALL, BUSY_ICON_HOSTILE, human, INTERRUPT_MOVED, BUSY_ICON_HOSTILE)) return if(!human.lying) to_chat(src, SPAN_WARNING("You can't reach \the [human], they need to be lying down.")) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm index f3a354b42ad0..53e30d374b2c 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm @@ -68,6 +68,7 @@ /mob/hologram/queen name = "Queen Eye" action_icon_state = "queen_exit" + motion_sensed = TRUE color = "#a800a8" diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm index 69e5b82aa307..f946ec44b5b7 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm @@ -71,7 +71,7 @@ /mob/living/carbon/xenomorph/runner/initialize_pass_flags(datum/pass_flags_container/PF) ..() if (PF) - PF.flags_pass = PASS_FLAGS_CRAWLER + PF.flags_pass |= PASS_FLAGS_CRAWLER /datum/behavior_delegate/runner_base name = "Base Runner Behavior Delegate" diff --git a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm index 9bdbf3a89d6d..acc72586e647 100644 --- a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm +++ b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm @@ -353,6 +353,8 @@ /// How many lesser drones the hive can support var/lesser_drone_limit = 0 + /// Slots available for lesser drones will never go below this number + var/lesser_drone_minimum = 3 var/datum/tacmap/xeno/tacmap var/minimap_type = MINIMAP_FLAG_XENO @@ -1052,7 +1054,7 @@ hugger.timeofdeath = user.timeofdeath // Keep old death time /datum/hive_status/proc/update_lesser_drone_limit() - lesser_drone_limit = Ceiling(totalXenos.len / 3) + lesser_drone_limit = lesser_drone_minimum + Ceiling(length(totalXenos) / 3) /datum/hive_status/proc/can_spawn_as_lesser_drone(mob/dead/observer/user) if(!GLOB.hive_datum || ! GLOB.hive_datum[hivenumber]) diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index 5325e89910ba..2178e2d53f5c 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -258,7 +258,8 @@ if(organ_status >= ORGAN_BROKEN && prob(5 * delta_time)) owner.apply_effect(1, PARALYZE) - owner.make_jittery(50) + if(owner.jitteriness < 100) + owner.make_jittery(50) to_chat(owner, SPAN_DANGER("Your body seizes up!")) /datum/internal_organ/brain/prosthetic //used by synthetic species diff --git a/code/modules/projectiles/guns/specialist.dm b/code/modules/projectiles/guns/specialist.dm index 22fb290878e9..66456f4e21fc 100644 --- a/code/modules/projectiles/guns/specialist.dm +++ b/code/modules/projectiles/guns/specialist.dm @@ -829,26 +829,27 @@ muzzle_flash(angle,user) simulate_recoil(0, user) - var/obj/item/explosive/grenade/F = cylinder.contents[1] - cylinder.remove_from_storage(F, user.loc) + var/obj/item/explosive/grenade/fired = cylinder.contents[1] + cylinder.remove_from_storage(fired, user.loc) var/pass_flags = NO_FLAGS if(is_lobbing) - if(istype(F, /obj/item/explosive/grenade/slug/baton)) + if(istype(fired, /obj/item/explosive/grenade/slug/baton)) if(ishuman(user)) var/mob/living/carbon/human/human_user = user - human_user.remember_dropped_object(F) + human_user.remember_dropped_object(fired) + fired.fingerprintslast = key_name(user) pass_flags |= PASS_MOB_THRU_HUMAN|PASS_MOB_IS_OTHER|PASS_OVER else pass_flags |= PASS_MOB_THRU|PASS_HIGH_OVER - msg_admin_attack("[key_name_admin(user)] fired a grenade ([F.name]) from \a ([name]).") + msg_admin_attack("[key_name_admin(user)] fired a grenade ([fired.name]) from \a ([name]).") log_game("[key_name_admin(user)] used a grenade ([name]).") - F.throw_range = 20 - F.det_time = min(10, F.det_time) - F.activate(user, FALSE) - F.forceMove(get_turf(src)) - F.throw_atom(target, 20, SPEED_VERY_FAST, user, null, NORMAL_LAUNCH, pass_flags) + fired.throw_range = 20 + fired.det_time = min(10, fired.det_time) + fired.activate(user, FALSE) + fired.forceMove(get_turf(src)) + fired.throw_atom(target, 20, SPEED_VERY_FAST, user, null, NORMAL_LAUNCH, pass_flags) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 2fc04e35f399..e4251f5f6b31 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -501,13 +501,14 @@ if(ammo.sound_miss) playsound_client(L.client, ammo.sound_miss, get_turf(L), 75, TRUE) L.visible_message(SPAN_AVOIDHARM("[src] misses [L]!"), SPAN_AVOIDHARM("[src] narrowly misses you!"), null, 4, CHAT_TYPE_TAKING_HIT) - log_attack("[src] narrowly missed [key_name(L)]") + var/log_message = "[src] narrowly missed [key_name(L)]" var/mob/living/carbon/shotby = firer if(istype(shotby)) - L.attack_log += "[time_stamp()]\] [src], fired by [key_name(firer)], narrowly missed [key_name(L)]" - shotby.attack_log += "[time_stamp()]\] [src], fired by [key_name(shotby)], narrowly missed [key_name(L)]" - + L.attack_log += "\[[time_stamp()]\] [src], fired by [key_name(firer)], narrowly missed [key_name(L)]" + shotby.attack_log += "\[[time_stamp()]\] [src], fired by [key_name(shotby)], narrowly missed [key_name(L)]" + log_message = "[src], fired by [key_name(firer)], narrowly missed [key_name(L)]" + log_attack(log_message) #if DEBUG_HIT_CHANCE to_world(SPAN_DEBUG("([L]) Missed.")) diff --git a/code/modules/reagents/chemistry_machinery/acid_harness.dm b/code/modules/reagents/chemistry_machinery/acid_harness.dm index 49cb8860fa00..ae54474c3aed 100644 --- a/code/modules/reagents/chemistry_machinery/acid_harness.dm +++ b/code/modules/reagents/chemistry_machinery/acid_harness.dm @@ -39,6 +39,10 @@ /obj/item/storage/internal/accessory/black_vest/acid_harness storage_slots = 2 + can_hold = list( + /obj/item/reagent_container/glass/beaker, + /obj/item/cell, + ) /obj/item/clothing/accessory/storage/black_vest/acid_harness name = "A.C.I.D. Harness" diff --git a/code/modules/shuttle/computers/dropship_computer.dm b/code/modules/shuttle/computers/dropship_computer.dm index 50449b32fcb9..5ad84e17f159 100644 --- a/code/modules/shuttle/computers/dropship_computer.dm +++ b/code/modules/shuttle/computers/dropship_computer.dm @@ -362,6 +362,9 @@ update_equipment(is_optimised) if(is_set_flyby) to_chat(user, SPAN_NOTICE("You begin the launch sequence for a flyby.")) + var/log = "[key_name(user)] launched the dropship [src.shuttleId] on flyby." + msg_admin_niche(log) + log_interact(user, msg = "[log]") shuttle.send_for_flyby() return TRUE var/dockId = params["target"] @@ -387,6 +390,9 @@ return TRUE SSshuttle.moveShuttle(shuttle.id, dock.id, TRUE) to_chat(user, SPAN_NOTICE("You begin the launch sequence to [dock].")) + var/log = "[key_name(user)] launched the dropship [src.shuttleId] on transport." + msg_admin_niche(log) + log_interact(user, msg = "[log]") return TRUE if("button-push") playsound(loc, get_sfx("terminal_button"), KEYBOARD_SOUND_VOLUME, 1) @@ -403,10 +409,14 @@ to_chat(user, SPAN_WARNING("Door controls have been overridden. Please call technical support.")) if("set-ferry") is_set_flyby = FALSE - msg_admin_niche("[key_name_admin(usr)] set the dropship [src.shuttleId] into transport") + var/log = "[key_name(user)] set the dropship [src.shuttleId] into transport" + msg_admin_niche(log) + log_interact(user, msg = "[log]") if("set-flyby") is_set_flyby = TRUE - msg_admin_niche("[key_name_admin(usr)] set the dropship [src.shuttleId] into flyby") + var/log = "[key_name(user)] set the dropship [src.shuttleId] into flyby." + msg_admin_niche(log) + log_interact(user, msg = "[log]") if("set-automate") var/almayer_lz = params["hangar_id"] var/ground_lz = params["ground_id"] @@ -426,7 +436,9 @@ shuttle.automated_lz_id = ground_lz shuttle.automated_delay = delay playsound(loc, get_sfx("terminal_button"), KEYBOARD_SOUND_VOLUME, 1) - message_admins("[key_name_admin(usr)] has set auto pilot on '[shuttle.name]'") + var/log = "[key_name(user)] has enabled auto pilot on '[shuttle.name]'" + message_admins(log) + log_interact(user, msg = "[log]") return /* TODO if(!dropship.automated_launch) //If we're toggling it on... @@ -440,7 +452,9 @@ shuttle.automated_lz_id = null shuttle.automated_delay = null playsound(loc, get_sfx("terminal_button"), KEYBOARD_SOUND_VOLUME, 1) - message_admins("[key_name_admin(usr)] has removed auto pilot on '[shuttle.name]'") + var/log = "[key_name(user)] has disabled auto pilot on '[shuttle.name]'" + message_admins(log) + log_interact(user, msg = "[log]") return if("cancel-flyby") diff --git a/code/modules/surgery/brainrepair.dm b/code/modules/surgery/brainrepair.dm index 6d3060c2a4a6..2b4e51292203 100644 --- a/code/modules/surgery/brainrepair.dm +++ b/code/modules/surgery/brainrepair.dm @@ -55,10 +55,11 @@ var/datum/internal_organ/brain/B = target.internal_organs_by_name["brain"] if(B) - B.damage = 0 + B.heal_damage(B.damage) target.disabilities &= ~NERVOUS target.sdisabilities &= ~DISABILITY_DEAF target.sdisabilities &= ~DISABILITY_MUTE + target.jitteriness = 0 target.pain.recalculate_pain() log_interact(user, target, "[key_name(user)] finished taking bone chips out of [key_name(target)]'s brain with \the [tool], finishing [surgery].") diff --git a/html/changelogs/AutoChangeLog-pr-3860.yml b/html/changelogs/AutoChangeLog-pr-3860.yml new file mode 100644 index 000000000000..c897739d6646 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3860.yml @@ -0,0 +1,4 @@ +author: "ghostsheet" +delete-after: True +changes: + - rscadd: "B5 Breaching Hammer will now slow down humans who picks it up." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3967.yml b/html/changelogs/AutoChangeLog-pr-3967.yml deleted file mode 100644 index 50154f014b9a..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3967.yml +++ /dev/null @@ -1,9 +0,0 @@ -author: "ihatethisengine" -delete-after: True -changes: - - balance: "you can stack scratched portable cades if their HP at least 75%. Doing so will reduce the health of all barricades in the stack to the level of the most damaged." - - balance: "you can repair stacked portable cades but it will take longer time depending on how many cades in stack." - - balance: "miniengi skill makes repairs of folded portable cades faster (10 seconds to 5 seconds, same as engineer)." - - balance: "with engineering skill at least of miniengi you can collapse deployed portable barricade with a crowbar (wrench is no longer required, slightly faster (2 sec to 1.5 sec))." - - balance: "you no longer need to have folded portable cade in hand in order to repair it." - - balance: "if you have folded portable cade in hand, you can move while repairing it." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4024.yml b/html/changelogs/AutoChangeLog-pr-4024.yml new file mode 100644 index 000000000000..1d20fc50b0a1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4024.yml @@ -0,0 +1,6 @@ +author: "realforest2001" +delete-after: True +changes: + - admin: "Added logs for speech through telephones and deferring ahelps to mentors." + - admin: "Chestburst logs now include location data. Mentor Imaginary Friend now logs its speech. Narrow miss shots now log who fired them (where applicable)." + - admin: "Dropship interactions (Launch/Flyby/Autopilot) are now logged again, and also included in attack logs for the user." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4039.yml b/html/changelogs/AutoChangeLog-pr-4039.yml deleted file mode 100644 index e5f8cdafacdc..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4039.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - bugfix: "Fixed ctrl+click joining as an afk xeno not checking banishment" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4040.yml b/html/changelogs/AutoChangeLog-pr-4040.yml deleted file mode 100644 index 86b53c8a1bb3..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4040.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "zzzmike" -delete-after: True -changes: - - spellcheck: "disordely -> disorderly and minor grammar fixes" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4041.yml b/html/changelogs/AutoChangeLog-pr-4041.yml deleted file mode 100644 index 9a9b57f35eb4..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4041.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - rscadd: "Added prompts for xeno candidates to optionally take over a larva when an unnested host is ready to burst" - - bugfix: "Fixed larva spawning in hosts not triggering the preference unpool taskbar flash." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4052.yml b/html/changelogs/AutoChangeLog-pr-4052.yml deleted file mode 100644 index 5253223c1464..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4052.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Morrow" -delete-after: True -changes: - - rscadd: "Brain damage now causes random wandering, dropping of items, paralysis, and jittering" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4057.yml b/html/changelogs/AutoChangeLog-pr-4057.yml new file mode 100644 index 000000000000..0677c85b9dd8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4057.yml @@ -0,0 +1,4 @@ +author: "realforest2001" +delete-after: True +changes: + - rscadd: "Added the falcon drone to marine motion detectors, appearing the same as Queen eye." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4059.yml b/html/changelogs/AutoChangeLog-pr-4059.yml new file mode 100644 index 000000000000..cef9e6ea95b2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4059.yml @@ -0,0 +1,4 @@ +author: "Ben10083" +delete-after: True +changes: + - mapadd: "ARES Chamber now has a security camera console" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4066.yml b/html/changelogs/AutoChangeLog-pr-4066.yml new file mode 100644 index 000000000000..db124283d592 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4066.yml @@ -0,0 +1,5 @@ +author: "stanalbatross" +delete-after: True +changes: + - ui: "changed the almayer control console from html to tgui" + - bugfix: "custom faction messages will now be named properly in the paper printed out from the almayer control console" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4068.yml b/html/changelogs/AutoChangeLog-pr-4068.yml new file mode 100644 index 000000000000..f0437bbca87c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4068.yml @@ -0,0 +1,5 @@ +author: "Zonespace27" +delete-after: True +changes: + - rscadd: "WJs now spawn in the ARES core." + - rscadd: "There is now a synthetic repair station in the ARES core." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4074.yml b/html/changelogs/AutoChangeLog-pr-4074.yml new file mode 100644 index 000000000000..cea925a9026d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4074.yml @@ -0,0 +1,4 @@ +author: "Zonespace27" +delete-after: True +changes: + - rscdel: "You can no longer move the carp nade in the yautja ship" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4075.yml b/html/changelogs/AutoChangeLog-pr-4075.yml new file mode 100644 index 000000000000..d590d7020367 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4075.yml @@ -0,0 +1,4 @@ +author: "Segrain" +delete-after: True +changes: + - bugfix: "Lesser drones now can pass through runners same as through any other castes." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4076.yml b/html/changelogs/AutoChangeLog-pr-4076.yml new file mode 100644 index 000000000000..0299cb845e98 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4076.yml @@ -0,0 +1,4 @@ +author: "Segrain" +delete-after: True +changes: + - rscadd: "Joining cryomarines now uses your assigned character slot for the role you get (as long as you have not already used that character name this round)." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4079.yml b/html/changelogs/AutoChangeLog-pr-4079.yml new file mode 100644 index 000000000000..5a7fcc03642b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4079.yml @@ -0,0 +1,4 @@ +author: "Zonespace27" +delete-after: True +changes: + - bugfix: "Predator ship health monitor console now works" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4080.yml b/html/changelogs/AutoChangeLog-pr-4080.yml new file mode 100644 index 000000000000..2f631b6d1a70 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4080.yml @@ -0,0 +1,5 @@ +author: "Zonespace27" +delete-after: True +changes: + - rscadd: "Predators and thralls are now visible on the predship tacmap." + - rscadd: "Anyone wearing a stolen predator bracer is now visible on the predship tacmap." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4082.yml b/html/changelogs/AutoChangeLog-pr-4082.yml new file mode 100644 index 000000000000..bc2e8e989ea7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4082.yml @@ -0,0 +1,4 @@ +author: "blackdragonTOW" +delete-after: True +changes: + - bugfix: "fixed a file reference that broke end of round music for some factions" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4083.yml b/html/changelogs/AutoChangeLog-pr-4083.yml new file mode 100644 index 000000000000..6fa9a43c2892 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4083.yml @@ -0,0 +1,4 @@ +author: "Zonespace27" +delete-after: True +changes: + - qol: "Predator emote panel emotes now look a bit cleaner in the menu" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4084.yml b/html/changelogs/AutoChangeLog-pr-4084.yml new file mode 100644 index 000000000000..51bc383a0eda --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4084.yml @@ -0,0 +1,4 @@ +author: "Zonespace27" +delete-after: True +changes: + - bugfix: "Predator flight computers can no longer be walked on." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4090.yml b/html/changelogs/AutoChangeLog-pr-4090.yml new file mode 100644 index 000000000000..786b56eed7bb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4090.yml @@ -0,0 +1,4 @@ +author: "realforest2001" +delete-after: True +changes: + - bugfix: "Yautja Bracers are no longer hyper lethal electrical outlets." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4093.yml b/html/changelogs/AutoChangeLog-pr-4093.yml new file mode 100644 index 000000000000..5b0503e1ec68 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4093.yml @@ -0,0 +1,4 @@ +author: "Ben10083" +delete-after: True +changes: + - rscadd: "Workin Joey now randomly talks and responds when attacked" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4094.yml b/html/changelogs/AutoChangeLog-pr-4094.yml new file mode 100644 index 000000000000..071aedb02f61 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4094.yml @@ -0,0 +1,4 @@ +author: "Huffie56" +delete-after: True +changes: + - bugfix: "forbidden all the items beside battery and beakers to avoid weirdness and bug." \ No newline at end of file diff --git a/html/changelogs/archive/2023-07.yml b/html/changelogs/archive/2023-07.yml index 79e77bff0de4..0ee8702c72e8 100644 --- a/html/changelogs/archive/2023-07.yml +++ b/html/changelogs/archive/2023-07.yml @@ -610,3 +610,30 @@ - admin: notes applied to players now include the round id it was applied in realforest2001: - bugfix: Donator custom masks now properly protect from cold weather. +2023-07-31: + Drathek: + - rscadd: Added prompts for xeno candidates to optionally take over a larva when + an unnested host is ready to burst + - bugfix: Fixed larva spawning in hosts not triggering the preference unpool taskbar + flash. + - bugfix: Fixed ctrl+click joining as an afk xeno not checking banishment + Morrow: + - rscadd: Brain damage now causes random wandering, dropping of items, paralysis, + and jittering + ihatethisengine: + - balance: you can stack scratched portable cades if their HP at least 75%. Doing + so will reduce the health of all barricades in the stack to the level of the + most damaged. + - balance: you can repair stacked portable cades but it will take longer time depending + on how many cades in stack. + - balance: miniengi skill makes repairs of folded portable cades faster (10 seconds + to 5 seconds, same as engineer). + - balance: with engineering skill at least of miniengi you can collapse deployed + portable barricade with a crowbar (wrench is no longer required, slightly faster + (2 sec to 1.5 sec)). + - balance: you no longer need to have folded portable cade in hand in order to repair + it. + - balance: if you have folded portable cade in hand, you can move while repairing + it. + zzzmike: + - spellcheck: disordely -> disorderly and minor grammar fixes diff --git a/html/changelogs/archive/2023-08.yml b/html/changelogs/archive/2023-08.yml new file mode 100644 index 000000000000..d8fa59382b06 --- /dev/null +++ b/html/changelogs/archive/2023-08.yml @@ -0,0 +1,24 @@ +2023-08-01: + Drathek: + - bugfix: Fixed hung mobs merging with weeds +2023-08-02: + Dorodomki: + - rscadd: Adds A Bipod and Rail Flashlight to the HPR kit + Drathek: + - balance: Facehugger attack windup duration is now 1s like the pounce windup. + Huffie56: + - bugfix: Care package for SG on WO will now spawn with the proper batteries for + them. + Morrow: + - bugfix: Fixes brain damage + - qol: Jittering from brain damage is now capped +2023-08-03: + Ben10083: + - rscadd: Lesser Drone Slots now have a minimum, currently set to 3. + Huffie56: + - balance: adding the possibility to buy "ES-4 stun magazine" for 10 point in the + portable vendor. + - bugfix: remove a bunch of ammo that where improper for ES-4 gun that are in the + lockbox. + Thwomper: + - maptweak: added Workin' Joey to maint bar. diff --git a/icons/mob/humans/onmob/back.dmi b/icons/mob/humans/onmob/back.dmi index fe04c9d66dc3..4689fd35ab50 100644 Binary files a/icons/mob/humans/onmob/back.dmi and b/icons/mob/humans/onmob/back.dmi differ diff --git a/icons/mob/humans/onmob/items_lefthand_0.dmi b/icons/mob/humans/onmob/items_lefthand_0.dmi index 1f154ef92396..a040ddb7a65e 100644 Binary files a/icons/mob/humans/onmob/items_lefthand_0.dmi and b/icons/mob/humans/onmob/items_lefthand_0.dmi differ diff --git a/icons/mob/humans/onmob/items_righthand_0.dmi b/icons/mob/humans/onmob/items_righthand_0.dmi index 858da88c29ed..a09244c30139 100644 Binary files a/icons/mob/humans/onmob/items_righthand_0.dmi and b/icons/mob/humans/onmob/items_righthand_0.dmi differ diff --git a/icons/obj/items/clothing/backpacks.dmi b/icons/obj/items/clothing/backpacks.dmi index 8dbba91502fe..26d2c944e9dd 100644 Binary files a/icons/obj/items/clothing/backpacks.dmi and b/icons/obj/items/clothing/backpacks.dmi differ diff --git a/icons/obj/structures/props/props.dmi b/icons/obj/structures/props/props.dmi index bd22e985b2ae..57485feeaecc 100644 Binary files a/icons/obj/structures/props/props.dmi and b/icons/obj/structures/props/props.dmi differ diff --git a/icons/ui_icons/map_blips.dmi b/icons/ui_icons/map_blips.dmi index 829d9b8a43b0..0034b4fd6ff7 100644 Binary files a/icons/ui_icons/map_blips.dmi and b/icons/ui_icons/map_blips.dmi differ diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm index f8c9cc99d534..741b511792b1 100644 --- a/maps/map_files/USS_Almayer/USS_Almayer.dmm +++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm @@ -23219,32 +23219,13 @@ }, /area/almayer/shipboard/brig/lobby) "bRo" = ( -/obj/structure/machinery/door/poddoor/shutters/almayer{ - id = "ARES StairsLower"; - name = "\improper ARES Core Shutters"; - plane = -7 - }, -/obj/effect/step_trigger/ares_alert/public{ - alert_id = "AresStairs"; - alert_message = "Caution: Movement detected in ARES Core."; - cooldown_duration = 1200 - }, -/obj/effect/step_trigger/ares_alert/public{ - alert_id = "AresStairs"; - alert_message = "Caution: Movement detected in ARES Core."; - cooldown_duration = 1200 - }, -/obj/structure/machinery/door/poddoor/almayer/blended/white/open{ - closed_layer = 3.2; - id = "ARES Emergency"; - layer = 3.2; - name = "ARES Emergency Lockdown"; - needs_power = 0; - open_layer = 1.9; - plane = -7 +/obj/effect/landmark/late_join/working_joe, +/obj/effect/landmark/start/working_joe, +/obj/structure/machinery/light{ + dir = 8 }, /turf/open/floor/almayer/no_build{ - icon_state = "test_floor4" + icon_state = "ai_floors" }, /area/almayer/command/airoom) "bRr" = ( @@ -23953,7 +23934,6 @@ }, /area/almayer/squads/delta) "bUx" = ( -/obj/effect/landmark/start/working_joe, /obj/structure/machinery/light/small{ dir = 8 }, @@ -28456,6 +28436,12 @@ icon_state = "redcorner" }, /area/almayer/shipboard/brig/execution) +"czG" = ( +/obj/structure/machinery/recharge_station, +/turf/open/floor/almayer/no_build{ + icon_state = "ai_floors" + }, +/area/almayer/command/airoom) "czJ" = ( /obj/structure/sign/safety/restrictedarea{ pixel_x = 8; @@ -37871,19 +37857,13 @@ /turf/open/floor/almayer, /area/almayer/hull/upper_hull/u_f_p) "gAe" = ( -/obj/structure/filingcabinet{ - density = 0; - pixel_x = -8; - pixel_y = 18 - }, -/obj/structure/filingcabinet{ - density = 0; - pixel_x = 8; - pixel_y = 18 +/obj/structure/machinery/door_control{ + id = "ARES JoeCryo"; + name = "Working Joe Cryogenics Lockdown"; + pixel_x = 24; + pixel_y = 8; + req_one_access_txt = "19;200;90;91;92" }, -/obj/item/folder/white, -/obj/item/folder/white, -/obj/item/folder/white, /turf/open/floor/almayer/no_build{ icon_state = "ai_floors" }, @@ -51742,7 +51722,6 @@ }, /area/almayer/living/pilotbunks) "mLE" = ( -/obj/effect/landmark/start/working_joe, /turf/open/floor/plating, /area/almayer/command/airoom) "mLF" = ( @@ -53990,7 +53969,7 @@ }, /area/almayer/hull/upper_hull/u_a_p) "nJH" = ( -/obj/structure/machinery/computer/cameras/almayer/ares{ +/obj/structure/machinery/computer/cameras/almayer{ dir = 8; pixel_x = 17 }, @@ -58708,6 +58687,25 @@ icon_state = "silvercorner" }, /area/almayer/command/computerlab) +"pTt" = ( +/obj/structure/machinery/door/poddoor/shutters/almayer{ + id = "ARES JoeCryo"; + name = "\improper ARES Core Shutters"; + plane = -7 + }, +/turf/open/floor/almayer/no_build{ + icon_state = "test_floor4" + }, +/area/almayer/command/airoom) +"pTM" = ( +/obj/structure/sign/safety/water{ + pixel_x = 8; + pixel_y = -32 + }, +/turf/open/floor/almayer{ + icon_state = "sterile_green_side" + }, +/area/almayer/medical/hydroponics) "pTT" = ( /obj/structure/platform{ dir = 4 @@ -62393,6 +62391,13 @@ icon_state = "redfull" }, /area/almayer/command/cic) +"rzf" = ( +/obj/effect/landmark/late_join/working_joe, +/obj/effect/landmark/start/working_joe, +/turf/open/floor/almayer/no_build{ + icon_state = "ai_floors" + }, +/area/almayer/command/airoom) "rzj" = ( /obj/structure/pipes/standard/simple/hidden/supply, /obj/structure/machinery/door/firedoor/border_only/almayer{ @@ -65411,8 +65416,8 @@ /area/almayer/living/briefing) "sTV" = ( /obj/structure/machinery/power/apc/almayer/hardened{ - dir = 1; - cell_type = /obj/item/cell/hyper + cell_type = /obj/item/cell/hyper; + dir = 1 }, /turf/open/floor/plating, /area/almayer/command/airoom) @@ -70813,12 +70818,19 @@ }, /area/almayer/hull/lower_hull/l_m_p) "vhe" = ( -/obj/structure/prop/server_equipment/yutani_server{ +/obj/structure/filingcabinet{ density = 0; - desc = "A powerful server tower housing various AI functions."; - name = "server tower"; - pixel_y = 16 + pixel_x = -8; + pixel_y = 18 }, +/obj/structure/filingcabinet{ + density = 0; + pixel_x = 8; + pixel_y = 18 + }, +/obj/item/folder/white, +/obj/item/folder/white, +/obj/item/folder/white, /turf/open/floor/almayer/no_build{ icon_state = "ai_floors" }, @@ -74141,6 +74153,20 @@ icon_state = "bluefull" }, /area/almayer/command/cichallway) +"wyv" = ( +/obj/structure/machinery/door_control{ + id = "ARES JoeCryo"; + name = "Working Joe Cryogenics Lockdown"; + pixel_x = -24; + pixel_y = -8; + req_one_access_txt = "19;200;90;91;92" + }, +/obj/effect/landmark/late_join/working_joe, +/obj/effect/landmark/start/working_joe, +/turf/open/floor/almayer/no_build{ + icon_state = "ai_floors" + }, +/area/almayer/command/airoom) "wyK" = ( /obj/structure/pipes/standard/simple/hidden/supply, /turf/open/floor/almayer{ @@ -75281,7 +75307,7 @@ /turf/open/floor/plating/plating_catwalk, /area/almayer/squads/delta) "wXv" = ( -/obj/structure/machinery/vending/cigarette, +/obj/structure/prop/invuln/joey, /turf/open/floor/almayer{ icon_state = "plate" }, @@ -75717,12 +75743,12 @@ pixel_y = 32 }, /obj/item/folded_tent/big{ - pixel_y = 10; - pixel_x = -6 + pixel_x = -6; + pixel_y = 10 }, /obj/item/storage/box/mousetraps{ - pixel_y = 12; - pixel_x = 3 + pixel_x = 3; + pixel_y = 12 }, /turf/open/floor/almayer{ icon_state = "plate" @@ -78348,6 +78374,12 @@ icon_state = "plate" }, /area/almayer/squads/delta) +"ylg" = ( +/obj/structure/machinery/cryopod, +/turf/open/floor/almayer/no_build{ + icon_state = "ai_floors" + }, +/area/almayer/command/airoom) "ylm" = ( /obj/structure/machinery/door/firedoor/border_only/almayer, /obj/structure/disposalpipe/segment{ @@ -136553,7 +136585,7 @@ pYi fMl gUN bLv -bRo +wkM xvM osy cBm @@ -137355,7 +137387,7 @@ lmz lmz lmz lmz -lmz +daz sbJ sbJ sbJ @@ -137558,11 +137590,11 @@ lmz lmz lmz lmz -lmz -lmz -lmz -lmz daz +rzf +bRo +wyv +pTt gAe rCi gba @@ -137761,10 +137793,10 @@ lmz lmz lmz lmz -lmz -lmz -lmz -lmz +daz +czG +ylg +ylg daz daz daz @@ -137964,11 +137996,11 @@ bdH bdH bdH lmz -lmz -lmz -lmz -lmz -lmz +daz +daz +daz +daz +daz lmz lmz lmz diff --git a/maps/predship/huntership.dmm b/maps/predship/huntership.dmm index 5680271c4df2..d7dcb49427a0 100644 --- a/maps/predship/huntership.dmm +++ b/maps/predship/huntership.dmm @@ -486,8 +486,7 @@ /obj/structure/pipes/standard/simple/hidden{ dir = 4 }, -/obj/structure/machinery/computer/crew/alt{ - faction = "Yautja"; +/obj/structure/machinery/computer/crew/alt/yautja{ pixel_y = 24 }, /turf/open/floor/corsat{ @@ -674,9 +673,9 @@ color = "#6b675e" }, /obj/item/weapon/claymore/mercsword/machete/arnold{ + anchored = 1; desc = "Won by an Elder during their youthful hunting days. None are allowed to touch it."; - name = "\improper Dutch's Machete"; - anchored = 1 + name = "\improper Dutch's Machete" }, /turf/open/floor/corsat{ dir = 1; @@ -1789,9 +1788,9 @@ /area/yautja) "gr" = ( /obj/structure/closet/crate/secure{ - req_one_access_txt = "252"; color = "#6b675e"; - name = "Secure Yautja crate" + name = "Secure Yautja crate"; + req_one_access_txt = "252" }, /obj/item/explosive/grenade/spawnergrenade/hellhound, /obj/item/explosive/grenade/spawnergrenade/hellhound, @@ -1806,9 +1805,9 @@ /obj/structure/machinery/door_control{ id = "Yautja Armory"; name = "Armory Shutters"; + needs_power = 0; pixel_x = 24; - req_one_access_txt = "252"; - needs_power = 0 + req_one_access_txt = "252" }, /turf/open/floor/corsat{ dir = 1; @@ -2424,9 +2423,9 @@ /area/yautja) "Bg" = ( /obj/structure/closet/crate/secure{ - req_one_access_txt = "252"; color = "#6b675e"; - name = "Secure Yautja crate" + name = "Secure Yautja crate"; + req_one_access_txt = "252" }, /obj/item/weapon/yautja/combistick, /obj/item/weapon/yautja/combistick{ @@ -2623,7 +2622,10 @@ /obj/structure/surface/table/reinforced/prison{ color = "#6b675e" }, -/obj/item/explosive/grenade/spawnergrenade/spesscarp, +/obj/item/explosive/grenade/spawnergrenade/spesscarp{ + anchored = 1; + desc = "A strange device taken from a far-off land. It looks incredibly fragile, best not to touch it." + }, /turf/open/floor/corsat{ dir = 1; icon_state = "squareswood" @@ -2686,14 +2688,14 @@ layer = 2.79 }, /obj/item/stack/medical/advanced/ointment/predator{ - pixel_x = 6; desc = "A poultice made of cold, blue petals that is rubbed on burns. Not to be removed from the ship."; - name = "arena soothing herbs" + name = "arena soothing herbs"; + pixel_x = 6 }, /obj/item/stack/medical/advanced/bruise_pack/predator{ - pixel_x = -6; desc = "A poultice made of soft leaves that is rubbed on bruises. Not to be removed from the ship."; - name = "arena mending herbs" + name = "arena mending herbs"; + pixel_x = -6 }, /turf/open/shuttle/predship, /area/yautja) @@ -2721,9 +2723,9 @@ "HD" = ( /obj/structure/surface/rack{ color = "#6b675e"; + density = 0; layer = 2.79; - pixel_y = 24; - density = 0 + pixel_y = 24 }, /obj/item/weapon/gun/energy/yautja/plasmarifle{ pixel_y = -8 @@ -2924,13 +2926,7 @@ }, /area/yautja) "LX" = ( -/obj/item/moneybag{ - anchored = 1; - desc = "A console designed by the Hunters to assist in flight pathing and navigation."; - icon = 'icons/obj/structures/machinery/computer.dmi'; - icon_state = "overwatch"; - name = "Hunter Flight Console" - }, +/obj/structure/prop/pred_flight, /turf/open/floor/corsat{ dir = 1; icon_state = "squareswood" diff --git a/tgui/packages/tgui/interfaces/AlmayerControl.js b/tgui/packages/tgui/interfaces/AlmayerControl.js new file mode 100644 index 000000000000..6cc44737626c --- /dev/null +++ b/tgui/packages/tgui/interfaces/AlmayerControl.js @@ -0,0 +1,259 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, Section, Flex, NoticeBox, Collapsible, Divider, Box } from '../components'; +import { Window } from '../layouts'; + +export const AlmayerControl = (_props, context) => { + const { act, data } = useBackend(context); + + const worldTime = data.worldtime; + const messages = data.messages; + + const evacstatus = data.evac_status; + const evacEta = data.evac_eta; + + const AlertLevel = data.alert_level; + + const minimumTimeElapsed = worldTime > data.distresstimelock; + + const canMessage = data.time_message < worldTime; // ship announcement + const canRequest = // requesting distress beacon + data.time_request < worldTime && AlertLevel === 2 && minimumTimeElapsed; + const canEvac = (evacstatus === 0, AlertLevel >= 2); // triggering evac + const canDestruct = + data.time_destruct < worldTime && minimumTimeElapsed && AlertLevel === 2; + const canCentral = data.time_central < worldTime; // messaging HC + + let distress_reason; + let destruct_reason; + if (AlertLevel === 3) { + distress_reason = 'Self-destruct in progress. Beacon disabled.'; + destruct_reason = 'Self-destruct is already active!'; + } else if (AlertLevel !== 2) { + distress_reason = 'Ship is not under an active emergency.'; + destruct_reason = 'Ship is not under an active emergency.'; + } else if (data.time_request < worldTime) { + distress_reason = + 'Beacon is currently recharging. Time remaining: ' + + Math.ceil((data.time_message - worldTime) / 10) + + 'secs.'; + } else if (data.time_destruct < worldTime) { + destruct_reason = + 'A request has already been sent to HC. Please wait: ' + + Math.ceil((data.time_destruct - worldTime) / 10) + + 'secs to send another.'; + } else if (!minimumTimeElapsed) { + distress_reason = "It's too early to launch a distress beacon."; + destruct_reason = "It's too early to initiate the self-destruct."; + } + + let alertLevelString; + let alertLevelColor; + if (AlertLevel === 3) { + alertLevelString = 'DELTA'; + alertLevelColor = 'purple'; + } + if (AlertLevel === 2) { + alertLevelString = 'RED'; + alertLevelColor = 'red'; + } + if (AlertLevel === 1) { + alertLevelString = 'BLUE'; + alertLevelColor = 'blue'; + } + if (AlertLevel === 0) { + alertLevelString = 'GREEN'; + alertLevelColor = 'green'; + } + + return ( + + +
+ + + + + + {!canMessage && ( + + )} + {!!canMessage && ( + + )} + {!!canCentral && ( +
+ + + {messages && ( + + + + + {messages.map((entry) => { + return ( + +
+ act('delmessage', { number: entry.number }) + } + /> + }> + {entry.text} +
+
+ ); + })} +
+
+
+ )} +
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/CommandTablet.js b/tgui/packages/tgui/interfaces/CommandTablet.js index f4cc882070b2..8b334d1dac62 100644 --- a/tgui/packages/tgui/interfaces/CommandTablet.js +++ b/tgui/packages/tgui/interfaces/CommandTablet.js @@ -28,7 +28,7 @@ export const CommandTablet = (_props, context) => { } else if (AlertLevel !== 2) { distress_reason = 'Ship is not under an active emergency.'; } else if (distressCooldown) { - distress_reason = 'Beacon is currently on cooldown.'; + distress_reason = 'Beacon is currently recharging.'; } else if (!minimumTimeElapsed) { distress_reason = "It's too early to launch a distress beacon."; } @@ -41,7 +41,7 @@ export const CommandTablet = (_props, context) => { {!canAnnounce && ( )}