Merge remote-tracking branch 'upstream/master' into Lambdastation

This commit is contained in:
Dap
2020-03-21 19:09:50 -06:00
118 changed files with 6740 additions and 4750 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+3
View File
@@ -1,3 +1,6 @@
#define TRAITOR_HUMAN /datum/traitor_class/human/freeform
#define TRAITOR_AI /datum/traitor_class/ai
#define NUKE_RESULT_FLUKE 0 #define NUKE_RESULT_FLUKE 0
#define NUKE_RESULT_NUKE_WIN 1 #define NUKE_RESULT_NUKE_WIN 1
#define NUKE_RESULT_CREW_WIN 2 #define NUKE_RESULT_CREW_WIN 2
+1 -1
View File
@@ -425,7 +425,7 @@
candidates -= M candidates -= M
/proc/pollGhostCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE) /proc/pollGhostCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE)
var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility) var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(list(/datum/element/ghost_role_eligibility))
var/list/candidates = eligibility.get_all_ghost_role_eligible() var/list/candidates = eligibility.get_all_ghost_role_eligible()
return pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category, flashwindow, candidates) return pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category, flashwindow, candidates)
+3 -1
View File
@@ -1426,7 +1426,9 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
/proc/get_random_drink() /proc/get_random_drink()
var/list/blocked = list(/obj/item/reagent_containers/food/drinks/soda_cans, var/list/blocked = list(/obj/item/reagent_containers/food/drinks/soda_cans,
/obj/item/reagent_containers/food/drinks/bottle /obj/item/reagent_containers/food/drinks/bottle,
/obj/item/reagent_containers/food/drinks/flask/russian,
/obj/item/reagent_containers/food/drinks/flask/steel
) )
return pick(subtypesof(/obj/item/reagent_containers/food/drinks) - blocked) return pick(subtypesof(/obj/item/reagent_containers/food/drinks) - blocked)
+1 -1
View File
@@ -103,7 +103,7 @@ SUBSYSTEM_DEF(jukeboxes)
for(var/mob/M in GLOB.player_list) for(var/mob/M in GLOB.player_list)
if(!M.client) if(!M.client)
continue continue
if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS)) if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS) || !M.can_hear())
M.stop_sound_channel(jukeinfo[2]) M.stop_sound_channel(jukeinfo[2])
continue continue
@@ -85,7 +85,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
our_quirks -= i our_quirks -= i
cut += i cut += i
pointscut += quirk_points_by_name(i) pointscut += quirk_points_by_name(i)
if (pointscut >= 0) //with how it works, it needs to be above zero, not below, as points for positive is positive, and negative is negative, we only want it to break if it's above zero, ie. we cut more positive than negative if (pointscut >= 0)
break break
/* //Code to automatically reduce positive quirks until balance is even. /* //Code to automatically reduce positive quirks until balance is even.
var/points_used = total_points(our_quirks) var/points_used = total_points(our_quirks)
@@ -102,7 +102,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
*/ */
//Nah, let's null all non-neutrals out. //Nah, let's null all non-neutrals out.
if (pointscut != 0)// only if the pointscutting didn't work. if (pointscut < 0)// only if the pointscutting didn't work.
if(cut.len) if(cut.len)
for(var/i in our_quirks) for(var/i in our_quirks)
if(quirk_points_by_name(i) != 0) if(quirk_points_by_name(i) != 0)
+1 -1
View File
@@ -443,7 +443,7 @@ SUBSYSTEM_DEF(vote)
var/admin = FALSE var/admin = FALSE
var/ckey = ckey(initiator_key) var/ckey = ckey(initiator_key)
if(GLOB.admin_datums[ckey]) if(GLOB.admin_datums[ckey] || initiator_key == "server")
admin = TRUE admin = TRUE
if(next_allowed_time > world.time && !admin) if(next_allowed_time > world.time && !admin)
+2 -1
View File
@@ -83,6 +83,7 @@
elements.Cut() elements.Cut()
/datum/beam/Destroy() /datum/beam/Destroy()
finished = TRUE
Reset() Reset()
target = null target = null
origin = null origin = null
@@ -100,7 +101,7 @@
var/length = round(sqrt((DX)**2+(DY)**2)) //hypotenuse of the triangle formed by target and origin's displacement var/length = round(sqrt((DX)**2+(DY)**2)) //hypotenuse of the triangle formed by target and origin's displacement
for(N in 0 to length-1 step 32)//-1 as we want < not <=, but we want the speed of X in Y to Z and step X for(N in 0 to length-1 step 32)//-1 as we want < not <=, but we want the speed of X in Y to Z and step X
if(QDELETED(src) || finished) if(finished)
break break
var/obj/effect/ebeam/X = new beam_type(origin_oldloc) var/obj/effect/ebeam/X = new beam_type(origin_oldloc)
X.owner = src X.owner = src
@@ -107,7 +107,7 @@
/obj/item/stack/cable_coil = 5) /obj/item/stack/cable_coil = 5)
category = CAT_CLOTHING category = CAT_CLOTHING
/datum/crafting_recipe/diagnostic_singlasses_removal /datum/crafting_recipe/diagnostic_sunglasses_removal
name = "Diagnostic HUDsunglasses removal" name = "Diagnostic HUDsunglasses removal"
result = /obj/item/clothing/glasses/sunglasses result = /obj/item/clothing/glasses/sunglasses
time = 20 time = 20
@@ -126,6 +126,85 @@
/obj/item/stack/cable_coil = 5) /obj/item/stack/cable_coil = 5)
category = CAT_CLOTHING category = CAT_CLOTHING
*/ */
// Eyepatch Glasses
/datum/crafting_recipe/secpatch
name = "Security Eyepatch HUD"
result = /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
parts = list(/obj/item/clothing/glasses/hud/security/sunglasses = 1,
/obj/item/clothing/glasses/eyepatch = 1)
reqs = list(/obj/item/clothing/glasses/hud/security/sunglasses = 1,
/obj/item/clothing/glasses/eyepatch = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/secpatch_removal
name = "Security HUDpatch Removal"
result = /obj/item/clothing/glasses/eyepatch
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
reqs = list(/obj/item/clothing/glasses/hud/security/sunglasses/eyepatch = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/medpatch
name = "Medical Eyepatch HUD"
result = /obj/item/clothing/glasses/hud/health/eyepatch
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
parts = list(/obj/item/clothing/glasses/hud/health = 1,
/obj/item/clothing/glasses/eyepatch = 1)
reqs = list(/obj/item/clothing/glasses/hud/health = 1,
/obj/item/clothing/glasses/eyepatch = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/medpatch_removal
name = "Medical HUDpatch Removal"
result = /obj/item/clothing/glasses/eyepatch
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
reqs = list(/obj/item/clothing/glasses/hud/health/eyepatch = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/diagpatch
name = "Diagnostic Eyepatch HUD"
result = /obj/item/clothing/glasses/hud/diagnostic/eyepatch
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
parts = list(/obj/item/clothing/glasses/hud/diagnostic = 1,
/obj/item/clothing/glasses/eyepatch = 1)
reqs = list(/obj/item/clothing/glasses/hud/diagnostic = 1,
/obj/item/clothing/glasses/eyepatch = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/diagpatch_removal
name = "Diagnostic HUDpatch Removal"
result = /obj/item/clothing/glasses/eyepatch
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
reqs = list(/obj/item/clothing/glasses/hud/diagnostic/eyepatch = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/mesonpatch
name = "Meson Scanner Eyepatch"
result = /obj/item/clothing/glasses/meson/eyepatch
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
parts = list(/obj/item/clothing/glasses/meson = 1,
/obj/item/clothing/glasses/eyepatch = 1)
reqs = list(/obj/item/clothing/glasses/meson = 1,
/obj/item/clothing/glasses/eyepatch = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/mesonpatch_removal
name = "Meson Scanner patch Removal"
result = /obj/item/clothing/glasses/eyepatch
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
reqs = list(/obj/item/clothing/glasses/meson/eyepatch = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/ghostsheet /datum/crafting_recipe/ghostsheet
name = "Ghost Sheet" name = "Ghost Sheet"
result = /obj/item/clothing/suit/ghost_sheet result = /obj/item/clothing/suit/ghost_sheet
+6 -2
View File
@@ -28,7 +28,7 @@ GLOBAL_LIST_EMPTY(uplinks)
var/compact_mode = FALSE var/compact_mode = FALSE
var/debug = FALSE var/debug = FALSE
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20, datum/ui_state/_checkstate) /datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20, datum/ui_state/_checkstate, datum/traitor_class/traitor_class)
if(!isitem(parent)) if(!isitem(parent))
return COMPONENT_INCOMPATIBLE return COMPONENT_INCOMPATIBLE
@@ -47,7 +47,11 @@ GLOBAL_LIST_EMPTY(uplinks)
RegisterSignal(parent, COMSIG_PEN_ROTATED, .proc/pen_rotation) RegisterSignal(parent, COMSIG_PEN_ROTATED, .proc/pen_rotation)
GLOB.uplinks += src GLOB.uplinks += src
uplink_items = get_uplink_items(gamemode, TRUE, allow_restricted) var/list/filters = list()
if(istype(traitor_class))
filters = traitor_class.uplink_filters
starting_tc = traitor_class.TC
uplink_items = get_uplink_items(gamemode, TRUE, allow_restricted, filters)
if(_owner) if(_owner)
owner = _owner owner = _owner
+6 -6
View File
@@ -32,16 +32,16 @@
..() ..()
switch(stage) switch(stage)
if(1) if(1)
if (prob(stage_prob) && stage1) if (prob(stage_prob) && length(stage1))
to_chat(affected_mob, pick(stage1)) to_chat(affected_mob, pick(stage1))
if(2) if(2)
if (prob(stage_prob) && stage2) if (prob(stage_prob) && length(stage2))
to_chat(affected_mob, pick(stage2)) to_chat(affected_mob, pick(stage2))
if(3) if(3)
if (prob(stage_prob*2) && stage3) if (prob(stage_prob*2) && length(stage3))
to_chat(affected_mob, pick(stage3)) to_chat(affected_mob, pick(stage3))
if(4) if(4)
if (prob(stage_prob*2) && stage4) if (prob(stage_prob*2) && length(stage4))
to_chat(affected_mob, pick(stage4)) to_chat(affected_mob, pick(stage4))
if(5) if(5)
do_disease_transformation(affected_mob) do_disease_transformation(affected_mob)
@@ -162,7 +162,7 @@
desc = "This disease, actually acute nanomachine infection, converts the victim into a cyborg." desc = "This disease, actually acute nanomachine infection, converts the victim into a cyborg."
severity = DISEASE_SEVERITY_BIOHAZARD severity = DISEASE_SEVERITY_BIOHAZARD
visibility_flags = 0 visibility_flags = 0
stage1 = list() stage1 = null
stage2 = list("Your joints feel stiff.", "<span class='danger'>Beep...boop..</span>") stage2 = list("Your joints feel stiff.", "<span class='danger'>Beep...boop..</span>")
stage3 = list("<span class='danger'>Your joints feel very stiff.</span>", "Your skin feels loose.", "<span class='danger'>You can feel something move...inside.</span>") stage3 = list("<span class='danger'>Your joints feel very stiff.</span>", "Your skin feels loose.", "<span class='danger'>You can feel something move...inside.</span>")
stage4 = list("<span class='danger'>Your skin feels very loose.</span>", "<span class='danger'>You can feel... something...inside you.</span>") stage4 = list("<span class='danger'>Your skin feels very loose.</span>", "<span class='danger'>You can feel... something...inside you.</span>")
@@ -195,7 +195,7 @@
desc = "This disease changes the victim into a xenomorph." desc = "This disease changes the victim into a xenomorph."
severity = DISEASE_SEVERITY_BIOHAZARD severity = DISEASE_SEVERITY_BIOHAZARD
visibility_flags = 0 visibility_flags = 0
stage1 = list() stage1 = null
stage2 = list("Your throat feels scratchy.", "<span class='danger'>Kill...</span>") stage2 = list("Your throat feels scratchy.", "<span class='danger'>Kill...</span>")
stage3 = list("<span class='danger'>Your throat feels very scratchy.</span>", "Your skin feels tight.", "<span class='danger'>You can feel something move...inside.</span>") stage3 = list("<span class='danger'>Your throat feels very scratchy.</span>", "Your skin feels tight.", "<span class='danger'>You can feel something move...inside.</span>")
stage4 = list("<span class='danger'>Your skin feels very tight.</span>", "<span class='danger'>Your blood boils!</span>", "<span class='danger'>You can feel... something...inside you.</span>") stage4 = list("<span class='danger'>Your skin feels very tight.</span>", "<span class='danger'>Your blood boils!</span>", "<span class='danger'>You can feel... something...inside you.</span>")
@@ -42,7 +42,7 @@
return candidates return candidates
/mob/proc/can_reenter_round(silent = FALSE) /mob/proc/can_reenter_round(silent = FALSE)
var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(/datum/element/ghost_role_eligibility) var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(list(/datum/element/ghost_role_eligibility))
return eli.can_reenter_round(src,silent) return eli.can_reenter_round(src,silent)
/datum/element/ghost_role_eligibility/proc/can_reenter_round(var/mob/M,silent = FALSE) /datum/element/ghost_role_eligibility/proc/can_reenter_round(var/mob/M,silent = FALSE)
+8 -6
View File
@@ -256,9 +256,11 @@
remove_rev() remove_rev()
SSticker.mode.update_cult_icons_removed(src) SSticker.mode.update_cult_icons_removed(src)
/datum/mind/proc/equip_traitor(employer = "The Syndicate", silent = FALSE, datum/antagonist/uplink_owner) /datum/mind/proc/equip_traitor(datum/traitor_class/traitor_class, silent = FALSE, datum/antagonist/uplink_owner)
if(!current) if(!current)
return return
if(!traitor_class)
traitor_class = GLOB.traitor_classes[TRAITOR_HUMAN]
var/mob/living/carbon/human/traitor_mob = current var/mob/living/carbon/human/traitor_mob = current
if (!istype(traitor_mob)) if (!istype(traitor_mob))
return return
@@ -306,21 +308,21 @@
if (!uplink_loc) if (!uplink_loc)
if(!silent) if(!silent)
to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.") to_chat(traitor_mob, "Unfortunately, [traitor_class.employer] wasn't able to get you an Uplink.")
. = 0 . = 0
else else
. = uplink_loc . = uplink_loc
var/datum/component/uplink/U = uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key) var/datum/component/uplink/U = uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key,traitor_class)
if(!U) if(!U)
CRASH("Uplink creation failed.") CRASH("Uplink creation failed.")
U.setup_unlock_code() U.setup_unlock_code()
if(!silent) if(!silent)
if(uplink_loc == R) if(uplink_loc == R)
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(U.unlock_code)] to unlock its hidden features.") to_chat(traitor_mob, "[traitor_class.employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(U.unlock_code)] to unlock its hidden features.")
else if(uplink_loc == PDA) else if(uplink_loc == PDA)
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[U.unlock_code]\" into the ringtone select to unlock its hidden features.") to_chat(traitor_mob, "[traitor_class.employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[U.unlock_code]\" into the ringtone select to unlock its hidden features.")
else if(uplink_loc == P) else if(uplink_loc == P)
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [U.unlock_code] from its starting position to unlock its hidden features.") to_chat(traitor_mob, "[traitor_class.employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [U.unlock_code] from its starting position to unlock its hidden features.")
if(uplink_owner) if(uplink_owner)
uplink_owner.antag_memory += U.unlock_note + "<br>" uplink_owner.antag_memory += U.unlock_note + "<br>"
+1 -1
View File
@@ -40,7 +40,7 @@
name = "Fire Breath" name = "Fire Breath"
desc = "You can breathe fire at a target." desc = "You can breathe fire at a target."
school = "evocation" school = "evocation"
charge_max = 1200 charge_max = 600
clothes_req = FALSE clothes_req = FALSE
range = 20 range = 20
base_icon_state = "fireball" base_icon_state = "fireball"
+2 -2
View File
@@ -108,10 +108,10 @@
var/mob/living/carbon/human/H = quirk_holder var/mob/living/carbon/human/H = quirk_holder
var/obj/item/choice_beacon/music/B = new(get_turf(H)) var/obj/item/choice_beacon/music/B = new(get_turf(H))
H.put_in_hands(B) H.put_in_hands(B)
H.equip_to_slot(B, SLOT_IN_BACKPACK) H.equip_to_slot_if_possible(B, SLOT_IN_BACKPACK)
var/obj/item/musicaltuner/musicaltuner = new(get_turf(H)) var/obj/item/musicaltuner/musicaltuner = new(get_turf(H))
H.put_in_hands(musicaltuner) H.put_in_hands(musicaltuner)
H.equip_to_slot(musicaltuner, SLOT_IN_BACKPACK) H.equip_to_slot_if_possible(musicaltuner, SLOT_IN_BACKPACK)
H.regenerate_icons() H.regenerate_icons()
/datum/quirk/photographer /datum/quirk/photographer
@@ -34,7 +34,7 @@
living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS]) living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS])
living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS]) living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS])
list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS]) list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS])
var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility) var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(list(/datum/element/ghost_role_eligibility))
ghost_eligible = trim_list(eligibility.get_all_ghost_role_eligible()) ghost_eligible = trim_list(eligibility.get_all_ghost_role_eligible())
/datum/dynamic_ruleset/midround/proc/trim_list(list/L = list()) /datum/dynamic_ruleset/midround/proc/trim_list(list/L = list())
@@ -678,5 +678,8 @@
log_game("[key_name(Ninja)] was spawned as a ninja by dynamic.") log_game("[key_name(Ninja)] was spawned as a ninja by dynamic.")
return Ninja return Ninja
/datum/dynamic_ruleset/midround/from_ghosts/ninja/finish_setup(mob/new_character, index)
return
#undef ABDUCTOR_MAX_TEAMS #undef ABDUCTOR_MAX_TEAMS
#undef REVENANT_SPAWN_THRESHOLD #undef REVENANT_SPAWN_THRESHOLD
+6 -1
View File
@@ -1163,12 +1163,17 @@ GLOBAL_LIST_EMPTY(possible_sabotages)
var/payout = 0 var/payout = 0
var/payout_bonus = 0 var/payout_bonus = 0
var/area/dropoff = null var/area/dropoff = null
var/static/list/blacklisted_areas = typecacheof(list(/area/ai_monitored/turret_protected,
/area/solar/,
/area/ruin/, //thank you station space ruins
/area/science/test_area/,
/area/shuttle/))
/datum/objective/contract/proc/generate_dropoff() // Generate a random valid area on the station that the dropoff will happen. /datum/objective/contract/proc/generate_dropoff() // Generate a random valid area on the station that the dropoff will happen.
var/found = FALSE var/found = FALSE
while(!found) while(!found)
var/area/dropoff_area = pick(GLOB.sortedAreas) var/area/dropoff_area = pick(GLOB.sortedAreas)
if(dropoff_area && is_station_level(dropoff_area.z) && !dropoff_area.outdoors && !istype(dropoff_area, /area/shuttle/)) if(dropoff_area && is_station_level(dropoff_area.z) && !dropoff_area.outdoors && !is_type_in_typecache(dropoff_area, blacklisted_areas))
dropoff = dropoff_area dropoff = dropoff_area
found = TRUE found = TRUE
+3 -3
View File
@@ -115,10 +115,10 @@
if(src.allowed(usr)) if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) in GLOB.silicon_mobs var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) in GLOB.silicon_mobs
if(can_control(usr, R)) if(can_control(usr, R))
var/choice = input("Are you certain you wish to [R.locked_down? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort") var/choice = input("Are you certain you wish to [!R.locked_down ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..()) if(choice == "Confirm" && can_control(usr, R) && !..())
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [R.locked_down? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!</span>") message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [!R.locked_down ? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!</span>")
log_game("[key_name(usr)] [R.locked_down? "locked down" : "released"] [key_name(R)]!") log_game("[key_name(usr)] [!R.locked_down ? "locked down" : "released"] [key_name(R)]!")
R.SetLockdown(!R.locked_down) R.SetLockdown(!R.locked_down)
to_chat(R, "[!R.locked_down ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>") to_chat(R, "[!R.locked_down ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
if(R.connected_ai) if(R.connected_ai)
+2 -2
View File
@@ -316,7 +316,7 @@
if("togglemoving") if("togglemoving")
moving = !moving moving = !moving
if(moving) if(moving)
spawn() MagnetMove() INVOKE_ASYNC(src, .proc/MagnetMove)
updateUsrDialog() updateUsrDialog()
@@ -325,7 +325,7 @@
if(looping) if(looping)
return return
while(moving && rpath.len >= 1) while(moving && length(rpath) >= 1)
if(stat & (BROKEN|NOPOWER)) if(stat & (BROKEN|NOPOWER))
break break
@@ -247,6 +247,7 @@
if(prob(70)) if(prob(70))
if(stored_gun) if(stored_gun)
stored_gun.forceMove(loc) stored_gun.forceMove(loc)
stored_gun = null
to_chat(user, "<span class='notice'>You remove the turret and salvage some components.</span>") to_chat(user, "<span class='notice'>You remove the turret and salvage some components.</span>")
if(prob(50)) if(prob(50))
new /obj/item/stack/sheet/metal(loc, rand(1,4)) new /obj/item/stack/sheet/metal(loc, rand(1,4))
+9 -9
View File
@@ -8,7 +8,7 @@
layer = ABOVE_ALL_MOB_LAYER // Overhead layer = ABOVE_ALL_MOB_LAYER // Overhead
density = TRUE density = TRUE
circuit = /obj/item/circuitboard/machine/recycler circuit = /obj/item/circuitboard/machine/recycler
var/safety_mode = FALSE // Temporarily stops machine if it detects a mob var/safety_mode = FALSE // Temporarily stops machine if it detects a mob, or upon deconstruction.
var/icon_name = "grinder-o" var/icon_name = "grinder-o"
var/blood = 0 var/blood = 0
var/eat_dir = WEST var/eat_dir = WEST
@@ -24,6 +24,10 @@
update_icon() update_icon()
req_one_access = get_all_accesses() + get_all_centcom_access() req_one_access = get_all_accesses() + get_all_centcom_access()
/obj/machinery/recycler/deconstruct(disassembled = TRUE)
safety_mode = TRUE //to stop stock parts and circuit from being deleted.
return ..()
/obj/machinery/recycler/RefreshParts() /obj/machinery/recycler/RefreshParts()
var/amt_made = 0 var/amt_made = 0
var/mat_mod = 0 var/mat_mod = 0
@@ -97,18 +101,14 @@
. = ..() . = ..()
/obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE) /obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE)
if(stat & (BROKEN|NOPOWER)) if(stat & (BROKEN|NOPOWER) || safety_mode)
return
if(safety_mode)
return return
var/list/to_eat var/list/to_eat
if(isitem(AM0))
to_eat = AM0.GetAllContentsIgnoring(GLOB.typecache_mob) to_eat = AM0.GetAllContentsIgnoring(GLOB.typecache_mob)
else
to_eat = list(AM0)
var/items_recycled = 0 var/items_recycled = 0
for(var/i in to_eat) for(var/i in to_eat)
var/atom/movable/AM = i var/atom/movable/AM = i
var/obj/item/bodypart/head/as_head = AM var/obj/item/bodypart/head/as_head = AM
+10
View File
@@ -152,6 +152,16 @@
else else
..() ..()
/obj/structure/spider/spiderling/attack_hand(mob/user)
. = ..()
if(user.a_intent != INTENT_HELP)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
user.visible_message("<span class='warning'>[user] splats [src].</span>", "<span class='warning'>You splat [src].</span>", "<span class='italics'>You hear a splat...</span>")
playsound(loc, 'sound/effects/snap.ogg', 25)
qdel(src)
return TRUE
/obj/structure/spider/spiderling/process() /obj/structure/spider/spiderling/process()
if(travelling_in_vent) if(travelling_in_vent)
if(isturf(loc)) if(isturf(loc))
@@ -173,37 +173,6 @@
R.module.basic_modules += S R.module.basic_modules += S
R.module.add_module(S, FALSE, TRUE) R.module.add_module(S, FALSE, TRUE)
/obj/item/borg/upgrade/premiumka
name = "mining cyborg premium KA"
desc = "A premium kinetic accelerator replacement for the mining module's standard kinetic accelerator."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = list(/obj/item/robot_module/miner)
/obj/item/borg/upgrade/premiumka/action(mob/living/silicon/robot/R, user = usr)
. = ..()
if(.)
for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA in R.module)
for(var/obj/item/borg/upgrade/modkit/M in KA.modkits)
M.uninstall(src)
R.module.remove_module(KA, TRUE)
var/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg/PKA = new /obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg(R.module)
R.module.basic_modules += PKA
R.module.add_module(PKA, FALSE, TRUE)
/obj/item/borg/upgrade/premiumka/deactivate(mob/living/silicon/robot/R, user = usr)
. = ..()
if (.)
for(var/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg/PKA in R.module)
for(var/obj/item/borg/upgrade/modkit/M in PKA.modkits)
M.uninstall(src)
R.module.remove_module(PKA, TRUE)
var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA = new (R.module)
R.module.basic_modules += KA
R.module.add_module(KA, FALSE, TRUE)
/obj/item/borg/upgrade/advcutter /obj/item/borg/upgrade/advcutter
name = "mining cyborg advanced plasma cutter" name = "mining cyborg advanced plasma cutter"
@@ -462,7 +431,7 @@
desc = "An upgrade to the Medical module's hypospray, containing \ desc = "An upgrade to the Medical module's hypospray, containing \
stronger versions of existing chemicals." stronger versions of existing chemicals."
additional_reagents = list(/datum/reagent/medicine/oxandrolone, /datum/reagent/medicine/sal_acid, additional_reagents = list(/datum/reagent/medicine/oxandrolone, /datum/reagent/medicine/sal_acid,
/datum/reagent/medicine/rezadone, /datum/reagent/medicine/pen_acid) /datum/reagent/medicine/rezadone, /datum/reagent/medicine/pen_acid, /datum/reagent/medicine/prussian_blue)
/obj/item/borg/upgrade/piercing_hypospray /obj/item/borg/upgrade/piercing_hypospray
name = "cyborg piercing hypospray" name = "cyborg piercing hypospray"
@@ -136,6 +136,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
merge_type = /obj/item/stack/sheet/metal merge_type = /obj/item/stack/sheet/metal
grind_results = list(/datum/reagent/iron = 20) grind_results = list(/datum/reagent/iron = 20)
point_value = 2 point_value = 2
tableVariant = /obj/structure/table
material_type = /datum/material/iron material_type = /datum/material/iron
/obj/item/stack/sheet/metal/ratvar_act() /obj/item/stack/sheet/metal/ratvar_act()
+2 -1
View File
@@ -219,8 +219,9 @@
O = new R.result_type(usr.drop_location()) O = new R.result_type(usr.drop_location())
if(O) if(O)
O.setDir(usr.dir) O.setDir(usr.dir)
log_craft("[O] crafted by [usr] at [loc_name(O.loc)]")
use(R.req_amount * multiplier) use(R.req_amount * multiplier)
log_craft("[O] crafted by [usr] at [loc_name(O.loc)]")
if(R.applies_mats && custom_materials && custom_materials.len) if(R.applies_mats && custom_materials && custom_materials.len)
var/list/used_materials = list() var/list/used_materials = list()
+1 -1
View File
@@ -66,7 +66,7 @@
return return
if(!istype(target)) if(!istype(target))
return return
if(target.anchored) if(target.anchored || (user in target))
return return
if(isitem(target)) if(isitem(target))
+6 -1
View File
@@ -54,7 +54,12 @@
icon_state = "holdingsat" icon_state = "holdingsat"
item_state = "holdingsat" item_state = "holdingsat"
species_exception = list(/datum/species/angel) species_exception = list(/datum/species/angel)
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/backpack/holding/duffel
name = "duffel bag of holding"
desc = "A duffel bag that opens into a localized pocket of Blue Space."
icon_state = "holdingduffel"
item_state = "holdingduffel"
/obj/item/storage/backpack/holding/ComponentInitialize() /obj/item/storage/backpack/holding/ComponentInitialize()
. = ..() . = ..()
+1 -3
View File
@@ -25,7 +25,7 @@
/obj/item/melee/baton/examine(mob/user) /obj/item/melee/baton/examine(mob/user)
. = ..() . = ..()
. += "<span class='notice'>Right click attack while in combat mode or attack while in disarm intent to disarm instead of stun.</span>" . += "<span class='notice'>Right click attack while in combat mode to disarm instead of stun.</span>"
/obj/item/melee/baton/get_cell() /obj/item/melee/baton/get_cell()
. = cell . = cell
@@ -149,8 +149,6 @@
//return TRUE to interrupt attack chain. //return TRUE to interrupt attack chain.
/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE) /obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE)
if(user.a_intent == INTENT_DISARM)
disarming = TRUE //override if they're in disarm intent.
if(iscyborg(M) || !isliving(M)) //can't baton cyborgs if(iscyborg(M) || !isliving(M)) //can't baton cyborgs
return FALSE return FALSE
if(status && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) if(status && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
+3 -3
View File
@@ -1012,7 +1012,7 @@
/obj/item/twohanded/electrostaff /obj/item/twohanded/electrostaff
icon = 'icons/obj/items_and_weapons.dmi' icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "electrostaff_3" icon_state = "electrostaff"
item_state = "electrostaff" item_state = "electrostaff"
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
@@ -1116,10 +1116,10 @@
/obj/item/twohanded/electrostaff/update_icon_state() /obj/item/twohanded/electrostaff/update_icon_state()
. = ..() . = ..()
if(!wielded) if(!wielded)
icon_state = "electrostaff_3" icon_state = "electrostaff"
item_state = "electrostaff" item_state = "electrostaff"
else else
icon_state = item_state = (on? "electrostaff_1" : "electrostaff_3") icon_state = item_state = (on? "electrostaff_1" : "electrostaff_0")
set_light(7, on? 1 : 0, LIGHT_COLOR_CYAN) set_light(7, on? 1 : 0, LIGHT_COLOR_CYAN)
/obj/item/twohanded/electrostaff/examine(mob/living/user) /obj/item/twohanded/electrostaff/examine(mob/living/user)
@@ -59,6 +59,7 @@
new_spawn.real_name = random_unique_lizard_name(gender) new_spawn.real_name = random_unique_lizard_name(gender)
if(is_mining_level(z)) if(is_mining_level(z))
to_chat(new_spawn, "<b>Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Glory to the Necropolis!</b>") to_chat(new_spawn, "<b>Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Glory to the Necropolis!</b>")
to_chat(new_spawn, "<b>You can expand the weather proof area provided by your shelters by using the 'New Area' key near the bottom right of your HUD.</b>")
else else
to_chat(new_spawn, "<span class='userdanger'>You have been born outside of your natural home! Whether you decide to return home, or make due with your new home is your own decision.</span>") to_chat(new_spawn, "<span class='userdanger'>You have been born outside of your natural home! Whether you decide to return home, or make due with your new home is your own decision.</span>")
+2 -1
View File
@@ -70,7 +70,8 @@
/turf/closed/wall/proc/break_wall() /turf/closed/wall/proc/break_wall()
new sheet_type(src, sheet_amount) new sheet_type(src, sheet_amount)
return new girder_type(src) if(girder_type)
return new girder_type(src)
/turf/closed/wall/proc/devastate_wall() /turf/closed/wall/proc/devastate_wall()
new sheet_type(src, sheet_amount) new sheet_type(src, sheet_amount)
+1 -3
View File
@@ -639,15 +639,13 @@
var/almcam = CONFIG_GET(flag/allow_ai_multicam) var/almcam = CONFIG_GET(flag/allow_ai_multicam)
CONFIG_SET(flag/allow_ai_multicam, !almcam) CONFIG_SET(flag/allow_ai_multicam, !almcam)
if (almcam) if (almcam)
to_chat(world, "<B>The AI no longer has multicam.</B>")
for(var/i in GLOB.ai_list) for(var/i in GLOB.ai_list)
var/mob/living/silicon/ai/aiPlayer = i var/mob/living/silicon/ai/aiPlayer = i
if(aiPlayer.multicam_on) if(aiPlayer.multicam_on)
aiPlayer.end_multicam() aiPlayer.end_multicam()
else
to_chat(world, "<B>The AI now has multicam.</B>")
log_admin("[key_name(usr)] toggled AI multicam.") log_admin("[key_name(usr)] toggled AI multicam.")
world.update_status() world.update_status()
to_chat(GLOB.ai_list | GLOB.admins, "<B>The AI [almcam ? "no longer" : "now"] has multicam.</B>")
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Multicam", "[!almcam ? "Disabled" : "Enabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Multicam", "[!almcam ? "Disabled" : "Enabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggleaban() /datum/admins/proc/toggleaban()
+1 -1
View File
@@ -1732,7 +1732,7 @@
var/mob/M = locate(href_list["makeeligible"]) var/mob/M = locate(href_list["makeeligible"])
if(!ismob(M)) if(!ismob(M))
to_chat(usr, "this can only be used on instances of type /mob.") to_chat(usr, "this can only be used on instances of type /mob.")
var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(/datum/element/ghost_role_eligibility) var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(list(/datum/element/ghost_role_eligibility))
if(M.ckey in eli.timeouts) if(M.ckey in eli.timeouts)
eli.timeouts -= M.ckey eli.timeouts -= M.ckey
+3 -3
View File
@@ -1315,15 +1315,15 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/creamy = new(get_turf(target)) var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/creamy = new(get_turf(target))
creamy.splat(target) creamy.splat(target)
if (ADMIN_PUNISHMENT_CUSTOM_PIE) if (ADMIN_PUNISHMENT_CUSTOM_PIE)
var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/A = new(get_turf(target)) var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/A = new()
if(!A.reagents) if(!A.reagents)
var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num|null
if(amount) if(amount)
A.create_reagents(amount) A.create_reagents(amount)
if(A.reagents) if(A.reagents)
var/chosen_id = choose_reagent_id(usr) var/chosen_id = choose_reagent_id(usr)
if(chosen_id) if(chosen_id)
var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num|null
if(amount) if(amount)
A.reagents.add_reagent(chosen_id, amount) A.reagents.add_reagent(chosen_id, amount)
A.splat(target) A.splat(target)
@@ -43,7 +43,7 @@
// EXPLANATION // EXPLANATION
/datum/objective/bloodsucker/lair/update_explanation_text() /datum/objective/bloodsucker/lair/update_explanation_text()
explanation_text = "Create a lair by claiming a coffin, and protect it until the end of the shift"// Make sure to keep it safe!" explanation_text = "Create a lair by claiming a coffin, and protect it until the end of the shift."// Make sure to keep it safe!"
// WIN CONDITIONS? // WIN CONDITIONS?
/datum/objective/bloodsucker/lair/check_completion() /datum/objective/bloodsucker/lair/check_completion()
@@ -250,15 +250,15 @@
// WIN CONDITIONS? // WIN CONDITIONS?
/datum/objective/bloodsucker/heartthief/check_completion() /datum/objective/bloodsucker/heartthief/check_completion()
// -Must have a body. // -Must have a body.
if (!owner.current) if(!owner.current)
return FALSE return FALSE
// Taken from /steal in objective.dm // Taken from /steal in objective.dm
var/list/all_items = owner.current.GetAllContents() // Includes items inside other items. var/list/all_items = owner.current.GetAllContents() // Includes items inside other items.
var/itemcount = FALSE var/itemcount = FALSE
for(var/obj/I in all_items) //Check for items for(var/obj/I in all_items) //Check for items
if(I == /obj/item/organ/heart) if(istype(I, /obj/item/organ/heart/))
itemcount ++ itemcount++
if (itemcount >= target_amount) // Got the right amount? if(itemcount >= target_amount) // Got the right amount?
return TRUE return TRUE
return FALSE return FALSE
@@ -120,7 +120,7 @@
/datum/antagonist/traitor/internal_affairs/reinstate_escape_objective() /datum/antagonist/traitor/internal_affairs/reinstate_escape_objective()
..() ..()
var/objtype = traitor_kind == TRAITOR_HUMAN ? /datum/objective/escape : /datum/objective/survive var/objtype = !istype(traitor_kind,TRAITOR_AI) ? /datum/objective/escape : /datum/objective/survive
var/datum/objective/escape_objective = new objtype var/datum/objective/escape_objective = new objtype
escape_objective.owner = owner escape_objective.owner = owner
add_objective(escape_objective) add_objective(escape_objective)
@@ -215,20 +215,12 @@
kill_objective.target = target_mind kill_objective.target = target_mind
kill_objective.update_explanation_text() kill_objective.update_explanation_text()
add_objective(kill_objective) add_objective(kill_objective)
//Optional traitor objective
if(prob(PROB_ACTUAL_TRAITOR))
employer = "The Syndicate"
owner.special_role = TRAITOR_AGENT_ROLE
special_role = TRAITOR_AGENT_ROLE
syndicate = TRUE
forge_single_objective()
return return
/datum/antagonist/traitor/internal_affairs/forge_traitor_objectives() /datum/antagonist/traitor/internal_affairs/forge_traitor_objectives()
forge_iaa_objectives() forge_iaa_objectives()
var/objtype = traitor_kind == TRAITOR_HUMAN ? /datum/objective/escape : /datum/objective/survive var/objtype = !istype(traitor_kind,TRAITOR_AI) ? /datum/objective/escape : /datum/objective/survive
var/datum/objective/escape_objective = new objtype var/datum/objective/escape_objective = new objtype
escape_objective.owner = owner escape_objective.owner = owner
add_objective(escape_objective) add_objective(escape_objective)
@@ -0,0 +1,68 @@
/datum/traitor_class/ai // this one is special, so has no weight
name = "Malfunctioning AI"
/datum/traitor_class/ai/forge_objectives(datum/antagonist/traitor/T)
var/objective_count = 0
if(prob(30))
objective_count += forge_single_objective()
for(var/i = objective_count, i < CONFIG_GET(number/traitor_objectives_amount), i++)
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = T.owner
kill_objective.find_target()
T.add_objective(kill_objective)
var/datum/objective/survive/exist/exist_objective = new
exist_objective.owner = T.owner
T.add_objective(exist_objective)
/datum/traitor_class/ai/forge_single_objective(datum/antagonist/traitor/T)
.=1
var/special_pick = rand(1,4)
switch(special_pick)
if(1)
var/datum/objective/block/block_objective = new
block_objective.owner = T.owner
T.add_objective(block_objective)
if(2)
var/datum/objective/purge/purge_objective = new
purge_objective.owner = T.owner
T.add_objective(purge_objective)
if(3)
var/datum/objective/robot_army/robot_objective = new
robot_objective.owner = T.owner
T.add_objective(robot_objective)
if(4) //Protect and strand a target
var/datum/objective/protect/yandere_one = new
yandere_one.owner = T.owner
T.add_objective(yandere_one)
yandere_one.find_target()
var/datum/objective/maroon/yandere_two = new
yandere_two.owner = T.owner
yandere_two.target = yandere_one.target
yandere_two.update_explanation_text() // normally called in find_target()
T.add_objective(yandere_two)
.=2
/datum/traitor_class/ai/on_removal(datum/antagonist/traitor/T)
var/mob/living/silicon/ai/A = T.owner.current
A.set_zeroth_law("")
A.verbs -= /mob/living/silicon/ai/proc/choose_modules
A.malf_picker.remove_malf_verbs(A)
qdel(A.malf_picker)
/datum/traitor_class/ai/apply_innate_effects(mob/living/M)
var/mob/living/silicon/ai/A = M
A.hack_software = TRUE
/datum/traitor_class/ai/remove_innate_effects(mob/living/M)
var/mob/living/silicon/ai/A = M
A.hack_software = FALSE
/datum/traitor_class/ai/finalize_traitor(datum/antagonist/traitor/T)
T.add_law_zero()
T.owner.current.playsound_local(get_turf(T.owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE)
T.owner.current.grant_language(/datum/language/codespeak)
return FALSE
@@ -0,0 +1,37 @@
/datum/traitor_class/human/assassin
name = "Donk Co Operative"
employer = "Donk Corporation"
weight = 0
chaos = 1
cost = 2
/datum/traitor_class/human/assassin/forge_single_objective(datum/antagonist/traitor/T)
.=1
var/permakill_prob = 20
var/is_dynamic = FALSE
var/datum/game_mode/dynamic/mode
if(istype(SSticker.mode,/datum/game_mode/dynamic))
mode = SSticker.mode
is_dynamic = TRUE
permakill_prob = max(0,mode.threat_level-50)
var/list/active_ais = active_ais()
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
var/datum/objective/destroy/destroy_objective = new
destroy_objective.owner = T.owner
destroy_objective.find_target()
T.add_objective(destroy_objective)
else if(prob(30) || (is_dynamic && (mode.storyteller.flags & NO_ASSASSIN)))
var/datum/objective/maroon/maroon_objective = new
maroon_objective.owner = T.owner
maroon_objective.find_target()
T.add_objective(maroon_objective)
else if(prob(permakill_prob))
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = T.owner
kill_objective.find_target()
T.add_objective(kill_objective)
else
var/datum/objective/assassinate/once/kill_objective = new
kill_objective.owner = T.owner
kill_objective.find_target()
T.add_objective(kill_objective)
@@ -0,0 +1,12 @@
/datum/traitor_class/human/freeform
name = "Waffle Co Agent"
employer = "Waffle Company"
weight = 16
chaos = 0
/datum/traitor_class/human/freeform/forge_objectives(datum/antagonist/traitor/T)
var/datum/objective/escape/O = new
O.explanation_text = "You have no goals! Whatever you can do do antagonize Nanotrasen, do it! The gimmickier, the better! Make sure to escape alive, though!"
O.owner = T.owner
T.add_objective(O)
return
@@ -0,0 +1,18 @@
/datum/traitor_class/human/hijack
name = "Gorlex Marauder"
employer = "The Gorlex Marauders"
weight = 3
chaos = 5
cost = 5
uplink_filters = list(/datum/uplink_item/stealthy_weapons/romerol_kit)
/datum/traitor_class/human/hijack/forge_objectives(datum/antagonist/traitor/T)
var/datum/objective/hijack/O = new
O.explanation_text = "The Gorlex Marauders are letting you do what you want, with one condition: the shuttle must be hijacked by hacking its navigational protocols through the control console (alt click emergency shuttle console)."
O.owner = T.owner
T.add_objective(O)
return
/datum/traitor_class/human/hijack/finalize_traitor(datum/antagonist/traitor/T)
T.hijack_speed=1
return TRUE
@@ -0,0 +1,82 @@
/datum/traitor_class/human
name = "Syndicate Agent"
chaos = 0
/datum/traitor_class/human/forge_objectives(datum/antagonist/traitor/T)
var/objective_count = 0 //Hijacking counts towards number of objectives
if(!SSticker.mode.exchange_blue && SSticker.mode.traitors.len >= 8) //Set up an exchange if there are enough traitors
if(!SSticker.mode.exchange_red)
SSticker.mode.exchange_red = T.owner
else
SSticker.mode.exchange_blue = T.owner
T.assign_exchange_role(SSticker.mode.exchange_red)
T.assign_exchange_role(SSticker.mode.exchange_blue)
objective_count += 1 //Exchange counts towards number of objectives
var/toa = CONFIG_GET(number/traitor_objectives_amount)
for(var/i = objective_count, i < toa, i++)
forge_single_objective(T)
if(!(locate(/datum/objective/escape) in T.objectives))
var/datum/objective/escape/escape_objective = new
escape_objective.owner = T.owner
T.add_objective(escape_objective)
return
/datum/traitor_class/human/forge_single_objective(datum/antagonist/traitor/T)
.=1
var/assassin_prob = 50
var/is_dynamic = FALSE
var/datum/game_mode/dynamic/mode
if(istype(SSticker.mode,/datum/game_mode/dynamic))
mode = SSticker.mode
is_dynamic = TRUE
assassin_prob = max(0,mode.threat_level-20)
if(prob(assassin_prob))
if(is_dynamic)
var/threat_spent = CONFIG_GET(number/dynamic_assassinate_cost)
mode.spend_threat(threat_spent)
mode.log_threat("[T.owner.name] spent [threat_spent] on an assassination target.")
var/list/active_ais = active_ais()
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
var/datum/objective/destroy/destroy_objective = new
destroy_objective.owner = T.owner
destroy_objective.find_target()
T.add_objective(destroy_objective)
else if(prob(30) || (is_dynamic && (mode.storyteller.flags & NO_ASSASSIN)))
var/datum/objective/maroon/maroon_objective = new
maroon_objective.owner = T.owner
maroon_objective.find_target()
T.add_objective(maroon_objective)
else if(prob(max(0,assassin_prob-20)))
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = T.owner
kill_objective.find_target()
T.add_objective(kill_objective)
else
var/datum/objective/assassinate/once/kill_objective = new
kill_objective.owner = T.owner
kill_objective.find_target()
T.add_objective(kill_objective)
else
if(prob(15) && !(locate(/datum/objective/download) in T.objectives) && !(T.owner.assigned_role in list("Research Director", "Scientist", "Roboticist")))
var/datum/objective/download/download_objective = new
download_objective.owner = T.owner
download_objective.gen_amount_goal()
T.add_objective(download_objective)
else if(prob(40)) // cum. not counting download: 40%.
var/datum/objective/steal/steal_objective = new
steal_objective.owner = T.owner
steal_objective.find_target()
T.add_objective(steal_objective)
else if(prob(100/3)) // cum. not counting download: 20%.
var/datum/objective/sabotage/sabotage_objective = new
sabotage_objective.owner = T.owner
sabotage_objective.find_target()
T.add_objective(sabotage_objective)
else // cum. not counting download: 40%
var/datum/objective/flavor/traitor/flavor_objective = new
flavor_objective.owner = T.owner
flavor_objective.forge_objective()
T.add_objective(flavor_objective)
/datum/traitor_class/human/greet(datum/antagonist/traitor/T)
to_chat(T.owner.current, "<B><font size=2 color=red>You are under contract with [employer]. They have given you your objectives.</font></B>")
@@ -0,0 +1,14 @@
/datum/traitor_class/human/martyr
name = "Tiger Cooperator"
employer = "The Tiger Cooperative"
weight = 2
chaos = 5
cost = 5
uplink_filters = list(/datum/uplink_item/stealthy_weapons/romerol_kit,/datum/uplink_item/bundles_TC/contract_kit)
/datum/traitor_class/human/martyr/forge_objectives(datum/antagonist/traitor/T)
var/datum/objective/martyr/O = new
O.explanation_text = "The tiger cooperative have given you free reign. You may do as you wish, as long as you die a glorious death!"
O.owner = T.owner
T.add_objective(O)
return
@@ -0,0 +1,40 @@
/datum/traitor_class/human/subterfuge
name = "MI13 Operative"
employer = "MI13"
weight = 20
chaos = -5
/datum/traitor_class/human/subterfuge/forge_single_objective(datum/antagonist/traitor/T)
.=1
var/assassin_prob = 30
var/datum/game_mode/dynamic/mode
if(istype(SSticker.mode,/datum/game_mode/dynamic))
mode = SSticker.mode
assassin_prob = max(0,mode.threat_level-40)
if(prob(assassin_prob))
if(prob(assassin_prob))
var/datum/objective/assassinate/once/kill_objective = new
kill_objective.owner = T.owner
kill_objective.find_target()
T.add_objective(kill_objective)
else
var/datum/objective/maroon/maroon_objective = new
maroon_objective.owner = T.owner
maroon_objective.find_target()
T.add_objective(maroon_objective)
else
if(prob(15) && !(locate(/datum/objective/download) in T.objectives) && !(T.owner.assigned_role in list("Research Director", "Scientist", "Roboticist")))
var/datum/objective/download/download_objective = new
download_objective.owner = T.owner
download_objective.gen_amount_goal()
T.add_objective(download_objective)
else if(prob(70)) // cum. not counting download: 40%.
var/datum/objective/steal/steal_objective = new
steal_objective.owner = T.owner
steal_objective.find_target()
T.add_objective(steal_objective)
else
var/datum/objective/sabotage/sabotage_objective = new
sabotage_objective.owner = T.owner
sabotage_objective.find_target()
T.add_objective(sabotage_objective)
@@ -0,0 +1,40 @@
GLOBAL_LIST_EMPTY(traitor_classes)
/datum/traitor_class
var/name = "Bad Coders Ltd."
var/employer = "The Syndicate"
var/weight = 0
var/chaos = 0
var/cost = 0
var/TC = 20
var/list/uplink_filters
/datum/traitor_class/New()
..()
if(src.type in GLOB.traitor_classes)
qdel(src)
else
GLOB.traitor_classes += src.type
GLOB.traitor_classes[src.type] = src
/datum/traitor_class/proc/forge_objectives(datum/antagonist/traitor/T)
// Like the old forge_human_objectives. Makes all the objectives for this traitor class.
/datum/traitor_class/proc/forge_single_objective(datum/antagonist/traitor/T)
// As forge_single_objective.
/datum/traitor_class/proc/on_removal(datum/antagonist/traitor/T)
// What this does to the antag datum on removal. Called before proper removal, obviously.
/datum/traitor_class/proc/apply_innate_effects(mob/living/M)
// What innate effects it should have. See: AI.
/datum/traitor_class/proc/remove_innate_effects(mob/living/M)
// Cleaning up the innate effects.
/datum/traitor_class/proc/greet(datum/antagonist/traitor/T)
// Message upon creation. Not necessary, but can be useful.
/datum/traitor_class/proc/finalize_traitor(datum/antagonist/traitor/T)
// Finalization. Return TRUE if should play standard traitor sound/equip, return FALSE if both are special case
return TRUE
+52 -227
View File
@@ -1,6 +1,3 @@
#define TRAITOR_HUMAN "human"
#define TRAITOR_AI "AI"
/datum/antagonist/traitor /datum/antagonist/traitor
name = "Traitor" name = "Traitor"
roundend_category = "traitors" roundend_category = "traitors"
@@ -12,43 +9,52 @@
var/give_objectives = TRUE var/give_objectives = TRUE
var/should_give_codewords = TRUE var/should_give_codewords = TRUE
var/should_equip = TRUE var/should_equip = TRUE
var/traitor_kind = TRAITOR_HUMAN //Set on initial assignment var/datum/traitor_class/traitor_kind
var/datum/contractor_hub/contractor_hub var/datum/contractor_hub/contractor_hub
hijack_speed = 0.5 //10 seconds per hijack stage by default hijack_speed = 0.5 //10 seconds per hijack stage by default
/datum/antagonist/traitor/New()
..()
if(!GLOB.traitor_classes.len)//Only need to fill the list when it's needed.
for(var/I in subtypesof(/datum/traitor_class))
new I
/datum/antagonist/traitor/proc/set_traitor_kind(var/kind)
traitor_kind = GLOB.traitor_classes[kind]
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(traitor_kind.cost)
mode.spend_threat(traitor_kind.cost)
mode.log_threat("[traitor_kind.cost] was spent due to [owner.name] being a [traitor_kind.name].")
/datum/antagonist/traitor/on_gain() /datum/antagonist/traitor/on_gain()
if(owner.current && isAI(owner.current)) if(owner.current && isAI(owner.current))
traitor_kind = TRAITOR_AI set_traitor_kind(TRAITOR_AI)
else
var/chaos_weight = 0
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
chaos_weight = (mode.threat - 50)/50
var/list/weights = list()
for(var/C in GLOB.traitor_classes)
var/datum/traitor_class/class = GLOB.traitor_classes[C]
var/weight = (1.5*class.weight)/(0.5+NUM_E**(-chaos_weight*class.chaos)) // just a logistic function
weights[C] = weight
var/choice = pickweightAllowZero(weights)
if(!choice)
choice = GLOB.traitor_classes[TRAITOR_HUMAN]
set_traitor_kind(pickweightAllowZero(weights))
traitor_kind.weight *= 0.8 // less likely this round
SSticker.mode.traitors += owner SSticker.mode.traitors += owner
owner.special_role = special_role owner.special_role = special_role
if(give_objectives) if(give_objectives)
forge_traitor_objectives() traitor_kind.forge_objectives(src)
finalize_traitor() finalize_traitor()
..() ..()
/datum/antagonist/traitor/apply_innate_effects()
if(owner.assigned_role == "Clown")
var/mob/living/carbon/human/traitor_mob = owner.current
if(traitor_mob && istype(traitor_mob))
if(!silent)
to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
traitor_mob.dna.remove_mutation(CLOWNMUT)
/datum/antagonist/traitor/remove_innate_effects()
if(owner.assigned_role == "Clown")
var/mob/living/carbon/human/traitor_mob = owner.current
if(traitor_mob && istype(traitor_mob))
traitor_mob.dna.add_mutation(CLOWNMUT)
/datum/antagonist/traitor/on_removal() /datum/antagonist/traitor/on_removal()
//Remove malf powers. //Remove malf powers.
if(traitor_kind == TRAITOR_AI && owner.current && isAI(owner.current)) traitor_kind.on_removal(src)
var/mob/living/silicon/ai/A = owner.current
A.set_zeroth_law("")
A.verbs -= /mob/living/silicon/ai/proc/choose_modules
A.malf_picker.remove_malf_verbs(A)
qdel(A.malf_picker)
SSticker.mode.traitors -= owner SSticker.mode.traitors -= owner
if(!silent && owner.current) if(!silent && owner.current)
to_chat(owner.current,"<span class='userdanger'> You are no longer the [special_role]! </span>") to_chat(owner.current,"<span class='userdanger'> You are no longer the [special_role]! </span>")
@@ -69,192 +75,11 @@
objectives -= O objectives -= O
/datum/antagonist/traitor/proc/forge_traitor_objectives() /datum/antagonist/traitor/proc/forge_traitor_objectives()
switch(traitor_kind) traitor_kind.forge_objectives(src)
if(TRAITOR_AI)
forge_ai_objectives()
else
forge_human_objectives()
/datum/antagonist/traitor/proc/forge_human_objectives()
var/is_hijacker = FALSE
var/datum/game_mode/dynamic/mode
var/is_dynamic = FALSE
var/hijack_prob = 0
if(istype(SSticker.mode,/datum/game_mode/dynamic))
mode = SSticker.mode
is_dynamic = TRUE
if(mode.threat >= CONFIG_GET(number/dynamic_hijack_cost))
hijack_prob = CLAMP(mode.threat_level-50,0,20)
if(GLOB.joined_player_list.len>=GLOB.dynamic_high_pop_limit)
is_hijacker = (prob(hijack_prob) && mode.threat_level > CONFIG_GET(number/dynamic_hijack_high_population_requirement))
else
var/indice_pop = min(10,round(GLOB.joined_player_list.len/mode.pop_per_requirement)+1)
is_hijacker = (prob(hijack_prob) && (mode.threat_level >= CONFIG_GET(number_list/dynamic_hijack_requirements)[indice_pop]))
if(mode.storyteller.flags & NO_ASSASSIN)
is_hijacker = FALSE
else if (GLOB.joined_player_list.len >= 30) // Less murderboning on lowpop thanks
hijack_prob = 10
is_hijacker = prob(10)
var/martyr_chance = prob(hijack_prob*2)
var/objective_count = is_hijacker //Hijacking counts towards number of objectives
if(!SSticker.mode.exchange_blue && SSticker.mode.traitors.len >= 8) //Set up an exchange if there are enough traitors
if(!SSticker.mode.exchange_red)
SSticker.mode.exchange_red = owner
else
SSticker.mode.exchange_blue = owner
assign_exchange_role(SSticker.mode.exchange_red)
assign_exchange_role(SSticker.mode.exchange_blue)
objective_count += 1 //Exchange counts towards number of objectives
var/toa = CONFIG_GET(number/traitor_objectives_amount)
for(var/i = objective_count, i < toa, i++)
forge_single_objective()
if(is_hijacker && objective_count <= toa) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
if (!(locate(/datum/objective/hijack) in objectives))
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = owner
add_objective(hijack_objective)
if(is_dynamic)
var/threat_spent = CONFIG_GET(number/dynamic_hijack_cost)
mode.spend_threat(threat_spent)
mode.log_threat("[owner.name] spent [threat_spent] on hijack.")
return
var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead.
for(var/datum/objective/O in objectives)
if(!O.martyr_compatible)
martyr_compatibility = 0
break
if(martyr_compatibility && martyr_chance)
var/datum/objective/martyr/martyr_objective = new
martyr_objective.owner = owner
add_objective(martyr_objective)
if(is_dynamic)
var/threat_spent = CONFIG_GET(number/dynamic_hijack_cost)
mode.spend_threat(threat_spent)
mode.log_threat("[owner.name] spent [threat_spent] on glorious death.")
return
else
if(!(locate(/datum/objective/escape) in objectives))
var/datum/objective/escape/escape_objective = new
escape_objective.owner = owner
add_objective(escape_objective)
return
/datum/antagonist/traitor/proc/forge_ai_objectives()
var/objective_count = 0
if(prob(30))
objective_count += forge_single_objective()
for(var/i = objective_count, i < CONFIG_GET(number/traitor_objectives_amount), i++)
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = owner
kill_objective.find_target()
add_objective(kill_objective)
var/datum/objective/survive/exist/exist_objective = new
exist_objective.owner = owner
add_objective(exist_objective)
/datum/antagonist/traitor/proc/forge_single_objective()
switch(traitor_kind)
if(TRAITOR_AI)
return forge_single_AI_objective()
else
return forge_single_human_objective()
/datum/antagonist/traitor/proc/forge_single_human_objective() //Returns how many objectives are added
.=1
var/assassin_prob = 50
var/is_dynamic = FALSE
var/datum/game_mode/dynamic/mode
if(istype(SSticker.mode,/datum/game_mode/dynamic))
mode = SSticker.mode
is_dynamic = TRUE
assassin_prob = max(0,mode.threat_level-20)
if(prob(assassin_prob))
if(is_dynamic)
var/threat_spent = CONFIG_GET(number/dynamic_assassinate_cost)
mode.spend_threat(threat_spent)
mode.log_threat("[owner.name] spent [threat_spent] on an assassination target.")
var/list/active_ais = active_ais()
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
var/datum/objective/destroy/destroy_objective = new
destroy_objective.owner = owner
destroy_objective.find_target()
add_objective(destroy_objective)
else if(prob(30) || (is_dynamic && (mode.storyteller.flags & NO_ASSASSIN)))
var/datum/objective/maroon/maroon_objective = new
maroon_objective.owner = owner
maroon_objective.find_target()
add_objective(maroon_objective)
else if(prob(max(0,assassin_prob-20)))
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = owner
kill_objective.find_target()
add_objective(kill_objective)
else
var/datum/objective/assassinate/once/kill_objective = new
kill_objective.owner = owner
kill_objective.find_target()
add_objective(kill_objective)
else
if(prob(15) && !(locate(/datum/objective/download) in objectives) && !(owner.assigned_role in list("Research Director", "Scientist", "Roboticist")))
var/datum/objective/download/download_objective = new
download_objective.owner = owner
download_objective.gen_amount_goal()
add_objective(download_objective)
else if(prob(40)) // cum. not counting download: 40%.
var/datum/objective/steal/steal_objective = new
steal_objective.owner = owner
steal_objective.find_target()
add_objective(steal_objective)
else if(prob(100/3)) // cum. not counting download: 20%.
var/datum/objective/sabotage/sabotage_objective = new
sabotage_objective.owner = owner
sabotage_objective.find_target()
add_objective(sabotage_objective)
else // cum. not counting download: 40%
var/datum/objective/flavor/traitor/flavor_objective = new
flavor_objective.owner = owner
flavor_objective.forge_objective()
add_objective(flavor_objective)
/datum/antagonist/traitor/proc/forge_single_AI_objective()
.=1
var/special_pick = rand(1,4)
switch(special_pick)
if(1)
var/datum/objective/block/block_objective = new
block_objective.owner = owner
add_objective(block_objective)
if(2)
var/datum/objective/purge/purge_objective = new
purge_objective.owner = owner
add_objective(purge_objective)
if(3)
var/datum/objective/robot_army/robot_objective = new
robot_objective.owner = owner
add_objective(robot_objective)
if(4) //Protect and strand a target
var/datum/objective/protect/yandere_one = new
yandere_one.owner = owner
add_objective(yandere_one)
yandere_one.find_target()
var/datum/objective/maroon/yandere_two = new
yandere_two.owner = owner
yandere_two.target = yandere_one.target
yandere_two.update_explanation_text() // normally called in find_target()
add_objective(yandere_two)
.=2
/datum/antagonist/traitor/greet() /datum/antagonist/traitor/greet()
to_chat(owner.current, "<B><font size=3 color=red>You are the [owner.special_role].</font></B>") to_chat(owner.current, "<B><font size=3 color=red>You are the [owner.special_role].</font></B>")
traitor_kind.greet(src)
owner.announce_objectives() owner.announce_objectives()
if(should_give_codewords) if(should_give_codewords)
give_codewords() give_codewords()
@@ -270,32 +95,33 @@
set_antag_hud(owner.current, null) set_antag_hud(owner.current, null)
/datum/antagonist/traitor/proc/finalize_traitor() /datum/antagonist/traitor/proc/finalize_traitor()
switch(traitor_kind) if(traitor_kind.finalize_traitor(src))
if(TRAITOR_AI) if(should_equip)
add_law_zero() equip(silent)
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE) owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
owner.current.grant_language(/datum/language/codespeak)
if(TRAITOR_HUMAN)
if(should_equip)
equip(silent)
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
/datum/antagonist/traitor/apply_innate_effects(mob/living/mob_override) /datum/antagonist/traitor/apply_innate_effects(mob/living/mob_override)
. = ..() . = ..()
update_traitor_icons_added() update_traitor_icons_added()
var/mob/M = mob_override || owner.current var/mob/M = mob_override || owner.current
if(isAI(M) && traitor_kind == TRAITOR_AI) traitor_kind.apply_innate_effects(M)
var/mob/living/silicon/ai/A = M if(owner.assigned_role == "Clown")
A.hack_software = TRUE var/mob/living/carbon/human/H = M
if(istype(H))
if(!silent)
to_chat(H, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
H.dna.remove_mutation(CLOWNMUT)
RegisterSignal(M, COMSIG_MOVABLE_HEAR, .proc/handle_hearing) RegisterSignal(M, COMSIG_MOVABLE_HEAR, .proc/handle_hearing)
/datum/antagonist/traitor/remove_innate_effects(mob/living/mob_override) /datum/antagonist/traitor/remove_innate_effects(mob/living/mob_override)
. = ..() . = ..()
update_traitor_icons_removed() update_traitor_icons_removed()
var/mob/M = mob_override || owner.current var/mob/M = mob_override || owner.current
if(isAI(M) && traitor_kind == TRAITOR_AI) traitor_kind.remove_innate_effects(M)
var/mob/living/silicon/ai/A = M if(owner.assigned_role == "Clown")
A.hack_software = FALSE var/mob/living/carbon/human/H = M
if(istype(H))
H.dna.add_mutation(CLOWNMUT)
UnregisterSignal(M, COMSIG_MOVABLE_HEAR) UnregisterSignal(M, COMSIG_MOVABLE_HEAR)
/datum/antagonist/traitor/proc/give_codewords() /datum/antagonist/traitor/proc/give_codewords()
@@ -326,8 +152,7 @@
killer.add_malf_picker() killer.add_malf_picker()
/datum/antagonist/traitor/proc/equip(var/silent = FALSE) /datum/antagonist/traitor/proc/equip(var/silent = FALSE)
if(traitor_kind == TRAITOR_HUMAN) owner.equip_traitor(traitor_kind, silent, src)
owner.equip_traitor(employer, silent, src)
/datum/antagonist/traitor/proc/assign_exchange_role() /datum/antagonist/traitor/proc/assign_exchange_role()
//set faction //set faction
+18 -39
View File
@@ -89,32 +89,17 @@
/datum/supply_pack/misc/paper_work /datum/supply_pack/misc/paper_work
name = "Freelance Paper work" name = "Freelance Paper work"
desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (20) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up. desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (10) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up.
cost = 700 // Net of 0 credits but makes (120 x 20 = 2400) cost = 700 // Net of 0 credits but makes (120 x 10 = 1200)
contains = list(/obj/item/folder/paperwork, contains = list(/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/pen/fountain /obj/item/pen/fountain
) )
crate_name = "Paperwork" crate_name = "Paperwork"
/datum/supply_pack/misc/paper_work/generate()
. = ..()
for(var/i in 1 to 9)
new /obj/item/folder/paperwork(.)
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
//////////////////////////////// Entertainment /////////////////////////////// //////////////////////////////// Entertainment ///////////////////////////////
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@@ -123,16 +108,14 @@
name = "Bedsheet Crate (R)" name = "Bedsheet Crate (R)"
desc = "Snuggle up in some sweet sheets with this assorted bedsheet crate. Each set comes with eight random bedsheets for your slumbering pleasure!" desc = "Snuggle up in some sweet sheets with this assorted bedsheet crate. Each set comes with eight random bedsheets for your slumbering pleasure!"
cost = 2000 cost = 2000
contains = list(/obj/item/bedsheet/random, contains = list(/obj/item/bedsheet/random)
/obj/item/bedsheet/random,
/obj/item/bedsheet/random,
/obj/item/bedsheet/random,
/obj/item/bedsheet/random,
/obj/item/bedsheet/random,
/obj/item/bedsheet/random,
/obj/item/bedsheet/random) //I'm lazy, and I copy paste stuff.
crate_name = "random bedsheet crate" crate_name = "random bedsheet crate"
/datum/supply_pack/misc/randombedsheets/generate()
. = ..()
for(var/i in 1 to 7)
new /obj/item/bedsheet/random(.)
/datum/supply_pack/misc/coloredsheets /datum/supply_pack/misc/coloredsheets
name = "Bedsheet Crate (C)" name = "Bedsheet Crate (C)"
desc = "Give your night life a splash of color with this crate filled with bedsheets! Contains a total of nine different-colored sheets." desc = "Give your night life a splash of color with this crate filled with bedsheets! Contains a total of nine different-colored sheets."
@@ -208,13 +191,14 @@
name = "Dueling Pistols" name = "Dueling Pistols"
desc = "Resolve all your quarrels with some nonlethal fun." desc = "Resolve all your quarrels with some nonlethal fun."
cost = 2000 cost = 2000
contains = list(/obj/item/storage/lockbox/dueling/hugbox/stamina, contains = list(/obj/item/storage/lockbox/dueling/hugbox/stamina)
/obj/item/storage/lockbox/dueling/hugbox/stamina,
/obj/item/storage/lockbox/dueling/hugbox/stamina,
/obj/item/storage/lockbox/dueling/hugbox/stamina,
/obj/item/storage/lockbox/dueling/hugbox/stamina)
crate_name = "dueling pistols" crate_name = "dueling pistols"
/datum/supply_pack/misc/dueling_stam/generate()
. = ..()
for(var/i in 1 to 3)
new /obj/item/storage/lockbox/dueling/hugbox/stamina(.)
/datum/supply_pack/misc/dueling_lethal /datum/supply_pack/misc/dueling_lethal
name = "Lethal Dueling Pistols" name = "Lethal Dueling Pistols"
desc = "Settle your differences the true spaceman way." desc = "Settle your differences the true spaceman way."
@@ -240,12 +224,7 @@
cost = 12000 cost = 12000
var/num_contained = 3 var/num_contained = 3
contains = list(/obj/item/ammo_box/a357, contains = list(/obj/item/ammo_box/a357,
/obj/item/ammo_box/a357,
/obj/item/ammo_box/a357,
/obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/magazine/pistolm9mm,
/obj/item/ammo_box/magazine/pistolm9mm,
/obj/item/ammo_box/magazine/pistolm9mm,
/obj/item/ammo_box/magazine/m45/kitchengun,
/obj/item/ammo_box/magazine/m45/kitchengun) /obj/item/ammo_box/magazine/m45/kitchengun)
crate_name = "crate" crate_name = "crate"
@@ -97,6 +97,11 @@
hitsound = 'sound/weapons/bladeslice.ogg' hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP sharpness = IS_SHARP
/obj/item/clothing/glasses/meson/eyepatch
name = "eyepatch mesons"
desc = "A meson system that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
icon_state = "mesonpatch"
/obj/item/clothing/glasses/science /obj/item/clothing/glasses/science
name = "science goggles" name = "science goggles"
desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents." desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents."
+17 -6
View File
@@ -83,6 +83,11 @@
name = "prescription medical HUDSunglasses" name = "prescription medical HUDSunglasses"
vision_correction = 1 vision_correction = 1
/obj/item/clothing/glasses/hud/health/eyepatch
name = "eyepatch medHUD"
desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
icon_state = "medpatch"
/////////////////// ///////////////////
//Diagnostic Huds// //Diagnostic Huds//
/////////////////// ///////////////////
@@ -97,7 +102,8 @@
/obj/item/clothing/glasses/hud/diagnostic/sunglasses /obj/item/clothing/glasses/hud/diagnostic/sunglasses
name = "diagnostic HUDSunglasses" name = "diagnostic HUDSunglasses"
desc = "Sunglasses with a diagnostic HUD." desc = "Sunglasses with a diagnostic HUD."
icon_state = "sunhuddiagnostic" icon_state = "sunhuddiag"
item_state = "glasses"
darkness_view = 1 darkness_view = 1
flash_protect = 1 flash_protect = 1
tint = 1 tint = 1
@@ -123,6 +129,11 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
glass_colour_type = /datum/client_colour/glass_colour/green glass_colour_type = /datum/client_colour/glass_colour/green
/obj/item/clothing/glasses/hud/diagnostic/eyepatch
name = "eyepatch diagnostic HUD"
desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
icon_state = "diagpatch"
//////////// ////////////
//Sec Huds// //Sec Huds//
//////////// ////////////
@@ -165,11 +176,6 @@
return return
chameleon_action.emp_randomise() chameleon_action.emp_randomise()
/obj/item/clothing/glasses/hud/security/sunglasses/eyepatch
name = "eyepatch HUD"
desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
icon_state = "hudpatch"
/obj/item/clothing/glasses/hud/security/sunglasses /obj/item/clothing/glasses/hud/security/sunglasses
name = "security HUDSunglasses" name = "security HUDSunglasses"
desc = "Sunglasses with a security HUD." desc = "Sunglasses with a security HUD."
@@ -179,6 +185,11 @@
tint = 1 tint = 1
glass_colour_type = /datum/client_colour/glass_colour/darkred glass_colour_type = /datum/client_colour/glass_colour/darkred
/obj/item/clothing/glasses/hud/security/sunglasses/eyepatch // why was this defined *before* the sunglasses it is a subtype of.
name = "eyepatch HUD"
desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
icon_state = "hudpatch"
/obj/item/clothing/glasses/hud/security/sunglasses/prescription /obj/item/clothing/glasses/hud/security/sunglasses/prescription
name = "prescription security HUDSunglasses" name = "prescription security HUDSunglasses"
vision_correction = 1 vision_correction = 1
@@ -44,8 +44,8 @@
if(ishuman(hit_atom)) if(ishuman(hit_atom))
var/mob/living/carbon/human/H = hit_atom var/mob/living/carbon/human/H = hit_atom
var/mutable_appearance/creamoverlay = mutable_appearance('icons/effects/creampie.dmi') var/mutable_appearance/creamoverlay = mutable_appearance('icons/effects/creampie.dmi')
if(H.dna.species.limbs_id == "lizard") if((("mam_snouts" in H.dna.species.default_features) && H.dna.features["mam_snouts"] != "None") || (("snout" in H.dna.species.default_features) && H.dna.features["snout"] != "None"))
creamoverlay.icon_state = "creampie_lizard" creamoverlay.icon_state = "creampie_snout"
else else
creamoverlay.icon_state = "creampie_human" creamoverlay.icon_state = "creampie_human"
if(stunning) if(stunning)
@@ -139,6 +139,9 @@
icon = 'icons/obj/lavaland/survival_pod.dmi' icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "sleeper" icon_state = "sleeper"
/obj/machinery/sleeper/survival_pod/update_icon_state()
return
/obj/machinery/sleeper/survival_pod/update_overlays() /obj/machinery/sleeper/survival_pod/update_overlays()
. = ..() . = ..()
if(!state_open) if(!state_open)
@@ -189,7 +192,7 @@
flags_1 = NODECONSTRUCT_1 flags_1 = NODECONSTRUCT_1
var/empty = FALSE var/empty = FALSE
/obj/machinery/stasis/survival_pod/ComponentInitialize() /obj/machinery/smartfridge/survival_pod/ComponentInitialize()
. = ..() . = ..()
AddElement(/datum/element/update_icon_blocker) AddElement(/datum/element/update_icon_blocker)
+3
View File
@@ -24,6 +24,9 @@
/obj/item/mmi/update_overlays() /obj/item/mmi/update_overlays()
. = ..() . = ..()
. += add_mmi_overlay()
/obj/item/mmi/proc/add_mmi_overlay()
if(brainmob && brainmob.stat != DEAD) if(brainmob && brainmob.stat != DEAD)
. += "mmi_alive" . += "mmi_alive"
else else
@@ -193,3 +193,6 @@ GLOBAL_VAR(posibrain_notify_cooldown)
icon_state = "[initial(icon_state)]-occupied" icon_state = "[initial(icon_state)]-occupied"
else else
icon_state = initial(icon_state) icon_state = initial(icon_state)
/obj/item/mmi/posibrain/add_mmi_overlay()
return
@@ -264,11 +264,11 @@
jitteriness += 1000 //High numbers for violent convulsions jitteriness += 1000 //High numbers for violent convulsions
do_jitter_animation(jitteriness) do_jitter_animation(jitteriness)
stuttering += 2 stuttering += 2
if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && (flags & SHOCK_NOSTUN)) if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN))
Stun(40) Stun(40)
spawn(20) spawn(20)
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && (flags & SHOCK_NOSTUN)) if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN))
DefaultCombatKnockdown(60) DefaultCombatKnockdown(60)
return shock_damage return shock_damage
@@ -242,6 +242,12 @@
return return
if(href_list["pockets"]) if(href_list["pockets"])
var/strip_mod = 1
var/strip_silence = FALSE
var/obj/item/clothing/gloves/g = gloves
if (istype(g))
strip_mod = g.strip_mod
strip_silence = g.strip_silence
var/pocket_side = href_list["pockets"] var/pocket_side = href_list["pockets"]
var/pocket_id = (pocket_side == "right" ? SLOT_R_STORE : SLOT_L_STORE) var/pocket_id = (pocket_side == "right" ? SLOT_R_STORE : SLOT_L_STORE)
var/obj/item/pocket_item = (pocket_id == SLOT_R_STORE ? r_store : l_store) var/obj/item/pocket_item = (pocket_id == SLOT_R_STORE ? r_store : l_store)
@@ -258,7 +264,7 @@
else else
return return
if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator, ignorehelditem = TRUE)) //placing an item into the pocket is 4 times faster if(do_mob(usr, src, max(round(POCKET_STRIP_DELAY/(delay_denominator*strip_mod)),1), ignorehelditem = TRUE)) //placing an item into the pocket is 4 times faster (and the strip_mod too)
if(pocket_item) if(pocket_item)
if(pocket_item == (pocket_id == SLOT_R_STORE ? r_store : l_store)) //item still in the pocket we search if(pocket_item == (pocket_id == SLOT_R_STORE ? r_store : l_store)) //item still in the pocket we search
dropItemToGround(pocket_item) dropItemToGround(pocket_item)
@@ -276,7 +282,8 @@
show_inv(usr) show_inv(usr)
else else
// Display a warning if the user mocks up // Display a warning if the user mocks up
to_chat(src, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>") if (!strip_silence)
to_chat(src, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>")
..() //CITADEL CHANGE - removes a tab from behind this ..() so that flavortext can actually be examined ..() //CITADEL CHANGE - removes a tab from behind this ..() so that flavortext can actually be examined
@@ -397,7 +397,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(I.flags_inv & HIDEFACIALHAIR) if(I.flags_inv & HIDEFACIALHAIR)
facialhair_hidden = TRUE facialhair_hidden = TRUE
if(H.wear_mask) if(H.wear_mask && istype(H.wear_mask))
var/obj/item/clothing/mask/M = H.wear_mask var/obj/item/clothing/mask/M = H.wear_mask
dynamic_fhair_suffix = M.dynamic_fhair_suffix //mask > head in terms of facial hair dynamic_fhair_suffix = M.dynamic_fhair_suffix //mask > head in terms of facial hair
if(M.flags_inv & HIDEFACIALHAIR) if(M.flags_inv & HIDEFACIALHAIR)
@@ -451,7 +451,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(I.flags_inv & HIDEHAIR) if(I.flags_inv & HIDEHAIR)
hair_hidden = TRUE hair_hidden = TRUE
if(H.wear_mask) if(H.wear_mask && istype(H.wear_mask))
var/obj/item/clothing/mask/M = H.wear_mask var/obj/item/clothing/mask/M = H.wear_mask
if(!dynamic_hair_suffix) //head > mask in terms of head hair if(!dynamic_hair_suffix) //head > mask in terms of head hair
dynamic_hair_suffix = M.dynamic_hair_suffix dynamic_hair_suffix = M.dynamic_hair_suffix
@@ -1116,6 +1116,7 @@
desc = "Stop controlling your shell and resume normal core operations." desc = "Stop controlling your shell and resume normal core operations."
icon_icon = 'icons/mob/actions/actions_AI.dmi' icon_icon = 'icons/mob/actions/actions_AI.dmi'
button_icon_state = "ai_core" button_icon_state = "ai_core"
required_mobility_flags = NONE
/datum/action/innate/undeployment/Trigger() /datum/action/innate/undeployment/Trigger()
if(!..()) if(!..())
@@ -821,7 +821,6 @@
/obj/item/gps/cyborg, /obj/item/gps/cyborg,
/obj/item/weapon/gripper/mining, /obj/item/weapon/gripper/mining,
/obj/item/cyborg_clamp, /obj/item/cyborg_clamp,
/obj/item/card/id/miningborg,
/obj/item/stack/marker_beacon, /obj/item/stack/marker_beacon,
/obj/item/destTagger, /obj/item/destTagger,
/obj/item/stack/packageWrap) /obj/item/stack/packageWrap)
@@ -363,10 +363,8 @@
icon_dead = "old_corgi_dead" icon_dead = "old_corgi_dead"
desc = "At a ripe old age of [record_age] Ian's not as spry as he used to be, but he'll always be the HoP's beloved corgi." //RIP desc = "At a ripe old age of [record_age] Ian's not as spry as he used to be, but he'll always be the HoP's beloved corgi." //RIP
turns_per_move = 20 turns_per_move = 20
var/datum/element/mob_holder/ele = SSdcs.GetElement(/datum/element/mob_holder, held_icon) RemoveElement(/datum/element/mob_holder, held_icon)
if(ele) AddElement(/datum/element/mob_holder, "old_corgi")
ele.Detach(src)
AddElement(/datum/element/mob_holder, "old_corgi")
/mob/living/simple_animal/pet/dog/corgi/Ian/Life() /mob/living/simple_animal/pet/dog/corgi/Ian/Life()
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
@@ -447,7 +445,7 @@
sleep(3) sleep(3)
step_to(src,movement_target,1) step_to(src,movement_target,1)
if(movement_target) //Not redundant due to sleeps, Item can be gone in 6 decisecomds if(movement_target?.loc) //Not redundant due to sleeps, Item can be gone in 6 decisecomds
if (movement_target.loc.x < src.x) if (movement_target.loc.x < src.x)
setDir(WEST) setDir(WEST)
else if (movement_target.loc.x > src.x) else if (movement_target.loc.x > src.x)
@@ -64,7 +64,7 @@
..() ..()
/mob/living/simple_animal/mouse/handle_automated_action() /mob/living/simple_animal/mouse/handle_automated_action()
if(isbelly(loc)) if(!isturf(loc))
return return
if(prob(chew_probability)) if(prob(chew_probability))
@@ -76,7 +76,7 @@
visible_message("<span class='warning'>[src] chews through the [C]. It's toast!</span>") visible_message("<span class='warning'>[src] chews through the [C]. It's toast!</span>")
playsound(src, 'sound/effects/sparks2.ogg', 100, 1) playsound(src, 'sound/effects/sparks2.ogg', 100, 1)
C.deconstruct() C.deconstruct()
death(toast=1) death(toast=TRUE)
else else
C.deconstruct() C.deconstruct()
visible_message("<span class='warning'>[src] chews through the [C].</span>") visible_message("<span class='warning'>[src] chews through the [C].</span>")
@@ -204,7 +204,7 @@
rapid = 2 rapid = 2
icon_state = "syndicate_smg" icon_state = "syndicate_smg"
icon_living = "syndicate_smg" icon_living = "syndicate_smg"
casingtype = /obj/item/ammo_casing/c45/nostamina casingtype = /obj/item/ammo_casing/c45
projectilesound = 'sound/weapons/gunshot_smg.ogg' projectilesound = 'sound/weapons/gunshot_smg.ogg'
/mob/living/simple_animal/hostile/syndicate/ranged/smg/pilot //caravan ambush ruin /mob/living/simple_animal/hostile/syndicate/ranged/smg/pilot //caravan ambush ruin
+8 -2
View File
@@ -19,9 +19,15 @@
/mob/proc/set_dizziness(amount) /mob/proc/set_dizziness(amount)
dizziness = max(amount, 0) dizziness = max(amount, 0)
///Blind a mobs eyes by amount /**
* Sets a mob's blindness to an amount if it was not above it already, similar to how status effects work
*/
/mob/proc/blind_eyes(amount) /mob/proc/blind_eyes(amount)
adjust_blindness(amount) var/old_blind = eye_blind || HAS_TRAIT(src, TRAIT_BLIND)
eye_blind = max(eye_blind, amount)
var/new_blind = eye_blind || HAS_TRAIT(src, TRAIT_BLIND)
if(old_blind != new_blind)
update_blindness()
/** /**
* Adjust a mobs blindness by an amount * Adjust a mobs blindness by an amount
@@ -12,6 +12,10 @@
battery = new battery_type(src) battery = new battery_type(src)
..() ..()
/obj/item/computer_hardware/battery/Destroy()
. = ..()
QDEL_NULL(battery)
/obj/item/computer_hardware/battery/try_insert(obj/item/I, mob/living/user = null) /obj/item/computer_hardware/battery/try_insert(obj/item/I, mob/living/user = null)
if(!holder) if(!holder)
return FALSE return FALSE
+3
View File
@@ -70,6 +70,9 @@
else else
. = FALSE //as to not cancel attack_hand() . = FALSE //as to not cancel attack_hand()
/obj/item/clothing/gloves/space_ninja/dropped(mob/user)
. = ..()
REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT)
/obj/item/clothing/gloves/space_ninja/proc/toggledrain() /obj/item/clothing/gloves/space_ninja/proc/toggledrain()
var/mob/living/carbon/human/U = loc var/mob/living/carbon/human/U = loc
+4
View File
@@ -10,3 +10,7 @@
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
blockTracking = 1//Roughly the only unique thing about this helmet. blockTracking = 1//Roughly the only unique thing about this helmet.
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
/obj/item/clothing/head/helmet/space/space_ninja/dropped(mob/user)
. = ..()
REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT)
+4
View File
@@ -19,6 +19,10 @@ Contents:
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
modifies_speech = TRUE modifies_speech = TRUE
/obj/item/clothing/mask/gas/space_ninja/dropped(mob/user)
. = ..()
REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT)
/obj/item/clothing/mask/gas/space_ninja/handle_speech(datum/source, list/speech_args) /obj/item/clothing/mask/gas/space_ninja/handle_speech(datum/source, list/speech_args)
var/message = speech_args[SPEECH_MESSAGE] var/message = speech_args[SPEECH_MESSAGE]
if(message[1] != "*") if(message[1] != "*")
@@ -24,9 +24,6 @@
caliber = ".45" caliber = ".45"
projectile_type = /obj/item/projectile/bullet/c45 projectile_type = /obj/item/projectile/bullet/c45
/obj/item/ammo_casing/c45/nostamina
projectile_type = /obj/item/projectile/bullet/c45_nostamina
/obj/item/ammo_casing/c45/kitchengun /obj/item/ammo_casing/c45/kitchengun
desc = "A .45 bullet casing. It has a small sponge attached to it." desc = "A .45 bullet casing. It has a small sponge attached to it."
projectile_type = /obj/item/projectile/bullet/c45_cleaning projectile_type = /obj/item/projectile/bullet/c45_cleaning
+1 -1
View File
@@ -60,7 +60,7 @@
/obj/item/ammo_box/magazine/smgm45 /obj/item/ammo_box/magazine/smgm45
name = "SMG magazine (.45)" name = "SMG magazine (.45)"
icon_state = "c20r45-24" icon_state = "c20r45-24"
ammo_type = /obj/item/ammo_casing/c45/nostamina ammo_type = /obj/item/ammo_casing/c45
caliber = ".45" caliber = ".45"
max_ammo = 24 max_ammo = 24
@@ -47,7 +47,7 @@
var/mob/current_user = null var/mob/current_user = null
var/list/obj/effect/projectile/tracer/current_tracers var/list/obj/effect/projectile/tracer/current_tracers
var/structure_piercing = 1 var/structure_piercing = 0
var/structure_bleed_coeff = 0.7 var/structure_bleed_coeff = 0.7
var/wall_pierce_amount = 0 var/wall_pierce_amount = 0
var/wall_devastate = 0 var/wall_devastate = 0
@@ -60,7 +60,7 @@
var/impact_structure_damage = 75 var/impact_structure_damage = 75
var/projectile_damage = 40 var/projectile_damage = 40
var/projectile_stun = 0 var/projectile_stun = 0
var/projectile_setting_pierce = TRUE var/projectile_setting_pierce = FALSE
var/delay = 30 var/delay = 30
var/lastfire = 0 var/lastfire = 0
@@ -160,6 +160,9 @@
add_overlay(drained_overlay) add_overlay(drained_overlay)
/obj/item/gun/energy/beam_rifle/attack_self(mob/user) /obj/item/gun/energy/beam_rifle/attack_self(mob/user)
if(!structure_piercing)
projectile_setting_pierce = FALSE
return
projectile_setting_pierce = !projectile_setting_pierce projectile_setting_pierce = !projectile_setting_pierce
to_chat(user, "<span class='boldnotice'>You set \the [src] to [projectile_setting_pierce? "pierce":"impact"] mode.</span>") to_chat(user, "<span class='boldnotice'>You set \the [src] to [projectile_setting_pierce? "pierce":"impact"] mode.</span>")
aiming_beam() aiming_beam()
@@ -402,7 +405,7 @@
/obj/item/ammo_casing/energy/beam_rifle/hitscan /obj/item/ammo_casing/energy/beam_rifle/hitscan
projectile_type = /obj/item/projectile/beam/beam_rifle/hitscan projectile_type = /obj/item/projectile/beam/beam_rifle/hitscan
select_name = "beam" select_name = "beam"
e_cost = 5000 e_cost = 10000
fire_sound = 'sound/weapons/beam_sniper.ogg' fire_sound = 'sound/weapons/beam_sniper.ogg'
/obj/item/projectile/beam/beam_rifle /obj/item/projectile/beam/beam_rifle
@@ -557,9 +560,4 @@
hitscan_light_color_override = "#99ff99" hitscan_light_color_override = "#99ff99"
/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/prehit(atom/target) /obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/prehit(atom/target)
qdel(src)
return FALSE return FALSE
/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/on_hit()
qdel(src)
return BULLET_ACT_HIT
@@ -1,18 +1,12 @@
// .45 (M1911 & C20r) // .45 (M1911 & C20r)
/obj/item/projectile/bullet/c45 /obj/item/projectile/bullet/c45
name = ".45 bullet"
damage = 20
stamina = 65
/obj/item/projectile/bullet/c45_nostamina
name = ".45 bullet" name = ".45 bullet"
damage = 30 damage = 30
/obj/item/projectile/bullet/c45_cleaning /obj/item/projectile/bullet/c45_cleaning
name = ".45 bullet" name = ".45 bullet"
damage = 24 damage = 40 //BANG BANG BANG
stamina = 10
/obj/item/projectile/bullet/c45_cleaning/on_hit(atom/target, blocked = FALSE) /obj/item/projectile/bullet/c45_cleaning/on_hit(atom/target, blocked = FALSE)
. = ..() . = ..()
+3 -4
View File
@@ -43,14 +43,14 @@
set_APTFT() set_APTFT()
return TRUE return TRUE
/obj/item/reagent_containers/proc/set_APTFT(mob/user) //set amount_per_transfer_from_this /obj/item/reagent_containers/proc/set_APTFT() //set amount_per_transfer_from_this
set name = "Set Transfer Amount" set name = "Set Transfer Amount"
set category = "Object" set category = "Object"
set waitfor = FALSE set waitfor = FALSE
var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts
if(N) if(N)
amount_per_transfer_from_this = N amount_per_transfer_from_this = N
to_chat(user, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>") to_chat(usr, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>")
/obj/item/reagent_containers/proc/add_initial_reagents() /obj/item/reagent_containers/proc/add_initial_reagents()
if(list_reagents) if(list_reagents)
@@ -134,6 +134,7 @@
throwerstring = " THROWN BY [key_name(thrownby)] at [AT] (AREACOORD(AT)]" throwerstring = " THROWN BY [key_name(thrownby)] at [AT] (AREACOORD(AT)]"
log_reagent("SPLASH: [src] mob SplashReagents() onto [key_name(target)] at [TT] ([AREACOORD(TT)])[throwerstring] - [R]") log_reagent("SPLASH: [src] mob SplashReagents() onto [key_name(target)] at [TT] ([AREACOORD(TT)])[throwerstring] - [R]")
reagents.reaction(target, TOUCH) reagents.reaction(target, TOUCH)
reagents.clear_reagents()
else if(bartender_check(target) && thrown) else if(bartender_check(target) && thrown)
visible_message("<span class='notice'>[src] lands without spilling a single drop.</span>") visible_message("<span class='notice'>[src] lands without spilling a single drop.</span>")
@@ -154,8 +155,6 @@
visible_message("<span class='notice'>[src] spills its contents all over [target].</span>") visible_message("<span class='notice'>[src] spills its contents all over [target].</span>")
reagents.reaction(target, TOUCH) reagents.reaction(target, TOUCH)
reagents.clear_reagents() reagents.clear_reagents()
if(QDELETED(src))
return
//melts plastic beakers //melts plastic beakers
/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M) /obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M)
@@ -28,7 +28,7 @@ Borg Hypospray
var/list/datum/reagents/reagent_list = list() var/list/datum/reagents/reagent_list = list()
var/list/reagent_ids = list(/datum/reagent/medicine/dexalin, /datum/reagent/medicine/kelotane, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/antitoxin, var/list/reagent_ids = list(/datum/reagent/medicine/dexalin, /datum/reagent/medicine/kelotane, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/antitoxin,
/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/spaceacillin, /datum/reagent/medicine/salglu_solution, /datum/reagent/medicine/insulin) /datum/reagent/medicine/epinephrine, /datum/reagent/medicine/spaceacillin, /datum/reagent/medicine/salglu_solution, /datum/reagent/medicine/insulin, /datum/reagent/medicine/potass_iodide)
var/accepts_reagent_upgrades = TRUE //If upgrades can increase number of reagents dispensed. var/accepts_reagent_upgrades = TRUE //If upgrades can increase number of reagents dispensed.
var/list/modes = list() //Basically the inverse of reagent_ids. Instead of having numbers as "keys" and strings as values it has strings as keys and numbers as values. var/list/modes = list() //Basically the inverse of reagent_ids. Instead of having numbers as "keys" and strings as values it has strings as keys and numbers as values.
//Used as list for input() in shakers. //Used as list for input() in shakers.
@@ -164,7 +164,7 @@ Borg Hypospray
icon_state = "borghypo_s" icon_state = "borghypo_s"
charge_cost = 20 charge_cost = 20
recharge_time = 2 recharge_time = 2
reagent_ids = list(/datum/reagent/medicine/syndicate_nanites, /datum/reagent/medicine/potass_iodide, /datum/reagent/medicine/morphine, /datum/reagent/medicine/insulin) reagent_ids = list(/datum/reagent/medicine/syndicate_nanites, /datum/reagent/medicine/prussian_blue, /datum/reagent/medicine/morphine, /datum/reagent/medicine/insulin)
bypass_protection = 1 bypass_protection = 1
accepts_reagent_upgrades = FALSE accepts_reagent_upgrades = FALSE
@@ -261,5 +261,5 @@ Borg Shaker
/obj/item/reagent_containers/borghypo/epi /obj/item/reagent_containers/borghypo/epi
name = "Stabilizer injector" name = "Stabilizer injector"
desc = "An advanced chemical synthesizer and injection system, designed to stabilize patients." desc = "An advanced chemical synthesizer and injection system, designed to stabilize patients."
reagent_ids = list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/insulin) reagent_ids = list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/insulin, /datum/reagent/medicine/potass_iodide)
accepts_reagent_upgrades = FALSE accepts_reagent_upgrades = FALSE
@@ -35,6 +35,17 @@
dangerous_construction = TRUE dangerous_construction = TRUE
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
/datum/design/duffelbag_holding
name = "Duffel Bag of Holding"
desc = "A duffel bag that opens into a localized pocket of bluespace."
id = "duffelbag_holding"
build_type = PROTOLATHE
materials = list(/datum/material/gold = 3000, /datum/material/diamond = 1500, /datum/material/uranium = 250, /datum/material/bluespace = 2000)
build_path = /obj/item/storage/backpack/holding/duffel
category = list("Bluespace Designs")
dangerous_construction = TRUE
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
/datum/design/biobag_holding /datum/design/biobag_holding
name = "Bio Bag of Holding" name = "Bio Bag of Holding"
desc = "A chemical holding thingy. Mostly used for xenobiology." desc = "A chemical holding thingy. Mostly used for xenobiology."
@@ -633,15 +633,6 @@
construction_time = 120 construction_time = 120
category = list("Cyborg Upgrade Modules") category = list("Cyborg Upgrade Modules")
/datum/design/borg_upgrade_premiumka
name = "Cyborg Upgrade (Premium Kinetic Accelerator)"
id = "borg_upgrade_premiumka"
build_type = MECHFAB
build_path = /obj/item/borg/upgrade/premiumka
materials = list(/datum/material/iron=8000, /datum/material/glass=4000, /datum/material/titanium=2000)
construction_time = 120
category = list("Cyborg Upgrade Modules")
/datum/design/borg_upgrade_lavaproof /datum/design/borg_upgrade_lavaproof
name = "Cyborg Upgrade (Lavaproof Tracks)" name = "Cyborg Upgrade (Lavaproof Tracks)"
id = "borg_upgrade_lavaproof" id = "borg_upgrade_lavaproof"
+2 -2
View File
@@ -278,7 +278,7 @@
display_name = "Bluespace Pockets" display_name = "Bluespace Pockets"
description = "Studies into the mysterious alternate dimension known as bluespace and how to place items in the threads of reality." description = "Studies into the mysterious alternate dimension known as bluespace and how to place items in the threads of reality."
prereq_ids = list("adv_power", "adv_bluespace", "adv_biotech", "adv_plasma") prereq_ids = list("adv_power", "adv_bluespace", "adv_biotech", "adv_plasma")
design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding", "bsblood_bag") design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding", "bsblood_bag", "duffelbag_holding")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5500) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5500)
/datum/techweb_node/bluespace_portal /datum/techweb_node/bluespace_portal
@@ -336,7 +336,7 @@
display_name = "Advanced Robotics Research" display_name = "Advanced Robotics Research"
description = "It can even do the dishes!" description = "It can even do the dishes!"
prereq_ids = list("robotics") prereq_ids = list("robotics")
design_ids = list("borg_upgrade_diamonddrill", "borg_upgrade_advancedmop", "borg_upgrade_advcutter", "borg_upgrade_premiumka") design_ids = list("borg_upgrade_diamonddrill", "borg_upgrade_advancedmop", "borg_upgrade_advcutter")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000)
/datum/techweb_node/neural_programming /datum/techweb_node/neural_programming
+2
View File
@@ -319,6 +319,8 @@
on_mob.forceMove(scanning) on_mob.forceMove(scanning)
for(var/i in 1 to light_beam_distance) for(var/i in 1 to light_beam_distance)
scanning = get_step(scanning, scandir) scanning = get_step(scanning, scandir)
if(!scanning)
break
if(scanning.opacity || scanning.has_opaque_atom) if(scanning.opacity || scanning.has_opaque_atom)
stop = TRUE stop = TRUE
var/obj/effect/abstract/eye_lighting/L = LAZYACCESS(eye_lighting, i) var/obj/effect/abstract/eye_lighting/L = LAZYACCESS(eye_lighting, i)
+3 -2
View File
@@ -1,4 +1,4 @@
/proc/get_uplink_items(datum/game_mode/gamemode, allow_sales = TRUE, allow_restricted = TRUE) /proc/get_uplink_items(datum/game_mode/gamemode, allow_sales = TRUE, allow_restricted = TRUE, other_filter = list())
var/list/filtered_uplink_items = GLOB.uplink_categories.Copy() // list of uplink categories without associated values. var/list/filtered_uplink_items = GLOB.uplink_categories.Copy() // list of uplink categories without associated values.
var/list/sale_items = list() var/list/sale_items = list()
@@ -18,7 +18,8 @@
continue continue
if (I.restricted && !allow_restricted) if (I.restricted && !allow_restricted)
continue continue
if (I.type in other_filter)
continue
LAZYSET(filtered_uplink_items[I.category], I.name, I) LAZYSET(filtered_uplink_items[I.category], I.name, I)
if(I.limited_stock < 0 && !I.cant_discount && I.item && I.cost > 1) if(I.limited_stock < 0 && !I.cant_discount && I.item && I.cost > 1)
@@ -159,7 +159,7 @@
/datum/uplink_item/role_restricted/kitchen_gun /datum/uplink_item/role_restricted/kitchen_gun
name = "Kitchen Gun (TM)" name = "Kitchen Gun (TM)"
desc = "A revolutionary .45 caliber cleaning solution! Say goodbye to daily stains and dirty surfaces with Kitchen Gun (TM)! \ desc = "A revolutionary .45 caliber cleaning solution! Say goodbye to daily stains and dirty surfaces with Kitchen Gun (TM)! \
Just five shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips!" Just three shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips!"
cost = 10 cost = 10
surplus = 40 surplus = 40
restricted_roles = list("Cook", "Janitor") restricted_roles = list("Cook", "Janitor")
@@ -0,0 +1,4 @@
author: "Putnam3145"
delete-after: True
changes:
- rscadd: "Traitor classes for traitors: a new way for traitors to have objectives assigned."
@@ -0,0 +1,5 @@
author: "Trilbyspaceclone"
delete-after: True
changes:
- tweak: "Number of paper work in the crate \"freelance paperwork\" is half"
- code_imp: "A few cases were something their is unneeded copy past replaced with many 1 in spawns"
@@ -0,0 +1,4 @@
author: "bunny232"
delete-after: True
changes:
- rscadd: "Box station captain office now has a standard issue renault"
@@ -0,0 +1,5 @@
author: "Trilbyspaceclone"
delete-after: True
changes:
- rscadd: "Potass Iodide has been fitted into standered borgs as well as medical ones. Upgraded hypos now have Prussian Blue as well."
- tweak: "Syndi borgs Potass Iodide has been swapped for Prussian Blue"
@@ -0,0 +1,4 @@
author: "Kraseo"
delete-after: True
changes:
- bugfix: "Mice don't chew on wires anymore while they're on your person."
@@ -0,0 +1,4 @@
author: "Kraseo"
delete-after: True
changes:
- bugfix: "Bloodsucker heart theft objective now completes successfully."
@@ -0,0 +1,7 @@
author: "Qustinnus/floyd, Ghommie"
delete-after: True
changes:
- bugfix: "To save costs, Nanotrasen has removed the emergency battery ejection systems in modular computers. We realized saving the batteries isn't really important."
- bugfix: "You can squash spiderlings with your bare hands now."
- bugfix: "Being deafened properly stops jukebox music from playing."
- bugfix: "admin multicam toggles no longer tells everyone but only admins and AIs"
@@ -0,0 +1,4 @@
author: "Putnam3145"
delete-after: True
changes:
- bugfix: "Server-run votes aren't subject to vote cooldown"
@@ -0,0 +1,4 @@
author: "Seris02"
delete-after: True
changes:
- rscadd: "duffel bags of holding"
@@ -0,0 +1,4 @@
author: "Seris02"
delete-after: True
changes:
- bugfix: "quirk blacklist fixing"
@@ -0,0 +1,4 @@
author: "Kraseo"
delete-after: True
changes:
- tweak: "Blacklists turret protected areas, the toxins test range, asteroid ruins, and solars from being valid dropoff locations for contracts."
@@ -0,0 +1,4 @@
author: "zeroisthebiggay"
delete-after: True
changes:
- rscadd: "Box Station has gotten a brand new brig. Go and check it out and discover all the quirky little soulbits."
@@ -0,0 +1,4 @@
author: "kappa-sama"
delete-after: True
changes:
- balance: "60 seconds instead of 120 for firebreath"
@@ -0,0 +1,4 @@
author: "Seris02"
delete-after: True
changes:
- bugfix: "robotics console button swapping"
@@ -0,0 +1,4 @@
author: "kevinz000"
delete-after: True
changes:
- balance: "Beam rifles shot count 10 --> 5 and can no longer pierce. Also renders properly for reflections against blobs and some other things."
@@ -0,0 +1,4 @@
author: "Hatterhat"
delete-after: True
changes:
- rscdel: "Mining cyborgs are no longer physically capable of claiming points nor wielding a premium accelerator."
@@ -0,0 +1,4 @@
author: "Yenwodyah"
delete-after: True
changes:
- bugfix: "Recycler doesn't delete people in mechs, cardboard boxes, spells, etc. anymore."
@@ -0,0 +1,4 @@
author: "bunny232"
delete-after: True
changes:
- bugfix: "Box bridge now actually has the air distro connected"
@@ -0,0 +1,4 @@
author: "Trilbyspaceclone"
delete-after: True
changes:
- bugfix: "No longer can you get the The End and Russian Flask without being the donator"
@@ -0,0 +1,6 @@
author: "Arreksuru and Detective Google"
delete-after: True
changes:
- rscadd: "new HUDpatches for medical, diagnostic, and mesons."
- rscadd: "crafting and de-crafting recipes for new HUDpatches."
- bugfix: "silly typo with \"singlasses\" in one of the crafting recipes for HUDglasses."
@@ -0,0 +1,5 @@
author: "BlackMajor"
delete-after: True
changes:
- tweak: "Adjusted the ash walker camp's storm proofing."
- rscadd: "Added a tip about creating areas to the ash walker spawn text."
@@ -0,0 +1,4 @@
author: "Seris02"
delete-after: True
changes:
- bugfix: "fixed thieving gloves not pickpocketing fast"

Some files were not shown because too many files have changed in this diff Show More