Merge remote-tracking branch 'origin/master' into perlin-genny
This commit is contained in:
@@ -331,6 +331,7 @@
|
||||
return
|
||||
. = anchored
|
||||
anchored = anchorvalue
|
||||
SEND_SIGNAL(src, COMSIG_OBJ_SETANCHORED, anchorvalue)
|
||||
// SEND_SIGNAL(src, COMSIG_MOVABLE_SET_ANCHORED, anchorvalue)
|
||||
|
||||
/atom/movable/proc/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
traitor_name = "Bloodsucker"
|
||||
antag_flag = ROLE_BLOODSUCKER
|
||||
false_report_weight = 1
|
||||
chaos = 4
|
||||
restricted_jobs = list("AI","Cyborg")
|
||||
protected_jobs = list("Chaplain", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
||||
required_players = 20
|
||||
@@ -87,7 +88,7 @@
|
||||
// Init Sunlight (called from datum_bloodsucker.on_gain(), in case game mode isn't even Bloodsucker
|
||||
/datum/game_mode/proc/check_start_sunlight()
|
||||
// Already Sunlight (and not about to cancel)
|
||||
if(istype(bloodsucker_sunlight) && !bloodsucker_sunlight.cancel_me)
|
||||
if(istype(bloodsucker_sunlight))
|
||||
return
|
||||
bloodsucker_sunlight = new ()
|
||||
|
||||
@@ -97,7 +98,6 @@
|
||||
if(!istype(bloodsucker_sunlight))
|
||||
return
|
||||
if(bloodsuckers.len <= 0)
|
||||
bloodsucker_sunlight.cancel_me = TRUE
|
||||
qdel(bloodsucker_sunlight)
|
||||
bloodsucker_sunlight = null
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
name = "traitor+brothers"
|
||||
config_tag = "traitorbro"
|
||||
required_players = 25
|
||||
chaos = 5
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
|
||||
config_tag = "changeling"
|
||||
antag_flag = ROLE_CHANGELING
|
||||
false_report_weight = 10
|
||||
chaos = 5
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to ling role blacklist
|
||||
required_players = 15
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "traitor+changeling"
|
||||
config_tag = "traitorchan"
|
||||
false_report_weight = 10
|
||||
chaos = 6
|
||||
traitors_possible = 3 //hard limit on traitors if scaling is turned off
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
required_players = 25
|
||||
|
||||
@@ -134,6 +134,7 @@ Credit where due:
|
||||
config_tag = "clockwork_cult"
|
||||
antag_flag = ROLE_SERVANT_OF_RATVAR
|
||||
false_report_weight = 10
|
||||
chaos = 8
|
||||
required_players = 24 //Fixing this directly for now since apparently config machine for forcing modes broke.
|
||||
required_enemies = 3
|
||||
recommended_enemies = 5
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/game_mode/nuclear/clown_ops
|
||||
name = "clown ops"
|
||||
config_tag = "clownops"
|
||||
|
||||
chaos = 8
|
||||
announce_span = "danger"
|
||||
announce_text = "Clown empire forces are approaching the station in an attempt to HONK it!\n\
|
||||
<span class='danger'>Operatives</span>: Secure the nuclear authentication disk and use your bananium fission explosive to HONK the station.\n\
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
config_tag = "cult"
|
||||
antag_flag = ROLE_CULTIST
|
||||
false_report_weight = 10
|
||||
chaos = 8
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
||||
required_players = 30
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/game_mode/devil/devil_agents
|
||||
name = "Devil Agents"
|
||||
config_tag = "devil_agents"
|
||||
chaos = 5
|
||||
required_players = 25
|
||||
required_enemies = 3
|
||||
recommended_enemies = 8
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
config_tag = "devil"
|
||||
antag_flag = ROLE_DEVIL
|
||||
false_report_weight = 1
|
||||
chaos = 3
|
||||
protected_jobs = list("Lawyer", "Curator", "Chaplain", "Head of Security", "Captain", "AI")
|
||||
required_players = 0
|
||||
required_enemies = 1
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
config_tag = "heresy"
|
||||
antag_flag = ROLE_HERETIC
|
||||
false_report_weight = 5
|
||||
chaos = 5
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to heretic role blacklist
|
||||
required_players = 15
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
config_tag = "secret_extended"
|
||||
false_report_weight = 5
|
||||
required_players = 0
|
||||
chaos = 0
|
||||
|
||||
announce_span = "notice"
|
||||
announce_text = "Just have fun and enjoy the game!"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/config_tag = null
|
||||
var/votable = 1
|
||||
var/probability = 0
|
||||
var/chaos = 5 // 0-9, used for weighting round-to-round
|
||||
var/false_report_weight = 0 //How often will this show up incorrectly in a centcom report?
|
||||
var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm
|
||||
var/nuke_off_station = 0 //Used for tracking where the nuke hit
|
||||
@@ -419,7 +420,7 @@
|
||||
|
||||
for(var/mob/dead/new_player/player in players)
|
||||
if(player.client && player.ready == PLAYER_READY_TO_PLAY)
|
||||
if(role in player.client.prefs.be_special)
|
||||
if((role in player.client.prefs.be_special) && (ROLE_SYNDICATE in player.client.prefs.be_special))
|
||||
if(!jobban_isbanned(player, ROLE_SYNDICATE) && !QDELETED(player) && !jobban_isbanned(player, role) && !QDELETED(player)) //Nodrak/Carn: Antag Job-bans
|
||||
if(age_check(player.client)) //Must be older than the minimum age
|
||||
candidates += player.mind // Get a list of all the people who want to be the antagonist for this round
|
||||
@@ -623,3 +624,10 @@
|
||||
/// Mode specific info for ghost game_info
|
||||
/datum/game_mode/proc/ghost_info()
|
||||
return
|
||||
|
||||
/datum/game_mode/proc/get_chaos()
|
||||
var/chaos_levels = CONFIG_GET(keyed_list/chaos_level)
|
||||
if(config_tag in chaos_levels)
|
||||
return chaos_levels[config_tag]
|
||||
else
|
||||
return chaos
|
||||
|
||||
@@ -6,6 +6,7 @@ GLOBAL_LIST_EMPTY(gangs)
|
||||
name = "gang war"
|
||||
config_tag = "gang"
|
||||
antag_flag = ROLE_GANG
|
||||
chaos = 9
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
||||
required_players = 15
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "meteor"
|
||||
config_tag = "meteor"
|
||||
false_report_weight = 1
|
||||
chaos = 9
|
||||
var/meteordelay = 2000
|
||||
var/nometeors = 0
|
||||
var/rampupdelta = 5
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
required_players = 20
|
||||
required_enemies = 1
|
||||
recommended_enemies = 1
|
||||
chaos = 9
|
||||
|
||||
restricted_jobs = list("Cyborg", "AI")
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "nuclear emergency"
|
||||
config_tag = "nuclear"
|
||||
false_report_weight = 10
|
||||
chaos = 9
|
||||
required_players = 28 // 30 players - 3 players to be the nuke ops = 25 players remaining
|
||||
required_enemies = 2
|
||||
recommended_enemies = 5
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
name = "overthrow"
|
||||
config_tag = "overthrow"
|
||||
antag_flag = ROLE_OVERTHROW
|
||||
chaos = 5
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
||||
required_players = 20 // the core idea is of a swift, bloodless coup, so it shouldn't be as chaotic as revs.
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
config_tag = "revolution"
|
||||
antag_flag = ROLE_REV
|
||||
false_report_weight = 10
|
||||
chaos = 8
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
|
||||
required_players = 20
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
required_enemies = 5
|
||||
recommended_enemies = 8
|
||||
reroll_friendly = 0
|
||||
chaos = 7
|
||||
traitor_name = "Nanotrasen Internal Affairs Agent"
|
||||
antag_flag = ROLE_INTERNAL_AFFAIRS
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
recommended_enemies = 4
|
||||
reroll_friendly = 1
|
||||
enemy_minimum_age = 0
|
||||
chaos = 2
|
||||
|
||||
announce_span = "danger"
|
||||
announce_text = "There are Syndicate agents on the station!\n\
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
recommended_enemies = 1
|
||||
enemy_minimum_age = 7
|
||||
round_ends_with_antag_death = 1
|
||||
chaos = 9
|
||||
announce_span = "danger"
|
||||
announce_text = "There is a space wizard attacking the station!\n\
|
||||
<span class='danger'>Wizard</span>: Accomplish your objectives and cause mayhem on the station.\n\
|
||||
|
||||
@@ -137,7 +137,7 @@ Class Procs:
|
||||
GLOB.machines += src
|
||||
|
||||
if(ispath(circuit, /obj/item/circuitboard))
|
||||
circuit = new circuit
|
||||
circuit = new circuit(src)
|
||||
circuit.apply_default_parts(src)
|
||||
|
||||
if(!speed_process && init_process)
|
||||
@@ -361,11 +361,11 @@ Class Procs:
|
||||
/obj/machinery/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
on_deconstruction()
|
||||
if(component_parts && component_parts.len)
|
||||
if(LAZYLEN(component_parts))
|
||||
spawn_frame(disassembled)
|
||||
for(var/obj/item/I in component_parts)
|
||||
I.forceMove(loc)
|
||||
component_parts.Cut()
|
||||
LAZYCLEARLIST(component_parts)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/proc/spawn_frame(disassembled)
|
||||
@@ -539,12 +539,17 @@ Class Procs:
|
||||
|
||||
/obj/machinery/Exited(atom/movable/AM, atom/newloc)
|
||||
. = ..()
|
||||
// if(AM == occupant)
|
||||
// set_occupant(null)
|
||||
if (AM == occupant)
|
||||
SEND_SIGNAL(src, COMSIG_MACHINE_EJECT_OCCUPANT, occupant)
|
||||
occupant = null
|
||||
if(AM == circuit && circuit.loc != src)
|
||||
component_parts -= AM //TODO: make the cmp part functions use lazyX
|
||||
circuit = null
|
||||
|
||||
/obj/machinery/proc/adjust_item_drop_location(atom/movable/AM) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8
|
||||
var/md5 = md5(AM.name) // Oh, and it's deterministic too. A specific item will always drop from the same slot.
|
||||
/obj/machinery/proc/adjust_item_drop_location(atom/movable/AM) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8
|
||||
var/md5 = md5(AM.name) // Oh, and it's deterministic too. A specific item will always drop from the same slot.
|
||||
for (var/i in 1 to 32)
|
||||
. += hex2num(md5[i])
|
||||
. = . % 9
|
||||
|
||||
@@ -8,7 +8,19 @@
|
||||
max_integrity = 200
|
||||
var/obj/item/bodypart/storedpart
|
||||
var/initial_icon_state
|
||||
var/static/list/style_list_icons = list("standard" = 'icons/mob/augmentation/augments.dmi', "engineer" = 'icons/mob/augmentation/augments_engineer.dmi', "security" = 'icons/mob/augmentation/augments_security.dmi', "mining" = 'icons/mob/augmentation/augments_mining.dmi')
|
||||
var/static/list/style_list_icons = list("standard" = 'icons/mob/augmentation/augments.dmi',
|
||||
"engineer" = 'icons/mob/augmentation/augments_engineer.dmi',
|
||||
"security" = 'icons/mob/augmentation/augments_security.dmi',
|
||||
"mining" = 'icons/mob/augmentation/augments_mining.dmi',
|
||||
"Talon" = 'icons/mob/augmentation/cosmetic_prosthetic/talon.dmi',
|
||||
"Nanotrasen" = 'icons/mob/augmentation/cosmetic_prosthetic/nanotrasen.dmi',
|
||||
"Hephaesthus" = 'icons/mob/augmentation/cosmetic_prosthetic/hephaestus.dmi',
|
||||
"Bishop" = 'icons/mob/augmentation/cosmetic_prosthetic/bishop.dmi',
|
||||
"Xion" = 'icons/mob/augmentation/cosmetic_prosthetic/xion.dmi',
|
||||
"Grayson" = 'icons/mob/augmentation/cosmetic_prosthetic/grayson.dmi',
|
||||
"Cybersolutions" = 'icons/mob/augmentation/cosmetic_prosthetic/cybersolutions.dmi',
|
||||
"Ward" = 'icons/mob/augmentation/cosmetic_prosthetic/ward.dmi'
|
||||
)
|
||||
|
||||
/obj/machinery/aug_manipulator/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -17,20 +17,16 @@
|
||||
|
||||
/obj/machinery/computer/Initialize(mapload, obj/item/circuitboard/C)
|
||||
. = ..()
|
||||
|
||||
power_change()
|
||||
if(!QDELETED(C))
|
||||
qdel(circuit)
|
||||
circuit = C
|
||||
C.moveToNullspace()
|
||||
|
||||
/obj/machinery/computer/Destroy()
|
||||
QDEL_NULL(circuit)
|
||||
return ..()
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/computer/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/ratvar_act()
|
||||
if(!clockwork)
|
||||
@@ -87,25 +83,32 @@
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
if(stat & BROKEN)
|
||||
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
|
||||
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, TRUE)
|
||||
else
|
||||
playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1)
|
||||
playsound(src.loc, 'sound/effects/glasshit.ogg', 75, TRUE)
|
||||
if(BURN)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, TRUE)
|
||||
|
||||
/obj/machinery/computer/obj_break(damage_flag)
|
||||
if(circuit && !(flags_1 & NODECONSTRUCT_1)) //no circuit, no breaking
|
||||
if(!(stat & BROKEN))
|
||||
playsound(loc, 'sound/effects/glassbr3.ogg', 100, 1)
|
||||
stat |= BROKEN
|
||||
update_icon()
|
||||
set_light(0)
|
||||
if(!circuit) //no circuit, no breaking
|
||||
return
|
||||
. = ..()
|
||||
if(. && !(stat & BROKEN))
|
||||
stat |= BROKEN
|
||||
playsound(loc, 'sound/effects/glassbr3.ogg', 100, TRUE)
|
||||
set_light(0)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/emp_act(severity)
|
||||
. = ..()
|
||||
if (!(. & EMP_PROTECT_SELF))
|
||||
if(prob(severity/1.8))
|
||||
obj_break("energy")
|
||||
switch(severity)
|
||||
if(1)
|
||||
if(prob(50))
|
||||
obj_break("energy")
|
||||
if(2)
|
||||
if(prob(10))
|
||||
obj_break("energy")
|
||||
|
||||
/obj/machinery/computer/deconstruct(disassembled = TRUE, mob/user)
|
||||
on_deconstruction()
|
||||
@@ -114,12 +117,14 @@
|
||||
var/obj/structure/frame/computer/A = new /obj/structure/frame/computer(src.loc)
|
||||
A.setDir(dir)
|
||||
A.circuit = circuit
|
||||
A.setAnchored(TRUE)
|
||||
// Circuit removal code is handled in /obj/machinery/Exited()
|
||||
circuit.forceMove(A)
|
||||
A.set_anchored(TRUE)
|
||||
if(stat & BROKEN)
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>The broken glass falls out.</span>")
|
||||
else
|
||||
playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
|
||||
playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, TRUE)
|
||||
new /obj/item/shard(drop_location())
|
||||
new /obj/item/shard(drop_location())
|
||||
A.state = 3
|
||||
@@ -129,8 +134,11 @@
|
||||
to_chat(user, "<span class='notice'>You disconnect the monitor.</span>")
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
circuit = null
|
||||
for(var/obj/C in src)
|
||||
C.forceMove(loc)
|
||||
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/computer/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!user.canUseTopic(src, !issilicon(user)) || !(stat & (NOPOWER|BROKEN)))
|
||||
return
|
||||
|
||||
@@ -243,13 +243,14 @@
|
||||
|
||||
// Check if the user can use it.
|
||||
/obj/machinery/telecomms/proc/canInteract(mob/user)
|
||||
var/get = user.get_active_held_item()
|
||||
var/obj/item/I = get
|
||||
if(I.tool_behaviour == TOOL_MULTITOOL)
|
||||
return TRUE
|
||||
var/obj/item/I = user.get_active_held_item()
|
||||
if(!issilicon(user) && I)
|
||||
if(I.tool_behaviour == TOOL_MULTITOOL)
|
||||
return TRUE
|
||||
if(hasSiliconAccessInArea(user))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// Check if the user is nearby and has a multitool.
|
||||
/obj/machinery/telecomms/proc/canAccess(mob/user)
|
||||
if((canInteract(user) && in_range(user, src)) || hasSiliconAccessInArea(user))
|
||||
@@ -262,14 +263,13 @@
|
||||
return null
|
||||
var/obj/item/P = user.get_active_held_item()
|
||||
// Is the ref not a null? and is it the actual type?
|
||||
if(P.tool_behaviour == TOOL_MULTITOOL)
|
||||
return P
|
||||
else if(isAI(user))
|
||||
if(isAI(user))
|
||||
var/mob/living/silicon/ai/U = user
|
||||
P = U.aiMulti
|
||||
else if(iscyborg(user) && in_range(user, src))
|
||||
var/get = user.get_active_held_item()
|
||||
var/obj/item/I = get
|
||||
if(I.tool_behaviour == TOOL_MULTITOOL)
|
||||
I = user.get_active_held_item()
|
||||
else if(iscyborg(user) && !in_range(user, src))
|
||||
return null
|
||||
if(!P)
|
||||
return null
|
||||
else if(P.tool_behaviour == TOOL_MULTITOOL)
|
||||
return P
|
||||
return P
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/Initialize(mapload)
|
||||
stored_research = new
|
||||
rmat = AddComponent(/datum/component/remote_materials, "mechfab", mapload && link_on_init)
|
||||
rmat = AddComponent(/datum/component/remote_materials, "mechfab", mapload && link_on_init, _after_insert=CALLBACK(src, .proc/AfterMaterialInsert))
|
||||
|
||||
RefreshParts() //Recalculating local material sizes if the fab isn't linked
|
||||
return ..()
|
||||
|
||||
@@ -132,7 +132,6 @@
|
||||
events = new
|
||||
icon_state += "-open"
|
||||
add_radio()
|
||||
add_cabin()
|
||||
spark_system.set_up(2, 0, src)
|
||||
spark_system.attach(src)
|
||||
smoke_system.set_up(3, src)
|
||||
@@ -153,6 +152,7 @@
|
||||
/obj/mecha/LateInitialize()
|
||||
. = ..()
|
||||
add_airtank()
|
||||
add_cabin()
|
||||
|
||||
/obj/mecha/get_cell()
|
||||
return cell
|
||||
@@ -255,9 +255,8 @@
|
||||
cell = new /obj/item/stock_parts/cell/high/plus(src)
|
||||
|
||||
/obj/mecha/proc/add_cabin()
|
||||
cabin_air = new
|
||||
cabin_air = new(200)
|
||||
cabin_air.set_temperature(T20C)
|
||||
cabin_air.set_volume(200)
|
||||
cabin_air.set_moles(/datum/gas/oxygen,O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
|
||||
cabin_air.set_moles(/datum/gas/nitrogen,N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
|
||||
return cabin_air
|
||||
|
||||
@@ -243,6 +243,17 @@
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/temp_visual/voidpush
|
||||
name = "eldritch energy"
|
||||
icon_state = "emark4"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/temp_visual/voidswap
|
||||
name = "altered space"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "voidalter"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/temp_visual/telekinesis
|
||||
name = "telekinetic force"
|
||||
icon_state = "empdisable"
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
if(isopenturf(target))
|
||||
deploy_bodybag(user, target)
|
||||
|
||||
/obj/item/bodybag/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
|
||||
return (user in src)
|
||||
|
||||
/obj/item/bodybag/proc/deploy_bodybag(mob/user, atom/location)
|
||||
var/obj/structure/closet/body_bag/R = new unfoldedbag_path(location)
|
||||
R.open(user)
|
||||
|
||||
@@ -721,24 +721,24 @@
|
||||
|
||||
/obj/item/disk/medical/defib_heal
|
||||
name = "Defibrillator Healing Disk"
|
||||
desc = "An upgrade which increases the healing power of the defibrillator"
|
||||
desc = "An upgrade which increases the healing power of the defibrillator."
|
||||
icon_state = "heal_disk"
|
||||
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 18000, /datum/material/gold = 6000, /datum/material/silver = 6000)
|
||||
|
||||
/obj/item/disk/medical/defib_shock
|
||||
name = "Defibrillator Anti-Shock Disk"
|
||||
desc = "A safety upgrade that guarantees only the patient will get shocked"
|
||||
desc = "A safety upgrade that guarantees only the patient will get shocked."
|
||||
icon_state = "zap_disk"
|
||||
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 18000, /datum/material/gold = 6000, /datum/material/silver = 6000)
|
||||
|
||||
/obj/item/disk/medical/defib_decay
|
||||
name = "Defibrillator Body-Decay Extender Disk"
|
||||
desc = "An upgrade allowing the defibrillator to work on more decayed bodies"
|
||||
desc = "An upgrade allowing the defibrillator to work on bodies that have decayed further."
|
||||
icon_state = "body_disk"
|
||||
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 18000, /datum/material/gold = 16000, /datum/material/silver = 6000, /datum/material/titanium = 2000)
|
||||
|
||||
/obj/item/disk/medical/defib_speed
|
||||
name = "Defibrillator Fast Charge Disk"
|
||||
desc = "An upgrade to the defibrillator capacitors, which let it charge faster"
|
||||
desc = "An upgrade to the defibrillator capacitors, which lets it charge faster."
|
||||
icon_state = "fast_disk"
|
||||
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 8000, /datum/material/gold = 26000, /datum/material/silver = 26000)
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
|
||||
/obj/item/melee/proc/check_martial_counter(mob/living/carbon/human/target, mob/living/carbon/human/user)
|
||||
if(target.check_martial_melee_block())
|
||||
target.visible_message("<span class='danger'>[target.name] blocks [src] and twists [user]'s arm behind [user.p_their()] back!</span>",
|
||||
target.visible_message("<span class='danger'>[target.name] blocks your attack!</span>",
|
||||
"<span class='userdanger'>You block the attack!</span>")
|
||||
user.Stun(40)
|
||||
return TRUE
|
||||
|
||||
/obj/item/melee/chainofcommand
|
||||
|
||||
@@ -332,6 +332,7 @@
|
||||
to_chat(occupant, "You pop out of the [src], slightly dazed!")
|
||||
occupant.Stun(5 SECONDS)
|
||||
|
||||
|
||||
/obj/item/pet_carrier/bluespace/return_air()
|
||||
if(!occupant_gas_supply)
|
||||
occupant_gas_supply = new
|
||||
@@ -353,4 +354,14 @@
|
||||
if(..())
|
||||
name = "[initial(name)] ([target])"
|
||||
|
||||
/obj/item/pet_carrier/bluespace/single_use
|
||||
desc = "A jar, that seems to be bigger on the inside, somehow allowing lifeforms to fit through its narrow entrance. This one looks exceptionally fragile."
|
||||
|
||||
/obj/item/pet_carrier/bluespace/single_use/remove_occupant(mob/living/occupant)
|
||||
. = ..()
|
||||
|
||||
if(!QDELETED(src))
|
||||
playsound(src, "shatter", 70, 1)
|
||||
qdel(src)
|
||||
|
||||
#undef pet_carrier_full
|
||||
|
||||
@@ -469,7 +469,7 @@
|
||||
//hijacking the minature first aids for hypospray boxes. <3
|
||||
/obj/item/storage/hypospraykit
|
||||
name = "hypospray kit"
|
||||
desc = "It's a kit containing a hypospray and specific treatment chemical-filled vials."
|
||||
desc = "It's a kit designed for containing a hypospray and specific treatment chemical-filled vials."
|
||||
icon_state = "firstaid-mini"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
/obj/item/tank/internals/air
|
||||
name = "air tank"
|
||||
desc = "Mixed anyone?"
|
||||
icon_state = "air"
|
||||
item_state = "air"
|
||||
force = 10
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
|
||||
@@ -80,9 +80,9 @@
|
||||
SStgui.close_uis(src)
|
||||
. = ..()
|
||||
|
||||
/// @depricated DO NOT USE
|
||||
/obj/proc/setAnchored(anchorvalue)
|
||||
SEND_SIGNAL(src, COMSIG_OBJ_SETANCHORED, anchorvalue)
|
||||
anchored = anchorvalue
|
||||
set_anchored(anchorvalue)
|
||||
|
||||
/obj/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, messy_throw = TRUE)
|
||||
. = ..()
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
//Adding canvases
|
||||
/obj/structure/easel/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/canvas))
|
||||
var/obj/item/canvas/C = I
|
||||
user.dropItemToGround(C)
|
||||
painting = C
|
||||
C.forceMove(get_turf(src))
|
||||
C.layer = layer+0.1
|
||||
user.visible_message("<span class='notice'>[user] puts \the [C] on \the [src].</span>","<span class='notice'>You place \the [C] on \the [src].</span>")
|
||||
var/obj/item/canvas/canvas = I
|
||||
user.dropItemToGround(canvas)
|
||||
painting = canvas
|
||||
canvas.forceMove(get_turf(src))
|
||||
canvas.layer = layer+0.1
|
||||
user.visible_message("<span class='notice'>[user] puts \the [canvas] on \the [src].</span>","<span class='notice'>You place \the [canvas] on \the [src].</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -40,13 +40,14 @@
|
||||
desc = "Draw out your soul on this canvas!"
|
||||
icon = 'icons/obj/artstuff.dmi'
|
||||
icon_state = "11x11"
|
||||
// flags_1 = UNPAINTABLE_1
|
||||
resistance_flags = FLAMMABLE
|
||||
var/width = 11
|
||||
var/height = 11
|
||||
var/list/grid
|
||||
var/canvas_color = "#ffffff" //empty canvas color
|
||||
var/used = FALSE
|
||||
var/painting_name //Painting name, this is set after framing.
|
||||
var/painting_name = "Untitled Artwork" //Painting name, this is set after framing.
|
||||
var/finalized = FALSE //Blocks edits
|
||||
var/author_ckey
|
||||
var/icon_generated = FALSE
|
||||
@@ -132,17 +133,19 @@
|
||||
|
||||
/obj/item/canvas/update_overlays()
|
||||
. = ..()
|
||||
if(!icon_generated)
|
||||
if(used)
|
||||
var/mutable_appearance/detail = mutable_appearance(icon,"[icon_state]wip")
|
||||
detail.pixel_x = 1
|
||||
detail.pixel_y = 1
|
||||
. += detail
|
||||
else
|
||||
if(icon_generated)
|
||||
var/mutable_appearance/detail = mutable_appearance(generated_icon)
|
||||
detail.pixel_x = 1
|
||||
detail.pixel_y = 1
|
||||
. += detail
|
||||
return
|
||||
if(!used)
|
||||
return
|
||||
|
||||
var/mutable_appearance/detail = mutable_appearance(icon, "[icon_state]wip")
|
||||
detail.pixel_x = 1
|
||||
detail.pixel_y = 1
|
||||
. += detail
|
||||
|
||||
/obj/item/canvas/proc/generate_proper_overlay()
|
||||
if(icon_generated)
|
||||
@@ -167,8 +170,8 @@
|
||||
if(!I)
|
||||
return
|
||||
if(istype(I, /obj/item/toy/crayon))
|
||||
var/obj/item/toy/crayon/C = I
|
||||
return C.paint_color
|
||||
var/obj/item/toy/crayon/crayon = I
|
||||
return crayon.paint_color
|
||||
else if(istype(I, /obj/item/pen))
|
||||
var/obj/item/pen/P = I
|
||||
switch(P.colour)
|
||||
@@ -184,7 +187,7 @@
|
||||
|
||||
/obj/item/canvas/proc/try_rename(mob/user)
|
||||
var/new_name = stripped_input(user,"What do you want to name the painting?")
|
||||
if(!painting_name && new_name && user.canUseTopic(src,BE_CLOSE))
|
||||
if(new_name != painting_name && new_name && user.canUseTopic(src,BE_CLOSE))
|
||||
painting_name = new_name
|
||||
SStgui.update_uis(src)
|
||||
|
||||
@@ -215,12 +218,23 @@
|
||||
framed_offset_x = 5
|
||||
framed_offset_y = 6
|
||||
|
||||
/obj/item/canvas/twentyfour_twentyfour
|
||||
name = "ai universal standard canvas"
|
||||
desc = "Besides being very large, the AI can accept these as a display from their internal database after you've hung it up."
|
||||
icon_state = "24x24"
|
||||
width = 24
|
||||
height = 24
|
||||
pixel_x = 2
|
||||
pixel_y = 1
|
||||
framed_offset_x = 4
|
||||
framed_offset_y = 5
|
||||
|
||||
/obj/item/wallframe/painting
|
||||
name = "painting frame"
|
||||
desc = "The perfect showcase for your favorite deathtrap memories."
|
||||
icon = 'icons/obj/decals.dmi'
|
||||
custom_materials = null
|
||||
flags_1 = 0
|
||||
custom_materials = list(/datum/material/wood = 2000)
|
||||
flags_1 = NONE
|
||||
icon_state = "frame-empty"
|
||||
result_path = /obj/structure/sign/painting
|
||||
|
||||
@@ -229,8 +243,13 @@
|
||||
desc = "Art or \"Art\"? You decide."
|
||||
icon = 'icons/obj/decals.dmi'
|
||||
icon_state = "frame-empty"
|
||||
// base_icon_state = "frame"
|
||||
custom_materials = list(/datum/material/wood = 2000)
|
||||
buildable_sign = FALSE
|
||||
var/obj/item/canvas/C
|
||||
///Canvas we're currently displaying.
|
||||
var/obj/item/canvas/current_canvas
|
||||
///Description set when canvas is added.
|
||||
var/desc_with_canvas
|
||||
var/persistence_id
|
||||
|
||||
/obj/structure/sign/painting/Initialize(mapload, dir, building)
|
||||
@@ -242,64 +261,78 @@
|
||||
if(building)
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? -30 : 30)
|
||||
pixel_y = (dir & 3)? (dir ==1 ? -30 : 30) : 0
|
||||
desc = current_canvas ? desc_with_canvas : initial(desc)
|
||||
|
||||
/obj/structure/sign/painting/Destroy()
|
||||
. = ..()
|
||||
SSpersistence.painting_frames -= src
|
||||
|
||||
/obj/structure/sign/painting/attackby(obj/item/I, mob/user, params)
|
||||
if(!C && istype(I, /obj/item/canvas))
|
||||
if(!current_canvas && istype(I, /obj/item/canvas))
|
||||
frame_canvas(user,I)
|
||||
else if(C && !C.painting_name && istype(I,/obj/item/pen))
|
||||
else if(current_canvas && current_canvas.painting_name == initial(current_canvas.painting_name) && istype(I,/obj/item/pen))
|
||||
try_rename(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/sign/painting/examine(mob/user)
|
||||
. = ..()
|
||||
if(C)
|
||||
C.ui_interact(user)
|
||||
if(persistence_id)
|
||||
. += "<span class='notice'>Any painting placed here will be archived at the end of the shift.</span>"
|
||||
if(current_canvas)
|
||||
current_canvas.ui_interact(user)
|
||||
. += "<span class='notice'>Use wirecutters to remove the painting.</span>"
|
||||
|
||||
/obj/structure/sign/painting/wirecutter_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(C)
|
||||
C.forceMove(drop_location())
|
||||
C = null
|
||||
if(current_canvas)
|
||||
current_canvas.forceMove(drop_location())
|
||||
current_canvas = null
|
||||
to_chat(user, "<span class='notice'>You remove the painting from the frame.</span>")
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/sign/painting/proc/frame_canvas(mob/user,obj/item/canvas/new_canvas)
|
||||
if(user.transferItemToLoc(new_canvas,src))
|
||||
C = new_canvas
|
||||
if(!C.finalized)
|
||||
C.finalize(user)
|
||||
to_chat(user,"<span class='notice'>You frame [C].</span>")
|
||||
current_canvas = new_canvas
|
||||
if(!current_canvas.finalized)
|
||||
current_canvas.finalize(user)
|
||||
to_chat(user,"<span class='notice'>You frame [current_canvas].</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/structure/sign/painting/proc/try_rename(mob/user)
|
||||
if(!C.painting_name)
|
||||
C.try_rename(user)
|
||||
if(current_canvas.painting_name == initial(current_canvas.painting_name))
|
||||
current_canvas.try_rename(user)
|
||||
|
||||
// /obj/structure/sign/painting/update_name(updates)
|
||||
// name = current_canvas ? "painting - [current_canvas.painting_name]" : initial(name)
|
||||
// return ..()
|
||||
|
||||
// /obj/structure/sign/painting/update_desc(updates)
|
||||
// desc = current_canvas ? desc_with_canvas : initial(desc)
|
||||
// return ..()
|
||||
|
||||
/obj/structure/sign/painting/update_icon_state()
|
||||
. = ..()
|
||||
if(C && C.generated_icon)
|
||||
icon_state = null
|
||||
else
|
||||
// icon_state = "[base_icon_state]-[current_canvas?.generated_icon ? "overlay" : "empty"]"
|
||||
if(current_canvas?.generated_icon)
|
||||
icon_state = "frame-empty"
|
||||
|
||||
else
|
||||
icon_state = null // or "frame-empty"
|
||||
return ..()
|
||||
|
||||
/obj/structure/sign/painting/update_overlays()
|
||||
. = ..()
|
||||
if(C && C.generated_icon)
|
||||
var/mutable_appearance/MA = mutable_appearance(C.generated_icon)
|
||||
MA.pixel_x = C.framed_offset_x
|
||||
MA.pixel_y = C.framed_offset_y
|
||||
. += MA
|
||||
var/mutable_appearance/frame = mutable_appearance(C.icon,"[C.icon_state]frame")
|
||||
frame.pixel_x = C.framed_offset_x - 1
|
||||
frame.pixel_y = C.framed_offset_y - 1
|
||||
. += frame
|
||||
if(!current_canvas?.generated_icon)
|
||||
return
|
||||
|
||||
var/mutable_appearance/MA = mutable_appearance(current_canvas.generated_icon)
|
||||
MA.pixel_x = current_canvas.framed_offset_x
|
||||
MA.pixel_y = current_canvas.framed_offset_y
|
||||
. += MA
|
||||
var/mutable_appearance/frame = mutable_appearance(current_canvas.icon,"[current_canvas.icon_state]frame")
|
||||
frame.pixel_x = current_canvas.framed_offset_x - 1
|
||||
frame.pixel_y = current_canvas.framed_offset_y - 1
|
||||
. += frame
|
||||
|
||||
/obj/structure/sign/painting/proc/load_persistent()
|
||||
if(!persistence_id)
|
||||
@@ -310,6 +343,10 @@
|
||||
var/title = chosen["title"]
|
||||
var/author = chosen["ckey"]
|
||||
var/png = "data/paintings/[persistence_id]/[chosen["md5"]].png"
|
||||
if(!title)
|
||||
title = "Untitled Artwork" //Should prevent NULL named art from loading as NULL, if you're still getting the admin log chances are persistence is broken
|
||||
if(!title)
|
||||
message_admins("<span class='notice'>Painting with NO TITLE loaded on a [persistence_id] frame in [get_area(src)]. Please delete it, it is saved in the database with no name and will create bad assets.</span>")
|
||||
if(!fexists(png))
|
||||
stack_trace("Persistent painting [chosen["md5"]].png was not found in [persistence_id] directory.")
|
||||
return
|
||||
@@ -328,17 +365,20 @@
|
||||
new_canvas.finalized = TRUE
|
||||
new_canvas.painting_name = title
|
||||
new_canvas.author_ckey = author
|
||||
C = new_canvas
|
||||
new_canvas.name = "painting - [title]"
|
||||
current_canvas = new_canvas
|
||||
update_icon()
|
||||
|
||||
/obj/structure/sign/painting/proc/save_persistent()
|
||||
if(!persistence_id || !C)
|
||||
if(!persistence_id || !current_canvas)
|
||||
return
|
||||
if(sanitize_filename(persistence_id) != persistence_id)
|
||||
stack_trace("Invalid persistence_id - [persistence_id]")
|
||||
return
|
||||
var/data = C.get_data_string()
|
||||
var/md5 = md5(data)
|
||||
if(!current_canvas.painting_name)
|
||||
current_canvas.painting_name = "Untitled Artwork"
|
||||
var/data = current_canvas.get_data_string()
|
||||
var/md5 = md5(lowertext(data))
|
||||
var/list/current = SSpersistence.paintings[persistence_id]
|
||||
if(!current)
|
||||
current = list()
|
||||
@@ -347,10 +387,10 @@
|
||||
return
|
||||
var/png_directory = "data/paintings/[persistence_id]/"
|
||||
var/png_path = png_directory + "[md5].png"
|
||||
var/result = rustg_dmi_create_png(png_path,"[C.width]","[C.height]",data)
|
||||
var/result = rustg_dmi_create_png(png_path,"[current_canvas.width]","[current_canvas.height]",data)
|
||||
if(result)
|
||||
CRASH("Error saving persistent painting: [result]")
|
||||
current += list(list("title" = C.painting_name , "md5" = md5, "ckey" = C.author_ckey))
|
||||
current += list(list("title" = current_canvas.painting_name , "md5" = md5, "ckey" = current_canvas.author_ckey))
|
||||
SSpersistence.paintings[persistence_id] = current
|
||||
|
||||
/obj/item/canvas/proc/fill_grid_from_icon(icon/I)
|
||||
@@ -361,12 +401,21 @@
|
||||
|
||||
//Presets for art gallery mapping, for paintings to be shared across stations
|
||||
/obj/structure/sign/painting/library
|
||||
name = "\improper Public Painting Exhibit mounting"
|
||||
desc = "For art pieces hung by the public."
|
||||
desc_with_canvas = "A piece of art (or \"art\"). Anyone could've hung it."
|
||||
persistence_id = "library"
|
||||
|
||||
/obj/structure/sign/painting/library_secure
|
||||
name = "\improper Curated Painting Exhibit mounting"
|
||||
desc = "For masterpieces hand-picked by the curator."
|
||||
desc_with_canvas = "A masterpiece hand-picked by the curator, supposedly."
|
||||
persistence_id = "library_secure"
|
||||
|
||||
/obj/structure/sign/painting/library_private // keep your smut away from prying eyes, or non-librarians at least
|
||||
name = "\improper Private Painting Exhibit mounting"
|
||||
desc = "For art pieces deemed too subversive or too illegal to be shared outside of curators."
|
||||
desc_with_canvas = "A painting hung away from lesser minds."
|
||||
persistence_id = "library_private"
|
||||
|
||||
/obj/structure/sign/painting/vv_get_dropdown()
|
||||
@@ -379,11 +428,11 @@
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
var/mob/user = usr
|
||||
if(!persistence_id || !C)
|
||||
if(!persistence_id || !current_canvas)
|
||||
to_chat(user,"<span class='warning'>This is not a persistent painting.</span>")
|
||||
return
|
||||
var/md5 = md5(C.get_data_string())
|
||||
var/author = C.author_ckey
|
||||
var/md5 = md5(lowertext(current_canvas.get_data_string()))
|
||||
var/author = current_canvas.author_ckey
|
||||
var/list/current = SSpersistence.paintings[persistence_id]
|
||||
if(current)
|
||||
for(var/list/entry in current)
|
||||
@@ -392,7 +441,8 @@
|
||||
var/png = "data/paintings/[persistence_id]/[md5].png"
|
||||
fdel(png)
|
||||
for(var/obj/structure/sign/painting/P in SSpersistence.painting_frames)
|
||||
if(P.C && md5(P.C.get_data_string()) == md5)
|
||||
QDEL_NULL(P.C)
|
||||
if(P.current_canvas && md5(P.current_canvas.get_data_string()) == md5)
|
||||
QDEL_NULL(P.current_canvas)
|
||||
P.update_icon()
|
||||
log_admin("[key_name(user)] has deleted a persistent painting made by [author].")
|
||||
message_admins("<span class='notice'>[key_name_admin(user)] has deleted persistent painting made by [author].</span>")
|
||||
|
||||
@@ -626,4 +626,4 @@
|
||||
T1.visible_message("<span class='warning'>[user] dives into [src]!</span>")
|
||||
|
||||
/obj/structure/closet/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
|
||||
return ..() && opened
|
||||
return (user in src)
|
||||
|
||||
Reference in New Issue
Block a user