diff --git a/code/citadel/cit_guns.dm b/code/citadel/cit_guns.dm index ec1caacdab..efab785d12 100644 --- a/code/citadel/cit_guns.dm +++ b/code/citadel/cit_guns.dm @@ -28,6 +28,8 @@ build_path = /obj/item/gun/energy/laser/carbine/nopin category = list("Weapons") +////////////Anti Tank Pistol//////////// + /obj/item/gun/ballistic/automatic/pistol/antitank name = "Anti Tank Pistol" desc = "A massively impractical and silly monstrosity of a pistol that fires .50 calliber rounds. The recoil is likely to dislocate your wrist." @@ -45,7 +47,6 @@ fire_sound = 'sound/weapons/blastcannon.ogg' spread = 30 //damn thing has no rifling. - /obj/item/gun/ballistic/automatic/pistol/antitank/update_icon() ..() if(magazine) @@ -61,3 +62,280 @@ pin = /obj/item/device/firing_pin/implant/pindicate origin_tech = "combat=7;syndicate=6" +/////////////spinfusor stuff//////////////// + +/obj/item/projectile/bullet/spinfusor + name ="spinfusor disk" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state= "spinner" + damage = 30 + dismemberment = 25 + +/obj/item/projectile/bullet/spinfusor/on_hit(atom/target, blocked = FALSE) //explosion to emulate the spinfusor's AOE + ..() + explosion(target, -1, -1, 2, 0, -1) + return 1 + +/obj/item/ammo_casing/caseless/spinfusor + name = "spinfusor disk" + desc = "A magnetic disk designed specifically for the Stormhammer magnetic cannon. Warning: extremely volatile!" + projectile_type = /obj/item/projectile/bullet/spinfusor + caliber = "spinfusor" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "disk" + throwforce = 15 //still deadly when thrown + throw_speed = 3 + +/obj/item/ammo_casing/caseless/spinfusor/throw_impact(atom/target) //disks detonate when thrown + if(!..()) // not caught in mid-air + visible_message("[src] detonates!") + playsound(src.loc, "sparks", 50, 1) + explosion(target, -1, -1, 1, 1, -1) + qdel(src) + return 1 + +/obj/item/ammo_box/magazine/internal/spinfusor + name = "spinfusor internal magazine" + ammo_type = /obj/item/ammo_casing/caseless/spinfusor + caliber = "spinfusor" + max_ammo = 1 + +/obj/item/gun/ballistic/automatic/spinfusor + name = "Stormhammer Magnetic Cannon" + desc = "An innovative weapon utilizing mag-lev technology to spin up a magnetic fusor and launch it at extreme velocities." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "spinfusor" + item_state = "spinfusor" + mag_type = /obj/item/ammo_box/magazine/internal/spinfusor + fire_sound = 'sound/weapons/rocketlaunch.ogg' + w_class = WEIGHT_CLASS_BULKY + can_suppress = 0 + burst_size = 1 + fire_delay = 20 + select = 0 + actions_types = list() + casing_ejector = 0 + origin_tech = "combat=6;magnets=6" + +/obj/item/gun/ballistic/automatic/spinfusor/attackby(obj/item/A, mob/user, params) + var/num_loaded = magazine.attackby(A, user, params, 1) + if(num_loaded) + to_chat(user, "You load [num_loaded] disk\s into \the [src].") + update_icon() + chamber_round() + +/obj/item/gun/ballistic/automatic/spinfusor/attack_self(mob/living/user) + return //caseless rounds are too glitchy to unload properly. Best to make it so that you cannot remove disks from the spinfusor + +/obj/item/gun/ballistic/automatic/spinfusor/update_icon() + ..() + icon_state = "spinfusor[magazine ? "-[get_ammo(1)]" : ""]" + +/obj/item/ammo_box/aspinfusor + name = "ammo box (spinfusor disks)" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "spinfusorbox" + ammo_type = /obj/item/ammo_casing/caseless/spinfusor + max_ammo = 8 + +/datum/supply_pack/security/armory/spinfusor + name = "Stormhammer Spinfusor Crate" + cost = 7000 + contains = list(/obj/item/gun/ballistic/automatic/spinfusor, + /obj/item/gun/ballistic/automatic/spinfusor) + crate_name = "spinfusor crate" + +/datum/supply_pack/security/armory/spinfusorammo + name = "Spinfusor Disk Crate" + cost = 4000 + contains = list(/obj/item/ammo_box/aspinfusor, + /obj/item/ammo_box/aspinfusor, + /obj/item/ammo_box/aspinfusor, + /obj/item/ammo_box/aspinfusor) + crate_name = "spinfusor disk crate" + +///////XCOM X9 AR/////// + +/obj/item/gun/ballistic/automatic/x9 //will be adminspawn only so ERT or something can use them + name = "\improper X9 Assault Rifle" + desc = "A rather old design of a cheap, reliable assault rifle made for combat against unknown enemies. Uses 5.56mm ammo." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "x9" + item_state = "arg" + slot_flags = 0 + origin_tech = "combat=7;engineering=7" + mag_type = /obj/item/ammo_box/magazine/m556 //Uses the m90gl's magazine, just like the NT-ARG + fire_sound = 'sound/weapons/gunshot_smg.ogg' + can_suppress = 0 + burst_size = 6 //in line with XCOMEU stats. This can fire 5 bursts from a full magazine. + fire_delay = 1 + spread = 30 //should be 40 for XCOM memes, but since its adminspawn only, might as well make it useable + recoil = 1 + +////////XCOM2 Magpistol///////// + +//////projectiles////// + +/obj/item/projectile/bullet/mags + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magjectile" + damage = 25 + armour_penetration = 10 + light_range = 2 + light_color = LIGHT_COLOR_RED + +/obj/item/projectile/bullet/nlmags //non-lethal boolets + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magjectile-nl" + damage = 2 + knockdown = 15 + stamina = 50 + armour_penetration = -10 + light_range = 2 + light_color = LIGHT_COLOR_BLUE + + +/////actual ammo///// + +/obj/item/ammo_casing/caseless/amags + desc = "A ferromagnetic slug intended to be launched out of a compatible weapon." + caliber = "mags" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "mag-casing-live" + projectile_type = /obj/item/projectile/bullet/mags + +/obj/item/ammo_casing/caseless/anlmags + desc = "A specialized ferromagnetic slug designed with a less-than-lethal payload." + caliber = "mags" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "mag-casing-live" + projectile_type = /obj/item/projectile/bullet/nlmags + +//////magazines///// + +/obj/item/ammo_box/magazine/mmags + name = "magpistol magazine (non-lethal disabler)" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "nlmagmag" + origin_tech = "magnets=5" + ammo_type = /obj/item/ammo_casing/caseless/anlmags + caliber = "mags" + max_ammo = 7 + multiple_sprites = 2 + +/obj/item/ammo_box/magazine/mmags/lethal + name = "magpistol magazine (lethal)" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "smallmagmag" + origin_tech = "combat=5" + ammo_type = /obj/item/ammo_casing/caseless/amags + +//////the gun itself////// + +/obj/item/gun/ballistic/automatic/pistol/mag + name = "magpistol" + desc = "A handgun utilizing maglev technologies to propel a ferromagnetic slug to extreme velocities." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magpistol" + force = 10 + fire_sound = 'sound/weapons/magpistol.ogg' + mag_type = /obj/item/ammo_box/magazine/mmags + can_suppress = 0 + casing_ejector = 0 + fire_delay = 5 + origin_tech = "combat=4;magnets=4" + +/obj/item/gun/ballistic/automatic/pistol/mag/update_icon() + ..() + if(magazine) + cut_overlays() + add_overlay("magpistol-magazine") + else + cut_overlays() + icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" + +///research memes/// + +/obj/item/gun/ballistic/automatic/pistol/mag/nopin + pin = null + +/datum/design/magpistol + name = "Magpistol" + desc = "A weapon which fires ferromagnetic slugs." + id = "magpisol" + req_tech = list("combat" = 5, "magnets" = 6, "powerstorage" = 5) + build_type = PROTOLATHE + materials = list(MAT_METAL = 7500, MAT_GLASS = 1000, MAT_URANIUM = 1000, MAT_TITANIUM = 5000, MAT_SILVER = 2000) + build_path = /obj/item/gun/ballistic/automatic/pistol/mag/nopin + category = list("Weapons") + +/datum/design/mag_magpistol + name = "Magpistol Magazine" + desc = "A 7 round magazine for the Magpistol." + id = "mag_magpistol" + req_tech = list("combat" = 5, "magnets" = 6, "materials" = 5, "syndicate" = 3) + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_SILVER = 500) + build_path = /obj/item/ammo_box/magazine/mmags/lethal + category = list("Ammo") + +/datum/design/mag_magpistol/nl + name = "Magpistol Magazine (Non-Lethal)" + desc = "A 7 round non-lethal magazine for the Magpistol." + id = "mag_magpistol_nl" + req_tech = list("combat" = 5, "magnets" = 6, "materials" = 5) + materials = list(MAT_METAL = 3000, MAT_SILVER = 250, MAT_TITANIUM = 250) + build_path = /obj/item/ammo_box/magazine/mmags + +//////toy memes///// + +/obj/item/projectile/bullet/reusable/foam_dart/mag + name = "magfoam dart" + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "magjectile-toy" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag + light_range = 2 + light_color = LIGHT_COLOR_YELLOW + +/obj/item/ammo_casing/caseless/foam_dart/mag + name = "magfoam dart" + desc = "A foam dart with fun light-up projectiles powered by magnets!" + projectile_type = /obj/item/projectile/bullet/reusable/foam_dart/mag + +/obj/item/ammo_box/magazine/internal/shot/toy/mag + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag + max_ammo = 7 + +/obj/item/gun/ballistic/shotgun/toy/mag + name = "foam force magpistol" + desc = "A fancy toy sold alongside light-up foam force darts. Ages 8 and up." + icon = 'icons/obj/guns/cit_guns.dmi' + icon_state = "toymag" + item_state = "gun" + mag_type = /obj/item/ammo_box/magazine/internal/shot/toy/mag + fire_sound = 'sound/weapons/magpistol.ogg' + slot_flags = SLOT_BELT + w_class = WEIGHT_CLASS_SMALL + +/obj/item/ammo_box/foambox/mag + name = "ammo box (Magnetic Foam Darts)" + icon = 'icons/obj/guns/toy.dmi' + icon_state = "foambox" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/mag + max_ammo = 42 + +/datum/design/magfoam_dart + name = "Box of MagFoam Darts" + id = "magfoam_dart" + build_type = AUTOLATHE + materials = list(MAT_METAL = 300, MAT_GLASS = 200) + build_path = /obj/item/ammo_box/foambox/mag + category = list("initial", "Misc") + +/datum/design/foam_magpistol + name = "Foam Force Magpistol" + id = "magfoam_launcher" + build_type = AUTOLATHE + materials = list(MAT_METAL = 7500, MAT_GLASS = 1000) + build_path = /obj/item/gun/ballistic/shotgun/toy/mag + category = list("hacked", "Misc") diff --git a/code/datums/antagonists/datum_traitor.dm b/code/datums/antagonists/datum_traitor.dm index 245c620dd3..eeb803ca1e 100644 --- a/code/datums/antagonists/datum_traitor.dm +++ b/code/datums/antagonists/datum_traitor.dm @@ -186,9 +186,9 @@ kill_objective.find_target() add_objective(kill_objective) - var/datum/objective/survive/survive_objective = new - survive_objective.owner = owner - add_objective(survive_objective) + var/datum/objective/survive/exist/exist_objective = new + exist_objective.owner = owner + add_objective(exist_objective) /datum/antagonist/traitor/proc/forge_single_objective() return 0 /datum/antagonist/traitor/human/forge_single_objective() //Returns how many objectives are added diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 8329298910..75ed90d712 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -348,6 +348,14 @@ return FALSE return TRUE +//Like survive, but works for silicons and zombies and such. +/datum/objective/survive/exist/considered_alive(var/datum/mind/M) + if(M && M.current) + if(isliving(M.current)) + var/mob/living/L = M.current + return L.stat != DEAD + return FALSE + /datum/objective/martyr explanation_text = "Die a glorious death." diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 54292a3af3..e7fa7447b5 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1347,19 +1347,19 @@ return TRUE operating = TRUE update_icon(AIRLOCK_OPENING, 1) - src.set_opacity(0) - sleep(5) - density = FALSE - sleep(9) - src.layer = OPEN_DOOR_LAYER - update_icon(AIRLOCK_OPEN, 1) + sleep(1) set_opacity(0) - operating = FALSE - air_update_turf(1) update_freelook_sight() + sleep(4) + density = FALSE + air_update_turf(1) + sleep(1) + layer = OPEN_DOOR_LAYER + update_icon(AIRLOCK_OPEN, 1) + operating = FALSE if(delayed_close_requested) delayed_close_requested = FALSE - addtimer(CALLBACK(src, .proc/close), 2) + addtimer(CALLBACK(src, .proc/close), 1) return TRUE @@ -1391,21 +1391,24 @@ return TRUE operating = TRUE update_icon(AIRLOCK_CLOSING, 1) - src.layer = CLOSED_DOOR_LAYER + layer = CLOSED_DOOR_LAYER if(air_tight) density = TRUE - sleep(5) - density = TRUE + air_update_turf(1) + sleep(1) + if(!air_tight) + density = TRUE + air_update_turf(1) + sleep(4) if(!safe) crush() - sleep(9) - update_icon(AIRLOCK_CLOSED, 1) if(visible && !glass) set_opacity(1) + update_freelook_sight() + sleep(1) + update_icon(AIRLOCK_CLOSED, 1) operating = FALSE delayed_close_requested = FALSE - air_update_turf(1) - update_freelook_sight() if(safe) CheckForMobs() return TRUE diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index ba7c8e68dc..417fa670cc 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -9,6 +9,7 @@ throw_speed = 3 throw_range = 4 throwforce = 10 + unique_rename = TRUE w_class = WEIGHT_CLASS_TINY var/reskinned = FALSE diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm index 2f59020cbe..76c61ade81 100644 --- a/code/game/objects/items/implants/implantchair.dm +++ b/code/game/objects/items/implants/implantchair.dm @@ -85,10 +85,17 @@ update_icon() /obj/machinery/implantchair/proc/implant_action(mob/living/M) - var/obj/item/implant/I = new implant_type - if(I.implant(M)) - visible_message("[M] has been implanted by the [name].") - return 1 + var/obj/item/I = new implant_type + if(istype(I, /obj/item/implant)) + var/obj/item/implant/P = I + if(P.implant(M)) + visible_message("[M] has been implanted by [src].") + return TRUE + else if(istype(I, /obj/item/organ)) + var/obj/item/organ/P = I + P.Insert(M, drop_if_replaced = FALSE) + visible_message("[M] has been implanted by [src].") + return TRUE /obj/machinery/implantchair/update_icon() icon_state = initial(icon_state) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm index 11f087d052..087f58c89f 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm @@ -1,72 +1,79 @@ -/obj/structure/closet/secure_closet/freezer - icon_state = "freezer" - -/obj/structure/closet/secure_closet/freezer/kitchen - name = "kitchen Cabinet" +/obj/structure/closet/secure_closet/freezer + icon_state = "freezer" + var/jones = FALSE + +/obj/structure/closet/secure_closet/freezer/ex_act() + if(!jones) + jones = TRUE + else + ..() + +/obj/structure/closet/secure_closet/freezer/kitchen + name = "kitchen Cabinet" req_access = list(ACCESS_KITCHEN) - -/obj/structure/closet/secure_closet/freezer/kitchen/PopulateContents() - ..() - for(var/i = 0, i < 3, i++) - new /obj/item/reagent_containers/food/condiment/flour(src) - new /obj/item/reagent_containers/food/condiment/rice(src) - new /obj/item/reagent_containers/food/condiment/sugar(src) - -/obj/structure/closet/secure_closet/freezer/kitchen/maintenance - name = "maintenance refrigerator" - desc = "This refrigerator looks quite dusty, is there anything edible still inside?" - req_access = list() - -/obj/structure/closet/secure_closet/freezer/kitchen/maintenance/PopulateContents() - ..() - for(var/i = 0, i < 5, i++) - new /obj/item/reagent_containers/food/condiment/milk(src) - for(var/i = 0, i < 5, i++) - new /obj/item/reagent_containers/food/condiment/soymilk(src) - for(var/i = 0, i < 2, i++) - new /obj/item/storage/fancy/egg_box(src) - -/obj/structure/closet/secure_closet/freezer/kitchen/mining - req_access = list() - -/obj/structure/closet/secure_closet/freezer/meat - name = "meat fridge" - -/obj/structure/closet/secure_closet/freezer/meat/PopulateContents() - ..() - for(var/i = 0, i < 4, i++) - new /obj/item/reagent_containers/food/snacks/meat/slab/monkey(src) -/obj/structure/closet/secure_closet/freezer/fridge - name = "refrigerator" - -/obj/structure/closet/secure_closet/freezer/fridge/PopulateContents() - ..() - for(var/i = 0, i < 5, i++) - new /obj/item/reagent_containers/food/condiment/milk(src) - for(var/i = 0, i < 5, i++) - new /obj/item/reagent_containers/food/condiment/soymilk(src) - for(var/i = 0, i < 2, i++) - new /obj/item/storage/fancy/egg_box(src) - -/obj/structure/closet/secure_closet/freezer/money - name = "freezer" - desc = "This contains cold hard cash." + +/obj/structure/closet/secure_closet/freezer/kitchen/PopulateContents() + ..() + for(var/i = 0, i < 3, i++) + new /obj/item/reagent_containers/food/condiment/flour(src) + new /obj/item/reagent_containers/food/condiment/rice(src) + new /obj/item/reagent_containers/food/condiment/sugar(src) + +/obj/structure/closet/secure_closet/freezer/kitchen/maintenance + name = "maintenance refrigerator" + desc = "This refrigerator looks quite dusty, is there anything edible still inside?" + req_access = list() + +/obj/structure/closet/secure_closet/freezer/kitchen/maintenance/PopulateContents() + ..() + for(var/i = 0, i < 5, i++) + new /obj/item/reagent_containers/food/condiment/milk(src) + for(var/i = 0, i < 5, i++) + new /obj/item/reagent_containers/food/condiment/soymilk(src) + for(var/i = 0, i < 2, i++) + new /obj/item/storage/fancy/egg_box(src) + +/obj/structure/closet/secure_closet/freezer/kitchen/mining + req_access = list() + +/obj/structure/closet/secure_closet/freezer/meat + name = "meat fridge" + +/obj/structure/closet/secure_closet/freezer/meat/PopulateContents() + ..() + for(var/i = 0, i < 4, i++) + new /obj/item/reagent_containers/food/snacks/meat/slab/monkey(src) +/obj/structure/closet/secure_closet/freezer/fridge + name = "refrigerator" + +/obj/structure/closet/secure_closet/freezer/fridge/PopulateContents() + ..() + for(var/i = 0, i < 5, i++) + new /obj/item/reagent_containers/food/condiment/milk(src) + for(var/i = 0, i < 5, i++) + new /obj/item/reagent_containers/food/condiment/soymilk(src) + for(var/i = 0, i < 2, i++) + new /obj/item/storage/fancy/egg_box(src) + +/obj/structure/closet/secure_closet/freezer/money + name = "freezer" + desc = "This contains cold hard cash." req_access = list(ACCESS_HEADS_VAULT) - -/obj/structure/closet/secure_closet/freezer/money/PopulateContents() - ..() - for(var/i = 0, i < 3, i++) - new /obj/item/stack/spacecash/c1000(src) - for(var/i = 0, i < 5, i++) - new /obj/item/stack/spacecash/c500(src) - for(var/i = 0, i < 6, i++) - new /obj/item/stack/spacecash/c200(src) - -/obj/structure/closet/secure_closet/freezer/cream_pie - name = "cream pie closet" - desc = "Contains pies filled with cream and/or custard, you sickos." + +/obj/structure/closet/secure_closet/freezer/money/PopulateContents() + ..() + for(var/i = 0, i < 3, i++) + new /obj/item/stack/spacecash/c1000(src) + for(var/i = 0, i < 5, i++) + new /obj/item/stack/spacecash/c500(src) + for(var/i = 0, i < 6, i++) + new /obj/item/stack/spacecash/c200(src) + +/obj/structure/closet/secure_closet/freezer/cream_pie + name = "cream pie closet" + desc = "Contains pies filled with cream and/or custard, you sickos." req_access = list(ACCESS_THEATRE) - -/obj/structure/closet/secure_closet/freezer/pie/PopulateContents() - ..() - new /obj/item/reagent_containers/food/snacks/pie/cream(src) + +/obj/structure/closet/secure_closet/freezer/pie/PopulateContents() + ..() + new /obj/item/reagent_containers/food/snacks/pie/cream(src) diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 08ff56a8a0..3bc5c2e762 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -43,8 +43,7 @@ death = FALSE anchored = FALSE density = FALSE - flavour_text = "You are an ash walker. Your tribe worships the Necropolis. The wastes are sacred ground, its monsters a blessed bounty. \ - You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest." + flavour_text = "You are an ash walker. Your tribe worships the Necropolis. The wastes are sacred ground, its monsters a blessed bounty. You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest. You do not know how their magic works, nor where they come from, or the significance of their items." assignedrole = "Ash Walker" /obj/effect/mob_spawn/human/ash_walker/special(mob/living/new_spawn) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index a127e7608f..15b0bd95df 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -46,6 +46,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/preferred_map = null var/uses_glasses_colour = 0 + + var/screenshake = 100 + var/damagescreenshake = 2 //character preferences var/real_name //our character's name @@ -363,6 +366,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "High" dat += "
" + dat += "Screen Shake: [(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]
" + + if (!user.client.prefs.screenshake==0) + dat += "Damage Screen Shake: [(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]
" + dat += "" dat += "

Special Role Settings

" @@ -1486,6 +1494,20 @@ GLOBAL_LIST_EMPTY(preferences_datums) features["exhibitionist"] = TRUE else features["exhibitionist"] = FALSE + if ("screenshake") + var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, 200 = maximum.)", "Character Preference", screenshake) as null|num + if (!isnull(desiredshake)) + screenshake = desiredshake + if("damagescreenshake") + switch(damagescreenshake) + if(0) + damagescreenshake = 1 + if(1) + damagescreenshake = 2 + if(2) + damagescreenshake = 0 + else + damagescreenshake = 1 if("publicity") if(unlock_content) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 947372bfcb..9daad5cae7 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -191,6 +191,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["menuoptions"] >> menuoptions //citadel code S["arousable"] >> arousable + S["screenshake"] >> screenshake + S["damagescreenshake"] >> damagescreenshake //try to fix any outdated data if necessary if(needs_update >= 0) @@ -215,6 +217,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car ghost_others = sanitize_inlist(ghost_others, GLOB.ghost_others_options, GHOST_OTHERS_DEFAULT_OPTION) menuoptions = SANITIZE_LIST(menuoptions) be_special = SANITIZE_LIST(be_special) + screenshake = sanitize_integer(screenshake, 0, 200, initial(screenshake)) + damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake)) return 1 @@ -256,6 +260,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["enable_tips"], enable_tips) WRITE_FILE(S["tip_delay"], tip_delay) //citadel code + WRITE_FILE(S["screenshake"], screenshake) + WRITE_FILE(S["damagescreenshake"], damagescreenshake) WRITE_FILE(S["arousable"], arousable) return 1 diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm index 4f251d68e3..0c16a2b764 100644 --- a/code/modules/clothing/spacesuits/flightsuit.dm +++ b/code/modules/clothing/spacesuits/flightsuit.dm @@ -18,7 +18,7 @@ var/icon_state_boost = "flightpack_boost" var/item_state_boost = "flightpack_boost" actions_types = list(/datum/action/item_action/flightpack/toggle_flight, /datum/action/item_action/flightpack/engage_boosters, /datum/action/item_action/flightpack/toggle_stabilizers, /datum/action/item_action/flightpack/change_power, /datum/action/item_action/flightpack/toggle_airbrake) - armor = list(melee = 20, bullet = 20, laser = 20, energy = 10, bomb = 30, bio = 100, rad = 75, fire = 100, acid = 75) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 10, bomb = 30, bio = 100, rad = 10, fire = 50, acid = 35) w_class = WEIGHT_CLASS_BULKY slot_flags = SLOT_BACK @@ -34,7 +34,7 @@ var/flight = FALSE var/flight_passflags = PASSTABLE var/powersetting = 1 - var/powersetting_high = 3 + var/powersetting_high = 6 var/powersetting_low = 1 var/override_safe = FALSE @@ -84,7 +84,7 @@ var/emp_disable_threshold = 3 //3 weak ion, 2 strong ion hits. var/emp_disabled = FALSE - var/crash_damage = 0 //Same thing, but for crashes. This is in addition to possible amounts of brute damage to the wearer. + var/crash_damage = 10 //Same thing, but for crashes. This is in addition to possible amounts of brute damage to the wearer. var/crash_damage_low = 1 var/crash_damage_high = 2.5 var/crash_disable_threshold = 5 @@ -102,9 +102,13 @@ var/obj/item/stock_parts/capacitor/part_cap = null var/obj/item/stock_parts/micro_laser/part_laser = null var/obj/item/stock_parts/matter_bin/part_bin = null + var/obj/item/stock_parts/cell/cell = null //Wew lad. about damn time now var/crashing = FALSE //Are we currently getting wrecked? + var/s_delay = 50 // cell replacement delay + + /obj/item/device/flightpack/proc/changeWearer(mob/changeto) if(wearer) LAZYREMOVE(wearer.user_movement_hooks, src) @@ -128,6 +132,8 @@ part_cap = new /obj/item/stock_parts/capacitor/super(src) part_laser = new /obj/item/stock_parts/micro_laser/ultra(src) part_bin = new /obj/item/stock_parts/matter_bin/super(src) + cell = new/obj/item/stock_parts/cell/high + cell.charge = 9000 ..() /obj/item/device/flightpack/proc/usermessage(message, span = "boldnotice", mob/mob_override = null) @@ -816,6 +822,22 @@ part_cap.forceMove(get_turf(src)) part_cap = I changed = TRUE + if(istype(S, /obj/item/stock_parts/cell)) + var/obj/item/stock_parts/cell/CELL = S + if(CELL.maxcharge > cell.maxcharge) + usermessage("Higher maximum capacity detected.\nUpgrading...", mob_override = user) + if (do_after(user,s_delay, target = src)) + user.transferItemToLoc(CELL, src) + CELL.charge = min(CELL.charge+cell.charge, CELL.maxcharge) + var/obj/item/stock_parts/cell/old_cell = cell + old_cell.charge = 0 + user.put_in_hands(old_cell) + old_cell.add_fingerprint(user) + old_cell.update_icon() + cell = CELL + usermessage("Upgrade complete. Maximum capacity: [round(cell.maxcharge/100)]%", mob_override = user) + else + usermessage("Procedure interrupted. Protocol terminated.", mob_override = user) if(changed) update_parts() ..() @@ -847,7 +869,7 @@ var/obj/item/device/flightpack/pack = null var/mob/living/carbon/human/wearer = null var/active = FALSE - resistance_flags = FIRE_PROOF | ACID_PROOF + resistance_flags = FIRE_PROOF /obj/item/clothing/shoes/flightshoes/Destroy() pack = null @@ -901,22 +923,28 @@ var/deployedpack = FALSE var/deployedshoes = FALSE var/locked = FALSE - resistance_flags = FIRE_PROOF | ACID_PROOF + resistance_flags = FIRE_PROOF helmettype = /obj/item/clothing/head/helmet/space/hardsuit/flightsuit jetpack = null var/flightpack var/flight = FALSE allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals, /obj/item/gun, /obj/item/reagent_containers/spray/pepper, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs) actions_types = list(/datum/action/item_action/flightsuit/toggle_helmet, /datum/action/item_action/flightsuit/toggle_boots, /datum/action/item_action/flightsuit/toggle_flightpack, /datum/action/item_action/flightsuit/lock_suit) - armor = list(melee = 20, bullet = 20, laser = 20, energy = 10, bomb = 30, bio = 100, rad = 75, fire = 100, acid = 100) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 10, bomb = 30, bio = 100, rad = 10, fire = 50, acid = 35) var/maint_panel = FALSE - max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT + var/obj/item/stock_parts/cell/cell + var/s_delay = 50 + +/obj/item/clothing/suit/space/hardsuit/flightsuit/get_cell() + return cell /obj/item/clothing/suit/space/hardsuit/flightsuit/full/Initialize() . = ..() makepack() makeshoes() resync() + get_cell() /obj/item/clothing/suit/space/hardsuit/flightsuit/proc/usermessage(message, span = "boldnotice") var/mob/targ = user @@ -931,6 +959,7 @@ to_chat(user, "SUIT: [locked ? "LOCKED" : "UNLOCKED"]") to_chat(user, "FLIGHTPACK: [deployedpack ? "ENGAGED" : "DISENGAGED"] FLIGHTSHOES : [deployedshoes ? "ENGAGED" : "DISENGAGED"] HELMET : [suittoggled ? "ENGAGED" : "DISENGAGED"]") to_chat(user, "Its maintainence panel is [maint_panel ? "OPEN" : "CLOSED"]") + to_chat(user, "Current energy capacity: [DisplayPower(cell.charge)]") /obj/item/clothing/suit/space/hardsuit/flightsuit/Destroy() dropped() @@ -1223,12 +1252,12 @@ icon_state = "flighthelmet" item_state = "flighthelmet" item_color = "flight" - resistance_flags = FIRE_PROOF | ACID_PROOF - brightness_on = 7 + resistance_flags = FIRE_PROOF + brightness_on = 4 light_color = "#30ffff" - armor = list(melee = 20, bullet = 20, laser = 20, energy = 10, bomb = 30, bio = 100, rad = 75, fire = 100, acid = 100) - max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT - var/list/datahuds = list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 10, bomb = 30, bio = 100, rad = 10, fire = 50, acid = 35) + max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT + var/list/datahuds = list(DATA_HUD_SECURITY_BASIC , DATA_HUD_MEDICAL_BASIC, DATA_HUD_DIAGNOSTIC) var/zoom_range = 14 var/zoom = FALSE actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/flightpack/zoom) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 15d05d37fe..38381ae9c5 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -67,6 +67,7 @@ possible_destinations = "mining_home;mining_away;landing_zone_dock;mining_public" no_destination_swap = 1 var/global/list/dumb_rev_heads = list() + req_access = list(ACCESS_MINING) // should slow the ashwalkers down. /obj/machinery/computer/shuttle/mining/attack_hand(mob/user) if((user.z in GLOB.station_z_levels) && user.mind && (user.mind in SSticker.mode.head_revolutionaries) && !(user.mind in dumb_rev_heads)) diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm index e83061b232..1fa3e89d3a 100644 --- a/code/modules/security_levels/security_levels.dm +++ b/code/modules/security_levels/security_levels.dm @@ -41,6 +41,7 @@ GLOBAL_VAR_INIT(security_level, 0) if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) SSshuttle.emergency.modTimer(2) GLOB.security_level = SEC_LEVEL_BLUE + sound_to_playing_players('sound/misc/voybluealert.ogg') for(var/obj/machinery/firealarm/FA in GLOB.machines) if(FA.z in GLOB.station_z_levels) FA.update_icon() @@ -60,7 +61,7 @@ GLOBAL_VAR_INIT(security_level, 0) var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world) if(CC) CC.post_status("alert", "redalert")*/ - + sound_to_playing_players('sound/misc/voyalert.ogg') for(var/obj/machinery/firealarm/FA in GLOB.machines) if(FA.z in GLOB.station_z_levels) FA.update_icon() @@ -74,6 +75,7 @@ GLOBAL_VAR_INIT(security_level, 0) else if(GLOB.security_level == SEC_LEVEL_BLUE) SSshuttle.emergency.modTimer(0.5) GLOB.security_level = SEC_LEVEL_DELTA + sound_to_playing_players('sound/misc/deltakalaxon.ogg') for(var/obj/machinery/firealarm/FA in GLOB.machines) if(FA.z in GLOB.station_z_levels) FA.update_icon() diff --git a/html/changelogs/AutoChangeLog-pr-2583.yml b/html/changelogs/AutoChangeLog-pr-2583.yml new file mode 100644 index 0000000000..fff14dec8e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2583.yml @@ -0,0 +1,8 @@ +author: "deathride58" +delete-after: True +changes: + - rscadd: "Firing most guns will now cause your screen to shake subtly." + - rscadd: "Being hit by melee weapons with a force over 10 will now cause subtle screenshake" + - rscadd: "Hitting someone with a melee weapon with a force over 10 will now cause subtle screenshake" + - rscadd: "Hitting an object with a melee weapon with a force over 20 will now cause subtle screenshake" + - rscadd: "Added two options to the Game Settings menu: Screen Shake and Damage Screen Shake. Screen Shake controls (most) screenshake in the game, and allows you to set the percentage of screenshake from most sources, or simply turn it off entirely. Damage Screen Shake controls the screenshake when you get hit by weapons, and has three settings, on, off, and only when down. The defaults are 100%, and only when down, respectively." diff --git a/html/changelogs/AutoChangeLog-pr-2907.yml b/html/changelogs/AutoChangeLog-pr-2907.yml new file mode 100644 index 0000000000..352432595c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2907.yml @@ -0,0 +1,8 @@ +author: "Toriate" +delete-after: True +changes: + - rscadd: "Adds Spinfusors, ordered from cargo, security locked crate" + - rscadd: "Adds the X9 Assault Rifle, adminspawn only" + - rscadd: "Adds the Magpistol, made in science, non-lethal by default, unlocked slightly later than the AEG" + - rscadd: "Adds the Foam Force Magpistol and Magfoam, made in autolathes" + - soundadd: "adds the Magpistol's firing sound" diff --git a/html/changelogs/AutoChangeLog-pr-2909.yml b/html/changelogs/AutoChangeLog-pr-2909.yml new file mode 100644 index 0000000000..65e957021b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2909.yml @@ -0,0 +1,7 @@ +author: "Poojawa" +delete-after: True +changes: + - tweak: "Flightsuits require power cells now to function" + - tweak: "Flightsuit HUDs reduced to AI standards rather than full advanced." + - tweak: "Suits will heavily drain while in gravity, but not much without it." + - tweak: "Swap batteries via clicking on your suit with one." diff --git a/html/changelogs/AutoChangeLog-pr-2923.yml b/html/changelogs/AutoChangeLog-pr-2923.yml new file mode 100644 index 0000000000..6ab464e82c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2923.yml @@ -0,0 +1,4 @@ +author: "Improvedname" +delete-after: True +changes: + - tweak: "You can now rename holy weapons" diff --git a/html/changelogs/AutoChangeLog-pr-2929.yml b/html/changelogs/AutoChangeLog-pr-2929.yml new file mode 100644 index 0000000000..884f951047 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2929.yml @@ -0,0 +1,4 @@ +author: "More Robust Than You" +delete-after: True +changes: + - rscadd: "Implant Chairs now also support organs" diff --git a/icons/obj/doors/airlocks/abductor/abductor_airlock.dmi b/icons/obj/doors/airlocks/abductor/abductor_airlock.dmi index d0ef3d2462..58be8d778e 100644 Binary files a/icons/obj/doors/airlocks/abductor/abductor_airlock.dmi and b/icons/obj/doors/airlocks/abductor/abductor_airlock.dmi differ diff --git a/icons/obj/doors/airlocks/survival/survival.dmi b/icons/obj/doors/airlocks/survival/survival.dmi index f96d174c47..b796b4c8e0 100644 Binary files a/icons/obj/doors/airlocks/survival/survival.dmi and b/icons/obj/doors/airlocks/survival/survival.dmi differ diff --git a/icons/obj/doors/airlocks/survival/survival_overlays.dmi b/icons/obj/doors/airlocks/survival/survival_overlays.dmi index e8bede8217..94c1a9fa34 100644 Binary files a/icons/obj/doors/airlocks/survival/survival_overlays.dmi and b/icons/obj/doors/airlocks/survival/survival_overlays.dmi differ diff --git a/icons/obj/guns/cit_guns.dmi b/icons/obj/guns/cit_guns.dmi index b5a2ae8fdc..2db84677d2 100644 Binary files a/icons/obj/guns/cit_guns.dmi and b/icons/obj/guns/cit_guns.dmi differ diff --git a/modular_citadel/README.md b/modular_citadel/README.md new file mode 100644 index 0000000000..dfae177607 --- /dev/null +++ b/modular_citadel/README.md @@ -0,0 +1,3 @@ +Hooray modularity! +Things that modify core files without directly touching said core files go here. This is similar to how Hippie handles things. +This stops dreammaker from throwing errors and warnings if you try to compile these files while they're inside code/citadel/. diff --git a/modular_citadel/cit_screenshake.dm b/modular_citadel/cit_screenshake.dm new file mode 100644 index 0000000000..2d0110c4e7 --- /dev/null +++ b/modular_citadel/cit_screenshake.dm @@ -0,0 +1,69 @@ +//we vlambeer now + +/obj/proc/shake_camera(mob/M, duration, strength=1)//byond's wonky with this shit + if(!M || !M.client || duration <= 0) + return + var/client/C = M.client + if (C.prefs.screenshake==0) + return + var/oldx = C.pixel_x + var/oldy = C.pixel_y + var/clientscreenshake = (C.prefs.screenshake * 0.01) + var/max = (strength*clientscreenshake) * world.icon_size + var/min = -((strength*clientscreenshake) * world.icon_size) + + for(var/i in 0 to duration-1) + if (i == 0) + animate(C, pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) + else + animate(pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) + animate(pixel_x=oldx, pixel_y=oldy, time=1) + +/obj/item/gun/energy + ..() + recoil = 0.1 + +/obj/item/gun/energy/kinetic_accelerator + ..() + recoil = 0.5 + +/obj/item/gun/ballistic + ..() + recoil = 0.25 + +/obj/item/gun/ballistic/shotgun + ..() + recoil = 1 + +/obj/item/gun/ballistic/revolver + ..() + recoil = 0.5 + +/obj/item/gun/ballistic/revolver/doublebarrel + ..() + recoil = 1 + +/obj/item/gun/syringe + ..() + recoil = 0.1 + +/obj/item/pneumatic_cannon/fire_items(turf/target, mob/user) + . = ..() + shake_camera(user, (pressureSetting * 0.75 + 1), (pressureSetting * 0.75)) + +/obj/item/attack(mob/living/M, mob/living/user) + . = ..() + if(force && force >=15) + shake_camera(user, ((force - 10) * 0.01 + 1), ((force - 10) * 0.01)) + if(M.client) + switch (M.client.prefs.damagescreenshake) + if (1) + shake_camera(M, ((force - 10) * 0.015 + 1), ((force - 10) * 0.015)) + if (2) + if (M.IsKnockdown()) + shake_camera(M, ((force - 10) * 0.015 + 1), ((force - 10) * 0.015)) + +/obj/item/attack_obj(obj/O, mob/living/user) + . = ..() + if(force && force >= 20) + shake_camera(user, ((force - 15) * 0.01 + 1), ((force - 15) * 0.01)) diff --git a/sound/weapons/magpistol.ogg b/sound/weapons/magpistol.ogg new file mode 100644 index 0000000000..c130714962 Binary files /dev/null and b/sound/weapons/magpistol.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 0d142f7973..eb1bfd6c11 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2274,6 +2274,7 @@ #include "code\modules\VR\vr_sleeper.dm" #include "code\modules\zombie\items.dm" #include "code\modules\zombie\organs.dm" +#include "modular_citadel\cit_screenshake.dm" #include "interface\interface.dm" #include "interface\menu.dm" #include "interface\stylesheet.dm"