Merge remote-tracking branch 'origin/master' into hardsync-1.5
@@ -881,7 +881,7 @@
|
||||
/turf/open/floor/plating,
|
||||
/area/awaymission/cabin)
|
||||
"cT" = (
|
||||
/obj/vehicle/ridden/atv,
|
||||
/obj/vehicle/ridden/atv/snowmobile,
|
||||
/turf/open/floor/plating{
|
||||
icon_state = "platingdmg3"
|
||||
},
|
||||
@@ -893,7 +893,7 @@
|
||||
/turf/open/floor/plating,
|
||||
/area/awaymission/cabin)
|
||||
"cV" = (
|
||||
/obj/vehicle/ridden/atv,
|
||||
/obj/vehicle/ridden/atv/snowmobile,
|
||||
/turf/open/floor/plating,
|
||||
/area/awaymission/cabin)
|
||||
"cW" = (
|
||||
|
||||
@@ -13605,13 +13605,10 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/structure/disposalpipe/sorting/mail{
|
||||
dir = 2;
|
||||
sortType = 18
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/turf/open/floor/plating,
|
||||
/area/maintenance/starboard/fore)
|
||||
"aEB" = (
|
||||
@@ -56987,6 +56984,17 @@
|
||||
icon_state = "wood-broken6"
|
||||
},
|
||||
/area/maintenance/bar)
|
||||
"lqO" = (
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/structure/disposalpipe/sorting/mail/flip{
|
||||
dir = 1;
|
||||
sortType = 18
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/maintenance/fore)
|
||||
"lre" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/structure/table/wood/poker,
|
||||
@@ -57108,6 +57116,12 @@
|
||||
},
|
||||
/turf/closed/wall,
|
||||
/area/maintenance/disposal/incinerator)
|
||||
"lLf" = (
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/maintenance/fore)
|
||||
"lMg" = (
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 9
|
||||
@@ -58655,8 +58669,11 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/door/airlock/vault,
|
||||
/obj/effect/mapping_helpers/airlock/locked,
|
||||
/obj/machinery/door/airlock/vault{
|
||||
name = "Vault Door";
|
||||
req_access_txt = "53"
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/ai_monitored/nuke_storage)
|
||||
"puh" = (
|
||||
@@ -58822,6 +58839,14 @@
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/maintenance/disposal)
|
||||
"pMQ" = (
|
||||
/obj/structure/window/reinforced,
|
||||
/obj/machinery/disposal/bin,
|
||||
/obj/structure/disposalpipe/trunk{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/wood,
|
||||
/area/crew_quarters/theatre)
|
||||
"pPi" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 4
|
||||
@@ -60860,11 +60885,13 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-8"
|
||||
},
|
||||
/obj/structure/disposalpipe/junction,
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/tile/neutral,
|
||||
/obj/structure/disposalpipe/sorting/mail{
|
||||
sortType = 26
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/crew_quarters/dorms)
|
||||
"uys" = (
|
||||
@@ -61051,7 +61078,6 @@
|
||||
/area/science/circuit)
|
||||
"uOJ" = (
|
||||
/obj/effect/mapping_helpers/airlock/locked,
|
||||
/obj/machinery/door/airlock/vault,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
@@ -61065,6 +61091,10 @@
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/door/airlock/vault{
|
||||
name = "Vault Door";
|
||||
req_access_txt = "53"
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/ai_monitored/nuke_storage)
|
||||
"uQR" = (
|
||||
@@ -84618,7 +84648,7 @@ ayD
|
||||
nez
|
||||
ngV
|
||||
xPY
|
||||
aOH
|
||||
pMQ
|
||||
hcb
|
||||
hcb
|
||||
syJ
|
||||
@@ -84875,7 +84905,7 @@ ayE
|
||||
ayE
|
||||
ayE
|
||||
ayE
|
||||
ayE
|
||||
lLf
|
||||
ayE
|
||||
ayE
|
||||
ayE
|
||||
@@ -85132,7 +85162,7 @@ ayH
|
||||
ayH
|
||||
ayH
|
||||
ayH
|
||||
ayH
|
||||
lqO
|
||||
ayH
|
||||
aFV
|
||||
ayH
|
||||
|
||||
@@ -47138,13 +47138,9 @@
|
||||
/turf/open/floor/plasteel,
|
||||
/area/engine/gravity_generator)
|
||||
"bEx" = (
|
||||
/obj/structure/closet/radiation,
|
||||
/obj/machinery/light/small{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/extinguisher_cabinet{
|
||||
pixel_x = 26
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 4
|
||||
},
|
||||
@@ -48383,7 +48379,10 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/light/small,
|
||||
/obj/structure/extinguisher_cabinet{
|
||||
pixel_x = 26
|
||||
},
|
||||
/obj/structure/closet/radiation,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/engine/gravity_generator)
|
||||
"bGg" = (
|
||||
@@ -49543,6 +49542,9 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/light/small{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/engine/gravity_generator)
|
||||
"bHV" = (
|
||||
|
||||
@@ -290,7 +290,7 @@
|
||||
|
||||
#define COMSIG_LIVING_ACTIVE_BLOCK_START "active_block_start" //from base of mob/living/keybind_start_active_blocking(): (obj/item/blocking_item, list/backup_items)
|
||||
#define COMPONENT_PREVENT_BLOCK_START 1
|
||||
#define COMSIG_LIVING_ACTIVE_PARRY_START "active_parry_start" //from base of mob/living/initiate_parry_sequence(): (parrying_method, datum/parrying_item_mob_or_art, list/backup_items)
|
||||
#define COMSIG_LIVING_ACTIVE_PARRY_START "active_parry_start" //from base of mob/living/initiate_parry_sequence(): (parrying_method, datum/parrying_item_mob_or_art, list/backup_items, list/override)
|
||||
#define COMPONENT_PREVENT_PARRY_START 1
|
||||
|
||||
//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
#define TRAIT_EMPATH "empath"
|
||||
#define TRAIT_FRIENDLY "friendly"
|
||||
#define TRAIT_SNOB "snob"
|
||||
#define TRAIT_MULTILINGUAL "multilingual"
|
||||
#define TRAIT_CULT_EYES "cult_eyes"
|
||||
#define TRAIT_AUTO_CATCH_ITEM "auto_catch_item"
|
||||
#define TRAIT_CLOWN_MENTALITY "clown_mentality" // The future is now, clownman.
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
announcement += "<br><h2 class='alert'>[html_encode(title)]</h2>"
|
||||
else if(type == "Captain")
|
||||
announcement += "<h1 class='alert'>Captain Announces</h1>"
|
||||
GLOB.news_network.SubmitArticle(text, "Captain's Announcement", "Station Announcements", null)
|
||||
GLOB.news_network.SubmitArticle(html_encode(text), "Captain's Announcement", "Station Announcements", null)
|
||||
|
||||
else
|
||||
if(!sender_override)
|
||||
|
||||
@@ -263,7 +263,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
return .
|
||||
|
||||
//Returns a list of all items of interest with their name
|
||||
/proc/getpois(mobs_only=0,skip_mindless=0)
|
||||
/proc/getpois(mobs_only = FALSE, skip_mindless = FALSE, specify_dead_role = TRUE)
|
||||
var/list/mobs = sortmobs()
|
||||
var/list/namecounts = list()
|
||||
var/list/pois = list()
|
||||
@@ -277,7 +277,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
|
||||
if(M.real_name && M.real_name != M.name)
|
||||
name += " \[[M.real_name]\]"
|
||||
if(M.stat == DEAD)
|
||||
if(M.stat == DEAD && specify_dead_role)
|
||||
if(isobserver(M))
|
||||
name += " \[ghost\]"
|
||||
else
|
||||
|
||||
@@ -484,6 +484,8 @@
|
||||
|
||||
/datum/config_entry/flag/modetier_voting
|
||||
|
||||
/datum/config_entry/flag/must_be_readied_to_vote_gamemode
|
||||
|
||||
/datum/config_entry/number/dropped_modes
|
||||
config_entry_value = 3
|
||||
|
||||
|
||||
@@ -68,6 +68,10 @@ SUBSYSTEM_DEF(vote)
|
||||
//get the highest number of votes
|
||||
var/greatest_votes = 0
|
||||
var/total_votes = 0
|
||||
if(mode == "gamemode" && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
|
||||
for(var/mob/dead/new_player/P in GLOB.player_list)
|
||||
if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
|
||||
choices[choices[voted[P.ckey]]]--
|
||||
for(var/option in choices)
|
||||
var/votes = choices[option]
|
||||
total_votes += votes
|
||||
@@ -101,6 +105,10 @@ SUBSYSTEM_DEF(vote)
|
||||
|
||||
/datum/controller/subsystem/vote/proc/calculate_condorcet_votes(var/blackbox_text)
|
||||
// https://en.wikipedia.org/wiki/Schulze_method#Implementation
|
||||
if((mode == "gamemode" || mode == "dynamic") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
|
||||
for(var/mob/dead/new_player/P in GLOB.player_list)
|
||||
if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
|
||||
voted -= P.ckey
|
||||
var/list/d[][] = new/list(choices.len,choices.len) // the basic vote matrix, how many times a beats b
|
||||
for(var/ckey in voted)
|
||||
var/list/this_vote = voted[ckey]
|
||||
@@ -147,6 +155,10 @@ SUBSYSTEM_DEF(vote)
|
||||
for(var/choice in choices)
|
||||
scores_by_choice += "[choice]"
|
||||
scores_by_choice["[choice]"] = list()
|
||||
if((mode == "gamemode" || mode == "dynamic") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
|
||||
for(var/mob/dead/new_player/P in GLOB.player_list)
|
||||
if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
|
||||
voted -= P.ckey
|
||||
for(var/ckey in voted)
|
||||
var/list/this_vote = voted[ckey]
|
||||
var/list/pretty_vote = list()
|
||||
|
||||
@@ -146,9 +146,11 @@
|
||||
if(!istype(A) || !get_turf(A) || A == src)
|
||||
return
|
||||
|
||||
orbit_target = A
|
||||
return A.AddComponent(/datum/component/orbiter, src, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
|
||||
|
||||
/atom/movable/proc/stop_orbit(datum/component/orbiter/orbits)
|
||||
orbit_target = null
|
||||
return // We're just a simple hook
|
||||
|
||||
/atom/proc/transfer_observers_to(atom/target)
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
qdel(src)
|
||||
|
||||
/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force)
|
||||
handle_vehicle_offsets()
|
||||
handle_vehicle_offsets(M.buckled?.dir)
|
||||
|
||||
/datum/component/riding/proc/handle_vehicle_layer(dir)
|
||||
var/atom/movable/AM = parent
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
var/antag_removal_text // Text will be given to the quirk holder if they get an antag that has it blacklisted.
|
||||
var/mood_quirk = FALSE //if true, this quirk affects mood and is unavailable if moodlets are disabled
|
||||
var/mob_trait //if applicable, apply and remove this mob trait
|
||||
/// should we immediately call on_spawn or add a timer to trigger
|
||||
var/on_spawn_immediate = TRUE
|
||||
var/mob/living/quirk_holder
|
||||
|
||||
/datum/quirk/New(mob/living/quirk_mob, spawn_effects)
|
||||
@@ -26,7 +28,10 @@
|
||||
START_PROCESSING(SSquirks, src)
|
||||
add()
|
||||
if(spawn_effects)
|
||||
on_spawn()
|
||||
if(on_spawn_immediate)
|
||||
on_spawn()
|
||||
else
|
||||
addtimer(CALLBACK(src, .proc/on_spawn), 0)
|
||||
addtimer(CALLBACK(src, .proc/post_add), 30)
|
||||
|
||||
/datum/quirk/Destroy()
|
||||
|
||||
@@ -219,3 +219,19 @@
|
||||
/datum/quirk/night_vision/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
H.update_sight()
|
||||
|
||||
/datum/quirk/multilingual
|
||||
name = "Multi-Lingual"
|
||||
desc = "You spent a portion of your life learning to understand an additional language. You may or may not be able to speak it based on your anatomy."
|
||||
value = 1
|
||||
mob_trait = TRAIT_MULTILINGUAL
|
||||
gain_text = "You've learned an extra language!"
|
||||
lose_text = "You've forgotten your extra language."
|
||||
|
||||
/datum/quirk/multilingual/add()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
H.grant_language(H.client.prefs.language, TRUE, TRUE, LANGUAGE_MIND)
|
||||
|
||||
/datum/quirk/multilingual/remove()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
H.remove_language(H.client.prefs.language, TRUE, TRUE, LANGUAGE_MIND)
|
||||
|
||||
@@ -184,6 +184,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
gain_text = null // Handled by trauma.
|
||||
lose_text = null
|
||||
medical_record_text = "Patient has an untreatable impairment in motor function in the lower extremities."
|
||||
on_spawn_immediate = FALSE
|
||||
|
||||
/datum/quirk/paraplegic/add()
|
||||
var/datum/brain_trauma/severe/paralysis/paraplegic/T = new()
|
||||
|
||||
@@ -99,6 +99,9 @@
|
||||
///Mobs that are currently do_after'ing this atom, to be cleared from on Destroy()
|
||||
var/list/targeted_by
|
||||
|
||||
///Reference to atom being orbited
|
||||
var/atom/orbit_target
|
||||
|
||||
/**
|
||||
* Called when an atom is created in byond (built in engine proc)
|
||||
*
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
/datum/sabotage_objective/processing/check_conditions()
|
||||
return won
|
||||
|
||||
/*
|
||||
/datum/sabotage_objective/processing/power_sink
|
||||
name = "Drain at least 100 megajoules of power using a power sink."
|
||||
sabotage_type = "powersink"
|
||||
@@ -44,6 +45,7 @@
|
||||
for(var/s in GLOB.power_sinks)
|
||||
var/obj/item/powersink/sink = s
|
||||
won = max(won,sink.power_drained/1e8)
|
||||
*/
|
||||
|
||||
/obj/item/paper/guides/antag/supermatter_sabotage
|
||||
info = "Ways to sabotage a supermatter:<br>\
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
circuit = /obj/item/circuitboard/machine/cell_charger
|
||||
pass_flags = PASSTABLE
|
||||
var/obj/item/stock_parts/cell/charging = null
|
||||
var/charge_rate = 500
|
||||
var/recharge_coeff = 1
|
||||
|
||||
/obj/machinery/cell_charger/update_overlays()
|
||||
. += ..()
|
||||
@@ -28,9 +28,10 @@
|
||||
. = ..()
|
||||
. += "There's [charging ? "a" : "no"] cell in the charger."
|
||||
if(charging)
|
||||
. += "Current charge: [round(charging.percent(), 1)]%."
|
||||
var/obj/item/stock_parts/cell/C = charging.get_cell()
|
||||
. += "Current charge: [C.percent()]%."
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: Charge rate at <b>[charge_rate]J</b> per cycle.</span>"
|
||||
. += "<span class='notice'>The status display reads: Charge rate at <b>[recharge_coeff*10]J</b> per cycle.</span>"
|
||||
|
||||
/obj/machinery/cell_charger/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/stock_parts/cell) && !panel_open)
|
||||
@@ -122,17 +123,18 @@
|
||||
charging.emp_act(severity)
|
||||
|
||||
/obj/machinery/cell_charger/RefreshParts()
|
||||
charge_rate = 500
|
||||
for(var/obj/item/stock_parts/capacitor/C in component_parts)
|
||||
charge_rate *= C.rating
|
||||
recharge_coeff = C.rating
|
||||
|
||||
/obj/machinery/cell_charger/process()
|
||||
if(!charging || !anchored || (stat & (BROKEN|NOPOWER)))
|
||||
return
|
||||
|
||||
if(charging.percent() >= 100)
|
||||
return
|
||||
use_power(charge_rate)
|
||||
charging.give(charge_rate) //this is 2558, efficient batteries exist
|
||||
if(charging)
|
||||
var/obj/item/stock_parts/cell/C = charging.get_cell()
|
||||
if(C)
|
||||
if(C.charge < C.maxcharge)
|
||||
C.give(C.chargerate * recharge_coeff)
|
||||
use_power(250 * recharge_coeff)
|
||||
|
||||
update_icon()
|
||||
|
||||
@@ -151,7 +151,14 @@
|
||||
var/obj/machinery/power/apc/target = locate(ref) in GLOB.apcs_list
|
||||
if(!target)
|
||||
return
|
||||
target.vars[type] = target.setsubsystem(text2num(value))
|
||||
value = target.setsubsystem(text2num(value))
|
||||
switch(type) // Sanity check
|
||||
if("equipment", "lighting", "environ")
|
||||
target.vars[type] = value
|
||||
else
|
||||
message_admins("Warning: possible href exploit by [key_name(usr)] - attempted to set [type] on [target] to [value]")
|
||||
log_game("Warning: possible href exploit by [key_name(usr)] - attempted to set [type] on [target] to [value]")
|
||||
return
|
||||
target.update_icon()
|
||||
target.update()
|
||||
var/setTo = ""
|
||||
|
||||
@@ -393,6 +393,27 @@
|
||||
spark_system.start() //creates some sparks because they look cool
|
||||
qdel(cover) //deletes the cover - no need on keeping it there!
|
||||
|
||||
//turret healing
|
||||
/obj/machinery/porta_turret/examine(mob/user)
|
||||
. = ..()
|
||||
if(obj_integrity < max_integrity)
|
||||
. += "<span class='notice'>[src] is damaged, use a lit welder to fix it.</span>"
|
||||
|
||||
/obj/machinery/porta_turret/welder_act(mob/living/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(cover && obj_integrity < max_integrity)
|
||||
if(!I.tool_start_check(user, amount=0))
|
||||
return
|
||||
user.visible_message("[user] is welding the turret.", \
|
||||
"<span class='notice'>You begin repairing the turret...</span>", \
|
||||
"<span class='italics'>You hear welding.</span>")
|
||||
if(I.use_tool(src, user, 40, volume=50))
|
||||
obj_integrity = max_integrity
|
||||
user.visible_message("[user.name] has repaired [src].", \
|
||||
"<span class='notice'>You finish repairing the turret.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The turret doesn't need repairing.</span>")
|
||||
|
||||
/obj/machinery/porta_turret/process()
|
||||
//the main machinery process
|
||||
if(cover == null && anchored) //if it has no cover and is anchored
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
icon_state = "mecha_ion"
|
||||
energy_drain = 120
|
||||
projectile = /obj/item/projectile/ion
|
||||
fire_sound = 'sound/weapons/laser.ogg'
|
||||
fire_sound = 'sound/weapons/IonRifle.ogg'
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla
|
||||
equip_cooldown = 35
|
||||
@@ -195,7 +195,7 @@
|
||||
//Base ballistic weapon type
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic
|
||||
name = "general ballistic weapon"
|
||||
fire_sound = 'sound/weapons/gunshot.ogg'
|
||||
fire_sound = 'sound/weapons/lmgshot.ogg'
|
||||
var/projectiles
|
||||
var/projectiles_cache //ammo to be loaded in, if possible.
|
||||
var/projectiles_cache_max
|
||||
@@ -285,6 +285,7 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot
|
||||
name = "\improper LBX AC 10 \"Scattershot\""
|
||||
desc = "A weapon for combat exosuits. Shoots a spread of pellets."
|
||||
fire_sound = 'sound/weapons/gunshotshotgunshot.ogg'
|
||||
icon_state = "mecha_scatter"
|
||||
equip_cooldown = 20
|
||||
projectile = /obj/item/projectile/bullet/scattershot
|
||||
@@ -299,6 +300,7 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/seedscatter
|
||||
name = "\improper Melon Seed \"Scattershot\""
|
||||
desc = "A weapon for combat exosuits. Shoots a spread of pellets, shaped as seed."
|
||||
fire_sound = 'sound/weapons/gunshotshotgunshot.ogg'
|
||||
icon_state = "mecha_scatter"
|
||||
equip_cooldown = 20
|
||||
projectile = /obj/item/projectile/bullet/seed
|
||||
@@ -331,7 +333,7 @@
|
||||
desc = "A weapon for combat exosuits. Launches light explosive missiles."
|
||||
icon_state = "mecha_missilerack"
|
||||
projectile = /obj/item/projectile/bullet/a84mm_he
|
||||
fire_sound = 'sound/weapons/grenadelaunch.ogg'
|
||||
fire_sound = 'sound/weapons/rocketlaunch.ogg'
|
||||
projectiles = 8
|
||||
projectiles_cache = 0
|
||||
projectiles_cache_max = 0
|
||||
@@ -345,7 +347,7 @@
|
||||
desc = "A weapon for combat exosuits. Launches low-explosive breaching missiles designed to explode only when striking a sturdy target."
|
||||
icon_state = "mecha_missilerack_six"
|
||||
projectile = /obj/item/projectile/bullet/a84mm_br
|
||||
fire_sound = 'sound/weapons/grenadelaunch.ogg'
|
||||
fire_sound = 'sound/weapons/rocketlaunch.ogg'
|
||||
projectiles = 6
|
||||
projectiles_cache = 0
|
||||
projectiles_cache_max = 0
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
|
||||
/obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose
|
||||
name = "blood"
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "ltrails_1"
|
||||
desc = "Your instincts say you shouldn't be following these."
|
||||
random_icon_states = null
|
||||
|
||||
@@ -69,7 +69,8 @@ GLOBAL_LIST_INIT(channel_tokens, list(
|
||||
/obj/item/radio/headset/talk_into(mob/living/M, message, channel, list/spans,datum/language/language)
|
||||
if (!listening)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
return ..()
|
||||
if (language != /datum/language/signlanguage)
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/headset/can_receive(freq, level, AIuser)
|
||||
if(ishuman(src.loc))
|
||||
|
||||
@@ -208,6 +208,8 @@
|
||||
return
|
||||
if(!M.IsVocal())
|
||||
return
|
||||
if(language == /datum/language/signlanguage)
|
||||
return
|
||||
|
||||
if(use_command)
|
||||
spans |= commandspan
|
||||
|
||||
@@ -245,6 +245,9 @@
|
||||
slowdown = 7
|
||||
breakouttime = 300 //Deciseconds = 30s = 0.5 minute
|
||||
|
||||
/obj/item/restraints/legcuffs/proc/on_removed()
|
||||
return
|
||||
|
||||
/obj/item/restraints/legcuffs/beartrap
|
||||
name = "bear trap"
|
||||
throw_speed = 1
|
||||
@@ -376,4 +379,8 @@
|
||||
icon_state = "ebola"
|
||||
hitsound = 'sound/weapons/taserhit.ogg'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
breakouttime = 60
|
||||
breakouttime = 25
|
||||
|
||||
/obj/item/restraints/legcuffs/bola/energy/on_removed()
|
||||
do_sparks(1, TRUE, src)
|
||||
qdel(src)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
icon_state = "warp"
|
||||
uses = -1
|
||||
var/total_delay = 10 SECONDS
|
||||
var/cooldown = 10 SECONDS
|
||||
var/cooldown = 30 SECONDS
|
||||
var/last_use = 0
|
||||
var/list/positions = list()
|
||||
var/next_prune = 0
|
||||
|
||||
@@ -20,7 +20,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
|
||||
custom_materials = list(/datum/material/iron=1000)
|
||||
max_amount = 50
|
||||
attack_verb = list("hit", "bludgeoned", "whacked")
|
||||
hitsound = 'sound/weapons/grenadelaunch.ogg'
|
||||
hitsound = 'sound/items/trayhit1.ogg'
|
||||
embedding = list()
|
||||
novariants = TRUE
|
||||
|
||||
|
||||
@@ -319,7 +319,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
damtype = STAMINA
|
||||
attack_verb = list("whacked", "smacked", "struck")
|
||||
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
|
||||
hitsound = 'sound/weapons/grenadelaunch.ogg' // no good wood thunk sounds
|
||||
hitsound = 'sound/weapons/woodbonk.ogg'
|
||||
var/harm = FALSE // TRUE = brute, FALSE = stam
|
||||
var/reinforced = FALSE
|
||||
var/burnt = FALSE
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
mutable = FALSE
|
||||
var/mob/camera/disease/overmind
|
||||
infectable_biotypes = MOB_ORGANIC|MOB_ROBOTIC
|
||||
|
||||
/datum/disease/advance/sentient_disease/New()
|
||||
..()
|
||||
|
||||
@@ -105,6 +105,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/be_random_body = 0 //whether we'll have a random body every round
|
||||
var/gender = MALE //gender of character (well duh)
|
||||
var/age = 30 //age of character
|
||||
var/language = "Random" //bonus language
|
||||
var/choselanguage = "Random" //language appearance
|
||||
var/underwear = "Nude" //underwear type
|
||||
var/undie_color = "FFFFFF"
|
||||
var/undershirt = "Nude" //undershirt type
|
||||
@@ -323,6 +325,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
dat += "<b>Gender:</b> <a href='?_src_=prefs;preference=gender;task=input'>[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]</a><BR>"
|
||||
dat += "<b>Age:</b> <a style='display:block;width:30px' href='?_src_=prefs;preference=age;task=input'>[age]</a><BR>"
|
||||
dat += "<b>Language:</b> <a href='?_src_=prefs;preference=language;task=input'>[choselanguage]</a><BR>"
|
||||
|
||||
dat += "<b>Special Names:</b><BR>"
|
||||
var/old_group
|
||||
@@ -2330,6 +2333,28 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
features["body_model"] = chosengender
|
||||
gender = chosengender
|
||||
|
||||
if("language")
|
||||
choselanguage = input(user, "Select a language.", "Language", language) as null|anything in list("Beachtongue","Draconic","Dwarven",
|
||||
"Chimpanzee","Space Sign Language","Random")
|
||||
if(!choselanguage)
|
||||
return
|
||||
switch(choselanguage)
|
||||
if("Rachidian")
|
||||
language = /datum/language/arachnid
|
||||
if("Beachtongue")
|
||||
language = /datum/language/beachbum
|
||||
if("Draconic")
|
||||
language = /datum/language/draconic
|
||||
if("Dwarven")
|
||||
language = /datum/language/dwarf
|
||||
if("Chimpanzee")
|
||||
language = /datum/language/monkey
|
||||
if("Space Sign Language")
|
||||
language = /datum/language/signlanguage
|
||||
if("Random")
|
||||
language = pick(list("Rachidian", "Beachtongue","Draconic","Dwarven",
|
||||
"Chimpanzee","Space Sign Language"))
|
||||
|
||||
if("body_size")
|
||||
var/new_body_size = input(user, "Choose your desired sprite size: (90-125%)\nWarning: This may make your character look distorted. Additionally, any size under 100% takes a 10% maximum health penalty", "Character Preference", features["body_size"]*100) as num|null
|
||||
if(new_body_size)
|
||||
|
||||
@@ -271,7 +271,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
loadout_data["SAVE_[i]"] = list()
|
||||
for(var/some_gear_item in saved_loadout_paths)
|
||||
if(!ispath(text2path(some_gear_item)))
|
||||
message_admins("Failed to copy item [some_gear_item] to new loadout system when migrating from version [current_version] to 40, issue: item is not a path")
|
||||
log_game("Failed to copy item [some_gear_item] to new loadout system when migrating from version [current_version] to 40, issue: item is not a path")
|
||||
continue
|
||||
var/datum/gear/gear_item = text2path(some_gear_item)
|
||||
if(!(initial(gear_item.loadout_flags) & LOADOUT_CAN_COLOR_POLYCHROMIC))
|
||||
@@ -604,6 +604,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["body_model"] >> features["body_model"]
|
||||
S["body_size"] >> features["body_size"]
|
||||
S["age"] >> age
|
||||
S["language"] >> language
|
||||
S["choselanguage"] >> choselanguage
|
||||
S["hair_color"] >> hair_color
|
||||
S["facial_hair_color"] >> facial_hair_color
|
||||
S["eye_type"] >> eye_type
|
||||
@@ -947,6 +949,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["body_model"] , features["body_model"])
|
||||
WRITE_FILE(S["body_size"] , features["body_size"])
|
||||
WRITE_FILE(S["age"] , age)
|
||||
WRITE_FILE(S["language"] , language)
|
||||
WRITE_FILE(S["choselanguage"] , choselanguage)
|
||||
WRITE_FILE(S["hair_color"] , hair_color)
|
||||
WRITE_FILE(S["facial_hair_color"] , facial_hair_color)
|
||||
WRITE_FILE(S["eye_type"] , eye_type)
|
||||
|
||||
@@ -161,6 +161,68 @@
|
||||
|
||||
return NO_AUTO_CLICKDELAY_HANDLING | ATTACK_IGNORE_ACTION
|
||||
|
||||
/obj/item/clothing/gloves/fingerless/ablative
|
||||
name = "ablative armwraps"
|
||||
desc = "Armwraps made out of a highly durable, reflective metal. Has the side effect of absorbing shocks."
|
||||
siemens_coefficient = 0
|
||||
icon_state = "ablative_armwraps"
|
||||
item_state = "ablative_armwraps"
|
||||
block_parry_data = /datum/block_parry_data/ablative_armwraps
|
||||
var/wornonce = FALSE
|
||||
|
||||
/obj/item/clothing/gloves/fingerless/ablative/proc/get_component_parry_data(datum/source, parrying_method, datum/parrying_item_mob_or_art, list/backup_items, list/override)
|
||||
if(parrying_method && !(parrying_method == UNARMED_PARRY))
|
||||
return
|
||||
override[src] = ITEM_PARRY
|
||||
|
||||
/obj/item/clothing/gloves/fingerless/ablative/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(current_equipped_slot == SLOT_GLOVES)
|
||||
RegisterSignal(user, COMSIG_LIVING_ACTIVE_PARRY_START, .proc/get_component_parry_data)
|
||||
wornonce = TRUE
|
||||
|
||||
/obj/item/clothing/gloves/fingerless/ablative/dropped(mob/user)
|
||||
. = ..()
|
||||
if(wornonce)
|
||||
UnregisterSignal(user, COMSIG_LIVING_ACTIVE_PARRY_START)
|
||||
wornonce = FALSE
|
||||
|
||||
/obj/item/clothing/gloves/fingerless/ablative/can_active_parry(mob/user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!istype(H))
|
||||
return FALSE
|
||||
return src == H.gloves
|
||||
|
||||
/obj/item/clothing/gloves/fingerless/ablative/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time)
|
||||
. = ..()
|
||||
if(parry_efficiency > 0)
|
||||
owner.visible_message("<span class='warning'>[owner] deflects \the [object] with their armwraps!</span>")
|
||||
|
||||
/datum/block_parry_data/ablative_armwraps
|
||||
parry_stamina_cost = 4
|
||||
parry_attack_types = ATTACK_TYPE_UNARMED | ATTACK_TYPE_PROJECTILE | ATTACK_TYPE_TACKLE | ATTACK_TYPE_THROWN | ATTACK_TYPE_MELEE
|
||||
parry_flags = NONE
|
||||
|
||||
parry_time_windup = 0
|
||||
parry_time_spindown = 0
|
||||
parry_time_active = 7.5
|
||||
|
||||
parry_time_perfect = 1
|
||||
parry_time_perfect_leeway = 7.5
|
||||
parry_imperfect_falloff_percent = 20
|
||||
parry_efficiency_perfect = 100
|
||||
parry_time_perfect_leeway_override = list(
|
||||
TEXT_ATTACK_TYPE_MELEE = 1
|
||||
)
|
||||
|
||||
parry_efficiency_considered_successful = 0.01
|
||||
parry_efficiency_to_counterattack = INFINITY // no auto counter
|
||||
parry_max_attacks = INFINITY
|
||||
parry_failed_cooldown_duration = 2.25 SECONDS
|
||||
parry_failed_stagger_duration = 2.25 SECONDS
|
||||
parry_cooldown = 0
|
||||
parry_failed_clickcd_duration = 0
|
||||
|
||||
/obj/item/clothing/gloves/botanic_leather
|
||||
name = "botanist's leather gloves"
|
||||
desc = "These leather gloves protect against thorns, barbs, prickles, spikes and other harmful objects of floral origin. They're also quite warm."
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
/obj/item/clothing/mask/surgical/aesthetic
|
||||
name = "aesthetic sterile mask"
|
||||
desc = "A sterile mask designed to help prevent the spread of diseases. This one doesn't seem like it does a whole lot, somehow."
|
||||
flags_inv = HIDEFACE
|
||||
flags_inv = null
|
||||
flags_cover = null
|
||||
visor_flags_inv = null
|
||||
visor_flags_cover = null
|
||||
|
||||
@@ -97,12 +97,14 @@
|
||||
SEND_SIGNAL(t_loc, COMSIG_TURF_MAKE_DRY, TURF_WET_WATER, TRUE, INFINITY)
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes
|
||||
desc = "The prankster's standard-issue clowning shoes. Damn, they're huge!"
|
||||
desc = "The prankster's standard-issue clowning shoes. Damn, they're huge! Ctrl-click to toggle waddle dampeners."
|
||||
name = "clown shoes"
|
||||
icon_state = "clown_shoes"
|
||||
slowdown = SHOES_SLOWDOWN+1
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes/clown
|
||||
lace_time = 20 SECONDS // how the hell do these laces even work??
|
||||
var/datum/component/waddle
|
||||
var/enabled_waddle = TRUE
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/Initialize()
|
||||
. = ..()
|
||||
@@ -110,14 +112,31 @@
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY))
|
||||
SEND_SIGNAL(user, COMSIG_CLEAR_MOOD_EVENT, "noshoes")
|
||||
if(slot == SLOT_SHOES)
|
||||
if(enabled_waddle)
|
||||
waddle = user.AddComponent(/datum/component/waddling)
|
||||
if(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY))
|
||||
SEND_SIGNAL(user, COMSIG_CLEAR_MOOD_EVENT, "noshoes")
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/dropped(mob/user)
|
||||
. = ..()
|
||||
QDEL_NULL(waddle)
|
||||
if(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY))
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "noshoes", /datum/mood_event/noshoes)
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/CtrlClick(mob/living/user)
|
||||
if(!isliving(user))
|
||||
return
|
||||
if(user.get_active_held_item() != src)
|
||||
to_chat(user, "<span class='warning'>You must hold the [src] in your hand to do this!</span>")
|
||||
return
|
||||
if (!enabled_waddle)
|
||||
to_chat(user, "<span class='notice'>You switch off the waddle dampeners!</span>")
|
||||
enabled_waddle = TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You switch on the waddle dampeners!</span>")
|
||||
enabled_waddle = FALSE
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/jester
|
||||
name = "jester shoes"
|
||||
desc = "A court jester's shoes, updated with modern squeaking technology."
|
||||
|
||||
@@ -487,6 +487,13 @@
|
||||
item_state = "militaryjacket"
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/radio)
|
||||
|
||||
/obj/item/clothing/suit/jacket/urbanjacket
|
||||
name = "urban jacket"
|
||||
desc = "A canvas jacket styled with a fur neck piece, stylish."
|
||||
icon_state = "urbanjacket"
|
||||
item_state = "urbanjacket"
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/radio)
|
||||
|
||||
/obj/item/clothing/suit/jacket/letterman
|
||||
name = "letterman jacket"
|
||||
desc = "A classic brown letterman jacket. Looks pretty hot and heavy."
|
||||
|
||||
@@ -91,6 +91,12 @@
|
||||
icon_state = "tan_suit"
|
||||
item_state = "tan_suit"
|
||||
|
||||
/obj/item/clothing/under/suit/charismatic_suit
|
||||
name = "charismatic suit"
|
||||
desc = "Luck is for losers, baby."
|
||||
icon_state = "charismatic_suit"
|
||||
item_state = "charismatic_suit"
|
||||
|
||||
/obj/item/clothing/under/suit/white
|
||||
name = "white suit"
|
||||
desc = "A white suit and jacket with a blue shirt. You wanna play rough? OKAY!"
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
//Shooting Code:
|
||||
A.preparePixelProjectile(target, src)
|
||||
A.fire()
|
||||
if(ismob(loc.loc))
|
||||
installed_gun.shoot_live_shot(loc.loc)
|
||||
else
|
||||
installed_gun.shoot_live_shot() //Shitcode, but we don't have much of a choice
|
||||
log_attack("[assembly] [REF(assembly)] has fired [installed_gun].")
|
||||
return A
|
||||
|
||||
|
||||
12
code/modules/language/signlanguage.dm
Normal file
@@ -0,0 +1,12 @@
|
||||
/datum/language/signlanguage
|
||||
name = "Space Sign Language"
|
||||
desc = "Those who cannot speak can learn this instead."
|
||||
speech_verb = "signs"
|
||||
whisper_verb = "gestures"
|
||||
key = "9"
|
||||
flags = TONGUELESS_SPEECH
|
||||
|
||||
syllables = list(".")
|
||||
|
||||
icon_state = "ssl"
|
||||
default_priority = 90
|
||||
@@ -522,7 +522,7 @@
|
||||
max_charges = 1
|
||||
item_flags = NEEDS_PERMIT | NOBLUDGEON
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 18
|
||||
force = 15
|
||||
|
||||
/obj/item/ammo_casing/magic/hook
|
||||
name = "hook"
|
||||
@@ -536,11 +536,11 @@
|
||||
icon_state = "hook"
|
||||
icon = 'icons/obj/lavaland/artefacts.dmi'
|
||||
pass_flags = PASSTABLE
|
||||
damage = 25
|
||||
armour_penetration = 100
|
||||
damage = 15
|
||||
armour_penetration = 10
|
||||
knockdown = 5
|
||||
damage_type = BRUTE
|
||||
hitsound = 'sound/effects/splat.ogg'
|
||||
knockdown = 30
|
||||
var/chain
|
||||
|
||||
/obj/item/projectile/hook/fire(setAngle)
|
||||
|
||||
@@ -556,7 +556,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
var/list/dest = list() //List of possible destinations (mobs)
|
||||
var/target = null //Chosen target.
|
||||
|
||||
dest += getpois(mobs_only=1) //Fill list, prompt user with list
|
||||
dest += getpois(mobs_only = TRUE) //Fill list, prompt user with list
|
||||
target = input("Please, select a player!", "Jump to Mob", null, null) as null|anything in dest
|
||||
|
||||
if (!target)//Make sure we actually have a target
|
||||
@@ -893,7 +893,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if (!eye_name)
|
||||
return
|
||||
|
||||
var/mob/mob_eye = creatures[eye_name]
|
||||
do_observe(creatures[eye_name])
|
||||
|
||||
/mob/dead/observer/proc/do_observe(mob/mob_eye)
|
||||
//Istype so we filter out points of interest that are not mobs
|
||||
if(client && mob_eye && istype(mob_eye))
|
||||
client.eye = mob_eye
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/datum/orbit_menu
|
||||
var/mob/dead/observer/owner
|
||||
var/auto_observe = FALSE
|
||||
|
||||
/datum/orbit_menu/New(mob/dead/observer/new_owner)
|
||||
if(!istype(new_owner))
|
||||
@@ -10,6 +11,7 @@
|
||||
return GLOB.observer_state
|
||||
|
||||
/datum/orbit_menu/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if (!ui)
|
||||
ui = new(user, src, "Orbit")
|
||||
ui.open()
|
||||
@@ -18,15 +20,35 @@
|
||||
if (..())
|
||||
return
|
||||
|
||||
if (action == "orbit")
|
||||
var/ref = params["ref"]
|
||||
var/atom/movable/poi = (locate(ref) in GLOB.mob_list) || (locate(ref) in GLOB.poi_list)
|
||||
if (poi != null)
|
||||
switch(action)
|
||||
if ("orbit")
|
||||
var/ref = params["ref"]
|
||||
var/atom/movable/poi = (locate(ref) in GLOB.mob_list) || (locate(ref) in GLOB.poi_list)
|
||||
if (poi == null)
|
||||
. = TRUE
|
||||
return
|
||||
owner.ManualFollow(poi)
|
||||
owner.reset_perspective(null)
|
||||
if (auto_observe)
|
||||
owner.do_observe(poi)
|
||||
. = TRUE
|
||||
if ("refresh")
|
||||
update_static_data(owner, ui)
|
||||
. = TRUE
|
||||
if ("toggle_observe")
|
||||
auto_observe = !auto_observe
|
||||
if (auto_observe && owner.orbit_target)
|
||||
owner.do_observe(owner.orbit_target)
|
||||
else
|
||||
owner.reset_perspective(null)
|
||||
|
||||
/datum/orbit_menu/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["auto_observe"] = auto_observe
|
||||
return data
|
||||
|
||||
/datum/orbit_menu/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/alive = list()
|
||||
var/list/antagonists = list()
|
||||
var/list/dead = list()
|
||||
@@ -34,7 +56,7 @@
|
||||
var/list/misc = list()
|
||||
var/list/npcs = list()
|
||||
|
||||
var/list/pois = getpois(skip_mindless = 1)
|
||||
var/list/pois = getpois(skip_mindless = TRUE, specify_dead_role = FALSE)
|
||||
for (var/name in pois)
|
||||
var/list/serialized = list()
|
||||
serialized["name"] = name
|
||||
@@ -80,7 +102,7 @@
|
||||
data["npcs"] = npcs
|
||||
|
||||
return data
|
||||
|
||||
|
||||
/datum/orbit_menu/ui_assets()
|
||||
. = ..() || list()
|
||||
. += get_asset_datum(/datum/asset/simple/orbit)
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
bubble_icon = "alien"
|
||||
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
|
||||
|
||||
/// Whether they can ventcrawl; this is set individually for 'humanoid' and 'royal' types
|
||||
/// 'royal' types (Praetorian, Queen) cannot ventcrawl
|
||||
var/can_ventcrawl
|
||||
|
||||
/// How much brute damage without armor piercing they do against mobs in melee
|
||||
var/meleeSlashHumanPower = 20
|
||||
/// How much power they have for DefaultCombatKnockdown when attacking humans
|
||||
@@ -38,7 +42,8 @@
|
||||
|
||||
create_internal_organs()
|
||||
|
||||
AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
if(can_ventcrawl)
|
||||
AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
bodyparts = list(/obj/item/bodypart/chest/alien, /obj/item/bodypart/head/alien, /obj/item/bodypart/l_arm/alien,
|
||||
/obj/item/bodypart/r_arm/alien, /obj/item/bodypart/r_leg/alien, /obj/item/bodypart/l_leg/alien)
|
||||
|
||||
can_ventcrawl = TRUE
|
||||
|
||||
|
||||
//This is fine right now, if we're adding organ specific damage this needs to be updated
|
||||
/mob/living/carbon/alien/humanoid/Initialize()
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
layer = LARGE_MOB_LAYER //above most mobs, but below speechbubbles
|
||||
pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper.
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 20, /obj/item/stack/sheet/animalhide/xeno = 3)
|
||||
can_ventcrawl = FALSE
|
||||
|
||||
meleeKnockdownPower = 125
|
||||
meleeSlashHumanPower = 30
|
||||
|
||||
@@ -434,6 +434,9 @@
|
||||
legcuffed.forceMove(drop_location())
|
||||
legcuffed = null
|
||||
I.dropped(src)
|
||||
if(istype(I, /obj/item/restraints/legcuffs))
|
||||
var/obj/item/restraints/legcuffs/lgcf = I
|
||||
lgcf.on_removed()
|
||||
update_inv_legcuffed()
|
||||
return
|
||||
else
|
||||
|
||||
@@ -281,11 +281,13 @@
|
||||
dropItemToGround(pocket_item)
|
||||
if(!usr.can_hold_items() || !usr.put_in_hands(pocket_item))
|
||||
pocket_item.forceMove(drop_location())
|
||||
log_combat(usr, src, "pickpocketed of item: [pocket_item]")
|
||||
else
|
||||
if(place_item)
|
||||
if(place_item.mob_can_equip(src, usr, pocket_id, FALSE, TRUE))
|
||||
usr.temporarilyRemoveItemFromInventory(place_item, TRUE)
|
||||
equip_to_slot(place_item, pocket_id, TRUE)
|
||||
log_combat(usr, src, "placed item [place_item] onto")
|
||||
//do nothing otherwise
|
||||
|
||||
// Update strip window
|
||||
@@ -293,8 +295,9 @@
|
||||
show_inv(usr)
|
||||
else
|
||||
// Display a warning if the user mocks up
|
||||
if (!strip_silence)
|
||||
if(!strip_silence)
|
||||
to_chat(src, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>")
|
||||
log_combat(usr, src, "failed to [pocket_item ? "pickpocket item [pocket_item] from" : "place item [place_item] onto "]")
|
||||
|
||||
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY, null, FALSE))
|
||||
// separate from first canusetopic
|
||||
@@ -938,43 +941,43 @@
|
||||
admin_ticket_log(src, msg)
|
||||
|
||||
/mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user)
|
||||
if(pulling == target && grab_state >= GRAB_AGGRESSIVE && stat == CONSCIOUS)
|
||||
var/GS_needed = istype(target, /mob/living/silicon/pai)? GRAB_PASSIVE : GRAB_AGGRESSIVE
|
||||
if(pulling == target && grab_state >= GS_needed && stat == CONSCIOUS)
|
||||
//If they dragged themselves and we're currently aggressively grabbing them try to piggyback
|
||||
if(user == target && can_piggyback(target))
|
||||
piggyback(target)
|
||||
return
|
||||
//If you dragged them to you and you're aggressively grabbing try to fireman carry them
|
||||
else if(user != target)
|
||||
else if(user == src)
|
||||
if(user.a_intent == INTENT_GRAB)
|
||||
fireman_carry(target)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
//src is the user that will be carrying, target is the mob to be carried
|
||||
/mob/living/carbon/human/proc/can_piggyback(mob/living/carbon/target)
|
||||
return (istype(target) && target.stat == CONSCIOUS)
|
||||
/mob/living/carbon/human/proc/can_piggyback(mob/living/target)
|
||||
return (iscarbon(target) || ispAI(target)) && target.stat == CONSCIOUS
|
||||
|
||||
/mob/living/carbon/human/proc/can_be_firemanned(mob/living/carbon/target)
|
||||
return (ishuman(target) && !CHECK_MOBILITY(target, MOBILITY_STAND))
|
||||
return (ishuman(target) && !CHECK_MOBILITY(target, MOBILITY_STAND)) || ispAI(target)
|
||||
|
||||
/mob/living/carbon/human/proc/fireman_carry(mob/living/carbon/target)
|
||||
var/carrydelay = 50 //if you have latex you are faster at grabbing
|
||||
var/skills_space = "" //cobby told me to do this
|
||||
if(HAS_TRAIT(src, TRAIT_QUICKER_CARRY))
|
||||
carrydelay = 30
|
||||
skills_space = "expertly"
|
||||
skills_space = "expertly "
|
||||
else if(HAS_TRAIT(src, TRAIT_QUICK_CARRY))
|
||||
carrydelay = 40
|
||||
skills_space = "quickly"
|
||||
skills_space = "quickly "
|
||||
if(can_be_firemanned(target) && !incapacitated(FALSE, TRUE))
|
||||
visible_message("<span class='notice'>[src] starts [skills_space] lifting [target] onto their back..</span>",
|
||||
visible_message("<span class='notice'>[src] starts [skills_space]lifting [target] onto their back..</span>",
|
||||
//Joe Medic starts quickly/expertly lifting Grey Tider onto their back..
|
||||
"<span class='notice'>[carrydelay < 35 ? "Using your gloves' nanochips, you" : "You"] [skills_space] start to lift [target] onto your back[carrydelay == 40 ? ", while assisted by the nanochips in your gloves.." : "..."]</span>")
|
||||
"<span class='notice'>[carrydelay < 35 ? "Using your gloves' nanochips, you" : "You"] [skills_space]start to lift [target] onto your back[carrydelay == 40 ? ", while assisted by the nanochips in your gloves.." : "..."]</span>")
|
||||
//(Using your gloves' nanochips, you/You) ( /quickly/expertly) start to lift Grey Tider onto your back(, while assisted by the nanochips in your gloves../...)
|
||||
if(do_after(src, carrydelay, TRUE, target))
|
||||
//Second check to make sure they're still valid to be carried
|
||||
if(can_be_firemanned(target) && !incapacitated(FALSE, TRUE))
|
||||
target.set_resting(FALSE, TRUE)
|
||||
buckle_mob(target, TRUE, TRUE, 90, 1, 0, TRUE)
|
||||
return
|
||||
visible_message("<span class='warning'>[src] fails to fireman carry [target]!")
|
||||
@@ -992,13 +995,13 @@
|
||||
if(target.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE))
|
||||
target.visible_message("<span class='warning'>[target] can't hang onto [src]!</span>")
|
||||
return
|
||||
buckle_mob(target, TRUE, TRUE, FALSE, 1, 2, FALSE)
|
||||
buckle_mob(target, TRUE, TRUE, 0, 1, 2, FALSE)
|
||||
else
|
||||
visible_message("<span class='warning'>[target] fails to climb onto [src]!</span>")
|
||||
else
|
||||
to_chat(target, "<span class='warning'>You can't piggyback ride [src] right now!</span>")
|
||||
|
||||
/mob/living/carbon/human/buckle_mob(mob/living/target, force = FALSE, check_loc = TRUE, lying_buckle = FALSE, hands_needed = 0, target_hands_needed = 0, fireman = FALSE)
|
||||
/mob/living/carbon/human/buckle_mob(mob/living/target, force = FALSE, check_loc = TRUE, lying_buckle = 0, hands_needed = 0, target_hands_needed = 0, fireman = FALSE)
|
||||
if(!force)//humans are only meant to be ridden through piggybacking and special cases
|
||||
return
|
||||
if(!is_type_in_typecache(target, can_ride_typecache))
|
||||
@@ -1010,6 +1013,9 @@
|
||||
riding_datum.ride_check_rider_restrained = TRUE
|
||||
if(buckled_mobs && ((target in buckled_mobs) || (buckled_mobs.len >= max_buckled_mobs)) || buckled)
|
||||
return
|
||||
if(istype(target, /mob/living/silicon/pai))
|
||||
hands_needed = 1
|
||||
target_hands_needed = 0
|
||||
var/equipped_hands_self
|
||||
var/equipped_hands_target
|
||||
if(hands_needed)
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
var/list/datum/bioware = list()
|
||||
|
||||
var/creamed = FALSE //to use with creampie overlays
|
||||
var/static/list/can_ride_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot))
|
||||
var/static/list/can_ride_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot, /mob/living/silicon/pai))
|
||||
var/lastpuke = 0
|
||||
var/account_id
|
||||
var/last_fire_update
|
||||
|
||||
@@ -30,10 +30,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
|
||||
/datum/species/dwarf/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
var/dwarf_hair = pick("Beard (Dwarf)", "Beard (Very Long)", "Beard (Long)") //beard roullette
|
||||
var/mob/living/carbon/human/H = C
|
||||
H.facial_hair_style = dwarf_hair
|
||||
H.update_hair()
|
||||
H.AddElement(/datum/element/dwarfism, COMSIG_SPECIES_LOSS, src)
|
||||
RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech) //We register handle_speech is being used.
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
/mob/living/carbon/can_speak_vocal(message)
|
||||
if(silent)
|
||||
return 0
|
||||
if(get_message_language(message) == /datum/language/signlanguage && (handcuffed || (!src.get_bodypart(BODY_ZONE_L_ARM) && !src.get_bodypart(BODY_ZONE_R_ARM)) || get_num_held_items() == held_items.len))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/could_speak_language(datum/language/language)
|
||||
|
||||
@@ -866,7 +866,7 @@
|
||||
if(istype(G))
|
||||
strip_mod = G.strip_mod
|
||||
strip_silence = G.strip_silence
|
||||
if (!strip_silence)
|
||||
if(!strip_silence)
|
||||
who.visible_message("<span class='danger'>[src] tries to remove [who]'s [what.name].</span>", \
|
||||
"<span class='userdanger'>[src] tries to remove your [what.name].</span>", target = src,
|
||||
target_message = "<span class='danger'>You try to remove [who]'s [what.name].</span>")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* Determines if we can actively parry.
|
||||
*/
|
||||
/obj/item/proc/can_active_parry()
|
||||
/obj/item/proc/can_active_parry(mob/user)
|
||||
return block_parry_data && (item_flags & ITEM_CAN_PARRY)
|
||||
|
||||
/**
|
||||
@@ -29,7 +29,7 @@
|
||||
var/datum/block_parry_data/data
|
||||
var/datum/tool
|
||||
var/method
|
||||
if(using_item?.can_active_parry())
|
||||
if(using_item?.can_active_parry(src))
|
||||
data = using_item.block_parry_data
|
||||
method = ITEM_PARRY
|
||||
tool = using_item
|
||||
@@ -50,9 +50,20 @@
|
||||
using_item = backup
|
||||
method = ITEM_PARRY
|
||||
var/list/other_items = list()
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_ACTIVE_PARRY_START, method, tool, other_items) & COMPONENT_PREVENT_PARRY_START)
|
||||
var/list/override = list()
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_ACTIVE_PARRY_START, method, tool, other_items, override) & COMPONENT_PREVENT_PARRY_START)
|
||||
to_chat(src, "<span class='warning'>Something is preventing you from parrying!</span>")
|
||||
return
|
||||
if(length(override))
|
||||
var/datum/thing = override[1]
|
||||
var/_method = override[thing]
|
||||
if(_method == ITEM_PARRY)
|
||||
using_item = thing
|
||||
method = ITEM_PARRY
|
||||
data = using_item.block_parry_data
|
||||
else if(_method == UNARMED_PARRY)
|
||||
method = UNARMED_PARRY
|
||||
data = thing
|
||||
if(!using_item && !method && length(other_items))
|
||||
using_item = other_items[1]
|
||||
method = ITEM_PARRY
|
||||
@@ -94,7 +105,7 @@
|
||||
*/
|
||||
/mob/living/proc/find_backup_parry_item()
|
||||
for(var/obj/item/I in held_items - get_active_held_item())
|
||||
if(I.can_active_parry())
|
||||
if(I.can_active_parry(src))
|
||||
return I
|
||||
|
||||
/**
|
||||
@@ -231,7 +242,7 @@
|
||||
var/efficiency = data.get_parry_efficiency(attack_type, get_parry_time())
|
||||
switch(parrying)
|
||||
if(ITEM_PARRY)
|
||||
if(!active_parry_item.can_active_parry())
|
||||
if(!active_parry_item.can_active_parry(src))
|
||||
return BLOCK_NONE
|
||||
. = active_parry_item.on_active_parry(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency, get_parry_time())
|
||||
if(UNARMED_PARRY)
|
||||
@@ -243,6 +254,18 @@
|
||||
if(efficiency <= 0) // Do not allow automatically handled/standardized parries that increase damage for now.
|
||||
return
|
||||
. |= BLOCK_SHOULD_PARTIAL_MITIGATE
|
||||
if(efficiency >= data.parry_efficiency_perfect)
|
||||
. |= data.perfect_parry_block_return_flags
|
||||
if(data.perfect_parry_block_return_list)
|
||||
return_list |= data.perfect_parry_block_return_list
|
||||
else if(efficiency >= data.parry_efficiency_considered_successful)
|
||||
. |= data.imperfect_parry_block_return_flags
|
||||
if(data.imperfect_parry_block_return_list)
|
||||
return_list |= data.imperfect_parry_block_return_list
|
||||
else
|
||||
. |= data.failed_parry_block_return_flags
|
||||
if(data.failed_parry_block_return_list)
|
||||
return_list |= data.failed_parry_block_return_list
|
||||
if(isnull(return_list[BLOCK_RETURN_MITIGATION_PERCENT])) // if one of the on_active_parry procs overrode. We don't have to worry about interference since parries are the first thing checked in the [do_run_block()] sequence.
|
||||
return_list[BLOCK_RETURN_MITIGATION_PERCENT] = clamp(efficiency, 0, 100) // do not allow > 100% or < 0% for now.
|
||||
if((return_list[BLOCK_RETURN_MITIGATION_PERCENT] >= 100) || (damage <= 0))
|
||||
|
||||
@@ -157,6 +157,16 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
/// Parry cooldown post-parry if failed. This is ADDED to parry_cooldown!!!
|
||||
var/parry_failed_cooldown_duration = 0 SECONDS
|
||||
|
||||
// Advanced
|
||||
/// Flags added to return value
|
||||
var/perfect_parry_block_return_flags = NONE
|
||||
var/imperfect_parry_block_return_flags = NONE
|
||||
var/failed_parry_block_return_flags = NONE
|
||||
/// List appended to block return
|
||||
var/perfect_parry_block_return_list
|
||||
var/imperfect_parry_block_return_list
|
||||
var/failed_parry_block_return_list
|
||||
|
||||
/**
|
||||
* Quirky proc to get average of flags in list that are in attack_type because why is attack_type a flag.
|
||||
*/
|
||||
|
||||
@@ -329,7 +329,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
return 1
|
||||
|
||||
/mob/living/proc/can_speak_vocal(message) //Check AFTER handling of xeno and ling channels
|
||||
if(HAS_TRAIT(src, TRAIT_MUTE))
|
||||
if(HAS_TRAIT(src, TRAIT_MUTE) && get_message_language(message) != /datum/language/signlanguage)
|
||||
return 0
|
||||
|
||||
if(is_muzzled())
|
||||
|
||||
@@ -143,6 +143,10 @@
|
||||
custom_holoform.Grant(src)
|
||||
emitter_next_use = world.time + 10 SECONDS
|
||||
|
||||
/mob/living/silicon/pai/deployed/Initialize()
|
||||
. = ..()
|
||||
fold_out(TRUE)
|
||||
|
||||
/mob/living/silicon/pai/ComponentInitialize()
|
||||
. = ..()
|
||||
if(possible_chassis[chassis])
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
if("PRG_edit")
|
||||
if(!computer || !authenticated || !target_id_card)
|
||||
return
|
||||
var/new_name = params["name"]
|
||||
var/new_name = reject_bad_name(params["name"])
|
||||
if(!new_name)
|
||||
return
|
||||
target_id_card.registered_name = new_name
|
||||
@@ -190,7 +190,7 @@
|
||||
return
|
||||
|
||||
if(target == "Custom")
|
||||
var/custom_name = params["custom_name"]
|
||||
var/custom_name = reject_bad_name(params["custom_name"])
|
||||
if(custom_name)
|
||||
target_id_card.assignment = custom_name
|
||||
target_id_card.update_label()
|
||||
|
||||
@@ -12,3 +12,7 @@
|
||||
|
||||
/datum/movespeed_modifier/reagent/nitryl
|
||||
multiplicative_slowdown = -1
|
||||
|
||||
/datum/movespeed_modifier/reagent/meth
|
||||
multiplicative_slowdown = -0.5
|
||||
absolute_max_tiles_per_second = 11
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
name = "\improper Nanotrasen Saber SMG"
|
||||
desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors."
|
||||
icon_state = "saber"
|
||||
fire_sound = "sound/weapons/gunshot_smg_alt.ogg"
|
||||
mag_type = /obj/item/ammo_box/magazine/smgm9mm
|
||||
pin = null
|
||||
|
||||
@@ -125,6 +126,7 @@
|
||||
desc = "An outdated personal defence weapon. Uses 4.6x30mm rounds and is designated the WT-550 Semi-Automatic SMG."
|
||||
icon_state = "wt550"
|
||||
item_state = "arg"
|
||||
fire_sound = "sound/weapons/gunshot_smg_alt.ogg"
|
||||
mag_type = /obj/item/ammo_box/magazine/wt550m9
|
||||
can_suppress = FALSE
|
||||
burst_size = 2
|
||||
@@ -138,6 +140,10 @@
|
||||
. = ..()
|
||||
spread = 15
|
||||
|
||||
/obj/item/gun/ballistic/automatic/wt550/afterattack()
|
||||
. = ..()
|
||||
empty_alarm()
|
||||
|
||||
/obj/item/gun/ballistic/automatic/wt550/disable_burst()
|
||||
. = ..()
|
||||
spread = 0
|
||||
@@ -158,7 +164,7 @@
|
||||
icon_state = "m90"
|
||||
item_state = "m90"
|
||||
mag_type = /obj/item/ammo_box/magazine/m556
|
||||
fire_sound = 'sound/weapons/gunshot_smg.ogg'
|
||||
fire_sound = 'sound/weapons/rifleshot.ogg'
|
||||
can_suppress = FALSE
|
||||
automatic_burst_overlay = FALSE
|
||||
var/obj/item/gun/ballistic/revolver/grenadelauncher/underbarrel
|
||||
@@ -243,7 +249,7 @@
|
||||
item_state = "arg"
|
||||
slot_flags = 0
|
||||
mag_type = /obj/item/ammo_box/magazine/m556
|
||||
fire_sound = 'sound/weapons/gunshot_smg.ogg'
|
||||
fire_sound = 'sound/weapons/rifleshot.ogg'
|
||||
can_suppress = FALSE
|
||||
burst_size = 3
|
||||
burst_shot_delay = 1
|
||||
@@ -258,7 +264,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
weapon_weight = WEAPON_MEDIUM
|
||||
mag_type = /obj/item/ammo_box/magazine/m12g
|
||||
fire_sound = 'sound/weapons/gunshot.ogg'
|
||||
fire_sound = 'sound/weapons/gunshotshotgunshot.ogg'
|
||||
automatic_burst_overlay = FALSE
|
||||
can_suppress = FALSE
|
||||
burst_size = 1
|
||||
@@ -293,11 +299,11 @@
|
||||
desc = "A heavily modified 1.95x129mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation."
|
||||
icon_state = "l6closed100"
|
||||
item_state = "l6closedmag"
|
||||
fire_sound = "sound/weapons/lmgshot.ogg"
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
slot_flags = 0
|
||||
mag_type = /obj/item/ammo_box/magazine/mm195x129
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
fire_sound = 'sound/weapons/gunshot_smg.ogg'
|
||||
var/cover_open = FALSE
|
||||
can_suppress = FALSE
|
||||
burst_size = 3
|
||||
@@ -363,6 +369,7 @@
|
||||
desc = "A long ranged weapon that does significant damage. No, you can't quickscope."
|
||||
icon_state = "sniper"
|
||||
item_state = "sniper"
|
||||
fire_sound = "sound/weapons/noscope.ogg"
|
||||
recoil = 2
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
mag_type = /obj/item/ammo_box/magazine/sniper_rounds
|
||||
@@ -397,6 +404,7 @@
|
||||
desc = "One of countless obsolete ballistic rifles that still sees use as a cheap deterrent. Uses 10mm ammo and its bulky frame prevents one-hand firing."
|
||||
icon_state = "surplus"
|
||||
item_state = "moistnugget"
|
||||
fire_sound = 'sound/weapons/rifleshot.ogg'
|
||||
weapon_weight = WEAPON_HEAVY
|
||||
mag_type = /obj/item/ammo_box/magazine/m10mm/rifle
|
||||
fire_delay = 30
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
name = "gyrojet pistol"
|
||||
desc = "A prototype pistol designed to fire self propelled rockets."
|
||||
icon_state = "gyropistol"
|
||||
fire_sound = 'sound/weapons/grenadelaunch.ogg'
|
||||
fire_sound = 'sound/weapons/rocketlaunch.ogg'
|
||||
mag_type = /obj/item/ammo_box/magazine/m75
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
can_suppress = FALSE
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
actions_types = list()
|
||||
fire_sound = 'sound/weapons/blastcannon.ogg'
|
||||
fire_sound = 'sound/weapons/noscope.ogg'
|
||||
spread = 20 //damn thing has no rifling.
|
||||
automatic_burst_overlay = FALSE
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "A suspicious revolver. Uses .357 ammo." //usually used by syndicates
|
||||
icon_state = "revolver"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/cylinder
|
||||
fire_sound = "sound/weapons/revolvershot.ogg"
|
||||
casing_ejector = FALSE
|
||||
|
||||
/obj/item/gun/ballistic/revolver/Initialize()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "A traditional shotgun with wood furniture and a four-shell capacity underneath."
|
||||
icon_state = "shotgun"
|
||||
item_state = "shotgun"
|
||||
fire_sound = "sound/weapons/gunshotshotgunshot.ogg"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
flags_1 = CONDUCT_1
|
||||
|
||||
@@ -973,10 +973,8 @@
|
||||
for(var/A in cached_reagents)
|
||||
var/datum/reagent/R = A
|
||||
if (R.type == reagent)
|
||||
if((total_volume - amount) <= 0)//Because this can result in 0, I don't want it to crash.
|
||||
pH = REAGENT_NORMAL_PH
|
||||
//In practice this is really confusing and players feel like it randomly melts their beakers, but I'm not sure how else to handle it. We'll see how it goes and I can remove this if it confuses people.
|
||||
else if (!ignore_pH)
|
||||
if(!ignore_pH)
|
||||
//if (((pH > R.pH) && (pH <= 7)) || ((pH < R.pH) && (pH >= 7)))
|
||||
pH = (((pH - R.pH) / total_volume) * amount) + pH
|
||||
if(istype(my_atom, /obj/item/reagent_containers/))
|
||||
@@ -987,6 +985,8 @@
|
||||
amount = clamp(amount, 0, R.volume)
|
||||
R.volume -= amount
|
||||
update_total()
|
||||
if(total_volume <= 0)//Because this can result in 0, I don't want it to crash.
|
||||
pH = REAGENT_NORMAL_PH
|
||||
if(!safety)//So it does not handle reactions when it need not to
|
||||
handle_reactions()
|
||||
if(my_atom)
|
||||
|
||||
@@ -24,9 +24,11 @@
|
||||
circuit = /obj/item/circuitboard/machine/chem_dispenser
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/powerefficiency = 0.0666666
|
||||
var/dispenceUnit = 5
|
||||
var/amount = 30
|
||||
var/recharge_amount = 10
|
||||
var/recharge_counter = 0
|
||||
var/canStore = TRUE//If this can hold reagents or not
|
||||
var/mutable_appearance/beaker_overlay
|
||||
var/working_state = "dispenser_working"
|
||||
var/nopower_state = "dispenser_nopower"
|
||||
@@ -102,6 +104,7 @@
|
||||
if(upgrade_reagents3)
|
||||
upgrade_reagents3 = sortList(upgrade_reagents3, /proc/cmp_reagents_asc)
|
||||
dispensable_reagents = sortList(dispensable_reagents, /proc/cmp_reagents_asc)
|
||||
create_reagents(200, NO_REACT)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/chem_dispenser/Destroy()
|
||||
@@ -190,24 +193,27 @@
|
||||
data["amount"] = amount
|
||||
data["energy"] = cell.charge ? cell.charge * powerefficiency : "0" //To prevent NaN in the UI.
|
||||
data["maxEnergy"] = cell.maxcharge * powerefficiency
|
||||
data["storedVol"] = reagents.total_volume
|
||||
data["maxVol"] = reagents.maximum_volume
|
||||
data["isBeakerLoaded"] = beaker ? 1 : 0
|
||||
data["stepAmount"] = dispenceUnit
|
||||
data["canStore"] = canStore
|
||||
|
||||
var/beakerContents[0]
|
||||
var/beakerCurrentVolume = 0
|
||||
if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
|
||||
beakerContents.Add(list(list("name" = R.name, "id" = R.type, "volume" = round(R.volume, 0.01)))) // list in a list because Byond merges the first list...
|
||||
beakerCurrentVolume += R.volume
|
||||
data["beakerContents"] = beakerContents
|
||||
|
||||
if (beaker)
|
||||
data["beakerCurrentVolume"] = beakerCurrentVolume
|
||||
data["beakerCurrentVolume"] = round(beakerCurrentVolume, 0.01)
|
||||
data["beakerMaxVolume"] = beaker.volume
|
||||
data["beakerTransferAmounts"] = beaker.possible_transfer_amounts
|
||||
data["beakerCurrentpH"] = beaker.reagents.pH
|
||||
//pH accuracy
|
||||
for(var/obj/item/stock_parts/capacitor/C in component_parts)
|
||||
data["partRating"]= 10**(C.rating-1)
|
||||
data["beakerCurrentpH"] = round(beaker.reagents.pH, 10**-(C.rating+1))
|
||||
|
||||
else
|
||||
data["beakerCurrentVolume"] = null
|
||||
@@ -225,11 +231,17 @@
|
||||
var/chemname = temp.name
|
||||
if(is_hallucinating && prob(5))
|
||||
chemname = "[pick_list_replacements("hallucination.json", "chemicals")]"
|
||||
chemicals.Add(list(list("title" = chemname, "id" = ckey(temp.name))))
|
||||
chemicals.Add(list(list("title" = chemname, "id" = ckey(temp.name), "pH" = temp.pH, "pHCol" = ConvertpHToCol(temp.pH))))
|
||||
data["chemicals"] = chemicals
|
||||
data["recipes"] = saved_recipes
|
||||
|
||||
data["recordingRecipe"] = recording_recipe
|
||||
|
||||
var/storedContents[0]
|
||||
if(reagents.total_volume)
|
||||
for(var/datum/reagent/N in reagents.reagent_list)
|
||||
storedContents.Add(list(list("name" = N.name, "id" = N.type, "volume" = N.volume)))
|
||||
data["storedContents"] = storedContents
|
||||
return data
|
||||
|
||||
/obj/machinery/chem_dispenser/ui_act(action, params)
|
||||
@@ -240,10 +252,9 @@
|
||||
if(!is_operational() || QDELETED(beaker))
|
||||
return
|
||||
var/target = text2num(params["target"])
|
||||
if(target in beaker.possible_transfer_amounts)
|
||||
amount = target
|
||||
work_animation()
|
||||
. = TRUE
|
||||
SetAmount(target)
|
||||
work_animation()
|
||||
. = TRUE
|
||||
if("dispense")
|
||||
if(!is_operational() || QDELETED(cell))
|
||||
return
|
||||
@@ -269,10 +280,9 @@
|
||||
if(!is_operational() || recording_recipe)
|
||||
return
|
||||
var/amount = text2num(params["amount"])
|
||||
if(beaker && (amount in beaker.possible_transfer_amounts))
|
||||
beaker.reagents.remove_all(amount)
|
||||
work_animation()
|
||||
. = TRUE
|
||||
beaker.reagents.remove_all(amount) //This should be set correctly in "amount"
|
||||
work_animation()
|
||||
. = TRUE
|
||||
if("eject")
|
||||
replace_beaker(usr)
|
||||
. = TRUE
|
||||
@@ -350,6 +360,52 @@
|
||||
recording_recipe = null
|
||||
. = TRUE
|
||||
|
||||
//Storing and unstoring reagents
|
||||
if("store")
|
||||
if(!is_operational() || QDELETED(cell))
|
||||
return
|
||||
if(!beaker)
|
||||
return
|
||||
if(recording_recipe)
|
||||
say("Cannot store while recording!")
|
||||
return
|
||||
if(beaker.reagents.fermiIsReacting)
|
||||
say("Cannot store ongoing reactions!")
|
||||
return
|
||||
var/reagent = text2path(params["id"])
|
||||
var/datum/reagent/R = beaker.reagents.has_reagent(reagent)
|
||||
var/potentialAmount = min(amount, R.volume)
|
||||
if(reagents.total_volume+potentialAmount > reagents.maximum_volume)
|
||||
say("Not enough storage space left!")
|
||||
return
|
||||
beaker.reagents.trans_id_to(src, R.type, potentialAmount)
|
||||
work_animation()
|
||||
. = TRUE
|
||||
|
||||
if("unstore")
|
||||
if(!is_operational() || QDELETED(cell))
|
||||
return
|
||||
if(!beaker)
|
||||
return
|
||||
if(recording_recipe)
|
||||
say("Cannot distribute while recording!")
|
||||
return
|
||||
var/reagent = text2path(params["id"])
|
||||
var/datum/reagent/R = reagents.has_reagent(reagent)
|
||||
reagents.trans_id_to(beaker, R.type, amount)
|
||||
work_animation()
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/chem_dispenser/proc/SetAmount(inputAmount)
|
||||
if(inputAmount % 5 == 0) //Always allow 5u values
|
||||
amount = inputAmount
|
||||
return
|
||||
inputAmount -= inputAmount % dispenceUnit
|
||||
if(inputAmount == 0) //Prevent ghost entries in macros
|
||||
amount = dispenceUnit
|
||||
return
|
||||
amount = inputAmount
|
||||
|
||||
/obj/machinery/chem_dispenser/attackby(obj/item/I, mob/user, params)
|
||||
if(default_unfasten_wrench(user, I))
|
||||
return
|
||||
@@ -402,6 +458,8 @@
|
||||
cell = P
|
||||
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
|
||||
newpowereff += 0.0166666666*M.rating
|
||||
if(reagents)
|
||||
reagents.maximum_volume = 200*(M.rating)
|
||||
for(var/obj/item/stock_parts/capacitor/C in component_parts)
|
||||
recharge_amount *= C.rating
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
@@ -411,6 +469,15 @@
|
||||
dispensable_reagents |= upgrade_reagents2
|
||||
if(M.rating > 3)
|
||||
dispensable_reagents |= upgrade_reagents3
|
||||
switch(M.rating)
|
||||
if(-INFINITY to 1)
|
||||
dispenceUnit = 5
|
||||
if(2)
|
||||
dispenceUnit = 3
|
||||
if(3)
|
||||
dispenceUnit = 2
|
||||
if(4 to INFINITY)
|
||||
dispenceUnit = 1
|
||||
powerefficiency = round(newpowereff, 0.01)
|
||||
|
||||
/obj/machinery/chem_dispenser/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
|
||||
@@ -421,6 +488,8 @@
|
||||
user.put_in_hands(B)
|
||||
if(new_beaker)
|
||||
beaker = new_beaker
|
||||
if(amount > beaker.reagents.maximum_volume)
|
||||
amount = beaker.reagents.maximum_volume
|
||||
else
|
||||
beaker = null
|
||||
update_icon()
|
||||
@@ -439,6 +508,32 @@
|
||||
replace_beaker(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/chem_dispenser/proc/ConvertpHToCol(pH)
|
||||
switch(pH)
|
||||
if(-INFINITY to 1)
|
||||
return "red"
|
||||
if(1 to 2)
|
||||
return "orange"
|
||||
if(2 to 3)
|
||||
return "average"
|
||||
if(3 to 4)
|
||||
return "yellow"
|
||||
if(4 to 5)
|
||||
return "olive"
|
||||
if(5 to 6)
|
||||
return "good"
|
||||
if(6 to 8)
|
||||
return "green"
|
||||
if(8 to 9.5)
|
||||
return "teal"
|
||||
if(9.5 to 11)
|
||||
return "blue"
|
||||
if(11 to 12.5)
|
||||
return "violet"
|
||||
if(12.5 to INFINITY)
|
||||
return "purple"
|
||||
|
||||
|
||||
/obj/machinery/chem_dispenser/drinks/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE)
|
||||
@@ -466,6 +561,7 @@
|
||||
b_o.pixel_x = rand(-9, 9)
|
||||
return b_o
|
||||
|
||||
|
||||
/obj/machinery/chem_dispenser/drinks
|
||||
name = "soda dispenser"
|
||||
desc = "Contains a large reservoir of soft drinks."
|
||||
@@ -479,6 +575,7 @@
|
||||
working_state = null
|
||||
nopower_state = null
|
||||
pass_flags = PASSTABLE
|
||||
canStore = FALSE
|
||||
dispensable_reagents = list(
|
||||
/datum/reagent/water,
|
||||
/datum/reagent/consumable/ice,
|
||||
@@ -611,12 +708,14 @@
|
||||
dispensable_reagents = list(/datum/reagent/toxin/mutagen)
|
||||
upgrade_reagents = null
|
||||
emagged_reagents = list(/datum/reagent/toxin/plasma)
|
||||
canStore = FALSE
|
||||
|
||||
|
||||
/obj/machinery/chem_dispenser/mutagensaltpeter
|
||||
name = "botanical chemical dispenser"
|
||||
desc = "Creates and dispenses chemicals useful for botany."
|
||||
flags_1 = NODECONSTRUCT_1
|
||||
canStore = FALSE
|
||||
|
||||
dispensable_reagents = list(
|
||||
/datum/reagent/toxin/mutagen,
|
||||
@@ -739,6 +838,7 @@
|
||||
working_state = "minidispenser_working"
|
||||
nopower_state = "minidispenser_nopower"
|
||||
circuit = /obj/item/circuitboard/machine/chem_dispenser/apothecary
|
||||
canStore = FALSE
|
||||
powerefficiency = 0.0833333
|
||||
dispensable_reagents = list( //radium and stable plasma moved to upgrade tier 1 and 2, they've little to do with most medicines anyway.
|
||||
/datum/reagent/hydrogen,
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
var beakerContents[0]
|
||||
if(beaker)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume, "purity" = R.purity))) // list in a list because Byond merges the first list...
|
||||
beakerContents.Add(list(list("name" = R.name, "volume" = round(R.volume, 0.01), "purity" = round(R.purity, 0.01)))) // list in a list because Byond merges the first list...
|
||||
data["beakerContents"] = beakerContents
|
||||
return data
|
||||
|
||||
|
||||
@@ -184,13 +184,13 @@
|
||||
var/beakerContents[0]
|
||||
if(beaker)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
beakerContents.Add(list(list("name" = R.name, "id" = ckey(R.name), "volume" = R.volume))) // list in a list because Byond merges the first list...
|
||||
beakerContents.Add(list(list("name" = R.name, "id" = R.type, "volume" = R.volume))) // list in a list because Byond merges the first list...
|
||||
data["beakerContents"] = beakerContents
|
||||
|
||||
var/bufferContents[0]
|
||||
if(reagents.total_volume)
|
||||
for(var/datum/reagent/N in reagents.reagent_list)
|
||||
bufferContents.Add(list(list("name" = N.name, "id" = ckey(N.name), "volume" = N.volume))) // ^
|
||||
bufferContents.Add(list(list("name" = N.name, "id" = N.type, "volume" = N.volume))) // ^
|
||||
data["bufferContents"] = bufferContents
|
||||
|
||||
//Calculated at init time as it never changes
|
||||
@@ -216,7 +216,7 @@
|
||||
if(action == "transfer")
|
||||
if(!beaker)
|
||||
return FALSE
|
||||
var/reagent = GLOB.name2reagent[params["id"]]
|
||||
var/reagent = text2path(params["id"])
|
||||
var/amount = text2num(params["amount"])
|
||||
var/to_container = params["to"]
|
||||
// Custom amount
|
||||
@@ -386,7 +386,7 @@
|
||||
|
||||
if(action == "analyze")
|
||||
// var/datum/reagent/R = GLOB.name2reagent[params["id"]]
|
||||
var/reagent = GLOB.name2reagent[params["id"]]
|
||||
var/reagent = text2path(params["id"])
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[reagent]
|
||||
if(R)
|
||||
var/state = "Unknown"
|
||||
@@ -405,7 +405,7 @@
|
||||
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = R.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
|
||||
else
|
||||
fermianalyze = FALSE
|
||||
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
|
||||
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = R.purity)
|
||||
screen = "analyze"
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -504,6 +504,14 @@
|
||||
glass_desc = "Don't cry, Don't raise your eye, It's only nuclear wasteland."
|
||||
value = REAGENT_VALUE_COMMON
|
||||
|
||||
/datum/reagent/consumable/nuka_cola/on_mob_metabolize(mob/living/carbon/M)
|
||||
M.add_movespeed_modifier(/datum/movespeed_modifier/reagent/meth)
|
||||
return ..()
|
||||
|
||||
/datum/reagent/consumable/nuka_cola/on_mob_end_metabolize(mob/living/carbon/M)
|
||||
M.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/meth)
|
||||
return ..()
|
||||
|
||||
/datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/carbon/M)
|
||||
M.Jitter(20)
|
||||
M.set_drugginess(30)
|
||||
|
||||
@@ -174,11 +174,13 @@
|
||||
ADD_TRAIT(L, TRAIT_IGNOREDAMAGESLOWDOWN, type)
|
||||
L.update_movespeed()
|
||||
ADD_TRAIT(L, TRAIT_TASED_RESISTANCE, type)
|
||||
L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/meth)
|
||||
|
||||
/datum/reagent/drug/methamphetamine/on_mob_end_metabolize(mob/living/L)
|
||||
REMOVE_TRAIT(L, TRAIT_IGNOREDAMAGESLOWDOWN, type)
|
||||
L.update_movespeed()
|
||||
REMOVE_TRAIT(L, TRAIT_TASED_RESISTANCE, type)
|
||||
L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/meth)
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/methamphetamine/on_mob_life(mob/living/carbon/M)
|
||||
|
||||
@@ -116,7 +116,10 @@
|
||||
holder.remove_reagent(id, added_volume*temp_ratio)
|
||||
if(St.purity < 1)
|
||||
St.volume *= St.purity
|
||||
added_volume *= St.purity
|
||||
St.purity = 1
|
||||
if(!N)
|
||||
return
|
||||
var/amount = clamp(0.002, 0, N.volume)
|
||||
N.volume -= amount
|
||||
St.data["grown_volume"] = St.data["grown_volume"] + added_volume
|
||||
|
||||
@@ -469,6 +469,10 @@
|
||||
qdel(src)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/Destroy()
|
||||
linked_extract = null
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/null //This shouldn't ever happen, but just in case.
|
||||
id = "stabilizednull"
|
||||
|
||||
@@ -884,7 +888,8 @@
|
||||
/datum/status_effect/stabilized/oil/tick()
|
||||
if(owner.stat == DEAD)
|
||||
explosion(get_turf(owner),1,2,4,flame_range = 5)
|
||||
owner.remove_status_effect(/datum/status_effect/stabilized/oil)
|
||||
qdel(linked_extract)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/black
|
||||
|
||||
@@ -404,6 +404,7 @@
|
||||
on_mob.set_light(1, 1, current_color_string)
|
||||
|
||||
/obj/effect/abstract/eye_lighting
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
var/obj/item/organ/eyes/robotic/glow/parent
|
||||
|
||||
/obj/effect/abstract/eye_lighting/Initialize()
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
/datum/language/slime,
|
||||
/datum/language/vampiric,
|
||||
/datum/language/dwarf,
|
||||
/datum/language/signlanguage,
|
||||
))
|
||||
healing_factor = STANDARD_ORGAN_HEALING*5 //Fast!!
|
||||
decay_factor = STANDARD_ORGAN_DECAY/2
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#define COOLDOWN_STUN 1200
|
||||
#define COOLDOWN_KNOCKDOWN 600
|
||||
#define COOLDOWN_DAMAGE 600
|
||||
#define COOLDOWN_MEME 300
|
||||
#define COOLDOWN_NONE 100
|
||||
@@ -213,7 +214,6 @@
|
||||
|
||||
var/static/regex/stun_words = regex("stop|wait|stand still|hold on|halt")
|
||||
var/static/regex/knockdown_words = regex("drop|fall|trip|knockdown")
|
||||
var/static/regex/sleep_words = regex("sleep|slumber|rest")
|
||||
var/static/regex/vomit_words = regex("vomit|throw up|sick")
|
||||
var/static/regex/silence_words = regex("shut up|silence|be silent|ssh|quiet|hush")
|
||||
var/static/regex/hallucinate_words = regex("see the truth|hallucinate")
|
||||
@@ -264,26 +264,20 @@
|
||||
cooldown = COOLDOWN_STUN
|
||||
for(var/V in listeners)
|
||||
var/mob/living/L = V
|
||||
L.Stun(60 * power_multiplier)
|
||||
L.Stagger(60 * power_multiplier)
|
||||
|
||||
//KNOCKDOWN
|
||||
else if(findtext(message, knockdown_words))
|
||||
cooldown = COOLDOWN_STUN
|
||||
cooldown = COOLDOWN_KNOCKDOWN
|
||||
for(var/V in listeners)
|
||||
var/mob/living/L = V
|
||||
L.DefaultCombatKnockdown(60 * power_multiplier)
|
||||
|
||||
//SLEEP
|
||||
else if((findtext(message, sleep_words)))
|
||||
cooldown = COOLDOWN_STUN
|
||||
for(var/mob/living/carbon/C in listeners)
|
||||
C.Sleeping(40 * power_multiplier)
|
||||
L.DefaultCombatKnockdown()
|
||||
|
||||
//VOMIT
|
||||
else if((findtext(message, vomit_words)))
|
||||
cooldown = COOLDOWN_STUN
|
||||
cooldown = COOLDOWN_DAMAGE
|
||||
for(var/mob/living/carbon/C in listeners)
|
||||
C.vomit(10 * power_multiplier, distance = power_multiplier)
|
||||
C.vomit(10 * power_multiplier, distance = power_multiplier, stun = FALSE)
|
||||
|
||||
//SILENCE
|
||||
else if((findtext(message, silence_words)))
|
||||
|
||||
@@ -104,3 +104,10 @@
|
||||
desc = "An eyepatch that connects itself to your eye socket, enhancing your shooting to an impossible degree, allowing your bullets to ricochet far more often than usual."
|
||||
item = /obj/item/clothing/glasses/eyepatch/syndicate
|
||||
cost = 8
|
||||
|
||||
/datum/uplink_item/device_tools/ablative_armwraps
|
||||
name = "Ablative Armwraps"
|
||||
desc = "A pair of highly reinforced armwraps allowing the user to parry almost anything. Fully reflects projectiles, no downsides to failing, but is very hard to parry melee with."
|
||||
cost = 6
|
||||
item = /obj/item/clothing/gloves/fingerless/ablative
|
||||
exclude_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
along with slurred speech, aggression, and the ability to infect others with this agent."
|
||||
item = /obj/item/storage/box/syndie_kit/romerol
|
||||
cost = 25
|
||||
player_minimum = 25
|
||||
cant_discount = TRUE
|
||||
exclude_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
|
||||
@@ -31,7 +31,10 @@
|
||||
/obj/item/clothing/under/suit/burgundy = 3,
|
||||
/obj/item/clothing/under/suit/charcoal = 3,
|
||||
/obj/item/clothing/under/suit/white = 3,
|
||||
/obj/item/clothing/under/suit/tan = 3,
|
||||
/obj/item/clothing/under/suit/charismatic_suit = 3,
|
||||
/obj/item/clothing/under/costume/kilt = 3,
|
||||
/obj/item/clothing/suit/suspenders = 3,
|
||||
/obj/item/clothing/under/misc/overalls = 3,
|
||||
/obj/item/clothing/under/suit/sl = 3,
|
||||
/obj/item/clothing/accessory/sweater = 3,
|
||||
@@ -70,6 +73,7 @@
|
||||
/obj/item/clothing/accessory/suitjacket/burgundy = 2,
|
||||
/obj/item/clothing/accessory/suitjacket/checkered = 2,
|
||||
/obj/item/clothing/suit/jacket/miljacket = 5,
|
||||
/obj/item/clothing/suit/jacket/urbanjacket = 5,
|
||||
/obj/item/clothing/under/suit/white_on_white/skirt = 2,
|
||||
/obj/item/clothing/under/rank/captain/suit/skirt = 2,
|
||||
/obj/item/clothing/under/rank/civilian/head_of_personnel/suit/skirt = 2,
|
||||
|
||||
@@ -207,6 +207,7 @@
|
||||
product_ads = "You turn me TRUE, use defines!;0110001101101100011011110111010001101000011001010111001101101000011001010111001001100101"
|
||||
vend_reply = "Thank you for using the RoboDrobe!"
|
||||
products = list(/obj/item/clothing/glasses/hud/diagnostic = 3,
|
||||
/obj/item/stack/medical/nanogel = 5,
|
||||
/obj/item/clothing/head/beret/robo = 3,
|
||||
/obj/item/clothing/under/rank/rnd/roboticist = 3,
|
||||
/obj/item/clothing/under/rank/rnd/roboticist/sleek = 3,
|
||||
|
||||
@@ -675,3 +675,6 @@ TURF_DIRT_THRESHOLD 100
|
||||
|
||||
## Default alpha of dirt on spawn
|
||||
DIRT_ALPHA_STARTING 127
|
||||
|
||||
## Allows pAI custom holoforms
|
||||
PAI_CUSTOM_HOLOFORMS
|
||||
|
||||
@@ -50,6 +50,149 @@
|
||||
-->
|
||||
<div class="commit sansserif">
|
||||
|
||||
<h2 class="date">12 February 2021</h2>
|
||||
<h3 class="author">Hatterhat updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="balance">The ATVs on SnowCabin.dmm have been replaced with snowmobiles.</li>
|
||||
</ul>
|
||||
<h3 class="author">MrJWhit updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Random deltastation fixes.</li>
|
||||
<li class="tweak">Gives boxstation vault door actual vault door access</li>
|
||||
</ul>
|
||||
<h3 class="author">silicons updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="balance">Voice of God - sleep removed, stun staggers instead, knockdown is faster but does not do stamina damage, vomit is faster but doesn't stun</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">11 February 2021</h2>
|
||||
<h3 class="author">Adelphon updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Charismatic Suit</li>
|
||||
<li class="rscadd">Urban Jacket</li>
|
||||
</ul>
|
||||
<h3 class="author">DeltaFire15 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Added nanogel to the robodrobe.</li>
|
||||
</ul>
|
||||
<h3 class="author">Putnam3145 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Config to keep unreadied players from mode voting</li>
|
||||
</ul>
|
||||
<h3 class="author">dzahlus updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">fixes grenadelaunch.ogg being used where it shouldn't and makes mech weapons use correct sound</li>
|
||||
</ul>
|
||||
<h3 class="author">keronshb updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="balance">10 > 30 second for Warp Implant cooldown</li>
|
||||
<li class="rscdel">Comments out power sink objective.</li>
|
||||
</ul>
|
||||
<h3 class="author">timothyteakettle updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">persistent blood should stop being invisible and alt clicking it shouldn't return the entire spritesheet</li>
|
||||
<li class="admin">pickpocketing is now logged using log_combat</li>
|
||||
</ul>
|
||||
<h3 class="author">zeroisthebiggay updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">the aesthetic sterile mask no longer hides faces so you can cosplay egirls and keep flavortexts</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">09 February 2021</h2>
|
||||
<h3 class="author">Chiirno updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Adds clown waddle to clown shoes. Enhanced Clown Waddle Dampeners can be engaged in-hand with ctrl+click, _but why would you?_</li>
|
||||
</ul>
|
||||
<h3 class="author">MrJWhit updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Re-adds theater disposal outlet, and makes dorms disposal able to have things sent to it on boxstation.</li>
|
||||
</ul>
|
||||
<h3 class="author">TyrianTyrell updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">made default tongue able to speak signed language.</li>
|
||||
</ul>
|
||||
<h3 class="author">timothyteakettle updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="balance">sentient viruses can now infect synths and ipcs</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">07 February 2021</h2>
|
||||
<h3 class="author">Thalpy updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="refactor">Dispenser: Adds the ability to store a small amount of reagents in the machine itself for dispensing. Reacting recipies cannot be stored. Size of storage increases with bin size.</li>
|
||||
<li class="refactor">Dispenser: Allows reagents to be color coded by pH</li>
|
||||
<li class="refactor">Dispenser: Each reagent displays it's pH on hover</li>
|
||||
<li class="refactor">Dispenser: Allows the user to toggle between buttons and a radial dial</li>
|
||||
<li class="refactor">Dispenser: When the dispencer is upgraded it can dispense 5/3/2/1 volumes based on rating refactor: Dispenser: as it was before. This does not break recorded recipes.</li>
|
||||
<li class="tweak">Adds a round function to some numbers so they're not huge</li>
|
||||
<li class="tweak">The Chem master can now get purity for all reagents when analysed</li>
|
||||
<li class="bugfix">Synthissue fixes</li>
|
||||
<li class="tweak">buffers now have a strong and weak variant. Weak can be dispensed, and strong can be created. Strong buffers are 6x more effective.</li>
|
||||
<li class="bugfix">Some buffer pH edge calculation fixes</li>
|
||||
</ul>
|
||||
<h3 class="author">TyrianTyrell updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">added a signed language, that can't be used over the radio but can be used if you're mute. also added the multilingual trait.</li>
|
||||
<li class="imageadd">hopefully added an icon for the signed language.</li>
|
||||
<li class="code_imp">changed how some traits function slightly.</li>
|
||||
</ul>
|
||||
<h3 class="author">dzahlus updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">tweaked a few sounds</li>
|
||||
<li class="soundadd">added a new weapon sounds</li>
|
||||
<li class="sounddel">removed old weapon sounds</li>
|
||||
<li class="code_imp">changed some sound related code</li>
|
||||
</ul>
|
||||
<h3 class="author">silicons updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">syndicate ablative armwraps have been added.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">05 February 2021</h2>
|
||||
<h3 class="author">SmArtKar updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">The orbit menu now has an Auto-Observe button! No more sifting through the lame observe menu to snoop in people's backpacks! Also, orbit menu now refreshes.</li>
|
||||
<li class="bugfix">KAs are no longer getting broken when fired by a circuit</li>
|
||||
</ul>
|
||||
<h3 class="author">keronshb updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="balance">Force and damage > 15 from 18/25</li>
|
||||
<li class="balance">Knockdown put down to 5 from 30</li>
|
||||
<li class="balance">Armor pen down to 10 from 100.</li>
|
||||
<li class="balance">Makes cell chargers, charge faster.</li>
|
||||
</ul>
|
||||
<h3 class="author">raspy-on-osu updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">alien royals can no longer ventcrawl</li>
|
||||
</ul>
|
||||
<h3 class="author">shellspeed1 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="balance">There actually needs to be people for zombies to happen now.</li>
|
||||
</ul>
|
||||
<h3 class="author">timothyteakettle updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">dwarf facial hair is no longer randomised</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">03 February 2021</h2>
|
||||
<h3 class="author">Hatterhat updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">The green energy sabre's sprite now respects proper handedness.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">02 February 2021</h2>
|
||||
<h3 class="author">silicons updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">pais can now be carried around piggybacking/fireman</li>
|
||||
<li class="balance">Meth and Nuka Cola once again, speed you up.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">31 January 2021</h2>
|
||||
<h3 class="author">Putnam3145 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="balance">fermichem explosion EMPs don't cover the entire station</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">30 January 2021</h2>
|
||||
<h3 class="author">timothyteakettle updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
|
||||
@@ -28358,3 +28358,99 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
|
||||
zeroisthebiggay:
|
||||
- rscadd: some more FUCKING hairs
|
||||
- imageadd: uncodersprites the advanced extinguisher
|
||||
2021-01-31:
|
||||
Putnam3145:
|
||||
- balance: fermichem explosion EMPs don't cover the entire station
|
||||
2021-02-02:
|
||||
silicons:
|
||||
- rscadd: pais can now be carried around piggybacking/fireman
|
||||
- balance: Meth and Nuka Cola once again, speed you up.
|
||||
2021-02-03:
|
||||
Hatterhat:
|
||||
- bugfix: The green energy sabre's sprite now respects proper handedness.
|
||||
2021-02-05:
|
||||
SmArtKar:
|
||||
- rscadd: The orbit menu now has an Auto-Observe button! No more sifting through
|
||||
the lame observe menu to snoop in people's backpacks! Also, orbit menu now refreshes.
|
||||
- bugfix: KAs are no longer getting broken when fired by a circuit
|
||||
keronshb:
|
||||
- balance: Force and damage > 15 from 18/25
|
||||
- balance: Knockdown put down to 5 from 30
|
||||
- balance: Armor pen down to 10 from 100.
|
||||
- balance: Makes cell chargers, charge faster.
|
||||
raspy-on-osu:
|
||||
- bugfix: alien royals can no longer ventcrawl
|
||||
shellspeed1:
|
||||
- balance: There actually needs to be people for zombies to happen now.
|
||||
timothyteakettle:
|
||||
- rscadd: dwarf facial hair is no longer randomised
|
||||
2021-02-07:
|
||||
Thalpy:
|
||||
- refactor: 'Dispenser: Adds the ability to store a small amount of reagents in
|
||||
the machine itself for dispensing. Reacting recipies cannot be stored. Size
|
||||
of storage increases with bin size.'
|
||||
- refactor: 'Dispenser: Allows reagents to be color coded by pH'
|
||||
- refactor: 'Dispenser: Each reagent displays it''s pH on hover'
|
||||
- refactor: 'Dispenser: Allows the user to toggle between buttons and a radial dial'
|
||||
- refactor: 'Dispenser: When the dispencer is upgraded it can dispense 5/3/2/1 volumes
|
||||
based on rating refactor: Dispenser: as it was before. This does not break recorded
|
||||
recipes.'
|
||||
- tweak: Adds a round function to some numbers so they're not huge
|
||||
- tweak: The Chem master can now get purity for all reagents when analysed
|
||||
- bugfix: Synthissue fixes
|
||||
- tweak: buffers now have a strong and weak variant. Weak can be dispensed, and
|
||||
strong can be created. Strong buffers are 6x more effective.
|
||||
- bugfix: Some buffer pH edge calculation fixes
|
||||
TyrianTyrell:
|
||||
- rscadd: added a signed language, that can't be used over the radio but can be
|
||||
used if you're mute. also added the multilingual trait.
|
||||
- imageadd: hopefully added an icon for the signed language.
|
||||
- code_imp: changed how some traits function slightly.
|
||||
dzahlus:
|
||||
- tweak: tweaked a few sounds
|
||||
- soundadd: added a new weapon sounds
|
||||
- sounddel: removed old weapon sounds
|
||||
- code_imp: changed some sound related code
|
||||
silicons:
|
||||
- rscadd: syndicate ablative armwraps have been added.
|
||||
2021-02-09:
|
||||
Chiirno:
|
||||
- rscadd: Adds clown waddle to clown shoes. Enhanced Clown Waddle Dampeners can
|
||||
be engaged in-hand with ctrl+click, _but why would you?_
|
||||
MrJWhit:
|
||||
- rscadd: Re-adds theater disposal outlet, and makes dorms disposal able to have
|
||||
things sent to it on boxstation.
|
||||
TyrianTyrell:
|
||||
- bugfix: made default tongue able to speak signed language.
|
||||
timothyteakettle:
|
||||
- balance: sentient viruses can now infect synths and ipcs
|
||||
2021-02-11:
|
||||
Adelphon:
|
||||
- rscadd: Charismatic Suit
|
||||
- rscadd: Urban Jacket
|
||||
DeltaFire15:
|
||||
- tweak: Added nanogel to the robodrobe.
|
||||
Putnam3145:
|
||||
- rscadd: Config to keep unreadied players from mode voting
|
||||
dzahlus:
|
||||
- bugfix: fixes grenadelaunch.ogg being used where it shouldn't and makes mech weapons
|
||||
use correct sound
|
||||
keronshb:
|
||||
- balance: 10 > 30 second for Warp Implant cooldown
|
||||
- rscdel: Comments out power sink objective.
|
||||
timothyteakettle:
|
||||
- bugfix: persistent blood should stop being invisible and alt clicking it shouldn't
|
||||
return the entire spritesheet
|
||||
- admin: pickpocketing is now logged using log_combat
|
||||
zeroisthebiggay:
|
||||
- tweak: the aesthetic sterile mask no longer hides faces so you can cosplay egirls
|
||||
and keep flavortexts
|
||||
2021-02-12:
|
||||
Hatterhat:
|
||||
- balance: The ATVs on SnowCabin.dmm have been replaced with snowmobiles.
|
||||
MrJWhit:
|
||||
- tweak: Random deltastation fixes.
|
||||
- tweak: Gives boxstation vault door actual vault door access
|
||||
silicons:
|
||||
- balance: Voice of God - sleep removed, stun staggers instead, knockdown is faster
|
||||
but does not do stamina damage, vomit is faster but doesn't stun
|
||||
|
||||
4
html/changelogs/AutoChangeLog-pr-14166.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
author: "Hatterhat"
|
||||
delete-after: True
|
||||
changes:
|
||||
- balance: "Energy bolas now take 2.5 seconds to remove and dissipate on removal."
|
||||
4
html/changelogs/AutoChangeLog-pr-14223.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
author: "timothyteakettle"
|
||||
delete-after: True
|
||||
changes:
|
||||
- admin: "migration error to version 39+ of savefiles is now logged instead of messaging all online admins in the chat"
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 444 KiB After Width: | Height: | Size: 460 KiB |
|
Before Width: | Height: | Size: 454 KiB After Width: | Height: | Size: 455 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 125 KiB |
@@ -537,4 +537,9 @@
|
||||
path = /obj/item/clothing/suit/custom/exo
|
||||
ckeywhitelist = list("jesterz7")
|
||||
|
||||
/datum/gear/donator/choker
|
||||
name = "NT Choker"
|
||||
slot = SLOT_NECK
|
||||
path = /obj/item/clothing/neck/petcollar/choker
|
||||
ckeywhitelist = list("trigillass")
|
||||
|
||||
|
||||
@@ -159,6 +159,11 @@
|
||||
path = /obj/item/clothing/suit/jacket/miljacket
|
||||
subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS
|
||||
|
||||
/datum/gear/suit/urbanjacket
|
||||
name = "Urban Jacket"
|
||||
path = /obj/item/clothing/suit/jacket/urbanjacket
|
||||
subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS
|
||||
|
||||
/datum/gear/suit/ianshirt
|
||||
name = "Ian Shirt"
|
||||
path = /obj/item/clothing/suit/ianshirt
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
name = "Tan suit"
|
||||
path = /obj/item/clothing/under/suit/tan
|
||||
|
||||
/datum/gear/uniform/suit/charismatic_suit
|
||||
name = "Charismatic suit"
|
||||
path = /obj/item/clothing/under/suit/charismatic_suit
|
||||
|
||||
/datum/gear/uniform/suit/white
|
||||
name = "White suit"
|
||||
path = /obj/item/clothing/under/suit/white
|
||||
|
||||
@@ -585,3 +585,12 @@
|
||||
icon = 'icons/obj/custom.dmi'
|
||||
mob_overlay_icon = 'icons/mob/clothing/custom_w.dmi'
|
||||
mutantrace_variation = NONE
|
||||
|
||||
/obj/item/clothing/neck/petcollar/choker
|
||||
name = "NT Choker"
|
||||
desc = "NT property since January 21st, 2562."
|
||||
icon = 'icons/obj/custom.dmi'
|
||||
icon_state = "choker"
|
||||
mob_overlay_icon = 'icons/mob/clothing/custom_w.dmi'
|
||||
item_state = "choker"
|
||||
tagname = null
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
item_state = "arg"
|
||||
slot_flags = 0
|
||||
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'
|
||||
fire_sound = 'sound/weapons/rifleshot.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 6 //in line with XCOMEU stats. This can fire 5 bursts from a full magazine.
|
||||
fire_delay = 1
|
||||
@@ -85,23 +85,20 @@
|
||||
|
||||
///projectiles///
|
||||
|
||||
/obj/item/projectile/bullet/cflechetteap //shreds armor
|
||||
/obj/item/projectile/bullet/cflechetteap //shreds armor but no wounds
|
||||
name = "flechette (armor piercing)"
|
||||
damage = 8
|
||||
armour_penetration = 80
|
||||
damage = 15
|
||||
armour_penetration = 100
|
||||
wound_bonus = -100
|
||||
|
||||
/obj/item/projectile/bullet/cflechettes //shreds flesh and forces bleeding
|
||||
/obj/item/projectile/bullet/cflechettes //causes wounds fast but is heavily countered by armor
|
||||
name = "flechette (serrated)"
|
||||
damage = 15
|
||||
dismemberment = 10
|
||||
armour_penetration = -80
|
||||
|
||||
/obj/item/projectile/bullet/cflechettes/on_hit(atom/target, blocked = FALSE)
|
||||
if((blocked != 100) && iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
C.bleed(10)
|
||||
return ..()
|
||||
|
||||
wound_bonus = 15
|
||||
sharpness = SHARP_EDGED
|
||||
wound_falloff_tile = 0
|
||||
|
||||
///ammo casings (CASELESS AMMO CASINGS WOOOOOOOO)///
|
||||
|
||||
/obj/item/ammo_casing/caseless/flechetteap
|
||||
@@ -148,7 +145,7 @@
|
||||
slot_flags = 0
|
||||
pin = /obj/item/firing_pin/implant/pindicate
|
||||
mag_type = /obj/item/ammo_box/magazine/flechette
|
||||
fire_sound = 'sound/weapons/gunshot_smg.ogg'
|
||||
fire_sound = 'sound/weapons/rifleshot.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 5
|
||||
fire_delay = 1
|
||||
@@ -168,15 +165,19 @@
|
||||
|
||||
///unique variant///
|
||||
|
||||
/obj/item/projectile/bullet/cflechetteshredder
|
||||
/obj/item/projectile/bullet/cflechetteshredder //you only get this with a 30TC bundle,5 magazines, as such this should be the superior ammotype
|
||||
name = "flechette (shredder)"
|
||||
damage = 5
|
||||
dismemberment = 40
|
||||
damage = 10
|
||||
dismemberment = 50
|
||||
wound_bonus = 50
|
||||
armour_penetration = 100
|
||||
sharpness = SHARP_EDGED
|
||||
wound_falloff_tile = 0
|
||||
|
||||
/obj/item/ammo_casing/caseless/flechetteshredder
|
||||
name = "flechette (shredder)"
|
||||
desc = "A serrated flechette made of a special alloy that forms a monofilament edge."
|
||||
projectile_type = /obj/item/projectile/bullet/cflechettes
|
||||
projectile_type = /obj/item/projectile/bullet/cflechetteshredder
|
||||
|
||||
/obj/item/ammo_box/magazine/flechette/shredder
|
||||
name = "flechette magazine (shredder)"
|
||||
@@ -185,7 +186,7 @@
|
||||
|
||||
/obj/item/gun/ballistic/automatic/flechette/shredder
|
||||
name = "\improper CX Shredder"
|
||||
desc = "A flechette launching machine pistol made of ultra-light CFRP optimized for firing serrated monofillament flechettes."
|
||||
desc = "A flechette launching machine pistol made of ultra-light CFRP optimized for firing serrated monofilament flechettes."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
spread = 15
|
||||
recoil = 0.1
|
||||
|
||||
@@ -334,39 +334,75 @@
|
||||
holder.clear_reagents()
|
||||
|
||||
/datum/reagent/fermi/acidic_buffer
|
||||
name = "Acidic buffer"
|
||||
name = "Strong acidic buffer"
|
||||
description = "This reagent will consume itself and move the pH of a beaker towards acidity when added to another."
|
||||
color = "#fbc314"
|
||||
pH = 0
|
||||
chemical_flags = REAGENT_FORCEONNEW
|
||||
can_synth = TRUE
|
||||
var/strength = 1.5
|
||||
|
||||
//Consumes self on addition and shifts pH
|
||||
/datum/reagent/fermi/acidic_buffer/on_new(datapH)
|
||||
if(!holder)
|
||||
return ..()
|
||||
if(holder.reagents_holder_flags & NO_REACT)
|
||||
return..()
|
||||
if(holder.has_reagent(/datum/reagent/stabilizing_agent))
|
||||
return ..()
|
||||
data = datapH
|
||||
if(LAZYLEN(holder.reagent_list) == 1)
|
||||
return ..()
|
||||
holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume))
|
||||
if(holder.pH < pH)
|
||||
holder.my_atom.visible_message("<span class='warning'>The beaker fizzes as the buffer is added, to no effect.</b></span>")
|
||||
playsound(holder.my_atom, 'sound/FermiChem/bufferadd.ogg', 50, 1)
|
||||
return ..()
|
||||
holder.pH = clamp((((holder.pH * (holder.total_volume-(volume*strength)))+(pH * (volume*strength)) )/holder.total_volume), 0, 14) //This is BEFORE removal
|
||||
holder.my_atom.visible_message("<span class='warning'>The beaker fizzes as the pH changes!</b></span>")
|
||||
playsound(holder.my_atom, 'sound/FermiChem/bufferadd.ogg', 50, 1)
|
||||
holder.remove_reagent(type, volume, ignore_pH = TRUE)
|
||||
..()
|
||||
|
||||
/datum/reagent/fermi/acidic_buffer/weak
|
||||
name = "Acidic buffer"
|
||||
description = "This reagent will consume itself and move the pH of a beaker towards acidity when added to another."
|
||||
color = "#fbf344"
|
||||
pH = 4
|
||||
can_synth = TRUE
|
||||
strength = 0.25
|
||||
|
||||
/datum/reagent/fermi/basic_buffer
|
||||
name = "Basic buffer"
|
||||
name = "Strong basic buffer"
|
||||
description = "This reagent will consume itself and move the pH of a beaker towards alkalinity when added to another."
|
||||
color = "#3853a4"
|
||||
pH = 14
|
||||
chemical_flags = REAGENT_FORCEONNEW
|
||||
can_synth = TRUE
|
||||
var/strength = 1.5
|
||||
|
||||
/datum/reagent/fermi/basic_buffer/weak
|
||||
name = "Basic buffer"
|
||||
description = "This reagent will consume itself and move the pH of a beaker towards alkalinity when added to another."
|
||||
color = "#5873c4"
|
||||
pH = 10
|
||||
can_synth = TRUE
|
||||
strength = 0.25
|
||||
|
||||
/datum/reagent/fermi/basic_buffer/on_new(datapH)
|
||||
if(!holder)
|
||||
return ..()
|
||||
if(holder.reagents_holder_flags & NO_REACT)
|
||||
return..()
|
||||
if(holder.has_reagent(/datum/reagent/stabilizing_agent))
|
||||
return ..()
|
||||
data = datapH
|
||||
if(LAZYLEN(holder.reagent_list) == 1)
|
||||
return ..()
|
||||
holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume))
|
||||
if(holder.pH > pH)
|
||||
holder.my_atom.visible_message("<span class='warning'>The beaker froths as the buffer is added, to no effect.</b></span>")
|
||||
playsound(holder.my_atom, 'sound/FermiChem/bufferadd.ogg', 50, 1)
|
||||
return ..()
|
||||
holder.pH = clamp((((holder.pH * (holder.total_volume-(volume*strength)))+(pH * (volume*strength)) )/holder.total_volume), 0, 14) //This is BEFORE removal
|
||||
holder.my_atom.visible_message("<span class='warning'>The beaker froths as the pH changes!</b></span>")
|
||||
playsound(holder.my_atom, 'sound/FermiChem/bufferadd.ogg', 50, 1)
|
||||
holder.remove_reagent(type, volume, ignore_pH = TRUE)
|
||||
|
||||
@@ -93,9 +93,8 @@
|
||||
e.set_up(round((volume/28)*(pH-9)), T, 0, 0)
|
||||
e.start()
|
||||
|
||||
if(!ImpureTot == 0) //If impure, v.small emp (0.6 or less)
|
||||
ImpureTot *= volume
|
||||
empulse(T, volume, 1)
|
||||
if(ImpureTot) //If impure, v.small emp (0.6 or less)
|
||||
empulse(T, ImpureTot, 1)
|
||||
|
||||
my_atom.reagents.clear_reagents() //just in case
|
||||
return
|
||||
|
||||