diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 77f2393e6542..d8f820ab382b 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -113,7 +113,7 @@ #define CANROOT (1<<6) #define GODMODE (1<<12) #define FAKEDEATH (1<<13) //Replaces stuff like changeling.changeling_fakedeath -#define DISFIGURED (1<<14) //I'll probably move this elsewhere if I ever get wround to writing a bitflag mob-damage system +//#define DISFIGURED (1<<14) //unused #define XENO_HOST (1<<15) //Tracks whether we're gonna be a baby alien's mummy. #define IMMOBILE_ACTION (1<<16) // If you are performing an action that prevents you from being pushed by your own people. #define PERMANENTLY_DEAD (1<<17) diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 47aa0e732c76..88496c79d630 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -123,6 +123,7 @@ #define SS_INIT_NIGHTMARE 21.5 #define SS_INIT_TIMETRACK 21.1 #define SS_INIT_HUMANS 21 +#define SS_INIT_WHO 20 #define SS_INIT_POWER 19 #define SS_INIT_INFLUXMCSTATS 12 #define SS_INIT_INFLUXSTATS 11 diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index e2c89df90e9b..17464b44dae8 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -1,6 +1,6 @@ // tgstation-server DMAPI -#define TGS_DMAPI_VERSION "7.1.2" +#define TGS_DMAPI_VERSION "7.1.3" // All functions and datums outside this document are subject to change with any version and should not be relied on. diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index e46c92df543a..aa73d6008e02 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -128,17 +128,23 @@ * You should only pass integers in. */ /proc/pick_weight(list/list_to_pick) + if(length(list_to_pick) == 0) + return null + var/total = 0 - var/item - for(item in list_to_pick) + for(var/item in list_to_pick) if(!list_to_pick[item]) list_to_pick[item] = 0 total += list_to_pick[item] - total = rand(0, total) - for(item in list_to_pick) - total -= list_to_pick[item] - if(total <= 0 && list_to_pick[item]) + total = rand(1, total) + for(var/item in list_to_pick) + var/item_weight = list_to_pick[item] + if(item_weight == 0) + continue + + total -= item_weight + if(total <= 0) return item return null diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index d5212611a04b..32ea0f5ec32e 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -87,22 +87,6 @@ result = first ^ second return result -//Pretends to pick an element based on its weight but really just seems to pick a random element. -/proc/pickweight(list/L) - var/total = 0 - var/item - for (item in L) - if (!L[item]) - L[item] = 1 - total += L[item] - - total = rand(1, total) - for (item in L) - total -=L [item] - if (total <= 0) - return item - return null - /// Pick a random element from the list and remove it from the list. /proc/pick_n_take(list/L) RETURN_TYPE(L[_].type) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index facc2b951ad3..d3fc9994414a 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -356,7 +356,6 @@ DEFINE_BITFIELD(status_flags, list( "PASSEMOTES" = PASSEMOTES, "GODMODE" = GODMODE, "FAKEDEATH" = FAKEDEATH, - "DISFIGURED" = DISFIGURED, "XENO_HOST" = XENO_HOST, "IMMOBILE_ACTION" = IMMOBILE_ACTION, "PERMANENTLY_DEAD" = PERMANENTLY_DEAD, diff --git a/code/controllers/subsystem/init/lobby_art.dm b/code/controllers/subsystem/init/lobby_art.dm index 7c49d5fe1787..4b26d576b8df 100644 --- a/code/controllers/subsystem/init/lobby_art.dm +++ b/code/controllers/subsystem/init/lobby_art.dm @@ -6,5 +6,5 @@ SUBSYSTEM_DEF(lobby_art) /datum/controller/subsystem/lobby_art/Initialize() var/list/lobby_arts = CONFIG_GET(str_list/lobby_art_images) if(length(lobby_arts)) - force_lobby_art(rand(1,length(lobby_arts))) + force_lobby_art(rand(1, length(lobby_arts))) return SS_INIT_SUCCESS diff --git a/code/controllers/subsystem/sound.dm b/code/controllers/subsystem/sound.dm index 13dd6a0dddf1..3cc3f0ef8090 100644 --- a/code/controllers/subsystem/sound.dm +++ b/code/controllers/subsystem/sound.dm @@ -19,7 +19,7 @@ SUBSYSTEM_DEF(sound) if(!run_hearers) // Initialize for handling next template run_hearers = run_queue[run_template] // get base hearers if(run_template.range) // ranging - run_hearers |= SSquadtree.players_in_range(SQUARE(run_template.x, run_template.y, run_template.range), run_template.z) + run_hearers |= SSquadtree.players_in_range(SQUARE(run_template.x, run_template.y, run_template.range * 2), run_template.z) if(MC_TICK_CHECK) return while(length(run_hearers)) // Output sound to hearers diff --git a/code/controllers/subsystem/who.dm b/code/controllers/subsystem/who.dm new file mode 100644 index 000000000000..43ecbb435587 --- /dev/null +++ b/code/controllers/subsystem/who.dm @@ -0,0 +1,312 @@ +SUBSYSTEM_DEF(who) + name = "Who" + flags = SS_BACKGROUND + runlevels = RUNLEVELS_DEFAULT|RUNLEVEL_LOBBY + init_order = SS_INIT_WHO + wait = 5 SECONDS + + var/datum/player_list/who = new + var/datum/player_list/staff/staff_who = new + +/datum/controller/subsystem/who/Initialize() + who.update_data() + staff_who.update_data() + return SS_INIT_SUCCESS + +/datum/controller/subsystem/who/fire(resumed = TRUE) + who.update_data() + staff_who.update_data() + +//datum +/datum/player_list + var/tgui_name = "Who" + var/tgui_interface_name = "Who" + var/list/mobs_ckey = list() + var/list/list_data = list() + +/datum/player_list/proc/update_data() + var/list/new_list_data = list() + var/list/new_mobs_ckey = list() + var/list/additional_data = list( + "lobby" = 0, + "admin_observers" = 0, + "observers" = 0, + "yautja" = 0, + "infected_preds" = 0, + "humans" = 0, + "infected_humans" = 0, + "uscm" = 0, + "uscm_marines" = 0, + ) + new_list_data["additional_info"] = list() + var/list/counted_factions = list() + for(var/client/client as anything in sortTim(GLOB.clients, GLOBAL_PROC_REF(cmp_ckey_asc))) + CHECK_TICK + new_list_data["all_clients"]++ + var/list/client_payload = list() + client_payload["ckey"] = "[client.key]" + client_payload["text"] = "[client.key]" + client_payload["ckey_color"] = "white" + var/mob/client_mob = client.mob + new_mobs_ckey[client.key] = client_mob + if(client_mob) + if(istype(client_mob, /mob/new_player)) + client_payload["text"] += " - in Lobby" + additional_data["lobby"]++ + + else if(isobserver(client_mob)) + client_payload["text"] += " - Playing as [client_mob.real_name]" + if(CLIENT_IS_STAFF(client)) + additional_data["admin_observers"]++ + else + additional_data["observers"]++ + + var/mob/dead/observer/observer = client_mob + if(observer.started_as_observer) + client_payload["color"] += "#ce89cd" + client_payload["text"] += " - Spectating" + else + client_payload["color"] += "#A000D0" + client_payload["text"] += " - DEAD" + + else + client_payload["text"] += " - Playing as [client_mob.real_name]" + + switch(client_mob.stat) + if(UNCONSCIOUS) + client_payload["color"] += "#B0B0B0" + client_payload["text"] += " - Unconscious" + if(DEAD) + client_payload["color"] += "#A000D0" + client_payload["text"] += " - DEAD" + + if(client_mob.stat != DEAD) + if(isxeno(client_mob)) + client_payload["color"] += "#ec3535" + client_payload["text"] += " - Xenomorph" + + else if(ishuman(client_mob)) + if(client_mob.faction == FACTION_ZOMBIE) + counted_factions[FACTION_ZOMBIE]++ + client_payload["color"] += "#2DACB1" + client_payload["text"] += " - Zombie" + else if(client_mob.faction == FACTION_YAUTJA) + client_payload["color"] += "#7ABA19" + client_payload["text"] += " - Yautja" + additional_data["yautja"]++ + if(client_mob.status_flags & XENO_HOST) + additional_data["infected_preds"]++ + else + additional_data["humans"]++ + if(client_mob.status_flags & XENO_HOST) + additional_data["infected_humans"]++ + if(client_mob.faction == FACTION_MARINE) + additional_data["uscm"]++ + if(client_mob.job in (GLOB.ROLES_MARINES)) + additional_data["uscm_marines"]++ + else + counted_factions[client_mob.faction]++ + + new_list_data["total_players"] += list(client_payload) + + new_list_data["additional_info"] += list(list( + "content" = "In Lobby: [additional_data["lobby"]]", + "color" = "#777", + "text" = "Player in lobby", + )) + + new_list_data["additional_info"] += list(list( + "content" = "Spectating Players: [additional_data["observers"]]", + "color" = "#777", + "text" = "Spectating players", + )) + + new_list_data["additional_info"] += list(list( + "content" = "Spectating Admins: [additional_data["admin_observers"]]", + "color" = "#777", + "text" = "Spectating administrators", + )) + + new_list_data["additional_info"] += list(list( + "content" = "Humans: [additional_data["humans"]]", + "color" = "#2C7EFF", + "text" = "Players playing as Human", + )) + + new_list_data["additional_info"] += list(list( + "content" = "Infected Humans: [additional_data["infected_humans"]]", + "color" = "#ec3535", + "text" = "Players playing as Infected Human", + )) + + new_list_data["additional_info"] += list(list( + "content" = "[MAIN_SHIP_NAME] Personnel: [additional_data["uscm"]]", + "color" = "#5442bd", + "text" = "Players playing as [MAIN_SHIP_NAME] Personnel", + )) + + new_list_data["additional_info"] += list(list( + "content" = "Marines: [additional_data["uscm_marines"]]", + "color" = "#5442bd", + "text" = "Players playing as Marines", + )) + + new_list_data["additional_info"] += list(list( + "content" = "Yautjas: [additional_data["yautja"]]", + "color" = "#7ABA19", + "text" = "Players playing as Yautja", + )) + + new_list_data["additional_info"] += list(list( + "content" = "Infected Predators: [additional_data["infected_preds"]]", + "color" = "#7ABA19", + "text" = "Players playing as Infected Yautja", + )) + + for(var/i in 1 to length(counted_factions)) + if(counted_factions[counted_factions[i]]) + new_list_data["factions"] += list(list( + "content" = "[counted_factions[i]]: [counted_factions[counted_factions[i]]]", + "color" = "#2C7EFF", + "text" = "Other", + )) + if(counted_factions[FACTION_NEUTRAL]) + new_list_data["factions"] += list(list( + "content" = "[FACTION_NEUTRAL] Humans: [counted_factions[FACTION_NEUTRAL]]", + "color" = "#688944", + "text" = "Neutrals", + )) + + for(var/faction_to_get in ALL_XENO_HIVES) + var/datum/hive_status/hive = GLOB.hive_datum[faction_to_get] + if(hive && length(hive.totalXenos)) + new_list_data["xenomorphs"] += list(list( + "content" = "[hive.name]: [length(hive.totalXenos)]", + "color" = hive.color ? hive.color : "#8200FF", + "text" = "Queen: [hive.living_xeno_queen ? "Alive" : "Dead"]", + )) + + list_data = new_list_data + mobs_ckey = new_mobs_ckey + +/datum/player_list/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, tgui_name, tgui_interface_name) + ui.open() + ui.set_autoupdate(TRUE) + +/datum/player_list/ui_data(mob/user) + . = list_data + +/datum/player_list/ui_static_data(mob/user) + . = list() + + .["admin"] = CLIENT_IS_STAFF(user.client) + +/datum/player_list/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + switch(action) + if("get_player_panel") + if(mobs_ckey[params["ckey"]]) + GLOB.admin_datums[usr.client.ckey].show_player_panel(mobs_ckey[params["ckey"]]) + +/datum/player_list/ui_status(mob/user, datum/ui_state/state) + return UI_INTERACTIVE + + +/datum/player_list/staff + tgui_name = "StaffWho" + tgui_interface_name = "Staff Who" + + var/list/category_colors = list( + "Management" = "purple", + "Maintainers" = "blue", + "Administrators" = "red", + "Moderators" = "orange", + "Mentors" = "green" + ) + +/datum/player_list/staff/update_data() + var/list/new_list_data = list() + mobs_ckey = list() + + var/list/listings + var/list/mappings + if(CONFIG_GET(flag/show_manager)) + LAZYSET(mappings, "Management", R_PERMISSIONS) + if(CONFIG_GET(flag/show_devs)) + LAZYSET(mappings, "Maintainers", R_PROFILER) + LAZYSET(mappings, "Administrators", R_ADMIN) + if(CONFIG_GET(flag/show_mods)) + LAZYSET(mappings, "Moderators", R_MOD && R_BAN) + if(CONFIG_GET(flag/show_mentors)) + LAZYSET(mappings, "Mentors", R_MENTOR) + + for(var/category in mappings) + LAZYSET(listings, category, list()) + + for(var/client/client as anything in GLOB.admins) + if(client.admin_holder?.fakekey && !CLIENT_IS_STAFF(client)) + continue + + for(var/category in mappings) + if(CLIENT_HAS_RIGHTS(client, mappings[category])) + LAZYADD(listings[category], client) + break + + for(var/category in listings) + var/list/admins = list() + for(var/client/entry as anything in listings[category]) + var/list/admin = list() + var/rank = entry.admin_holder.rank + if(entry.admin_holder.extra_titles?.len) + for(var/srank in entry.admin_holder.extra_titles) + rank += " & [srank]" + + admin["content"] = "[entry.key] ([rank])" + admin["text"] = "" + + if(entry.admin_holder?.fakekey) + admin["text"] += " (HIDDEN)" + + if(istype(entry.mob, /mob/dead/observer)) + admin["color"] = "#808080" + admin["text"] += " Spectating" + + else if(istype(entry.mob, /mob/new_player)) + admin["color"] = "#688944" + admin["text"] += " in Lobby" + else + admin["color"] = "#688944" + admin["text"] += " Playing" + + if(entry.is_afk()) + admin["color"] = "#A040D0" + admin["text"] += " (AFK)" + + admins += list(admin) + + new_list_data["administrators"] += list(list( + "category" = category, + "category_color" = category_colors[category], + "category_administrators" = length(listings[category]), + "admins" = admins, + )) + + list_data = new_list_data + +/mob/verb/who() + set category = "OOC" + set name = "Who" + + SSwho.who.tgui_interact(src) + +/mob/verb/staffwho() + set category = "Admin" + set name = "StaffWho" + + SSwho.staff_who.tgui_interact(src) diff --git a/code/datums/action.dm b/code/datums/action.dm index 8dbf6c9df5a5..e6c87eca6a0d 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -187,12 +187,6 @@ holder_item = null return ..() -/datum/action/item_action/action_activate() - . = ..() - if(target) - var/obj/item/I = target - I.ui_action_click(owner, holder_item) - /datum/action/item_action/can_use_action() if(ishuman(owner) && !owner.is_mob_incapacitated()) var/mob/living/carbon/human/human = owner @@ -213,6 +207,17 @@ name = "Toggle [target]" button.name = name +/datum/action/item_action/toggle/action_activate() + . = ..() + if(target) + var/obj/item/I = target + I.ui_action_click(owner, holder_item) + +/datum/action/item_action/toggle/use/New(target) + . = ..() + name = "Use [target]" + button.name = name + //This is the proc used to update all the action buttons. /mob/proc/update_action_buttons(reload_screen) if(!client) diff --git a/code/datums/ammo/misc.dm b/code/datums/ammo/misc.dm index 9a9ed2fb505b..28610f283df2 100644 --- a/code/datums/ammo/misc.dm +++ b/code/datums/ammo/misc.dm @@ -49,10 +49,21 @@ drop_flame(get_turf(P), P.weapon_cause_data) /datum/ammo/flamethrower/tank_flamer - flamer_reagent_id = "napalmx" - + flamer_reagent_id = "highdamagenapalm" max_range = 8 +/datum/ammo/flamethrower/tank_flamer/drop_flame(turf/turf, datum/cause_data/cause_data) + if(!istype(turf)) + return + + var/datum/reagent/napalm/high_damage/reagent = new() + new /obj/flamer_fire(turf, cause_data, reagent, 1) + + var/datum/effect_system/smoke_spread/landingsmoke = new /datum/effect_system/smoke_spread + landingsmoke.set_up(1, 0, turf, null, 4, cause_data) + landingsmoke.start() + landingsmoke = null + /datum/ammo/flamethrower/sentry_flamer flags_ammo_behavior = AMMO_IGNORE_ARMOR|AMMO_IGNORE_COVER|AMMO_FLAME flamer_reagent_id = "napalmx" diff --git a/code/datums/autocells/explosion.dm b/code/datums/autocells/explosion.dm index ecc6f9925800..ec310e80367c 100644 --- a/code/datums/autocells/explosion.dm +++ b/code/datums/autocells/explosion.dm @@ -264,7 +264,9 @@ as having entered the turf. falloff = max(falloff, power/100) - msg_admin_attack("Explosion with Power: [power], Falloff: [falloff], Shape: [falloff_shape] in [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]).", epicenter.x, epicenter.y, epicenter.z) + var/obj/causing_obj = explosion_cause_data?.resolve_cause() + var/mob/causing_mob = explosion_cause_data?.resolve_mob() + msg_admin_attack("Explosion with Power: [power], Falloff: [falloff], Shape: [falloff_shape],[causing_obj ? " from [causing_obj]" : ""][causing_mob ? " by [key_name(causing_mob)]" : ""] in [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]).", epicenter.x, epicenter.y, epicenter.z) playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(power^2,1)) diff --git a/code/datums/components/bonus_damage_stack.dm b/code/datums/components/bonus_damage_stack.dm index 78da5e036ce4..7a9bf5aa9560 100644 --- a/code/datums/components/bonus_damage_stack.dm +++ b/code/datums/components/bonus_damage_stack.dm @@ -60,7 +60,7 @@ var/color = COLOR_BONUS_DAMAGE var/intensity = bonus_damage_stacks / (initial(bonus_damage_cap) * 2) // if intensity is too high of a value, the hex code will become invalid - color += num2text(BONUS_DAMAGE_MAX_ALPHA * clamp(intensity, 0, 0.5), 1, 16) + color += num2text(BONUS_DAMAGE_MAX_ALPHA * clamp(intensity, 0, 0.5), 2, 16) if(parent) var/atom/A = parent A.add_filter("bonus_damage_stacks", 2, list("type" = "outline", "color" = color, "size" = 1 + clamp(intensity, 0, 1))) diff --git a/code/datums/quadtree.dm b/code/datums/quadtree.dm index 200a51b358a0..9056dfd6bd59 100644 --- a/code/datums/quadtree.dm +++ b/code/datums/quadtree.dm @@ -82,7 +82,7 @@ /// Returns TRUE if this shape's bounding box intersects the provided shape's bounding box, otherwise FALSE. Generally faster than a full intersection test. /datum/shape/proc/intersects_aabb(datum/shape/aabb) - return (abs(src.center_x - aabb.center_x) <= (src.bounds_x + aabb.bounds_x) * 0.5) && (abs(src.center_y - aabb.center_y) <= (src.bounds_x + aabb.bounds_x) * 0.5) + return (abs(src.center_x - aabb.center_x) <= (src.bounds_x + aabb.bounds_x) * 0.5) && (abs(src.center_y - aabb.center_y) <= (src.bounds_y + aabb.bounds_y) * 0.5) /// Returns TRUE if this shape intersects the provided rectangle shape, otherwise FALSE. /datum/shape/proc/intersects_rect(datum/shape/rectangle/rect) diff --git a/code/datums/supply_packs/explosives.dm b/code/datums/supply_packs/explosives.dm index 032ef047c78a..78f0f3e9251a 100644 --- a/code/datums/supply_packs/explosives.dm +++ b/code/datums/supply_packs/explosives.dm @@ -89,6 +89,18 @@ containername = "\improper explosive M40 HEDP grenades crate (WARNING)" group = "Explosives" +/datum/supply_packs/explosives_sebb + name = "G2 electroshock grenades crate (x6)" + contains = list( + /obj/item/storage/box/packet/sebb, + /obj/item/storage/box/packet/sebb, + ) + cost = 30 + containertype = /obj/structure/closet/crate/explosives + containername = "\improper G2 electroshock grenades crate (WARNING)" + group = "Explosives" + + /datum/supply_packs/explosives_hedp name = "M40 HEDP blast grenade box crate (x25)" contains = list( diff --git a/code/datums/tutorial/xenomorph/abomination.dm b/code/datums/tutorial/xenomorph/abomination.dm index db9b77cf2e75..83ac86b8f09e 100644 --- a/code/datums/tutorial/xenomorph/abomination.dm +++ b/code/datums/tutorial/xenomorph/abomination.dm @@ -147,6 +147,7 @@ /datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_4() var/mob/living/carbon/human/marine = new(loc_from_corner(4, 2)) add_to_tracking_atoms(marine) + RegisterSignal(marine, COMSIG_MOB_DEATH, PROC_REF(on_marine_early_death)) arm_equipment(marine, /datum/equipment_preset/uscm/private_equipped) var/datum/action/frenzy = give_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) @@ -202,6 +203,7 @@ return UnregisterSignal(frenzy, COMSIG_XENO_ACTION_USED) + UnregisterSignal(marine, COMSIG_MOB_DEATH) remove_highlight(frenzy.button) message_to_player("Good. As you may have noticed, the AOE version of Feral Frenzy takes longer to wind up, in addition to doing less overall damage.") addtimer(CALLBACK(src, PROC_REF(kill_marines)), 6 SECONDS) @@ -245,3 +247,10 @@ tutorial_end_in(7 SECONDS, TRUE) // END OF SCRIPTING + +/// In case a marine dies early to prevent softlocks +/datum/tutorial/xenomorph/abomination/proc/on_marine_early_death(datum/source) + SIGNAL_HANDLER + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) + marine.rejuvenate() diff --git a/code/game/machinery/autolathe_datums.dm b/code/game/machinery/autolathe_datums.dm index 78a8e46b64aa..9c8ee271845d 100644 --- a/code/game/machinery/autolathe_datums.dm +++ b/code/game/machinery/autolathe_datums.dm @@ -136,11 +136,6 @@ path = /obj/item/circuitboard/apc category = AUTOLATHE_CATEGORY_ENGINEERING -/datum/autolathe/recipe/rcd_ammo - name = "matter cartridge" - path = /obj/item/ammo_rcd - category = AUTOLATHE_CATEGORY_ENGINEERING - /datum/autolathe/recipe/table_parts name = "table parts" path = /obj/item/frame/table diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index ff8f3959d64e..4f6f4df4ef08 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -123,7 +123,7 @@ src.temp = "[src.enemy_name] has fallen! Rejoice!" if(!length(contents)) - var/prizeselect = pickweight(prizes) + var/prizeselect = pick_weight(prizes) new prizeselect(src.loc) if(istype(prizeselect, /obj/item/toy/gun)) //Ammo comes with the gun @@ -176,5 +176,5 @@ if(2) num_of_prizes = rand(0,2) for(num_of_prizes; num_of_prizes > 0; num_of_prizes--) - empprize = pickweight(prizes) + empprize = pick_weight(prizes) new empprize(src.loc) diff --git a/code/game/machinery/medical_pod/autodoc.dm b/code/game/machinery/medical_pod/autodoc.dm index ef335c6841e6..b5fd43b35651 100644 --- a/code/game/machinery/medical_pod/autodoc.dm +++ b/code/game/machinery/medical_pod/autodoc.dm @@ -238,11 +238,6 @@ surgery_list += create_autodoc_surgery(L,ORGAN_SURGERY,"damage",0,I) organdamagesurgery++ - if(istype(L,/obj/limb/head)) - var/obj/limb/head/H = L - if(H.disfigured) - surgery_list += create_autodoc_surgery(L,LIMB_SURGERY,"facial") - if(L.status & LIMB_BROKEN) surgery_list += create_autodoc_surgery(L,LIMB_SURGERY,"broken") if(L.status & LIMB_DESTROYED) @@ -521,20 +516,6 @@ if(!surgery) break close_incision(H,S.limb_ref) - if("facial") - if(prob(30)) visible_message("[icon2html(src, viewers(src))] \The [src] speaks: Beginning Facial Reconstruction Surgery."); - if(S.unneeded) - sleep(UNNEEDED_DELAY) - visible_message("[icon2html(src, viewers(src))] \The [src] speaks: Procedure has been deemed unnecessary."); - surgery_todo_list -= S - continue - if(istype(S.limb_ref, /obj/limb/head)) - var/obj/limb/head/F = S.limb_ref - sleep(SCALPEL_MAX_DURATION + HEMOSTAT_MAX_DURATION + RETRACTOR_MAX_DURATION + CAUTERY_MAX_DURATION) - F.remove_all_bleeding(TRUE) - F.disfigured = 0 - F.owner.name = F.owner.get_visible_name() - if("open") if(prob(30)) visible_message("[icon2html(src, viewers(src))] \The [src]croaks: Closing surgical incision."); close_encased(H,S.limb_ref) @@ -753,9 +734,6 @@ if("shrapnel") surgeryqueue["shrapnel"] = 1 dat += "Shrapnel Removal Surgery" - if("facial") - surgeryqueue["facial"] = 1 - dat += "Facial Reconstruction Surgery" if("open") surgeryqueue["open"] = 1 dat += "Close Open Incisions" @@ -902,18 +880,6 @@ N.fields["autodoc_manual"] += create_autodoc_surgery(null,LIMB_SURGERY,"shrapnel",1) updateUsrDialog() - if(href_list["facial"]) - for(var/obj/limb/L in connected.occupant.limbs) - if(L) - if(istype(L,/obj/limb/head)) - var/obj/limb/head/J = L - if(J.disfigured) - N.fields["autodoc_manual"] += create_autodoc_surgery(L,LIMB_SURGERY,"facial") - else - N.fields["autodoc_manual"] += create_autodoc_surgery(L,LIMB_SURGERY,"facial",1) - updateUsrDialog() - break - if(href_list["open"]) for(var/obj/limb/L in connected.occupant.limbs) if(L) diff --git a/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm b/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm index b0894ca2a5a2..81bee126dbc8 100644 --- a/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm +++ b/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm @@ -3,9 +3,11 @@ GLOBAL_LIST_INIT(cm_vending_clothing_combat_correspondent, list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), list("Essential Reporter's Set", 0, /obj/effect/essentials_set/cc, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_MANDATORY), + list("Leather Satchel", 0, /obj/item/storage/backpack/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR), + + list("CIVILIAN EQUIPMENT (TAKE ALL)", 0, null, null, null), list("Portable Press Fax Machine", 0, /obj/item/device/fax_backpack, CIVILIAN_CAN_BUY_BACKPACK, VENDOR_ITEM_RECOMMENDED), list("Press Broadcasting Camera", 0, /obj/item/device/camera/broadcasting, CIVILIAN_CAN_BUY_UTILITY, VENDOR_ITEM_RECOMMENDED), - list("Leather Satchel", 0, /obj/item/storage/backpack/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR), list("UNIFORM (CHOOSE 1)", 0, null, null, null), list("Black Uniform", 0, /obj/item/clothing/under/marine/reporter/black, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm b/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm index d7d49a8ae044..dd2fc9c4a5b7 100644 --- a/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm +++ b/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm @@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_commanding_officer, list( list("HEDP Grenade Pack", 15, /obj/item/storage/box/packet/high_explosive, null, VENDOR_ITEM_REGULAR), list("HEFA Grenade Pack", 15, /obj/item/storage/box/packet/hefa, null, VENDOR_ITEM_REGULAR), list("WP Grenade Pack", 15, /obj/item/storage/box/packet/phosphorus, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Packet (x3 grenades)", 15, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR), list("RAIL ATTACHMENTS", 0, null, null, null), list("Red-Dot Sight", 15, /obj/item/attachable/reddot, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/crew/senior_officers.dm b/code/game/machinery/vending/vendor_types/crew/senior_officers.dm index 71a38154f735..2b9a56496bae 100644 --- a/code/game/machinery/vending/vendor_types/crew/senior_officers.dm +++ b/code/game/machinery/vending/vendor_types/crew/senior_officers.dm @@ -455,7 +455,6 @@ GLOBAL_LIST_INIT(cm_vending_clothing_auxiliary_officer, list( list("Insulated Gloves", 0, /obj/item/clothing/gloves/yellow, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Officer Uniform", 0, /obj/item/clothing/under/marine/officer/bridge, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/almayer/qm, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), - list("Patrol Cap", 0, /obj/item/clothing/head/cmcap, MARINE_CAN_BUY_MASK, VENDOR_ITEM_MANDATORY), list("Auxiliary Support Officer Jacket", 0, /obj/item/clothing/suit/storage/jacket/marine/service/aso, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY), list("BAG (CHOOSE 1)", 0, null, null, null), @@ -467,6 +466,13 @@ GLOBAL_LIST_INIT(cm_vending_clothing_auxiliary_officer, list( list("Mod 88 Pistol", 0, /obj/item/storage/belt/gun/m4a3/mod88, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_RECOMMENDED), list("M44 Custom Revolver", 0, /obj/item/storage/belt/gun/m44/custom, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_RECOMMENDED), + list("HAT (CHOOSE 1)", 0, null, null, null), + list("Beret, Green", 0, /obj/item/clothing/head/beret/cm, MARINE_CAN_BUY_MASK, VENDOR_ITEM_RECOMMENDED), + list("Beret, Tan", 0, /obj/item/clothing/head/beret/cm/tan, MARINE_CAN_BUY_MASK, VENDOR_ITEM_RECOMMENDED), + list("Patrol Cap", 0, /obj/item/clothing/head/cmcap, MARINE_CAN_BUY_MASK, VENDOR_ITEM_RECOMMENDED), + list("Officer Cap", 0, /obj/item/clothing/head/cmcap/bridge, MARINE_CAN_BUY_MASK, VENDOR_ITEM_RECOMMENDED), + list("Service Peaked Cap", 0, /obj/item/clothing/head/marine/peaked/service, MARINE_CAN_BUY_MASK, VENDOR_ITEM_RECOMMENDED), + list("COMBAT EQUIPMENT (TAKE ALL)", 0, null, null, null), list("Officer M3 Armor", 0, /obj/item/clothing/suit/storage/marine/MP/SO, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY), list("Officer M10 Helmet", 0, /obj/item/clothing/head/helmet/marine/MP/SO, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY), diff --git a/code/game/machinery/vending/vendor_types/crew/staff_officer_armory.dm b/code/game/machinery/vending/vendor_types/crew/staff_officer_armory.dm index 1e21f2f7256d..46de6ed028d0 100644 --- a/code/game/machinery/vending/vendor_types/crew/staff_officer_armory.dm +++ b/code/game/machinery/vending/vendor_types/crew/staff_officer_armory.dm @@ -18,7 +18,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_staff_officer_armory, list( list("Marine Combat Gloves", 0, /obj/item/clothing/gloves/marine, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY), list("Aviator Shades", 0, /obj/item/clothing/glasses/sunglasses/aviator, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_REGULAR), - list("Bayonet", 0, /obj/item/attachable/bayonet, null, VENDOR_ITEM_REGULAR), + list("Bayonet", 0, /obj/item/attachable/bayonet, MARINE_CAN_BUY_ATTACHMENT, VENDOR_ITEM_REGULAR), list("SPECIALISATION KIT (CHOOSE 1)", 0, null, null, null), list("Essential Engineer Set", 0, /obj/effect/essentials_set/engi, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_RECOMMENDED), diff --git a/code/game/machinery/vending/vendor_types/crew/synthetic.dm b/code/game/machinery/vending/vendor_types/crew/synthetic.dm index 3f8eff44d052..9ce15535e2da 100644 --- a/code/game/machinery/vending/vendor_types/crew/synthetic.dm +++ b/code/game/machinery/vending/vendor_types/crew/synthetic.dm @@ -188,7 +188,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_synth, list( GLOBAL_LIST_INIT(cm_vending_clothing_synth_snowflake, list( list("USCM UNIFORMS", 0, null, null, null), list("Medical Scrubs, Blue", 12, /obj/item/clothing/under/rank/medical/blue, null, VENDOR_ITEM_REGULAR), - list("Medical Scrubs, Light Blue", 0, /obj/item/clothing/under/rank/medical/lightblue, null, VENDOR_ITEM_REGULAR), + list("Medical Scrubs, Light Blue", 12, /obj/item/clothing/under/rank/medical/lightblue, null, VENDOR_ITEM_REGULAR), list("Medical Scrubs, Green", 12, /obj/item/clothing/under/rank/medical/green, null, VENDOR_ITEM_REGULAR), list("Medical Scrubs, Purple", 12, /obj/item/clothing/under/rank/medical/purple, null, VENDOR_ITEM_REGULAR), list("Medical Scrubs, Olive", 12, /obj/item/clothing/under/rank/medical/olive, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/requisitions.dm b/code/game/machinery/vending/vendor_types/requisitions.dm index a8d44a8b5012..5c5362257da2 100644 --- a/code/game/machinery/vending/vendor_types/requisitions.dm +++ b/code/game/machinery/vending/vendor_types/requisitions.dm @@ -55,6 +55,7 @@ list("M74 AGM-Smoke Airburst Grenade", floor(scale * 4), /obj/item/explosive/grenade/smokebomb/airburst, VENDOR_ITEM_REGULAR), list("M74 AGM-Star Shell", floor(scale * 2), /obj/item/explosive/grenade/high_explosive/airburst/starshell, VENDOR_ITEM_REGULAR), list("M74 AGM-Hornet Shell", floor(scale * 4), /obj/item/explosive/grenade/high_explosive/airburst/hornet_shell, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade", round(scale * 5), /obj/item/explosive/grenade/sebb, VENDOR_ITEM_REGULAR), list("M40 HIRR Baton Slug", floor(scale * 8), /obj/item/explosive/grenade/slug/baton, VENDOR_ITEM_REGULAR), list("M40 MFHS Metal Foam Grenade", floor(scale * 6), /obj/item/explosive/grenade/metal_foam, VENDOR_ITEM_REGULAR), list("Plastic Explosives", floor(scale * 3), /obj/item/explosive/plastic, VENDOR_ITEM_REGULAR), @@ -154,6 +155,7 @@ list("M74 AGM-Airburst Smoke Grenade Packet", 0, /obj/item/storage/box/packet/airburst_smoke, VENDOR_ITEM_REGULAR), list("M74 AGM-S Star Shell Packet", 0, /obj/item/storage/box/packet/flare, VENDOR_ITEM_REGULAR), list("M74 AGM-H Hornet Shell Packet", 0, /obj/item/storage/box/packet/hornet, VENDOR_ITEM_REGULAR), + list("G2 Electroshock grenade packet", 0, /obj/item/storage/box/packet/sebb, VENDOR_ITEM_REGULAR), list("M20 mine box", 0, /obj/item/storage/box/explosive_mines, VENDOR_ITEM_REGULAR), list("OTHER BOXES", -1, null, null), 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 aaf134c4a459..9c19a5b172c6 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 @@ -35,6 +35,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_engi, list( list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR), list("M20 Mine Box (x4 mines)", 18, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR), list("M40 MFHS Metal Foam Grenade", 5, /obj/item/explosive/grenade/metal_foam, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR), list("PRIMARY AMMUNITION", 0, null, null, null), list("M4RA AP Magazine (10x24mm)", 6, /obj/item/ammo_magazine/rifle/m4ra/ap, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm index 17d3419ac2f8..7f8d70db4328 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm @@ -61,6 +61,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_leader, list( list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR), list("M20 Mine Box (x4 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR), list("M40 MFHS Metal Foam Grenade", 5, /obj/item/explosive/grenade/metal_foam, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR), list("MEDICAL SUPPLIES", 0, null, null, null), list("Burn Kit", 2, /obj/item/stack/medical/advanced/ointment, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm index a73df202d4ef..e9d69ad396de 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm @@ -57,6 +57,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_medic, list( list("M74 AGM-Smoke Airburst Packet (x3 airburst grenades)", 10, /obj/item/storage/box/packet/airburst_smoke, null, VENDOR_ITEM_REGULAR), list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR), list("M20 Mine Box (x4 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR), list("PRIMARY AMMUNITION", 0, null, null, null), list("M4RA AP Magazine (10x24mm)", 6, /obj/item/ammo_magazine/rifle/m4ra/ap, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm index 4d14b7b89ccd..8fbf574d36d7 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm @@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_spec, list( list("M74 AGM-F Fragmentation Grenades x6", 40, /obj/effect/essentials_set/agmf_6_pack, null, VENDOR_ITEM_REGULAR), list("M74 AGM-I Incendiary Grenades x6", 40, /obj/effect/essentials_set/agmi_6_pack, null, VENDOR_ITEM_REGULAR), list("M74 AGM-S Smoke Grenades x6", 20, /obj/effect/essentials_set/agms_6_pack, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Pack x6", 40, /obj/effect/essentials_set/sebb_6_pack, null, VENDOR_ITEM_REGULAR), list("EXTRA FLAMETHROWER TANKS", 0, null, null, null), list("Large Incinerator Tank", 40, /obj/item/ammo_magazine/flamer_tank/large, null, VENDOR_ITEM_REGULAR), @@ -249,3 +250,13 @@ GLOBAL_LIST_INIT(cm_vending_clothing_specialist, list( /obj/item/explosive/grenade/smokebomb/airburst, /obj/item/explosive/grenade/smokebomb/airburst, ) + +/obj/effect/essentials_set/sebb_6_pack + spawned_gear_list = list( + /obj/item/explosive/grenade/sebb, + /obj/item/explosive/grenade/sebb, + /obj/item/explosive/grenade/sebb, + /obj/item/explosive/grenade/sebb, + /obj/item/explosive/grenade/sebb, + /obj/item/explosive/grenade/sebb, + ) diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm index c37dd98ed263..73efbe1148e5 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm @@ -12,6 +12,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_tl, list( list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR), list("M20 Mine Box (x4 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR), list("M40 MFHS Metal Foam Grenade", 5, /obj/item/explosive/grenade/metal_foam, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR), list("PRIMARY AMMUNITION", 0, null, null, null), list("M4RA AP Magazine (10x24mm)", 10, /obj/item/ammo_magazine/rifle/m4ra/ap, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/objects/effects/effect_system/particle_effects.dm b/code/game/objects/effects/effect_system/particle_effects.dm index 972d242bf359..9440c16f2d4e 100644 --- a/code/game/objects/effects/effect_system/particle_effects.dm +++ b/code/game/objects/effects/effect_system/particle_effects.dm @@ -8,10 +8,10 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT unacidable = TRUE // So effect are not targeted by alien acid. -/obj/effect/particle_effect/initialize_pass_flags(datum/pass_flags_container/PF) +/obj/effect/particle_effect/initialize_pass_flags(datum/pass_flags_container/pass_flags) ..() - if (PF) - PF.flags_pass = PASS_OVER|PASS_AROUND|PASS_UNDER|PASS_THROUGH|PASS_MOB_THRU + if (pass_flags) + pass_flags.flags_pass = PASS_OVER|PASS_AROUND|PASS_UNDER|PASS_THROUGH|PASS_MOB_THRU //Water @@ -22,17 +22,14 @@ var/life = 15 mouse_opacity = MOUSE_OPACITY_TRANSPARENT -/obj/effect/particle_effect/water/initialize_pass_flags(datum/pass_flags_container/PF) +/obj/effect/particle_effect/water/initialize_pass_flags(datum/pass_flags_container/pass_flags) ..() - if (PF) - PF.flags_pass = PASS_THROUGH|PASS_OVER|PASS_MOB_THRU|PASS_UNDER + if (pass_flags) + pass_flags.flags_pass = PASS_THROUGH|PASS_OVER|PASS_MOB_THRU|PASS_UNDER /obj/effect/particle_effect/water/Move(turf/newloc) - //var/turf/T = src.loc - //if (istype(T, /turf)) - // T.firelevel = 0 //TODO: FIX - if (--src.life < 1) - //SN src = null + life -= 1 + if (life < 1) qdel(src) if(newloc.density) return 0 diff --git a/code/game/objects/effects/effect_system/smoke.dm b/code/game/objects/effects/effect_system/smoke.dm index d4152bdee37e..d0ea5d2ed5ef 100644 --- a/code/game/objects/effects/effect_system/smoke.dm +++ b/code/game/objects/effects/effect_system/smoke.dm @@ -731,7 +731,7 @@ location = get_turf(loca) if(direct) direction = direct - if(lifetime) + if(smoke_time) lifetime = smoke_time radius = min(radius, 10) amount = radius diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index ce0fd5506cd7..d559137f79b1 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -223,6 +223,7 @@ icon_state = "empdisable" name = "emp sparks" effect_duration = 10 + mouse_opacity = MOUSE_OPACITY_TRANSPARENT /obj/effect/overlay/temp/emp_sparks/New(loc) setDir(pick(GLOB.cardinals)) @@ -234,8 +235,12 @@ icon_state = "emppulse" effect_duration = 20 - - +/obj/effect/overlay/temp/elec_arc + icon = 'icons/effects/effects.dmi' + icon_state = "electricity" + name = "electric arc" + effect_duration = 3 SECONDS + mouse_opacity = MOUSE_OPACITY_TRANSPARENT //gib animation diff --git a/code/game/objects/explosion_recursive.dm b/code/game/objects/explosion_recursive.dm index 2ec61b0cc1f1..855f6c2f43c7 100644 --- a/code/game/objects/explosion_recursive.dm +++ b/code/game/objects/explosion_recursive.dm @@ -71,7 +71,9 @@ explosion resistance exactly as much as their health falloff = max(falloff0, power/100) //prevent explosions with a range larger than 100 tiles minimum_spread_power = -power * reflection_amplification_limit - msg_admin_attack("Explosion with Power: [power], Falloff: [falloff] in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]).", src.loc.x, src.loc.y, src.loc.z) + var/obj/causing_obj = explosion_cause_data?.resolve_cause() + var/mob/causing_mob = explosion_cause_data?.resolve_mob() + msg_admin_attack("Explosion with Power: [power], Falloff: [falloff],[causing_obj ? " from [causing_obj]" : ""][causing_mob ? " by [key_name(causing_mob)]" : ""] in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]).", loc.x, loc.y, loc.z) playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(power^2,1)) playsound(epicenter, "explosion", 90, 1, max(round(power,1),7) ) diff --git a/code/game/objects/items/devices/RCD.dm b/code/game/objects/items/devices/RCD.dm deleted file mode 100644 index 00e569800314..000000000000 --- a/code/game/objects/items/devices/RCD.dm +++ /dev/null @@ -1,194 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - -/* -CONTAINS: -RCD -*/ -/obj/item/device/rcd - name = "rapid-construction-device (RCD)" - desc = "A device used to rapidly build walls/floor." - icon = 'icons/obj/items/devices.dmi' - icon_state = "rcd" - opacity = FALSE - density = FALSE - anchored = FALSE - flags_atom = FPRINT|CONDUCT - force = 10 - throwforce = 10 - throw_speed = SPEED_FAST - throw_range = 5 - w_class = SIZE_MEDIUM - matter = list("metal" = 50000) - - var/datum/effect_system/spark_spread/spark_system - var/stored_matter = 0 - var/working = 0 - var/mode = 1 - var/canRwall = 0 - var/disabled = 0 - - -/obj/item/device/rcd/New() - desc = "A RCD. It currently holds [stored_matter]/30 matter-units." - src.spark_system = new /datum/effect_system/spark_spread - spark_system.set_up(5, 0, src) - spark_system.attach(src) - return - -/obj/item/device/rcd/Destroy() - QDEL_NULL(spark_system) - return ..() - - -/obj/item/device/rcd/attackby(obj/item/W, mob/user) - ..() - if(istype(W, /obj/item/ammo_rcd)) - if((stored_matter + 10) > 30) - to_chat(user, SPAN_NOTICE("The RCD cant hold any more matter-units.")) - return - user.drop_held_item() - qdel(W) - stored_matter += 10 - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - to_chat(user, SPAN_NOTICE("The RCD now holds [stored_matter]/30 matter-units.")) - desc = "A RCD. It currently holds [stored_matter]/30 matter-units." - return - - -/obj/item/device/rcd/attack_self(mob/user) - ..() - - //Change the mode - playsound(src.loc, 'sound/effects/pop.ogg', 15, 0) - switch(mode) - if(1) - mode = 2 - to_chat(user, SPAN_NOTICE("Changed mode to 'Airlock'")) - if(prob(20)) - src.spark_system.start() - return - if(2) - mode = 3 - to_chat(user, SPAN_NOTICE("Changed mode to 'Deconstruct'")) - if(prob(20)) - src.spark_system.start() - return - if(3) - mode = 1 - to_chat(user, SPAN_NOTICE("Changed mode to 'Floor & Walls'")) - if(prob(20)) - src.spark_system.start() - return - -/obj/item/device/rcd/proc/activate() - playsound(src.loc, 'sound/items/Deconstruct.ogg', 25, 1) - - -/obj/item/device/rcd/afterattack(atom/A, mob/user, proximity) - if(!proximity) return - if(disabled) - return 0 - if(istype(A,/area/shuttle) || istype(A,/turf/open/space/transit)) - return 0 - if(!(istype(A, /turf) || istype(A, /obj/structure/machinery/door/airlock))) - return 0 - - switch(mode) - if(1) - if(istype(A, /turf/open/space)) - if(useResource(1, user)) - to_chat(user, "Building Floor...") - activate() - A:ChangeTurf(/turf/open/floor/plating/airless) - return 1 - return 0 - - if(istype(A, /turf/open/floor)) - if(checkResource(3, user)) - to_chat(user, "Building Wall ...") - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - if(do_after(user, 20, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) - if(!useResource(3, user)) return 0 - activate() - A:ChangeTurf(/turf/closed/wall) - return 1 - return 0 - - if(2) - if(istype(A, /turf/open/floor)) - if(checkResource(10, user)) - to_chat(user, "Building Airlock...") - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - if(do_after(user, 50, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) - if(!useResource(10, user)) return 0 - activate() - var/obj/structure/machinery/door/airlock/T = new /obj/structure/machinery/door/airlock( A ) - T.autoclose = 1 - return 1 - return 0 - return 0 - - if(3) - if(istype(A, /turf/closed/wall)) - var/turf/closed/wall/WL = A - if(WL.hull) - return 0 - if(istype(A, /turf/closed/wall/r_wall) && !canRwall) - return 0 - if(checkResource(5, user)) - to_chat(user, "Deconstructing Wall...") - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - if(do_after(user, 40, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) - if(!useResource(5, user)) return 0 - activate() - A:ChangeTurf(/turf/open/floor/plating/airless) - return 1 - return 0 - - if(istype(A, /turf/open/floor) && !istype(A, /turf/open/floor/plating)) - if(checkResource(5, user)) - to_chat(user, "Deconstructing Floor...") - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - if(do_after(user, 50, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) - if(!useResource(5, user)) return 0 - activate() - A:ChangeTurf(/turf/open/floor/plating/airless) - return 1 - return 0 - - if(istype(A, /obj/structure/machinery/door/airlock)) - if(checkResource(10, user)) - to_chat(user, "Deconstructing Airlock...") - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - if(do_after(user, 50, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) - if(!useResource(10, user)) return 0 - activate() - qdel(A) - return 1 - return 0 - return 0 - else - to_chat(user, "ERROR: RCD in MODE: [mode] attempted use by [user]. Send this text #coderbus or an admin.") - return 0 - -/obj/item/device/rcd/proc/useResource(amount, mob/user) - if(stored_matter < amount) - return 0 - stored_matter -= amount - desc = "A RCD. It currently holds [stored_matter]/30 matter-units." - return 1 - -/obj/item/device/rcd/proc/checkResource(amount, mob/user) - return stored_matter >= amount - -/obj/item/ammo_rcd - name = "compressed matter cartridge" - desc = "Highly compressed matter for the RCD." - icon = 'icons/obj/items/weapons/guns/legacy/old_bayguns.dmi' - icon_state = "rcd" - item_state = "rcdammo" - opacity = FALSE - density = FALSE - anchored = FALSE - - matter = list("metal" = 30000,"glass" = 15000) diff --git a/code/game/objects/items/devices/RSF.dm b/code/game/objects/items/devices/RSF.dm deleted file mode 100644 index 29f84c7c6d0c..000000000000 --- a/code/game/objects/items/devices/RSF.dm +++ /dev/null @@ -1,98 +0,0 @@ -/* -CONTAINS: -RSF - -*/ - -/obj/item/device/rsf - name = "\improper Rapid-Service-Fabricator" - desc = "A device used to rapidly deploy service items." - icon = 'icons/obj/items/devices.dmi' - icon_state = "rcd" - opacity = FALSE - density = FALSE - anchored = FALSE - var/stored_matter = 30 - var/mode = 1 - w_class = SIZE_MEDIUM - -/obj/item/device/rsf/get_examine_text(mob/user) - . = ..() - . += "It currently holds [stored_matter]/30 fabrication-units." - -/obj/item/device/rsf/attackby(obj/item/W, mob/user) - ..() - if (istype(W, /obj/item/ammo_rcd)) - - if ((stored_matter + 10) > 30) - to_chat(user, "The RSF can't hold any more matter.") - return - - qdel(W) - - stored_matter += 10 - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - to_chat(user, "The RSF now holds [stored_matter]/30 fabrication-units.") - return - -/obj/item/device/rsf/attack_self(mob/user) - ..() - playsound(src.loc, 'sound/effects/pop.ogg', 15, 0) - if (mode == 1) - mode = 2 - to_chat(user, "Changed dispensing mode to 'Drinking Glass'") - return - if (mode == 2) - mode = 3 - to_chat(user, "Changed dispensing mode to 'Paper'") - return - if (mode == 3) - mode = 4 - to_chat(user, "Changed dispensing mode to 'Pen'") - return - if (mode == 4) - mode = 5 - to_chat(user, "Changed dispensing mode to 'Dice Pack'") - return - if (mode == 5) - mode = 6 - to_chat(user, "Changed dispensing mode to 'Cigarette'") - return - if (mode == 6) - mode = 1 - to_chat(user, "Changed dispensing mode to 'Dosh'") - return - // Change mode - -/obj/item/device/rsf/afterattack(atom/A, mob/user, proximity) - - if(!proximity) return - - if(stored_matter <= 0) - return - - if(!istype(A, /obj/structure/surface/table) && !istype(A, /turf/open/floor)) - return - - playsound(src.loc, 'sound/machines/click.ogg', 25, 1) - var/obj/product - - switch(mode) - if(1) - product = new /obj/item/spacecash/c10() - if(2) - product = new /obj/item/reagent_container/food/drinks/drinkingglass() - if(3) - product = new /obj/item/paper() - if(4) - product = new /obj/item/tool/pen() - if(5) - product = new /obj/item/storage/pill_bottle/dice() - if(6) - product = new /obj/item/clothing/mask/cigarette() - - to_chat(user, "Dispensing [product ? product : "product"]...") - product.forceMove(get_turf(A)) - - stored_matter-- - to_chat(user, "The RSF now holds [stored_matter]/30 fabrication-units.") diff --git a/code/game/objects/items/devices/RSP.dm b/code/game/objects/items/devices/RSP.dm deleted file mode 100644 index cb61de1a77cc..000000000000 --- a/code/game/objects/items/devices/RSP.dm +++ /dev/null @@ -1,11 +0,0 @@ -/obj/item/device/rsp - name = "\improper Rapid-Seed-Producer (RSP)" - desc = "A device used to rapidly deploy seeds." - icon = 'icons/obj/items/devices.dmi' - icon_state = "rsp" - opacity = FALSE - density = FALSE - anchored = FALSE - var/stored_matter = 0 - var/mode = 1 - w_class = SIZE_MEDIUM diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 8d5e3cc752ff..e506f51ce21c 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -15,7 +15,7 @@ ground_offset_x = 2 ground_offset_y = 6 - actions_types = list(/datum/action/item_action) + actions_types = list(/datum/action/item_action/toggle) var/on = FALSE var/raillight_compatible = TRUE //Can this be turned into a rail light ? var/toggleable = TRUE diff --git a/code/game/objects/items/devices/motion_detector.dm b/code/game/objects/items/devices/motion_detector.dm index dcbcc0dd8bc7..f68295001f92 100644 --- a/code/game/objects/items/devices/motion_detector.dm +++ b/code/game/objects/items/devices/motion_detector.dm @@ -33,7 +33,7 @@ var/long_range_cooldown = 2 var/blip_type = "detector" var/iff_signal = FACTION_MARINE - actions_types = list(/datum/action/item_action) + actions_types = list(/datum/action/item_action/toggle) var/scanning = FALSE // controls if MD is in process of scan var/datum/shape/rectangle/square/range_bounds var/long_range_locked = FALSE //only long-range MD diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm deleted file mode 100644 index 564b3e41f591..000000000000 --- a/code/game/objects/items/devices/suit_cooling.dm +++ /dev/null @@ -1,179 +0,0 @@ -/obj/item/device/suit_cooling_unit - name = "portable suit cooling unit" - desc = "A portable heat sink and liquid cooled radiator that can be hooked up to a space suit's existing temperature controls to provide industrial levels of cooling." - w_class = SIZE_LARGE - icon_state = "suitcooler0" - flags_equip_slot = SLOT_BACK //you can carry it on your back if you want, but it won't do anything unless attached to suit storage - - //copied from tank.dm - flags_atom = FPRINT|CONDUCT - force = 5 - throwforce = 10 - throw_speed = SPEED_FAST - throw_range = 4 - - - - var/on = 0 //is it turned on? - var/cover_open = 0 //is the cover open? - var/obj/item/cell/cell - var/max_cooling = 12 //in degrees per second - probably don't need to mess with heat capacity here - var/charge_consumption = 16.6 //charge per second at max_cooling - var/thermostat = T20C - - //TODO: make it heat up the surroundings when not in space - -/obj/item/device/suit_cooling_unit/Initialize(mapload, ...) - . = ..() - - START_PROCESSING(SSobj, src) - - cell = new/obj/item/cell(src) //comes with the crappy default power cell - high-capacity ones shouldn't be hard to find - -/obj/item/device/suit_cooling_unit/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/device/suit_cooling_unit/process() - if (!on || !cell) - return - - if (!ismob(loc)) - return - - if (!attached_to_suit(loc)) //make sure they have a suit and we are attached to it - return - - var/mob/living/carbon/human/H = loc - - var/efficiency = 1 - H.get_pressure_weakness() //you need to have a good seal for effective cooling - var/env_temp = get_environment_temperature() //wont save you from a fire - var/temp_adj = min(H.bodytemperature - max(thermostat, env_temp), max_cooling) - - if (temp_adj < 0.5) //only cools, doesn't heat, also we don't need extreme precision - return - - var/charge_usage = (temp_adj/max_cooling)*charge_consumption - - H.bodytemperature -= temp_adj*efficiency - H.recalculate_move_delay = TRUE - - cell.use(charge_usage) - - if(cell.charge <= 0) - turn_off() - -/obj/item/device/suit_cooling_unit/proc/get_environment_temperature() - if (ishuman(loc)) - var/mob/living/carbon/human/H = loc - return H.return_temperature() - - var/turf/T = get_turf(src) - return T.return_temperature() - -/obj/item/device/suit_cooling_unit/proc/attached_to_suit(mob/M) - if (!ishuman(M)) - return 0 - - var/mob/living/carbon/human/H = M - - if (!H.wear_suit || H.s_store != src) - return 0 - - return 1 - -/obj/item/device/suit_cooling_unit/proc/turn_on() - if(!cell) - return - if(cell.charge <= 0) - return - - on = 1 - updateicon() - -/obj/item/device/suit_cooling_unit/proc/turn_off() - if (ismob(src.loc)) - var/mob/M = src.loc - M.show_message("\The [src] clicks and whines as it powers down.", SHOW_MESSAGE_AUDIBLE) //let them know in case it's run out of power. - on = 0 - updateicon() - -/obj/item/device/suit_cooling_unit/attack_self(mob/user) - ..() - - if(cover_open && cell) - if(ishuman(user)) - user.put_in_hands(cell) - else - cell.forceMove(get_turf(loc)) - - cell.add_fingerprint(user) - cell.update_icon() - - to_chat(user, "You remove [cell].") - src.cell = null - updateicon() - return - - //TODO use a UI like the air tanks - if(on) - turn_off() - else - turn_on() - if (on) - to_chat(user, "You switch on [src].") - -/obj/item/device/suit_cooling_unit/attackby(obj/item/W as obj, mob/user as mob) - if (HAS_TRAIT(W, TRAIT_TOOL_SCREWDRIVER)) - if(cover_open) - cover_open = 0 - to_chat(user, "You screw the panel into place.") - else - cover_open = 1 - to_chat(user, "You unscrew the panel.") - updateicon() - return - - if (istype(W, /obj/item/cell)) - if(cover_open) - if(cell) - to_chat(user, "There is \a [cell] already installed here.") - else - if(user.drop_held_item()) - W.forceMove(src) - cell = W - to_chat(user, "You insert [cell].") - updateicon() - return - - return ..() - -/obj/item/device/suit_cooling_unit/proc/updateicon() - if (cover_open) - if (cell) - icon_state = "suitcooler1" - else - icon_state = "suitcooler2" - else - icon_state = "suitcooler0" - -/obj/item/device/suit_cooling_unit/get_examine_text(mob/user) - . = ..() - if (on) - if (attached_to_suit(src.loc)) - . += "It's switched on and running." - else - . += "It's switched on, but not attached to anything." - else - . += "It is switched off." - - if (cover_open) - if(cell) - . += "The panel is open, exposing [cell]." - else - . += "The panel is open." - - if (cell) - . += "The charge meter reads [floor(cell.percent())]%." - else - . += "It doesn't have a power cell installed." diff --git a/code/game/objects/items/devices/whistle.dm b/code/game/objects/items/devices/whistle.dm index 331df3ffa006..07196a3e1bb9 100644 --- a/code/game/objects/items/devices/whistle.dm +++ b/code/game/objects/items/devices/whistle.dm @@ -5,7 +5,7 @@ w_class = SIZE_TINY flags_atom = FPRINT|CONDUCT flags_equip_slot = SLOT_FACE - actions_types = list(/datum/action/item_action) + actions_types = list(/datum/action/item_action/toggle/use) var/volume = 60 var/spam_cooldown_time = 10 SECONDS @@ -51,7 +51,6 @@ usr.put_in_l_hand(src) add_fingerprint(usr) - /obj/item/device/hailer name = "hailer" desc = "Used by obese officers to save their breath for running." diff --git a/code/game/objects/items/explosives/grenades/marines.dm b/code/game/objects/items/explosives/grenades/marines.dm index 1cd3e1577c57..09c0197cda7f 100644 --- a/code/game/objects/items/explosives/grenades/marines.dm +++ b/code/game/objects/items/explosives/grenades/marines.dm @@ -465,6 +465,187 @@ icon_state = "grenade_phos_clf" item_state = "grenade_phos_clf" +/obj/item/explosive/grenade/sebb + name = "\improper G2 Electroshock grenade" + desc = "This is a G2 Electroshock Grenade. Produced by Armat Battlefield Systems, it's sometimes referred to as the Sonic Electric Ball Breaker, \ + after a rash of incidents where the intense 1.2 gV sonic payload caused... rupturing. \ + A bounding landmine mode is available for this weapon which activates a small drill to self-bury itself when planted. Simply plant it at your feet and walk away." + icon_state = "grenade_sebb" + item_state = "grenade_sebb" + det_time = 3 SECONDS + underslug_launchable = TRUE + /// Maximum range of effect + var/range = 5 + /// Maximum possible damage before falloff. + var/damage = 110 + /// Factor to mutiply the effect range has on damage. + var/falloff_dam_reduction_mult = 20 + /// Post falloff calc damage is divided by this to get xeno slowdown + var/xeno_slowdown_numerator = 12 + /// Post falloff calc damage is multipled by this to get human stamina damage + var/human_stam_dam_factor = 0.9 + +/obj/item/explosive/grenade/sebb/get_examine_text(mob/user) + . = ..() + . += SPAN_NOTICE("To put into mine mode, plant at feet.") + +/obj/item/explosive/grenade/sebb/afterattack(atom/target, mob/user, proximity) + var/turf/user_turf = get_turf(user) + if(active) + return + + if(!isturf(target)) + return + + if(user.action_busy) + return + + if(target != get_turf(user)) + return + + if(locate(/obj/item/explosive/mine) in get_turf(src)) + to_chat(user, SPAN_WARNING("There already is a mine at this position!")) + return + + if(antigrief_protection && user.faction == FACTION_MARINE && explosive_antigrief_check(src, user)) + to_chat(user, SPAN_WARNING("\The [name]'s safe-area accident inhibitor prevents you from planting!")) + msg_admin_niche("[key_name(user)] attempted to plant \a [name] in [get_area(src)] [ADMIN_JMP(src.loc)]") + return + + if(ishuman(user)) + var/mob/living/carbon/human/human = user + if(!human.allow_gun_usage) + to_chat(user, SPAN_WARNING("Your programming prevents you from using this!")) + return + + if(user_turf && (user_turf.density || locate(/obj/structure/fence) in user_turf)) + to_chat(user, SPAN_WARNING("You can't plant a mine here.")) + return + + if(Adjacent(/obj/item/explosive/mine)) // bit more strict on this than normal mines + to_chat(user, SPAN_WARNING("Too close to another mine! Plant it somewhere less obvious.")) + return + + user.visible_message(SPAN_NOTICE("[user] starts deploying [src]."), + SPAN_NOTICE("You switch [src] into landmine mode and start placing it...")) + playsound(user.loc, 'sound/effects/thud.ogg', 40) + if(!do_after(user, 5 SECONDS * user.get_skill_duration_multiplier(SKILL_CONSTRUCTION), INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) + to_chat(user, SPAN_NOTICE("You stop planting.")) + return + + user.visible_message(SPAN_NOTICE("[user] finishes deploying [src]."), + SPAN_NOTICE("You finish deploying [src].")) + var/obj/item/explosive/mine/sebb/planted = new /obj/item/explosive/mine/sebb(get_turf(user)) + planted.activate_sensors() + planted.iff_signal = user.faction // assuring IFF is set + planted.pixel_x += rand(-5, 5) + planted.pixel_y += rand(-5, 5) + qdel(src) + +/obj/item/explosive/grenade/sebb/activate() + ..() + var/beeplen = 6 // Actual length of the sound rounded up to nearest decisecond + var/soundtime = det_time - beeplen + if(det_time < beeplen) // just play sound if detonation shorter than the sound + playsound(loc, 'sound/effects/sebb_explode.ogg', 90, 0, 10) + else + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), loc, 'sound/effects/sebb_beep.ogg', 60, 0, 10), soundtime) + + + +/obj/item/explosive/grenade/sebb/prime() + var/datum/effect_system/spark_spread/sparka = new + var/turf/sebb_turf = get_turf(src) + var/list/full_range = oview(range, src) // Fill a list of stuff in the range so we won't have to spam oview + new /obj/effect/overlay/temp/sebb(sebb_turf) + + playsound(src.loc, 'sound/effects/sebb_explode.ogg', 90, 0, 10) + + for(var/obj/structure/machinery/defenses/sentry/sentry_stun in full_range) + sentry_stun.sentry_range = 0 // Temporarily "disable" the sentry by killing its range then setting it back. + new /obj/effect/overlay/temp/elec_arc(get_turf(sentry_stun)) // sprites are meh but we need visual indication that the sentry was messed up + addtimer(VARSET_CALLBACK(sentry_stun, sentry_range, initial(sentry_stun.sentry_range)), 5 SECONDS) // assure to set it back + sentry_stun.visible_message(SPAN_DANGER("[src]'s screen flickes violently as it's shocked!")) + sentry_stun.visible_message(SPAN_DANGER("[src] says \"ERROR: Fire control system resetting due to critical voltage flucuation!\"")) + sparka.set_up(1, 1, sentry_stun) + sparka.start() + + for(var/turf/turf in full_range) + if(prob(8)) + var/datum/effect_system/spark_spread/sparkTurf = new //using a different spike system because the spark system doesn't like when you reuse it for differant things + sparkTurf.set_up(1, 1, turf) + sparkTurf.start() + if(prob(10)) + new /obj/effect/overlay/temp/emp_sparks(turf) + + for(var/mob/living/carbon/mob in full_range) // no legacy mob support + + var/mob_dist = get_dist(src, mob) // Distance from mob + + /** + * Damage equation: damage - (mob distance * falloff_dam_reduction_mult) + * Example: A marine is 3 tiles out, the distance (3) is multiplied by falloff_dam_reduction_mult to get falloff. + * The raw damage is minused by falloff to get actual damage + */ + + var/falloff = mob_dist * falloff_dam_reduction_mult + var/damage_applied = damage - falloff // Final damage applied after falloff calc + sparka.set_up(1, 1, mob) + sparka.start() + shake_camera(mob, 1, 1) + if(ishuman(mob)) + var/mob/living/carbon/human/shocked_human = mob + if(isspeciessynth(shocked_human)) // Massive overvoltage to ungrounded robots is pretty bad + shocked_human.Stun(1 + (damage_applied/40)) + damage_applied *= 1.5 + new /obj/effect/overlay/temp/elec_arc(get_turf(shocked_human)) + to_chat(mob, SPAN_HIGHDANGER("All of your systems jam up as your main bus is overvolted by [damage_applied*2] volts.")) + mob.visible_message(SPAN_WARNING("[mob] seizes up from the elctric shock")) + shocked_human.take_overall_armored_damage(damage_applied, ARMOR_ENERGY, BURN, 90) // 90% chance to be on additional limbs + shocked_human.make_dizzy(damage_applied) + mob.apply_stamina_damage(damage_applied*human_stam_dam_factor) // Stamina damage + shocked_human.emote("pain") + else //nonhuman damage + slow + mob.apply_damage(damage_applied, BURN) + if((mob_dist < (range-3))) // 2 tiles around small superslow + mob.Superslow(2) + mob.Slow(damage_applied/11) + + if(mob_dist < 1) // Range based stuff, standing ontop of the equivalent of a canned lighting bolt should mess you up. + mob.Superslow(3) // Note that humans will likely be in stamcrit so it's always worse for them when ontop of it and we can just balancing it on xenos. + mob.eye_blurry = damage_applied/4 + mob.Daze(1) + else if((mob_dist < (range-1)) && (mob.mob_size < MOB_SIZE_XENO_VERY_SMALL)) // Flicker stun humans that are closer to the grenade and larvas too. + mob.apply_effect(1 + (damage_applied/100),WEAKEN) // 1 + damage/40 + mob.eye_blurry = damage_applied/8 + + else + to_chat(mob, SPAN_HIGHDANGER("Your entire body seizes up as a powerful shock courses through it!")) + + + new /obj/effect/overlay/temp/emp_sparks(mob) + mob.make_jittery(damage_applied*2) + empulse(src, 1, 2) // mini EMP + qdel(src) + + +/obj/item/explosive/grenade/sebb/primed + desc = "A G2 Electroshock Grenade, looks like it's quite angry! Oh shit!" + det_time = 7 // 0.7 seconds to blow up. We want them to get caught if they go through. + +/obj/item/explosive/grenade/sebb/primed/Initialize() + . = ..() + src.visible_message(SPAN_HIGHDANGER("[src] pops out of the ground!")) + activate() + +/obj/effect/overlay/temp/sebb + icon = 'icons/effects/sebb.dmi' + icon_state = "sebb_explode" + layer = ABOVE_LIGHTING_PLANE + pixel_x = -175 // We need these offsets to force center the sprite because BYOND is dumb + pixel_y = -175 + appearance_flags = RESET_COLOR + /* //================================================ Nerve Gas Grenades diff --git a/code/game/objects/items/explosives/mine.dm b/code/game/objects/items/explosives/mine.dm index 45065a2de1de..6e7aa2bdccc3 100644 --- a/code/game/objects/items/explosives/mine.dm +++ b/code/game/objects/items/explosives/mine.dm @@ -14,6 +14,7 @@ throw_speed = SPEED_VERY_FAST unacidable = TRUE flags_atom = FPRINT|CONDUCT + antigrief_protection = TRUE allowed_sensors = list(/obj/item/device/assembly/prox_sensor) max_container_volume = 120 reaction_limits = list( "max_ex_power" = 105, "base_ex_falloff" = 60, "max_ex_shards" = 32, @@ -71,7 +72,12 @@ if(active || user.action_busy) return - user.visible_message(SPAN_NOTICE("[user] starts deploying [src]."), \ + if(antigrief_protection && user.faction == FACTION_MARINE && explosive_antigrief_check(src, user)) + to_chat(user, SPAN_WARNING("\The [name]'s safe-area accident inhibitor prevents you from planting!")) + msg_admin_niche("[key_name(user)] attempted to plant \a [name] in [get_area(src)] [ADMIN_JMP(src.loc)]") + return + + user.visible_message(SPAN_NOTICE("[user] starts deploying [src]."), SPAN_NOTICE("You start deploying [src].")) if(!do_after(user, 40, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) user.visible_message(SPAN_NOTICE("[user] stops deploying [src]."), \ @@ -317,3 +323,19 @@ customizable = TRUE matter = list("metal" = 3750) has_blast_wave_dampener = TRUE + +/obj/item/explosive/mine/sebb + name = "\improper G2 Electroshock grenade" + icon_state = "grenade_sebb_planted" + desc = "A G2 electroshock grenade planted as a landmine." + pixel_y = -5 + anchored = TRUE // this is supposed to be planeted already when spawned + +/obj/item/explosive/mine/sebb/disarm() + . = ..() + new /obj/item/explosive/grenade/sebb(get_turf(src)) + qdel(src) + +/obj/item/explosive/mine/sebb/prime() + new /obj/item/explosive/grenade/sebb/primed(get_turf(src)) + qdel(src) diff --git a/code/game/objects/items/stacks/flags.dm b/code/game/objects/items/stacks/flags.dm index e032e2c80157..14833812b06c 100644 --- a/code/game/objects/items/stacks/flags.dm +++ b/code/game/objects/items/stacks/flags.dm @@ -106,7 +106,7 @@ user.visible_message(SPAN_NOTICE("[user] starts taking [src] down..."), SPAN_NOTICE("You start taking [src] down...")) playsound(loc, 'sound/effects/flag_raising.ogg', 30) - if(!do_after(user, 6 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC)) + if(!do_after(user, 6 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC) || QDELETED(src)) return playsound(loc, 'sound/effects/flag_raised.ogg', 30) @@ -170,7 +170,11 @@ icon = 'icons/obj/structures/plantable_flag.dmi' inhand_x_dimension = 64 inhand_y_dimension = 64 + force = 15 + throwforce = 5 + hitsound = "swing_hit" unacidable = TRUE + indestructible = TRUE item_icons = list( WEAR_L_HAND = 'icons/mob/humans/onmob/items_lefthand_64.dmi', WEAR_R_HAND = 'icons/mob/humans/onmob/items_righthand_64.dmi' @@ -233,12 +237,10 @@ if(play_warcry && user.faction == faction && user.a_intent == INTENT_HARM) var/allies_nearby = 0 if(COOLDOWN_FINISHED(src, warcry_cooldown_item)) - for (var/mob/living/carbon/human in orange(planted_flag, 7)) - if (human.is_dead() || human.faction != faction) + for(var/mob/living/carbon/human in orange(planted_flag, 7)) + if(human.is_dead() || human.faction != faction) continue allies_nearby++ - if (prob(40) && human != user) - human.emote("warcry") user.show_speech_bubble("warcry") if(allies_nearby >= allies_required) diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm deleted file mode 100644 index 3a5afef6cf1e..000000000000 --- a/code/game/objects/items/tanks/jetpack.dm +++ /dev/null @@ -1,85 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - -/obj/item/tank/jetpack - name = "Jetpack (Empty)" - desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution." - icon_state = "jetpack" - w_class = SIZE_LARGE - item_state = "jetpack" - distribute_pressure = ONE_ATMOSPHERE*O2STANDARD - var/datum/effect_system/ion_trail_follow/ion_trail - var/on = 0 - var/stabilization_on = 0 - var/volume_rate = 500 //Needed for borg jetpack transfer - actions_types = list(/datum/action/item_action) - -/obj/item/tank/jetpack/Initialize() - . = ..() - src.ion_trail = new /datum/effect_system/ion_trail_follow() - src.ion_trail.set_up(src) - -/obj/item/tank/jetpack/Destroy() - QDEL_NULL(ion_trail) - return ..() - - -/obj/item/tank/jetpack/verb/toggle_rockets() - set name = "Toggle Jetpack Stabilization" - set category = "Object" - set src in usr - src.stabilization_on = !( src.stabilization_on ) - to_chat(usr, "You toggle the stabilization [stabilization_on? "on":"off"].") - -/obj/item/tank/jetpack/verb/toggle() - set name = "Toggle Jetpack" - set category = "Object" - set src in usr - on = !on - if(on) - icon_state = "[icon_state]-on" - ion_trail.start() - else - icon_state = initial(icon_state) - ion_trail.stop() - - if (ismob(usr)) - var/mob/M = usr - M.update_inv_back() - - for(var/X in actions) - var/datum/action/A = X - A.update_button_icon() - -/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user) - if(!(src.on)) - return 0 - - if(pressure > 5) - return 1 - else - ion_trail.stop() - return 0 - - -/obj/item/tank/jetpack/ui_action_click() - toggle() - - -/obj/item/tank/jetpack/void - name = "Void Jetpack (Oxygen)" - desc = "It works well in a void." - icon_state = "jetpack-void" - item_state = "jetpack-void" - -/obj/item/tank/jetpack/oxygen - name = "Jetpack (Oxygen)" - desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution." - icon_state = "jetpack" - item_state = "jetpack" - -/obj/item/tank/jetpack/carbondioxide - name = "Jetpack (Carbon Dioxide)" - desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals." - distribute_pressure = 0 - icon_state = "jetpack-black" - item_state = "jetpack-black" diff --git a/code/game/objects/items/tools/cleaning_tools.dm b/code/game/objects/items/tools/cleaning_tools.dm index f392f096bcf6..fba21de3328d 100644 --- a/code/game/objects/items/tools/cleaning_tools.dm +++ b/code/game/objects/items/tools/cleaning_tools.dm @@ -99,13 +99,15 @@ desc = "This cone is trying to warn you of something!" icon_state = "cone" icon = 'icons/obj/janitor.dmi' + item_icons = 'icons/mob/humans/onmob/head_0.dmi' force = 1 throwforce = 3 throw_speed = SPEED_FAST throw_range = 5 w_class = SIZE_SMALL attack_verb = list("warned", "cautioned", "smashed") - + flags_equip_slot = SLOT_HEAD + flags_inv_hide = HIDEEARS|HIDETOPHAIR diff --git a/code/game/objects/items/tools/kitchen_tools.dm b/code/game/objects/items/tools/kitchen_tools.dm index d6473b156a67..a4c4925fba2c 100644 --- a/code/game/objects/items/tools/kitchen_tools.dm +++ b/code/game/objects/items/tools/kitchen_tools.dm @@ -48,7 +48,7 @@ var/fullness = M.nutrition + (M.reagents.get_reagent_amount("nutriment") * 25) if(fullness > NUTRITION_HIGH) to_chat(user, SPAN_WARNING("[user == M ? "You" : "They"] don't feel like eating more right now.")) - return ..() + return reagents.set_source_mob(user) reagents.trans_to_ingest(M, reagents.total_volume) if(M == user) diff --git a/code/game/objects/structures/crates_lockers/closets/malfunction.dm b/code/game/objects/structures/crates_lockers/closets/malfunction.dm deleted file mode 100644 index 704e2c79157a..000000000000 --- a/code/game/objects/structures/crates_lockers/closets/malfunction.dm +++ /dev/null @@ -1,16 +0,0 @@ - -/obj/structure/closet/malf/suits - desc = "It's a storage unit for operational gear." - icon_state = "syndicate" - icon_closed = "syndicate" - icon_opened = "syndicate_open" - -/obj/structure/closet/malf/suits/Initialize() - . = ..() - new /obj/item/tank/jetpack/void(src) - new /obj/item/clothing/mask/breath(src) - new /obj/item/clothing/head/helmet/space/uscm(src) - new /obj/item/clothing/suit/space/uscm(src) - new /obj/item/tool/crowbar(src) - new /obj/item/cell(src) - new /obj/item/device/multitool(src) diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index b000fd5733a2..0bf39322d107 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -23,7 +23,7 @@ . = ..() #ifndef UNIT_TESTS - switch (pickweight(list("small" = 55, "aid" = 25, "tank" = 10, "both" = 10, "nothing" = 0, "delete" = 0))) + switch (pick_weight(list("small" = 55, "aid" = 25, "tank" = 10, "both" = 10, "nothing" = 1, "delete" = 1))) #else var/test = "both" switch (test) // We don't want randomness in tests diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index d891119a8404..8a10cd4d93ea 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -277,13 +277,6 @@ name = "RCD crate" desc = "A crate for the storage of the RCD." -/obj/structure/closet/crate/rcd/Initialize() - . = ..() - new /obj/item/ammo_rcd(src) - new /obj/item/ammo_rcd(src) - new /obj/item/ammo_rcd(src) - new /obj/item/device/rcd(src) - /obj/structure/closet/crate/freezer/rations //Fpr use in the escape shuttle desc = "A crate of emergency rations." name = "Emergency Rations" diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm index 986ae99739aa..f71882374518 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm @@ -36,12 +36,12 @@ move_delay += 4 //harder to move a wheelchair with a single hand working_hands-- else if((left_hand.status & LIMB_BROKEN) && !(left_hand.status & LIMB_SPLINTED)) - move_delay++ + move_delay ++ if(!right_hand || (right_hand.status & LIMB_DESTROYED)) move_delay += 4 working_hands-- else if((right_hand.status & LIMB_BROKEN) && !(right_hand.status & LIMB_SPLINTED)) - move_delay += 2 + move_delay++ if(!working_hands) return // No hands to drive your chair? Tough luck! if(driver.pulling && driver.pulling.drag_delay && driver.get_pull_miltiplier()) //Dragging stuff can slow you down a bit. diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index 53b64cbedfad..8974eb36187f 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -532,7 +532,7 @@ GLOBAL_DATUM_INIT(supply_controller, /datum/controller/supply, new()) for(var/datum/supply_packs_asrs/crate in cratelist) var/weight = (floor(10000/crate.cost)) weighted_crate_list[crate] = weight - return pickweight(weighted_crate_list) + return pick_weight(weighted_crate_list) //To stop things being sent to centcomm which should not be sent to centcomm. Recursively checks for these types. /datum/controller/supply/proc/forbidden_atoms_check(atom/A) diff --git a/code/game/turfs/walls/wall_types.dm b/code/game/turfs/walls/wall_types.dm index 21839d35af03..6db61002c2fe 100644 --- a/code/game/turfs/walls/wall_types.dm +++ b/code/game/turfs/walls/wall_types.dm @@ -297,11 +297,10 @@ INITIALIZE_IMMEDIATE(/turf/closed/wall/indestructible/splashscreen) /turf/closed/wall/indestructible/splashscreen name = "Lobby Art" desc = "Assorted artworks." - icon = 'icons/lobby/title.dmi' - icon_state = "" -// icon_state = "title_holiday" + icon = 'icons/lobby/title_loading.dmi' + icon_state = "title" layer = FLY_LAYER - special_icon = 1 + special_icon = TRUE /turf/closed/wall/indestructible/splashscreen/Initialize() . = ..() @@ -309,16 +308,19 @@ INITIALIZE_IMMEDIATE(/turf/closed/wall/indestructible/splashscreen) /proc/force_lobby_art(art_id) GLOB.displayed_lobby_art = art_id - var/turf/closed/wall/indestructible/splashscreen/SS = locate("LOBBYART") + var/turf/closed/wall/indestructible/splashscreen/lobby_art = locate("LOBBYART") var/list/lobby_arts = CONFIG_GET(str_list/lobby_art_images) var/list/lobby_authors = CONFIG_GET(str_list/lobby_art_authors) - SS.icon_state = lobby_arts[GLOB.displayed_lobby_art] - SS.desc = "Artwork by [lobby_authors[GLOB.displayed_lobby_art]]" - for(var/client/C in GLOB.clients) + lobby_art.icon = 'icons/lobby/title.dmi' + lobby_art.icon_state = lobby_arts[GLOB.displayed_lobby_art] + lobby_art.desc = "Artwork by [lobby_authors[GLOB.displayed_lobby_art]]" + lobby_art.pixel_x = -288 + lobby_art.pixel_y = -288 + for(var/client/player in GLOB.clients) if(GLOB.displayed_lobby_art != -1) var/author = lobby_authors[GLOB.displayed_lobby_art] if(author != "Unknown") - to_chat_forced(C, SPAN_ROUNDBODY("