Merge branch 'master' into upstream-merge-27890

This commit is contained in:
LetterJay
2017-06-10 08:02:27 -05:00
committed by GitHub
296 changed files with 4909 additions and 9181 deletions
+3 -1
View File
@@ -95,11 +95,13 @@
//tablecrafting defines
#define CAT_NONE ""
#define CAT_WEAPON "Weaponry"
#define CAT_WEAPONRY "Weaponry"
#define CAT_WEAPON "Weapons"
#define CAT_AMMO "Ammunition"
#define CAT_ROBOT "Robots"
#define CAT_MISC "Misc"
#define CAT_PRIMAL "Tribal"
#define CAT_FOOD "Foods"
#define CAT_BREAD "Breads"
#define CAT_BURGER "Burgers"
#define CAT_CAKE "Cakes"
+5 -1
View File
@@ -429,4 +429,8 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define GIBTONITE_UNSTRUCK 0
#define GIBTONITE_ACTIVE 1
#define GIBTONITE_STABLE 2
#define GIBTONITE_DETONATE 3
#define GIBTONITE_DETONATE 3
//Gangster starting influences
#define GANGSTER_SOLDIER_STARTING_INFLUENCE 5
#define GANGSTER_BOSS_STARTING_INFLUENCE 20
+27
View File
@@ -0,0 +1,27 @@
#define REBOOT_MODE_NORMAL 0
#define REBOOT_MODE_HARD 1
#define REBOOT_MODE_SHUTDOWN 2
#define IRC_STATUS_THROTTLE 50
//keep these in sync with TGS3
#define SERVICE_WORLD_PARAM "server_service"
#define SERVICE_PR_TEST_JSON "..\\..\\prtestjob.json"
#define SERVICE_CMD_HARD_REBOOT "hard_reboot"
#define SERVICE_CMD_GRACEFUL_SHUTDOWN "graceful_shutdown"
#define SERVICE_CMD_WORLD_ANNOUNCE "world_announce"
#define SERVICE_CMD_IRC_STATUS "irc_status"
#define SERVICE_CMD_ADMIN_MSG "adminmsg"
#define SERVICE_CMD_NAME_CHECK "namecheck"
#define SERVICE_CMD_ADMIN_WHO "adminwho"
//#define SERVICE_CMD_PARAM_KEY //defined in __compile_options.dm
#define SERVICE_CMD_PARAM_COMMAND "command"
#define SERVICE_CMD_PARAM_MESSAGE "message"
#define SERVICE_CMD_PARAM_TARGET "target"
#define SERVICE_CMD_PARAM_SENDER "sender"
#define SERVICE_REQUEST_KILL_PROCESS "killme"
#define SERVICE_REQUEST_IRC_BROADCAST "irc"
#define SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE "send2irc"
+9 -1
View File
@@ -30,7 +30,6 @@
// DEBUFFS //
/////////////
#define STATUS_EFFECT_SIGILMARK /datum/status_effect/sigil_mark
#define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run
#define STATUS_EFFECT_MANIAMOTOR /datum/status_effect/maniamotor //disrupts, damages, and confuses the affected as long as they're in range of the motor
@@ -41,3 +40,12 @@
#define STATUS_EFFECT_SUMMONEDGHOST /datum/status_effect/cultghost //is a cult ghost and can't use manifest runes
#define STATUS_EFFECT_CRUSHERMARK /datum/status_effect/crusher_mark //if struck with a proto-kinetic crusher, takes a ton of damage
/////////////
// NEUTRAL //
/////////////
#define STATUS_EFFECT_SIGILMARK /datum/status_effect/sigil_mark
#define STATUS_EFFECT_CRUSHERDAMAGETRACKING /datum/status_effect/crusher_damage //tracks total kinetic crusher damage on a target
+4 -1
View File
@@ -131,9 +131,12 @@
return
//Removes any null entries from the list
//Returns TRUE if the list had nulls, FALSE otherwise
/proc/listclearnulls(list/L)
var/list/N = new(L.len)
var/start_len = L.len
var/list/N = new(start_len)
L -= N
return L.len < start_len
/*
* Returns list containing all the entries from first list that are not present in second.
+8 -4
View File
@@ -3,7 +3,7 @@
for(var/file in args)
src << browse_rsc(file)
/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list(".txt",".log",".htm"))
/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list("txt","log","htm", "html"))
var/path = root
for(var/i=0, i<max_iterations, i++)
@@ -22,9 +22,13 @@
if(copytext(path,-1,0) != "/") //didn't choose a directory, no need to iterate again
break
var/extension = copytext(path,-4,0)
if( !fexists(path) || !(extension in valid_extensions) )
var/extensions
for(var/i in valid_extensions)
if(extensions)
extensions += "|"
extensions += "[i]"
var/regex/valid_ext = new("\\.([extensions])$", "i")
if( !fexists(path) || !(valid_ext.Find(path)) )
to_chat(src, "<font color='red'>Error: browse_files(): File not found/Invalid file([path]).</font>")
return
+2 -1
View File
@@ -507,7 +507,8 @@
return
//First we spawn a dude.
var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin))//The mob being spawned.
var/mob/living/carbon/human/new_character = new//The mob being spawned.
SSjob.SendToLateJoin(new_character)
G_found.client.prefs.copy_to(new_character)
new_character.dna.update_dna_identity()
+1 -1
View File
@@ -1344,7 +1344,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
//kevinz000 if you touch this I will hunt you down
GLOBAL_VAR_INIT(valid_HTTPSGet, FALSE)
GLOBAL_PROTECT(valid_HTTPSGet)
/proc/HTTPSGet(url)
/proc/HTTPSGet(url) //tgs2 support
if(findtext(url, "\""))
GLOB.valid_HTTPSGet = FALSE
+4 -6
View File
@@ -35,7 +35,7 @@
//MINOR TWEAKS/MISC
#define AGE_MIN 17 //youngest a character can be
#define AGE_MAX 85 //oldest a character can be
#define WIZARD_AGE_MIN 30 //youngest a wizard can be
#define WIZARD_AGE_MIN 30 //youngest a wizard can be
#define SHOES_SLOWDOWN 0 //How much shoes slow you down by default. Negative values speed you up
#define POCKET_STRIP_DELAY 40 //time taken (in deciseconds) to search somebody's pockets
#define DOOR_CRUSH_DAMAGE 15 //the amount of damage that airlocks deal when they crush you
@@ -62,14 +62,12 @@
#endif
//Update this whenever you need to take advantage of more recent byond features
#define MIN_COMPILER_VERSION 511
#define MIN_COMPILER_VERSION 511
#if DM_VERSION < MIN_COMPILER_VERSION
//Don't forget to update this part
#error Your version of BYOND is too out-of-date to compile this project. Go to byond.com/download and update.
#error You need version 511 or higher
#error You need version 511 or higher
#endif
#ifndef SERVERTOOLS
#define SERVERTOOLS 0
#endif
#define SERVICE_CMD_PARAM_KEY "serviceCommsKey"
-1
View File
@@ -32,7 +32,6 @@ GLOBAL_LIST_EMPTY(generic_event_spawns) //list of all spawns for events
GLOBAL_LIST_EMPTY(wizardstart)
GLOBAL_LIST_EMPTY(newplayer_start)
GLOBAL_LIST_EMPTY(latejoin)
GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these
GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here
GLOBAL_LIST_EMPTY(xeno_spawn)//Aliens spawn at these.
+3 -1
View File
@@ -32,4 +32,6 @@ GLOBAL_LIST_EMPTY(ladders)
GLOBAL_LIST_EMPTY(trophy_cases)
GLOBAL_LIST_EMPTY(wire_color_directory)
GLOBAL_LIST_EMPTY(wire_name_directory)
GLOBAL_LIST_EMPTY(wire_name_directory)
GLOBAL_LIST_EMPTY(ai_status_displays)
+2
View File
@@ -31,4 +31,6 @@ GLOBAL_PROTECT(OOClog)
GLOBAL_LIST_EMPTY(adminlog)
GLOBAL_PROTECT(adminlog)
GLOBAL_LIST_EMPTY(individual_log_list) // Logs each mob individual logs, a global so it doesn't get lost on cloning/changing mobs
GLOBAL_LIST_EMPTY(active_turfs_startlist)
+11 -1
View File
@@ -208,6 +208,8 @@
var/generate_minimaps = 0
var/grey_assistants = 0
var/id_console_jobslot_delay = 30
var/lavaland_budget = 60
var/space_budget = 16
@@ -261,6 +263,8 @@
var/mice_roundstart = 10 // how many wire chewing rodents spawn at roundstart.
var/irc_announce_new_game = FALSE
/datum/configuration/New()
gamemode_cache = typecacheof(/datum/game_mode,TRUE)
for(var/T in gamemode_cache)
@@ -409,6 +413,8 @@
usewhitelist = TRUE
if("allow_metadata")
allow_Metadata = 1
if("id_console_jobslot_delay")
id_console_jobslot_delay = text2num(value)
if("inactivity_period")
inactivity_period = text2num(value) * 10 //documented as seconds in config.txt
if("afk_period")
@@ -423,7 +429,7 @@
popup_admin_pm = 1
if("allow_holidays")
allow_holidays = 1
if("useircbot")
if("useircbot") //tgs2 support
useircbot = 1
if("ticklag")
var/ticklag = text2num(value)
@@ -536,6 +542,8 @@
error_silence_time = text2num(value)
if("error_msg_delay")
error_msg_delay = text2num(value)
if("irc_announce_new_game")
irc_announce_new_game = TRUE
else
GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
@@ -827,6 +835,8 @@
if ("endmap")
maplist[currentmap.map_name] = currentmap
currentmap = null
if ("disabled")
currentmap = null
else
GLOB.config_error_log << "Unknown command in map vote config: '[command]'"
+2 -2
View File
@@ -27,7 +27,7 @@ SUBSYSTEM_DEF(blackbox)
if(M.client)
playercount += 1
var/admincount = GLOB.admins.len
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON('[world.internet_address]'), '[world.port]')")
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')")
query_record_playercount.Execute()
/datum/controller/subsystem/blackbox/Recover()
@@ -176,7 +176,7 @@ SUBSYSTEM_DEF(blackbox)
var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
var/coord = sanitizeSQL("[L.x], [L.y], [L.z]")
var/map = sanitizeSQL(SSmapping.config.map_name)
var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON('[world.internet_address]'), '[world.port]')")
var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')")
query_report_death.Execute()
+46 -15
View File
@@ -11,6 +11,7 @@ SUBSYSTEM_DEF(job)
var/initial_players_to_assign = 0 //used for checking against population caps
var/list/prioritized_jobs = list()
var/list/latejoin_trackers = list() //Don't read this list, use GetLateJoinTurfs() instead
/datum/controller/subsystem/job/Initialize(timeofday)
if(!occupations.len)
@@ -378,23 +379,11 @@ SUBSYSTEM_DEF(job)
continue
S = sloc
break
if(S)
SendToAtom(H, S, buckle = FALSE)
if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
log_world("Couldn't find a round start spawn point for [rank]")
S = get_turf(pick(GLOB.latejoin))
if(!S) //final attempt, lets find some area in the arrivals shuttle to spawn them in to.
log_world("Couldn't find a round start latejoin spawn point.")
for(var/turf/T in get_area_turfs(/area/shuttle/arrival))
if(!T.density)
var/clear = 1
for(var/obj/O in T)
if(O.density)
clear = 0
break
if(clear)
S = T
continue
if(istype(S, /obj/effect/landmark) && isturf(S.loc))
H.loc = S.loc
SendToLateJoin(H)
if(H.mind)
H.mind.assigned_role = rank
@@ -516,3 +505,45 @@ SUBSYSTEM_DEF(job)
newjob.total_positions = J.total_positions
newjob.spawn_positions = J.spawn_positions
newjob.current_positions = J.current_positions
/datum/controller/subsystem/job/proc/SendToAtom(mob/M, atom/A, buckle)
if(buckle && isliving(M) && istype(A, /obj/structure/chair))
var/obj/structure/chair/C = A
if(C.buckle_mob(M, FALSE, FALSE))
return
M.forceMove(get_turf(A))
/datum/controller/subsystem/job/proc/SendToLateJoin(mob/M, buckle = TRUE)
if(latejoin_trackers.len)
SendToAtom(M, pick(latejoin_trackers), buckle)
else
//bad mojo
var/area/shuttle/arrival/A = locate() in GLOB.sortedAreas
if(A)
//first check if we can find a chair
var/obj/structure/chair/C = locate() in A
if(C)
SendToAtom(M, C, buckle)
return
else //last hurrah
var/list/avail = list()
for(var/turf/T in A)
if(!is_blocked_turf(T, TRUE))
avail += T
if(avail.len)
SendToAtom(M, pick(avail), FALSE)
return
//pick an open spot on arrivals and dump em
var/list/arrivals_turfs = shuffle(get_area_turfs(/area/shuttle/arrival))
if(arrivals_turfs.len)
for(var/turf/T in arrivals_turfs)
if(!is_blocked_turf(T, TRUE))
SendToAtom(M, T, FALSE)
return
//last chance, pick ANY spot on arrivals and dump em
SendToAtom(M, arrivals_turfs[1], FALSE)
else
var/msg = "Unable to send mob [M] to late join!"
message_admins(msg)
CRASH(msg)
@@ -161,7 +161,7 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
if(NOT_QUEUED_ALREADY && need_compile) //have we caught more pokemon?
QUEUE_FOR_COMPILE
/atom/proc/copy_overlays(atom/other, cut_old = FALSE) //copys our_overlays from another atom
/atom/proc/copy_overlays(atom/other, cut_old) //copys our_overlays from another atom
if(!other)
if(cut_old)
cut_overlays()
@@ -190,3 +190,18 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
/image/proc/cut_overlays(x)
overlays.Cut()
/image/proc/copy_overlays(atom/other, cut_old)
if(!other)
if(cut_old)
cut_overlays()
return
var/list/cached_other = other.our_overlays
if(cached_other)
if(cut_old || !overlays.len)
overlays = cached_other.Copy()
else
overlays |= cached_other
else if(cut_old)
cut_overlays()
+1 -1
View File
@@ -223,7 +223,7 @@ SUBSYSTEM_DEF(shuttle)
/datum/controller/subsystem/shuttle/proc/centcom_recall(old_timer, admiral_message)
if(emergency.mode != SHUTTLE_CALL || emergency.timer != old_timer)
return
emergency.cancel(/area/centcom)
emergency.cancel()
if(!admiral_message)
admiral_message = pick(GLOB.admiral_messages)
+7 -41
View File
@@ -239,6 +239,8 @@ SUBSYSTEM_DEF(ticker)
/datum/controller/subsystem/ticker/proc/PostSetup()
set waitfor = 0
mode.post_setup()
GLOB.start_state = new /datum/station_state()
GLOB.start_state.count(1)
//Cleanup some stuff
for(var/obj/effect/landmark/start/S in GLOB.landmarks_list)
//Deleting Startpoints but we need the ai point to AI-ize people later
@@ -438,7 +440,7 @@ SUBSYSTEM_DEF(ticker)
/datum/controller/subsystem/ticker/proc/transfer_characters()
var/list/livings = list()
for(var/mob/dead/new_player/player in GLOB.player_list)
for(var/mob/dead/new_player/player in GLOB.mob_list)
var/mob/living = player.transfer_character()
if(living)
qdel(player)
@@ -579,43 +581,6 @@ SUBSYSTEM_DEF(ticker)
CHECK_TICK
//Borers
var/borerwin = FALSE
if(GLOB.borers.len)
var/borertext = "<br><font size=3><b>The borers were:</b></font>"
for(var/mob/living/simple_animal/borer/B in GLOB.borers)
if((B.key || B.controlling) && B.stat != DEAD)
borertext += "<br>[B.controlling ? B.victim.key : B.key] was [B.truename] ("
var/turf/location = get_turf(B)
if(location.z == ZLEVEL_CENTCOM && B.victim)
borertext += "escaped with host"
else
borertext += "failed"
borertext += ")"
to_chat(world, borertext)
var/total_borers = 0
for(var/mob/living/simple_animal/borer/B in GLOB.borers)
if((B.key || B.victim) && B.stat != DEAD)
total_borers++
if(total_borers)
var/total_borer_hosts = 0
for(var/mob/living/carbon/C in GLOB.mob_list)
var/mob/living/simple_animal/borer/D = C.has_brain_worms()
var/turf/location = get_turf(C)
if(location.z == ZLEVEL_CENTCOM && D && D.stat != DEAD)
total_borer_hosts++
if(GLOB.total_borer_hosts_needed <= total_borer_hosts)
borerwin = TRUE
to_chat(world, "<b>There were [total_borers] borers alive at round end!</b>")
to_chat(world, "<b>A total of [total_borer_hosts] borers with hosts escaped on the shuttle alive. The borers needed [GLOB.total_borer_hosts_needed] hosts to escape.</b>")
if(borerwin)
to_chat(world, "<b><font color='green'>The borers were successful!</font></b>")
else
to_chat(world, "<b><font color='red'>The borers have failed!</font></b>")
CHECK_TICK
mode.declare_station_goal_completion()
CHECK_TICK
@@ -852,7 +817,8 @@ SUBSYSTEM_DEF(ticker)
if(!delay)
delay = config.round_end_countdown * 10
if(delay_end)
var/skip_delay = check_rights()
if(delay_end && !skip_delay)
to_chat(world, "<span class='boldannounce'>An admin has delayed the round end.</span>")
return
@@ -862,7 +828,7 @@ SUBSYSTEM_DEF(ticker)
UNTIL(round_end_sound_sent || (world.time - start_wait) > (delay * 2)) //don't wait forever
sleep(delay - (world.time - start_wait))
if(delay_end)
if(delay_end && !skip_delay)
to_chat(world, "<span class='boldannounce'>Reboot was cancelled by an admin.</span>")
return
@@ -886,4 +852,4 @@ SUBSYSTEM_DEF(ticker)
'sound/roundend/disappointed.ogg'\
)
world << sound(round_end_sound)
world << sound(round_end_sound)
+12 -5
View File
@@ -115,12 +115,19 @@
else
return
if(isturf(source.loc))
var/turf/T = source.loc
if(istype(T))
for(var/mob/living/carbon/C in oview(spread_range, source))
if(isturf(C.loc))
if(AStar(source, C.loc,/turf/proc/Distance, spread_range, adjacent = (spread_flags & AIRBORNE) ? /turf/proc/reachableAdjacentAtmosTurfs : /turf/proc/reachableAdjacentTurfs))
C.ContractDisease(src)
var/turf/V = get_turf(C)
if(V)
while(TRUE)
if(V == T)
C.ContractDisease(src)
break
var/turf/Temp = get_step_towards(V, T)
if(!CANATMOSPASS(V, Temp))
break
V = Temp
/datum/disease/process()
if(!holder)
+11
View File
@@ -38,6 +38,8 @@
if(findtext(msg, "%s"))
msg = replacetext(msg, "%s", user.p_s())
msg = replace_pronoun(user, msg)
var/mob/living/L = user
for(var/obj/item/weapon/implant/I in L.implants)
I.trigger(key, L)
@@ -61,6 +63,15 @@
user.visible_message(msg)
log_emote("[key_name(user)] : [msg]")
/datum/emote/proc/replace_pronoun(mob/user, message)
if(findtext(message, "their"))
message = replacetext(message, "their", user.p_their())
if(findtext(message, "them"))
message = replacetext(message, "them", user.p_them())
if(findtext(message, "%s"))
message = replacetext(message, "%s", user.p_s())
return message
/datum/emote/proc/select_message_type(mob/user)
. = message
if(!muzzle_ignore && user.is_muzzled() && emote_type == EMOTE_AUDIBLE)
+1 -1
View File
@@ -249,7 +249,7 @@ GLOBAL_LIST_EMPTY(explosions)
if(GLOB.Debug2)
log_world("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.")
if(!stopped) //if we aren't in a hurry
if(running) //if we aren't in a hurry
//Machines which report explosions.
for(var/array in GLOB.doppler_arrays)
var/obj/machinery/doppler_array/A = array
+38 -28
View File
@@ -1,37 +1,44 @@
/datum/getrev
var/originmastercommit
var/originmastercommit
var/commit
var/list/testmerge = list()
var/has_pr_details = FALSE //example data in a testmerge entry when this is true: https://api.github.com/repositories/3234987/pulls/22586
var/has_pr_details = FALSE //tgs2 support
var/date
/datum/getrev/New()
if(SERVERTOOLS && fexists("..\\prtestjob.lk"))
if(fexists(SERVICE_PR_TEST_JSON))
testmerge = json_decode(file2text(SERVICE_PR_TEST_JSON))
else if(!world.RunningService() && fexists("../prtestjob.lk")) //tgs2 support
var/list/tmp = world.file2list("..\\prtestjob.lk")
for(var/I in tmp)
if(I)
testmerge |= I
log_world("Running /tg/ revision:")
var/list/logs = world.file2list(".git/logs/HEAD")
if(logs)
logs = splittext(logs[logs.len - 1], " ")
date = unix2date(text2num(logs[5]))
commit = logs[2]
log_world("[date]")
logs = world.file2list(".git/logs/refs/remotes/origin/master")
if(logs)
originmastercommit = splittext(logs[logs.len - 1], " ")[2]
var/list/logs = world.file2list(".git/logs/HEAD")
if(logs)
logs = splittext(logs[logs.len - 1], " ")
date = unix2date(text2num(logs[5]))
commit = logs[2]
log_world("[date]")
logs = world.file2list(".git/logs/refs/remotes/origin/master")
if(logs)
originmastercommit = splittext(logs[logs.len - 1], " ")[2]
if(testmerge.len)
log_world(commit)
for(var/line in testmerge)
if(line)
log_world("Test merge active of PR #[line]")
SSblackbox.add_details("testmerged_prs","[line]")
log_world("Based off origin/master commit [originmastercommit]")
if(world.RunningService())
var/tmcommit = testmerge[line]["commit"]
log_world("Test merge active of PR #[line] commit [tmcommit]")
SSblackbox.add_details("testmerged_prs","[line]|[tmcommit]")
else //tgs2 support
log_world("Test merge active of PR #[line]")
SSblackbox.add_details("testmerged_prs","[line]")
log_world("Based off origin/master commit [originmastercommit]")
else
log_world(originmastercommit)
log_world(originmastercommit)
/datum/getrev/proc/DownloadPRDetails()
if(!config.githubrepoid)
@@ -66,8 +73,11 @@
return ""
. = header ? "The following pull requests are currently test merged:<br>" : ""
for(var/line in testmerge)
var/details = ""
if(has_pr_details)
var/cm = testmerge[line]["commit"]
var/details
if(world.RunningService())
details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["author"]) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 7)))
else if(has_pr_details) //tgs2 support
details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["user"]["login"])
. += "<a href='[config.githuburl]/pull/[line]'>#[line][details]</a><br>"
@@ -76,14 +86,14 @@
set name = "Show Server Revision"
set desc = "Check the current server code revision"
if(GLOB.revdata.originmastercommit)
if(GLOB.revdata.originmastercommit)
to_chat(src, "<b>Server revision compiled on:</b> [GLOB.revdata.date]")
var/prefix = ""
var/prefix = ""
if(GLOB.revdata.testmerge.len)
to_chat(src, GLOB.revdata.GetTestMergeInfo())
prefix = "Based off origin/master commit: "
var/pc = GLOB.revdata.originmastercommit
to_chat(src, "[prefix]<a href='[config.githuburl]/commit/[pc]'>[copytext(pc, 1, min(length(pc), 7))]</a>")
prefix = "Based off origin/master commit: "
var/pc = GLOB.revdata.originmastercommit
to_chat(src, "[prefix]<a href='[config.githuburl]/commit/[pc]'>[copytext(pc, 1, min(length(pc), 7))]</a>")
else
to_chat(src, "Revision unknown")
to_chat(src, "<b>Current Infomational Settings:</b>")
@@ -94,7 +104,7 @@
to_chat(src, "Enforce Continuous Rounds: [config.continuous.len] of [config.modes.len] roundtypes")
to_chat(src, "Allow Midround Antagonists: [config.midround_antag.len] of [config.modes.len] roundtypes")
if(config.show_game_type_odds)
if(SSticker.IsRoundInProgress())
if(SSticker.IsRoundInProgress())
var/prob_sum = 0
var/current_odds_differ = FALSE
var/list/probs = list()
@@ -110,13 +120,13 @@
probs[ctag] = 1
prob_sum += config.probabilities[ctag]
if(current_odds_differ)
to_chat(src, "<b>Game Mode Odds for current round:</b>")
to_chat(src, "<b>Game Mode Odds for current round:</b>")
for(var/ctag in probs)
if(config.probabilities[ctag] > 0)
var/percentage = round(config.probabilities[ctag] / prob_sum * 100, 0.1)
to_chat(src, "[ctag] [percentage]%")
to_chat(src, "<b>All Game Mode Odds:</b>")
to_chat(src, "<b>All Game Mode Odds:</b>")
var/sum = 0
for(var/ctag in config.probabilities)
sum += config.probabilities[ctag]
+31 -12
View File
@@ -1,4 +1,3 @@
#define HOLOPAD_MAX_DIAL_TIME 200
/mob/camera/aiEye/remote/holo/setLoc()
@@ -16,6 +15,7 @@
var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected
var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected
var/datum/action/innate/end_holocall/hangup //hangup action
var/call_start_time
@@ -43,19 +43,25 @@
//cleans up ALL references :)
/datum/holocall/Destroy()
user.reset_perspective()
if(!QDELETED(eye) && user.client)
for(var/datum/camerachunk/chunk in eye.visibleCameraChunks)
chunk.remove(eye)
QDEL_NULL(hangup)
var/user_good = !QDELETED(user)
if(user_good)
user.reset_perspective()
user.remote_control = null
if(!QDELETED(eye))
if(user_good && user.client)
for(var/datum/camerachunk/chunk in eye.visibleCameraChunks)
chunk.remove(eye)
qdel(eye)
eye = null
user.remote_control = null
user = null
if(hologram)
hologram.HC = null
hologram = null
calling_holopad.outgoing_call = null
hologram = null
for(var/I in dialed_holopads)
var/obj/machinery/holopad/H = I
@@ -63,6 +69,7 @@
dialed_holopads.Cut()
if(calling_holopad)
calling_holopad.outgoing_call = null
calling_holopad.SetLightsAndPower()
calling_holopad = null
if(connected_holopad)
@@ -87,7 +94,7 @@
/datum/holocall/proc/ConnectionFailure(obj/machinery/holopad/H, graceful = FALSE)
testing("Holocall connection failure: graceful [graceful]")
if(H == connected_holopad || H == calling_holopad)
if(!graceful)
if(!graceful && H != calling_holopad)
calling_holopad.say("Connection failure.")
qdel(src)
return
@@ -140,6 +147,8 @@
user.reset_perspective(eye)
eye.setLoc(H.loc)
hangup = new(eye, src)
//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise
/datum/holocall/proc/Check()
for(var/I in dialed_holopads)
@@ -153,9 +162,7 @@
. = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && calling_holopad.is_operational() && user.loc == calling_holopad.loc
if(.)
if(connected_holopad)
. = !QDELETED(connected_holopad) && connected_holopad.is_operational()
else
if(!connected_holopad)
. = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME)
if(!.)
calling_holopad.say("No answer recieved.")
@@ -164,3 +171,15 @@
if(!.)
testing("Holocall Check fail")
qdel(src)
/datum/action/innate/end_holocall
name = "End Holocall"
button_icon_state = "camera_off"
var/datum/holocall/hcall
/datum/action/innate/end_holocall/New(Target, datum/holocall/HC)
..()
hcall = HC
/datum/action/innate/end_holocall/Activate()
hcall.Disconnect(hcall.calling_holopad)
+10
View File
@@ -0,0 +1,10 @@
diff a/code/datums/holocall.dm b/code/datums/holocall.dm (rejected hunks)
@@ -42,6 +43,8 @@
//cleans up ALL references :)
/datum/holocall/Destroy()
+ QDEL_NULL(hangup)
+
var/user_good = !QDELETED(user)
if(user_good)
user.reset_perspective()
+3 -3
View File
@@ -68,6 +68,7 @@
/datum/mind/New(var/key)
src.key = key
soulOwner = src
martial_art = default_martial_art
/datum/mind/Destroy()
SSticker.minds -= src
@@ -988,7 +989,7 @@
if(!G || (src in G.bosses))
return
SSticker.mode.remove_gangster(src,0,2,1)
G.bosses += src
G.bosses[src] = GANGSTER_BOSS_STARTING_INFLUENCE
gang_datum = G
special_role = "[G.name] Gang Boss"
G.add_gang_hud(src)
@@ -1288,7 +1289,6 @@
else if (istype(M) && length(M.viruses))
for(var/datum/disease/D in M.viruses)
D.cure(0)
sleep(0) //because deleting of virus is done through spawn(0)
if("infected")
if (check_rights(R_ADMIN, 0))
var/mob/living/carbon/human/H = current
@@ -1447,7 +1447,7 @@
special_role = "Wizard"
assigned_role = "Wizard"
if(!GLOB.wizardstart.len)
current.loc = pick(GLOB.latejoin)
SSjob.SendToLateJoin(current)
to_chat(current, "HOT INSERTION, GO GO GO")
else
current.loc = pick(GLOB.wizardstart)
+2
View File
@@ -23,6 +23,8 @@
var/list/backpack_contents = null // In the list(path=count,otherpath=count) format
var/list/implants = null
var/can_be_admin_equipped = TRUE // Set to FALSE if your outfit requires runtime parameters
/datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
//to be overriden for customization depending on client prefs,species etc
return
+2 -2
View File
@@ -45,7 +45,7 @@
if(offsetdir == ridden_dir)
var/list/diroffsets = offsets[offsetdir]
buckled_mob.pixel_x = diroffsets[1]
if(diroffsets.len == 2)
if(diroffsets.len >= 2)
buckled_mob.pixel_y = diroffsets[2]
if(diroffsets.len == 3)
buckled_mob.layer = diroffsets[3]
@@ -164,7 +164,7 @@
/datum/riding/janicart/get_offsets(pass_index) // list(dir = x, y, layer)
return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(-12, 7), "[EAST]" = list(0, 7), "[WEST]" = list( 12, 7))
return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 7), "[EAST]" = list(-12, 7), "[WEST]" = list( 12, 7))
//scooter
/datum/riding/scooter/handle_vehicle_layer()
+1 -7
View File
@@ -241,10 +241,4 @@
id = "miracle"
suffix = "miracle.dmm"
name = "Ordinary Space Tile"
description = "Absolutely nothing strange going on here please move along, plenty more space to see right this way!"
/datum/map_template/ruin/space/dragoon
id = "dragoon"
suffix = "dragoontomb.dmm"
name = "Sky Bulge Tomb"
description = "A tomb of a dice-loving dragoon in space. Turns out he got too good and jumped too high. Contains the Sky Bulge, which when thrown, warps the thrower."
description = "Absolutely nothing strange going on here please move along, plenty more space to see right this way!"
-10
View File
@@ -1,15 +1,5 @@
//Largely negative status effects go here, even if they have small benificial effects
/datum/status_effect/sigil_mark //allows the affected target to always trigger sigils while mindless
id = "sigil_mark"
duration = -1
alert_type = null
var/stat_allowed = DEAD //if owner's stat is below this, will remove itself
/datum/status_effect/sigil_mark/tick()
if(owner.stat < stat_allowed)
qdel(src)
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
id = "his_wrath"
duration = -1
+18
View File
@@ -0,0 +1,18 @@
//entirely neutral or internal status effects go here
/datum/status_effect/sigil_mark //allows the affected target to always trigger sigils while mindless
id = "sigil_mark"
duration = -1
alert_type = null
var/stat_allowed = DEAD //if owner's stat is below this, will remove itself
/datum/status_effect/sigil_mark/tick()
if(owner.stat < stat_allowed)
qdel(src)
/datum/status_effect/crusher_damage //tracks the damage dealt to this mob by kinetic crushers
id = "crusher_damage"
duration = -1
status_type = STATUS_EFFECT_UNIQUE
alert_type = null
var/total_damage = 0
+6 -3
View File
@@ -50,9 +50,9 @@
R.show_laws()
if(WIRE_LOCKDOWN)
R.SetLockdown(!R.lockcharge) // Toggle
if(WIRE_RESET_MODULE)
if(R.has_module())
R.ResetModule()
if(WIRE_RESET_MODULE)
if(R.has_module())
R.visible_message("[R]'s module servos twitch.", "Your module display flickers.")
/datum/wires/robot/on_cut(wire, mend)
var/mob/living/silicon/robot/R = holder
@@ -74,3 +74,6 @@
R.visible_message("[R]'s camera lense focuses loudly.", "Your camera lense focuses loudly.")
if(WIRE_LOCKDOWN) // Simple lockdown.
R.SetLockdown(!mend)
if(WIRE_RESET_MODULE)
if(R.has_module() && !mend)
R.ResetModule()
+2 -2
View File
@@ -1435,8 +1435,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "AI Satellite Atmos"
icon_state = "ai"
/area/ai_monitored/turret_protected/aisat/atmos
name = "AI Satellite Atmos"
/area/ai_monitored/turret_protected/aisat/foyer
name = "AI Satellite Foyer"
icon_state = "ai"
/area/ai_monitored/turret_protected/aisat/service
+4
View File
@@ -37,6 +37,7 @@
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
requires_power = 0
has_gravity = 1
flags = NONE
/area/tdome/arena
name = "Thunderdome Arena"
@@ -75,6 +76,7 @@
requires_power = 0
has_gravity = 1
noteleport = 1
flags = NONE
//Abductors
/area/abductor_ship
@@ -83,6 +85,7 @@
requires_power = 0
noteleport = 1
has_gravity = 1
flags = NONE
//Syndicates
/area/syndicate_mothership
@@ -92,6 +95,7 @@
has_gravity = 1
noteleport = 1
blob_allowed = 0 //Not... entirely sure this will ever come up... but if the bus makes blobs AND ops, it shouldn't aim for the ops to win.
flags = NONE
/area/syndicate_mothership/control
name = "Syndicate Control Room"
-9
View File
@@ -1,9 +0,0 @@
diff a/code/game/atoms.dm b/code/game/atoms.dm (rejected hunks)
@@ -274,6 +274,7 @@
return
/atom/proc/ex_act(severity, target)
+ set waitfor = FALSE
contents_explosion(severity, target)
/atom/proc/blob_act(obj/structure/blob/B)
@@ -59,3 +59,6 @@
//changes construction value
/proc/change_construction_value(amount)
GLOB.clockwork_construction_value += amount
/proc/can_recite_scripture(mob/living/L)
return (is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal() && (GLOB.ratvar_awakens || (ishuman(L) || issilicon(L))))
@@ -25,7 +25,7 @@
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
armor = list(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
flags &= STOPSPRESSUREDMAGE
flags &= ~STOPSPRESSUREDMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -81,7 +81,7 @@
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
armor = list(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
flags &= STOPSPRESSUREDMAGE
flags &= ~STOPSPRESSUREDMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -142,7 +142,7 @@
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
armor = list(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
flags &= STOPSPRESSUREDMAGE
flags &= ~STOPSPRESSUREDMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -194,7 +194,7 @@
if(GLOB.ratvar_awakens)
flags |= NOSLIP
else
flags &= NOSLIP
flags &= ~NOSLIP
/obj/item/clothing/shoes/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0)
if(equipper && !is_servant_of_ratvar(equipper))
@@ -14,7 +14,6 @@
var/target_component_id //the target component ID to create, if any
var/no_cost = FALSE //If the slab is admin-only and needs no components and has no scripture locks
var/speed_multiplier = 1 //multiples how fast this slab recites scripture
var/nonhuman_usable = FALSE //if the slab can be used by nonhumans, defaults to off
var/produces_components = TRUE //if it produces components at all
var/selected_scripture = SCRIPTURE_DRIVER
var/recollecting = FALSE //if we're looking at fancy recollection
@@ -33,13 +32,9 @@
no_cost = TRUE
produces_components = FALSE
/obj/item/clockwork/slab/scarab
nonhuman_usable = TRUE
/obj/item/clockwork/slab/debug
speed_multiplier = 0
no_cost = TRUE
nonhuman_usable = TRUE
/obj/item/clockwork/slab/debug/attack_hand(mob/living/user)
..()
@@ -49,7 +44,6 @@
/obj/item/clockwork/slab/cyborg //three scriptures, plus a spear and proselytizer
clockwork_desc = "A divine link to the Celestial Derelict, allowing for limited recital of scripture.\n\
Hitting a slab, a Servant with a slab, or a cache will <b>transfer</b> this slab's components into the target, the target's slab, or the global cache, respectively."
nonhuman_usable = TRUE
quickbound = list(/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/ranged_ability/linked_vanguard, \
/datum/clockwork_scripture/create_object/tinkerers_cache)
maximum_quickbound = 6 //we usually have one or two unique scriptures, so if ratvar is up let us bind one more
@@ -106,12 +100,6 @@
slab_ability = null
return ..()
/obj/item/clockwork/slab/ratvar_act()
if(GLOB.ratvar_awakens)
nonhuman_usable = TRUE
else
nonhuman_usable = initial(nonhuman_usable)
/obj/item/clockwork/slab/dropped(mob/user)
. = ..()
addtimer(CALLBACK(src, .proc/check_on_mob, user), 1) //dropped is called before the item is out of the slot, so we need to check slightly later
@@ -138,7 +126,7 @@
production_time = world.time + SLAB_PRODUCTION_TIME + production_slowdown
var/mob/living/L
L = get_atom_on_turf(src, /mob/living)
if(istype(L) && is_servant_of_ratvar(L) && (nonhuman_usable || ishuman(L)))
if(istype(L) && can_recite_scripture(L))
var/component_to_generate = target_component_id
if(!component_to_generate)
component_to_generate = get_weighted_component_id(src) //more likely to generate components that we have less of
@@ -268,7 +256,7 @@
if(busy)
to_chat(user, "<span class='warning'>[src] refuses to work, displaying the message: \"[busy]!\"</span>")
return 0
if(!nonhuman_usable && !ishuman(user))
if(!can_recite_scripture(user))
to_chat(user, "<span class='nezbere'>[src] hums fitfully in your hands, but doesn't seem to do anything...</span>")
return 0
access_display(user)
@@ -288,7 +276,7 @@
ui.open()
/obj/item/clockwork/slab/proc/recite_scripture(datum/clockwork_scripture/scripture, mob/living/user)
if(!scripture || !user || !user.canUseTopic(src) || (!nonhuman_usable && !ishuman(user)))
if(!scripture || !user || !user.canUseTopic(src) || !can_recite_scripture(user))
return FALSE
if(user.get_active_held_item() != src)
to_chat(user, "<span class='warning'>You need to hold the slab in your active hand to recite scripture!</span>")
@@ -120,7 +120,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
if(multiple_invokers_used && !multiple_invokers_optional && !GLOB.ratvar_awakens && !slab.no_cost)
var/nearby_servants = 0
for(var/mob/living/L in range(1, get_turf(invoker)))
if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
if(can_recite_scripture(L))
nearby_servants++
if(nearby_servants < invokers_required)
to_chat(invoker, "<span class='warning'>There aren't enough non-mute servants nearby ([nearby_servants]/[invokers_required])!</span>")
@@ -170,7 +170,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
if(!channel_time && invocations.len)
if(multiple_invokers_used)
for(var/mob/living/L in range(1, invoker))
if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
if(can_recite_scripture(L))
for(var/invocation in invocations)
clockwork_say(L, text2ratvar(invocation), whispered)
else
@@ -185,7 +185,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
return FALSE
if(multiple_invokers_used)
for(var/mob/living/L in range(1, get_turf(invoker)))
if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
if(can_recite_scripture(L))
clockwork_say(L, text2ratvar(invocation), whispered)
else
clockwork_say(invoker, text2ratvar(invocation), whispered)
@@ -53,7 +53,7 @@
/datum/clockwork_scripture/fellowship_armory/run_scripture()
for(var/mob/living/L in orange(1, invoker))
if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
if(can_recite_scripture(L))
channel_time = max(channel_time - 10, 0)
return ..()
+4 -1
View File
@@ -225,7 +225,10 @@ This file contains the arcane tome files.
"<span class='cult'>You [user.blood_volume ? "slice open your arm and ":""]begin drawing a sigil of the Geometer.</span>")
if(user.blood_volume)
user.apply_damage(initial(rune_to_scribe.scribe_damage), BRUTE, pick("l_arm", "r_arm"))
if(!do_after(user, initial(rune_to_scribe.scribe_delay), target = get_turf(user)))
var/scribe_mod = initial(rune_to_scribe.scribe_delay)
if(istype(get_turf(user), /turf/open/floor/engine/cult))
scribe_mod *= 0.5
if(!do_after(user, scribe_mod, target = get_turf(user)))
for(var/V in shields)
var/obj/structure/emergency_shield/sanguine/S = V
if(S && !QDELETED(S))
@@ -46,7 +46,10 @@
if(damage_interrupt && isliving(owner))
var/mob/living/L = owner
health = list("health" = L.health)
if(do_after(owner, scribe_time, target = owner, extra_checks = CALLBACK(owner, /mob.proc/break_do_after_checks, health, action_interrupt)))
var/scribe_mod = scribe_time
if(istype(get_turf(owner), /turf/open/floor/engine/cult))
scribe_mod *= 0.5
if(do_after(owner, scribe_mod, target = owner, extra_checks = CALLBACK(owner, /mob.proc/break_do_after_checks, health, action_interrupt)))
var/obj/effect/rune/new_rune = new rune_type(owner.loc)
new_rune.keyword = chosen_keyword
else
+38 -3
View File
@@ -94,8 +94,6 @@
if(report)
addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h))
generate_station_goals()
GLOB.start_state = new /datum/station_state()
GLOB.start_state.count(1)
return 1
@@ -265,6 +263,43 @@
send2irc("Server", "Round just ended.")
if(cult.len && !istype(SSticker.mode,/datum/game_mode/cult))
datum_cult_completion()
if(GLOB.borers.len)
var/borerwin = FALSE
var/borertext = "<br><font size=3><b>The borers were:</b></font>"
for(var/mob/living/simple_animal/borer/B in GLOB.borers)
if((B.key || B.controlling) && B.stat != DEAD)
borertext += "<br>[B.controlling ? B.victim.key : B.key] was [B.truename] ("
var/turf/location = get_turf(B)
if(location.z == ZLEVEL_CENTCOM && B.victim)
borertext += "escaped with host"
else
borertext += "failed"
borertext += ")"
to_chat(world, borertext)
var/total_borers = 0
for(var/mob/living/simple_animal/borer/B in GLOB.borers)
if((B.key || B.victim) && B.stat != DEAD)
total_borers++
if(total_borers)
var/total_borer_hosts = 0
for(var/mob/living/carbon/C in GLOB.mob_list)
var/mob/living/simple_animal/borer/D = C.has_brain_worms()
var/turf/location = get_turf(C)
if(location.z == ZLEVEL_CENTCOM && D && D.stat != DEAD)
total_borer_hosts++
if(GLOB.total_borer_hosts_needed <= total_borer_hosts)
borerwin = TRUE
to_chat(world, "<b>There were [total_borers] borers alive at round end!</b>")
to_chat(world, "<b>A total of [total_borer_hosts] borers with hosts escaped on the shuttle alive. The borers needed [GLOB.total_borer_hosts_needed] hosts to escape.</b>")
if(borerwin)
to_chat(world, "<b><font color='green'>The borers were successful!</font></b>")
else
to_chat(world, "<b><font color='red'>The borers have failed!</font></b>")
CHECK_TICK
return 0
@@ -565,4 +600,4 @@
/datum/game_mode/proc/declare_station_goal_completion()
for(var/V in station_goals)
var/datum/station_goal/G = V
G.print_result()
G.print_result()
+26 -7
View File
@@ -1,5 +1,6 @@
#define DOM_BLOCKED_SPAM_CAP 6
#define DOM_REQUIRED_TURFS 30
#define DOM_HULK_HITS_REQUIRED 10
/obj/machinery/dominator
name = "dominator"
@@ -20,6 +21,9 @@
var/datum/effect_system/spark_spread/spark_system
var/obj/effect/countdown/dominator/countdown
/obj/machinery/dominator/hulk_damage()
return (max_integrity - integrity_failure) / DOM_HULK_HITS_REQUIRED
/proc/dominator_excessive_walls(atom/A)
var/open = 0
for(var/turf/T in view(3, A))
@@ -33,13 +37,14 @@
/obj/machinery/dominator/tesla_act()
qdel(src)
/obj/machinery/dominator/New()
..()
/obj/machinery/dominator/Initialize()
. = ..()
set_light(2)
GLOB.poi_list |= src
spark_system = new
spark_system.set_up(5, TRUE, src)
countdown = new(src)
update_icon()
/obj/machinery/dominator/examine(mob/user)
..()
@@ -103,8 +108,23 @@
spark_system.start()
else if(!(stat & BROKEN))
spark_system.start()
cut_overlays()
update_icon()
/obj/machinery/dominator/update_icon()
cut_overlays()
if(!(stat & BROKEN))
icon_state = "dominator-active"
if(operating)
var/mutable_appearance/dominator_overlay = mutable_appearance('icons/obj/machines/dominator.dmi', "dominator-overlay")
if(gang)
dominator_overlay.color = gang.color_hex
add_overlay(dominator_overlay)
else
icon_state = "dominator"
if(obj_integrity/max_integrity < 0.66)
add_overlay("damage")
else
icon_state = "dominator-broken"
/obj/machinery/dominator/obj_break(damage_flag)
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT))
@@ -142,10 +162,9 @@
gang.message_gangtools("Hostile takeover cancelled: Dominator is no longer operational.[gang.dom_attempts ? " You have [gang.dom_attempts] attempt remaining." : " The station network will have likely blocked any more attempts by us."]",1,1)
set_light(0)
icon_state = "dominator-broken"
cut_overlays()
operating = 0
stat |= BROKEN
update_icon()
STOP_PROCESSING(SSmachines, src)
/obj/machinery/dominator/Destroy()
@@ -196,9 +215,9 @@
priority_announce("Network breach detected in [locname]. The [gang.name] Gang is attempting to seize control of the station!","Network Alert")
gang.domination()
SSshuttle.registerHostileEnvironment(src)
src.name = "[gang.name] Gang [src.name]"
name = "[gang.name] Gang [name]"
operating = 1
icon_state = "dominator-[gang.color]"
update_icon()
countdown.color = gang.color_hex
countdown.start()
+12 -2
View File
@@ -62,7 +62,7 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
for(var/n in 1 to 3)
var/datum/mind/boss = pick(antag_candidates)
antag_candidates -= boss
G.bosses += boss
G.bosses[boss] = GANGSTER_BOSS_STARTING_INFLUENCE
boss.gang_datum = G
var/title
if(n == 1)
@@ -85,6 +85,7 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
sleep(rand(10,100))
for(var/datum/gang/G in gangs)
for(var/datum/mind/boss_mind in G.bosses)
G.bosses[boss_mind] = GANGSTER_BOSS_STARTING_INFLUENCE //Force influence to be put on it.
G.add_gang_hud(boss_mind)
forge_gang_objectives(boss_mind)
greet_gang(boss_mind)
@@ -170,7 +171,7 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
return 0
if(check && gangster_mind.current.isloyal()) //Check to see if the potential gangster is implanted
return 1
G.gangsters += gangster_mind
G.gangsters[gangster_mind] = GANGSTER_SOLDIER_STARTING_INFLUENCE
gangster_mind.gang_datum = G
if(check)
if(iscarbon(gangster_mind.current))
@@ -209,15 +210,24 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
if(!G.is_deconvertible && !remove_bosses)
return 0
if(gangster_mind in G.gangsters)
G.reclaim_points(G.gangsters[gangster_mind])
G.gangsters -= gangster_mind
removed = 1
if(remove_bosses && (gangster_mind in G.bosses))
G.reclaim_points(G.bosses[gangster_mind])
G.bosses -= gangster_mind
removed = 1
if(G.tags_by_mind[gangster_mind] && islist(G.tags_by_mind[gangster_mind]))
var/list/tags_cache = G.tags_by_mind[gangster_mind]
for(var/v in tags_cache)
var/obj/effect/decal/cleanable/crayon/gang/c = v
c.set_mind_owner(null)
G.tags_by_mind -= gangster_mind
if(!removed)
return 0
gangster_mind.special_role = null
gangster_mind.gang_datum = null
+87 -43
View File
@@ -8,6 +8,7 @@
var/list/datum/mind/gangsters = list() //gang B Members
var/list/datum/mind/bosses = list() //gang A Bosses
var/list/obj/item/device/gangtool/gangtools = list()
var/list/tags_by_mind = list() //Assoc list in format of tags_by_mind[mind_of_gangster] = list(tag1, tag2, tag3) where tags are the actual object decals.
var/style
var/fighting_style = "normal"
var/list/territory = list()
@@ -75,7 +76,7 @@
/datum/gang_item/clothing/hands,
/datum/gang_item/clothing/belt,
/datum/gang_item/weapon/shuriken,
/datum/gang_item/weapon/shuriken,
/datum/gang_item/weapon/switchblade,
/datum/gang_item/weapon/improvised,
/datum/gang_item/weapon/ammo/improvised_ammo,
@@ -202,9 +203,9 @@
return
var/added_names = ""
var/lost_names = ""
SSticker.mode.shuttle_check() // See if its time to start wrapping things up
//Re-add territories that were reclaimed, so if they got tagged over, they can still earn income if they tag it back before the next status report
var/list/reclaimed_territories = territory_new & territory_lost
territory |= reclaimed_territories
@@ -245,47 +246,90 @@
set_domination_time(new_time)
message += "<b>[seconds_remaining] seconds remain</b> in hostile takeover.<BR>"
else
for(var/obj/item/device/gangtool/G in gangtools)
var/pmessage = message
var/points_new = 0
if(istype(G, /obj/item/device/gangtool/soldier))
points_new = max(0,round(3 - G.points/10)) + (sbonus) + (LAZYLEN(G.tags)/2) // Soldier points
pmessage += "Your influence has increased by [round(sbonus)] from your gang holding [LAZYLEN(territory)] territories, and a bonus of [round(LAZYLEN(G.tags)/2)] for territories you have personally marked and kept intact.<BR>"
else
points_new = max(0,round(5 - G.points/10)) + LAZYLEN(territory) // Boss points, more focused on big picture
pmessage += "Your influence has increased by [round(points_new)] from your gang holding [territory.len] territories<BR>"
G.points += points_new
var/mob/living/carbon/human/ganger = get(G.loc, /mob/living)
var/points_newer = 0
var/static/inner = inner_outfit
var/static/outer = outer_outfit
if(ishuman(ganger) && ganger.mind in (gangsters|bosses))
for(var/obj/C in ganger.contents)
if(C.type == inner_outfit)
points_newer += 2
continue
if(C.type == outer_outfit)
points_newer += 2
continue
switch(C.type)
if(/obj/item/clothing/neck/necklace/dope)
points_newer += 2
if(/obj/item/clothing/head/collectable/petehat/gang)
points_newer += 4
if(/obj/item/clothing/shoes/gang)
points_newer += 6
if(/obj/item/clothing/mask/gskull)
points_newer += 5
if(/obj/item/clothing/gloves/gang)
points_newer += 3
if(/obj/item/weapon/storage/belt/military/gang)
points_newer += 4
if(points_newer)
G.points += points_newer
pmessage += "Your influential choice of clothing has further increased your influence by [points_newer] points.<BR>"
pmessage += "You now have <b>[G.points] influence</b>.<BR>"
to_chat(ganger, "<span class='notice'>\icon[G] [pmessage]</span>")
pay_territory_income_to_bosses()
pay_territory_income_to_soldiers(sbonus)
pay_all_clothing_bonuses()
announce_all_influence()
/datum/gang/proc/pay_all_clothing_bonuses()
for(var/datum/mind/mind in gangsters|bosses)
pay_clothing_bonus(mind)
/datum/gang/proc/pay_clothing_bonus(var/datum/mind/gangsta)
var/mob/living/carbon/human/gangbanger = gangsta.current
. = 0
if(!istype(gangbanger) || gangbanger.stat == DEAD) //Dead gangsters aren't influential at all!
return 0
var/static/inner = inner_outfit
var/static/outer = outer_outfit
for(var/obj/item/C in gangbanger.contents)
if(C.type == inner_outfit)
. += 2
continue
else if(C.type == outer_outfit)
. += 2
continue
. += C.gang_contraband_value()
adjust_influence(gangsta, .)
if(.)
announce_to_mind(gangsta, "<span class='notice'>Your influential choice of clothing has increased your influence by [.] points!</span>")
else
announce_to_mind(gangsta, "<span class='warning'>Unfortunately, you have not gained any additional influence from your drab, old, boring clothing. Learn to dress like a gangsta, bro!</span>") //Kek
/datum/gang/proc/pay_soldier_territory_income(datum/mind/soldier, sbonus = 0)
. = 0
. = max(0,round(3 - gangsters[soldier]/10)) + (sbonus) + (get_soldier_territories(soldier)/2)
adjust_influence(soldier, .)
/datum/gang/proc/get_soldier_territories(datum/mind/soldier)
if(!islist(tags_by_mind[soldier])) //They have no tagged territories!
return 0
var/list/tags = tags_by_mind[soldier]
return tags.len
/datum/gang/proc/pay_territory_income_to_soldiers(sbonus = 0)
for(var/datum/mind/soldier in gangsters)
var/returned = pay_soldier_territory_income(soldier)
if(!returned)
announce_to_mind(soldier, "<span class='warning'>You have not gained any influence from territories you personally tagged. Get to work, soldier!</span>")
else
announce_to_mind(soldier, "<span class='notice'>You have gained [returned] influence from [get_soldier_territories(soldier)] territories you have personally tagged.</span>")
/datum/gang/proc/announce_all_influence()
for(var/datum/mind/MG in bosses|gangsters)
announce_total_influence(MG)
/datum/gang/proc/pay_territory_income_to_bosses()
. = 0
for(var/datum/mind/boss_mind in bosses)
var/inc = max(0,round(5 - bosses[boss_mind]/10)) + LAZYLEN(territory)
. += inc
adjust_influence(boss_mind, inc)
announce_to_mind(boss_mind, "<span class='boldnotice'>Your influence has increased by [inc] from your gang holding [LAZYLEN(territory)] territories!</span>")
/datum/gang/proc/get_influence(datum/mind/gangster_mind)
if(gangster_mind in gangsters)
return gangsters[gangster_mind]
if(gangster_mind in bosses)
return bosses[gangster_mind]
/datum/gang/proc/adjust_influence(datum/mind/gangster_mind, amount)
if(gangster_mind in gangsters)
gangsters[gangster_mind] += amount
if(gangster_mind in bosses)
bosses[gangster_mind] += amount
/datum/gang/proc/announce_to_mind(datum/mind/gangster_mind, message)
if(gangster_mind.current && gangster_mind.current.stat != DEAD)
to_chat(gangster_mind.current, message)
/datum/gang/proc/announce_total_influence(datum/mind/gangster_mind)
announce_to_mind(gangster_mind, "<span class='boldnotice'>[name] Gang: You now have a total of [get_influence(gangster_mind)] influence!</span>")
/datum/gang/proc/reclaim_points(amount)
for(var/datum/mind/bawss in bosses)
adjust_influence(bawss, amount/bosses.len)
announce_to_mind(bawss, "<span class='notice'>[name] Gang: [amount/bosses.len] influence given from internal automatic restructuring.</span>")
//Multiverse
+32 -13
View File
@@ -11,7 +11,7 @@
if(check_canbuy && !can_buy(user, gang, gangtool))
return FALSE
var/real_cost = get_cost(user, gang, gangtool)
gangtool.points -= real_cost
gang.adjust_influence(user.mind, -real_cost)
spawn_item(user, gang, gangtool)
return TRUE
@@ -23,7 +23,7 @@
to_chat(user, spawn_msg)
/datum/gang_item/proc/can_buy(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
return gang && (gangtool.points >= get_cost(user, gang, gangtool)) && can_see(user, gang, gangtool)
return gang && (gang.get_influence(user.mind) >= get_cost(user, gang, gangtool)) && can_see(user, gang, gangtool)
/datum/gang_item/proc/can_see(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
return TRUE
@@ -111,17 +111,20 @@
/datum/gang_item/clothing/hat
name = "Pimp Hat"
id = "hat"
cost = 18
cost = 16
item_path = /obj/item/clothing/head/collectable/petehat/gang
/obj/item/clothing/head/collectable/petehat/gang
name = "pimpin' hat"
desc = "The undisputed king of style."
/obj/item/clothing/head/collectable/petehat/gang/gang_contraband_value()
return 4
/datum/gang_item/clothing/mask
name = "Golden Death Mask"
id = "mask"
cost = 20
cost = 18
item_path = /obj/item/clothing/mask/gskull
/obj/item/clothing/mask/gskull
@@ -129,11 +132,13 @@
icon_state = "gskull"
desc = "Strike terror, and envy, into the hearts of your enemies."
/obj/item/clothing/mask/gskull/gang_contraband_value()
return 5
/datum/gang_item/clothing/shoes
name = "Bling Boots"
id = "boots"
cost = 25
cost = 22
item_path = /obj/item/clothing/shoes/gang
/obj/item/clothing/shoes/gang
@@ -141,17 +146,19 @@
desc = "Stand aside peasants."
icon_state = "bling"
/obj/item/clothing/shoes/gang/gang_contraband_value()
return 6
/datum/gang_item/clothing/neck
name = "Gold Necklace"
id = "necklace"
cost = 10
cost = 9
item_path = /obj/item/clothing/neck/necklace/dope
/datum/gang_item/clothing/hands
name = "Decorative Brass Knuckles"
id = "hand"
cost = 12
cost = 11
item_path = /obj/item/clothing/gloves/gang
/obj/item/clothing/gloves/gang
@@ -160,10 +167,13 @@
icon_state = "knuckles"
w_class = 3
/obj/item/clothing/gloves/gang/gang_contraband_value()
return 3
/datum/gang_item/clothing/belt
name = "Badass Belt"
id = "belt"
cost = 15
cost = 13
item_path = /obj/item/weapon/storage/belt/military/gang
/obj/item/weapon/storage/belt/military/gang
@@ -173,7 +183,8 @@
desc = "The belt buckle simply reads 'BAMF'."
storage_slots = 1
/obj/item/weapon/storage/belt/military/gang/gang_contraband_value()
return 4
///////////////////
//WEAPONS
@@ -236,16 +247,24 @@
item_path = /obj/item/ammo_box/magazine/m10mm
/datum/gang_item/weapon/sniper
name = ".50cal Sniper Rifle"
name = "Black Market .50cal Sniper Rifle"
id = "sniper"
cost = 40
item_path = /obj/item/weapon/gun/ballistic/automatic/sniper_rifle
/datum/gang_item/weapon/ammo/sniper_ammo
name = "Standard .50cal Sniper Rounds"
name = "Smuggled .50cal Sniper Rounds"
id = "sniper_ammo"
cost = 15
item_path = /obj/item/ammo_box/magazine/sniper_rounds
item_path = /obj/item/ammo_box/magazine/sniper_rounds/gang
/datum/gang_item/weapon/ammo/sleeper_ammo
name = "Illicit Tranquilizer Cartridges"
id = "sniper_ammo"
cost = 15
item_path = /obj/item/ammo_box/magazine/sniper_rounds/gang/sleeper
/datum/gang_item/weapon/machinegun
name = "Mounted Machine Gun"
+4 -7
View File
@@ -15,7 +15,6 @@
var/outfits = 2
var/free_pen = 0
var/promotable = 0
var/points = 15
var/list/tags = list()
/obj/item/device/gangtool/Initialize() //Initialize supply point income if it hasn't already been started
@@ -50,7 +49,7 @@
var/isboss = (user.mind == gang.bosses[1])
dat += "Registration: <B>[gang.name] Gang [isboss ? "Boss" : "Lieutenant"]</B><br>"
dat += "Organization Size: <B>[gang.gangsters.len + gang.bosses.len]</B> | Station Control: <B>[round((gang.territory.len/GLOB.start_state.num_territories)*100, 1)]%</B><br>"
dat += "Your Influence: <B>[points]</B><br>"
dat += "Your Influence: <B>[gang.get_influence(user.mind)]</B><br>"
dat += "Time until Influence grows: <B>[time2text(SSticker.mode.gang_points.next_point_time - world.time, "mm:ss")]</B><br>"
dat += "<hr>"
@@ -147,8 +146,9 @@
gang.gangtools += src
icon_state = "gangtool-[gang.color]"
if(!(user.mind in gang.bosses))
var/cached_influence = gang.gangsters[user.mind]
SSticker.mode.remove_gangster(user.mind, 0, 2)
gang.bosses += user.mind
gang.bosses[user.mind] = cached_influence
user.mind.gang_datum = gang
user.mind.special_role = "[gang.name] Gang Lieutenant"
gang.add_gang_hud(user.mind)
@@ -246,9 +246,6 @@
///////////// Internal tool used by gang regulars ///////////
/obj/item/device/gangtool/soldier
points = 5
/obj/item/device/gangtool/soldier/New(mob/user)
. = ..()
gang = user.mind.gang_datum
@@ -264,7 +261,7 @@
dat += "<center><font color='red'>Takeover In Progress:<br><B>[gang.domination_time_remaining()] seconds remain</B></font></center>"
dat += "Registration: <B>[gang.name] - Foot Soldier</B><br>"
dat += "Organization Size: <B>[gang.gangsters.len + gang.bosses.len]</B> | Station Control: <B>[round((gang.territory.len/GLOB.start_state.num_territories)*100, 1)]%</B><br>"
dat += "Your Influence: <B>[points]</B><br>"
dat += "Your Influence: <B>[gang.get_influence(user.mind)]</B><br>"
if(LAZYLEN(tags))
dat += "Your tags generate bonus influence for you.<br> You have tagged the following territories:"
for(var/obj/effect/decal/cleanable/crayon/gang/T in tags)
@@ -194,7 +194,7 @@
set desc = "Detonate all RCDs on the station, while sparing onboard cyborg RCDs."
set waitfor = FALSE
if(!canUseTopic() || malf_cooldown)
if(!canUseTopic() || malf_cooldown > world.time)
return
for(var/I in GLOB.rcd_list)
@@ -203,9 +203,7 @@
RCD.detonate_pulse()
to_chat(src, "<span class='warning'>RCD detonation pulse emitted.</span>")
malf_cooldown = TRUE
sleep(100)
malf_cooldown = FALSE
malf_cooldown = world.time + 100
/datum/AI_Module/large/mecha_domination
module_name = "Viral Mech Domination"
@@ -446,7 +444,7 @@
set name = "Reactivate Cameranet"
set category = "Malfunction"
if(!canUseTopic() || malf_cooldown)
if(!canUseTopic() || malf_cooldown > world.time)
return
var/fixedcams = 0 //Tells the AI how many cams it fixed. Stats are fun.
@@ -469,9 +467,7 @@
break
to_chat(src, "<span class='notice'>Diagnostic complete! Operations completed: [fixedcams].</span>")
malf_cooldown = 1
spawn(30) //Lag protection
malf_cooldown = 0
malf_cooldown = world.time + 30
/datum/AI_Module/large/upgrade_cameras
module_name = "Upgrade Camera Network"
+4 -4
View File
@@ -31,15 +31,15 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
var/max_i = 10//number of tries to spawn meteor.
while(!isspaceturf(pickedstart))
var/startSide = pick(GLOB.cardinal)
pickedstart = spaceDebrisStartLoc(startSide, 1)
pickedgoal = spaceDebrisFinishLoc(startSide, 1)
pickedstart = spaceDebrisStartLoc(startSide, ZLEVEL_STATION)
pickedgoal = spaceDebrisFinishLoc(startSide, ZLEVEL_STATION)
max_i--
if(max_i<=0)
return
var/Me = pickweight(meteortypes)
var/obj/effect/meteor/M = new Me(pickedstart)
M.dest = pickedgoal
M.z_original = 1
M.z_original = ZLEVEL_STATION
spawn(0)
walk_towards(M, M.dest, 1)
@@ -96,7 +96,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
pass_flags = PASSTABLE
var/heavy = 0
var/meteorsound = 'sound/effects/meteorimpact.ogg'
var/z_original = 1
var/z_original = ZLEVEL_STATION
var/threat = 0 // used for determining which meteors are most interesting
var/lifetime = DEFAULT_METEOR_LIFETIME
@@ -212,13 +212,12 @@
/obj/machinery/abductor/experiment/proc/SendBack(mob/living/carbon/human/H)
H.Sleeping(8)
H.uncuff()
if(console && console.pad && console.pad.teleport_target)
H.forceMove(console.pad.teleport_target)
H.uncuff()
return
//Area not chosen / It's not safe area - teleport to arrivals
H.forceMove(pick(GLOB.latejoin))
H.uncuff()
SSjob.SendToLateJoin(H, FALSE)
return
+1 -1
View File
@@ -243,7 +243,7 @@
if(!is_gangster(user))
var/datum/gang/multiverse/G = new(src, "[user.real_name]")
SSticker.mode.gangs += G
G.bosses += user.mind
G.bosses[user.mind] = 0
G.add_gang_hud(user.mind)
user.mind.gang_datum = G
to_chat(user, "<span class='warning'><B>With your new found power you could easily conquer the station!</B></span>")
+2 -1
View File
@@ -142,7 +142,8 @@
return
//First we spawn a dude.
var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin))//The mob being spawned.
var/mob/living/carbon/human/new_character = new//The mob being spawned.
SSjob.SendToLateJoin(new_character)
G_found.client.prefs.copy_to(new_character)
new_character.dna.update_dna_identity()
+19 -20
View File
@@ -5,7 +5,7 @@
start_active = 1
/obj/machinery/camera/emp_proof/Initialize()
..()
. = ..()
upgradeEmpProof()
// X-RAY
@@ -15,7 +15,7 @@
icon_state = "xraycam" // Thanks to Krutchen for the icons.
/obj/machinery/camera/xray/Initialize()
..()
. = ..()
upgradeXRay()
// MOTION
@@ -32,7 +32,7 @@
start_active = 1
/obj/machinery/camera/all/Initialize()
..()
. = ..()
upgradeEmpProof()
upgradeXRay()
upgradeMotion()
@@ -43,23 +43,22 @@
var/number = 0 //camera number in area
//This camera type automatically sets it's name to whatever the area that it's in is called.
/obj/machinery/camera/autoname/Initialize(mapload)
if(mapload)
..()
return TRUE
else
if(!initialized)
..()
number = 1
var/area/A = get_area(src)
if(A)
for(var/obj/machinery/camera/autoname/C in GLOB.machines)
if(C == src) continue
var/area/CA = get_area(C)
if(CA.type == A.type)
if(C.number)
number = max(number, C.number+1)
c_tag = "[A.name] #[number]"
/obj/machinery/camera/autoname/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/camera/autoname/LateInitialize()
. = ..()
number = 1
var/area/A = get_area(src)
if(A)
for(var/obj/machinery/camera/autoname/C in GLOB.machines)
if(C == src) continue
var/area/CA = get_area(C)
if(CA.type == A.type)
if(C.number)
number = max(number, C.number+1)
c_tag = "[A.name] #[number]"
// CHECKS
+2 -2
View File
@@ -331,8 +331,8 @@
to_chat(user, "<span class='danger'>Error: Pod has no occupant.</span>")
return
else
connected_message("Authorized Ejection")
SPEAK("An authorized ejection of [clonemind.name] has occurred.")
connected_message("Emergency Ejection")
SPEAK("An emergency ejection of [clonemind.name] has occurred. Survival not guaranteed.")
to_chat(user, "<span class='notice'>You force an emergency ejection. </span>")
go_out()
else
+2 -4
View File
@@ -134,12 +134,10 @@
D["Cancel"] = "Cancel"
for(var/obj/machinery/camera/C in L)
if(!C.network)
spawn(0)
throw EXCEPTION("Camera in a cameranet has no camera network")
stack_trace("Camera in a cameranet has no camera network")
continue
if(!(istype(C.network,/list)))
spawn(0)
throw EXCEPTION("Camera in a cameranet has a non-list camera network")
stack_trace("Camera in a cameranet has a non-list camera network")
continue
var/list/tempnetwork = C.network&network
if(tempnetwork.len)
+7 -2
View File
@@ -24,7 +24,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
//Cooldown for closing positions in seconds
//if set to -1: No cooldown... probably a bad idea
//if set to 0: Not able to close "original" positions. You can only close positions that you have opened before
var/change_position_cooldown = 60
var/change_position_cooldown = 30
//Jobs you cannot open new positions for
var/list/blacklisted = list(
"AI",
@@ -46,6 +46,11 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/card/Initialize()
. = ..()
change_position_cooldown = config.id_console_jobslot_delay
/obj/machinery/computer/card/attackby(obj/O, mob/user, params)//TODO:SANITY
if(istype(O, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/idcard = O
@@ -532,7 +537,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
else
SSjob.prioritized_jobs += j
prioritycount++
to_chat(usr, "<span class='notice'>[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request.</span>")
to_chat(usr, "<span class='notice'>[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request.</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if ("print")
+1 -1
View File
@@ -1,7 +1,7 @@
// The communications computer
/obj/machinery/computer/communications
name = "communications console"
desc = "This can be used for various important functions. Still under developement."
desc = "A console used for high-priority announcements and emergencies."
icon_screen = "comm"
icon_keyboard = "tech_key"
req_access = list(GLOB.access_heads)
+8 -11
View File
@@ -28,7 +28,7 @@
var/list/buffer[NUMBER_OF_BUFFERS]
var/injectorready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete
var/injectorready = 0 //world timer cooldown var
var/current_screen = "mainmenu"
var/obj/machinery/dna_scannernew/connected = null
var/obj/item/weapon/disk/data/diskette = null
@@ -61,8 +61,7 @@
connected = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
if(!isnull(connected))
break
spawn(250)
injectorready = 1
injectorready = world.time + INJECTOR_TIMEOUT
return
return
@@ -213,7 +212,7 @@
else
temp_html += "<span class='linkOff'>Occupant</span>"
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_UE]'>Occupant:Delayed</a> "
if(injectorready)
if(injectorready < world.time)
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=ue'>Injector</a>"
else
temp_html += "<span class='linkOff'>Injector</span>"
@@ -227,7 +226,7 @@
else
temp_html += "<span class='linkOff'>Occupant</span>"
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_UI]'>Occupant:Delayed</a> "
if(injectorready)
if(injectorready < world.time)
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=ui'>Injector</a>"
else
temp_html += "<span class='linkOff'>Injector</span>"
@@ -240,7 +239,7 @@
else
temp_html += "<span class='linkOff'>Occupant</span>"
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_MIXED]'>Occupant:Delayed</a> "
if(injectorready)
if(injectorready < world.time)
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=mixed'>UI+UE Injector</a>"
else
temp_html += "<span class='linkOff'>UI+UE Injector</span>"
@@ -251,7 +250,7 @@
else
temp_html += "<span class='linkOff'>Occupant</span> "
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_SE]'>Occupant:Delayed</a> "
if(injectorready)
if(injectorready < world.time )
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=se'>Injector</a>"
else
temp_html += "<span class='linkOff'>Injector</span>"
@@ -391,7 +390,7 @@
if("mixed")
apply_buffer(SCANNER_ACTION_MIXED,num)
if("injector")
if(num && injectorready)
if(num && injectorready < world.time)
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
var/list/buffer_slot = buffer[num]
if(istype(buffer_slot))
@@ -439,9 +438,7 @@
if(connected)
I.damage_coeff = connected.damage_coeff
if(I)
injectorready = 0
spawn(INJECTOR_TIMEOUT)
injectorready = 1
injectorready = world.time + INJECTOR_TIMEOUT
if("loaddisk")
if(num && diskette && diskette.fields)
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
+2 -2
View File
@@ -620,7 +620,7 @@ What a mess.*/
if("mi_crim_add")
if(istype(active1, /datum/data/record))
var/t1 = stripped_input(usr, "Please input minor crime names:", "Secure. records", "", null)
var/t2 = stripped_multiline_input(usr, "Please input minor crime details:", "Secure. records", "", null)
var/t2 = stripped_input(usr, "Please input minor crime details:", "Secure. records", "", null)
if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, worldtime2text())
@@ -634,7 +634,7 @@ What a mess.*/
if("ma_crim_add")
if(istype(active1, /datum/data/record))
var/t1 = stripped_input(usr, "Please input major crime names:", "Secure. records", "", null)
var/t2 = stripped_multiline_input(usr, "Please input major crime details:", "Secure. records", "", null)
var/t2 = stripped_input(usr, "Please input major crime details:", "Secure. records", "", null)
if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, worldtime2text())
+15 -14
View File
@@ -98,20 +98,14 @@
/obj/machinery/door/airlock/Initialize()
. = ..()
wires = new /datum/wires/airlock(src)
if (cyclelinkeddir)
cyclelinkairlock()
if(frequency)
set_frequency(frequency)
update_icon()
wires = new /datum/wires/airlock(src)
if(src.closeOtherId != null)
spawn (5)
for (var/obj/machinery/door/airlock/A in GLOB.airlocks)
if(A.closeOtherId == src.closeOtherId && A != src)
src.closeOther = A
break
if(closeOtherId != null)
addtimer(CALLBACK(.proc/update_other_id), 5)
if(glass)
airlock_material = "glass"
if(security_level > AIRLOCK_SECURITY_METAL)
@@ -127,6 +121,15 @@
diag_hud.add_to_hud(src)
diag_hud_set_electrified()
update_icon()
/obj/machinery/door/airlock/proc/update_other_id()
for(var/obj/machinery/door/airlock/A in GLOB.airlocks)
if(A.closeOtherId == closeOtherId && A != src)
closeOther = A
break
/obj/machinery/door/airlock/proc/cyclelinkairlock()
if (cyclelinkedairlock)
cyclelinkedairlock.cyclelinkedairlock = null
@@ -330,16 +333,14 @@
/obj/machinery/door/airlock/proc/shock(mob/user, prb)
if(!hasPower()) // unpowered, no shock
return FALSE
if(hasShocked)
if(hasShocked > world.time)
return FALSE //Already shocked someone recently?
if(!prob(prb))
return FALSE //you lucked out, no shock for you
do_sparks(5, TRUE, src)
var/tmp/check_range = TRUE
if(electrocute_mob(user, get_area(src), src, 1, check_range))
hasShocked = TRUE
spawn(10)
hasShocked = FALSE
hasShocked = world.time + 10
return TRUE
else
return FALSE
+10 -19
View File
@@ -58,12 +58,11 @@ Possible to do for anyone motivated enough:
/obj/machinery/holopad/Destroy()
if(outgoing_call)
LAZYADD(holo_calls, outgoing_call)
outgoing_call.ConnectionFailure(src)
for(var/I in holo_calls)
var/datum/holocall/HC = I
HC.ConnectionFailure(src)
LAZYCLEARLIST(holo_calls)
for (var/I in masters)
clear_holo(I)
@@ -74,7 +73,14 @@ Possible to do for anyone motivated enough:
if (powered())
stat &= ~NOPOWER
else
stat |= ~NOPOWER
stat |= NOPOWER
if(outgoing_call)
outgoing_call.ConnectionFailure(src)
/obj/machinery/holopad/obj_break()
. = ..()
if(outgoing_call)
outgoing_call.ConnectionFailure(src)
/obj/machinery/holopad/RefreshParts()
var/holograph_range = 4
@@ -99,26 +105,11 @@ Possible to do for anyone motivated enough:
return
return ..()
/obj/machinery/holopad/proc/CheckCallClose()
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(usr == HC.eye)
HC.Disconnect(HC.calling_holopad) //disconnect via clicking the called holopad
return TRUE
return FALSE
/obj/machinery/holopad/Click(location,control,params)
if(!CheckCallClose())
return ..()
/obj/machinery/holopad/AltClick(mob/living/carbon/human/user)
if(isAI(user))
hangup_all_calls()
return
if(!CheckCallClose())
interact(user)
/obj/machinery/holopad/interact(mob/living/carbon/human/user) //Carn: Hologram requests.
if(!istype(user))
return
@@ -402,4 +393,4 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
req_components = list(/obj/item/weapon/stock_parts/capacitor = 1)
#undef HOLOPAD_PASSIVE_POWER_USAGE
#undef HOLOGRAM_POWER_USAGE
#undef HOLOGRAM_POWER_USAGE
+7 -15
View File
@@ -58,15 +58,11 @@
var/p_dir = text2num(href_list["dir"])
var/obj/item/pipe/P = new (src.loc, pipe_type=p_type, dir=p_dir)
P.add_fingerprint(usr)
wait = 1
spawn(10)
wait = 0
wait = world.time + 10
if(href_list["makemeter"])
if(!wait)
if(wait < world.time )
new /obj/item/pipe_meter(src.loc)
wait = 1
spawn(15)
wait = 0
wait = world.time + 15
return
/obj/machinery/pipedispenser/attackby(obj/item/W, mob/user, params)
@@ -165,7 +161,7 @@ Nah
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["dmake"])
if(!wait)
if(wait < world.time)
var/p_type = text2num(href_list["dmake"])
var/obj/structure/disposalconstruct/C = new (src.loc,p_type)
@@ -176,9 +172,7 @@ Nah
C.add_fingerprint(usr)
C.update_icon()
wait = 1
spawn(15)
wait = 0
wait = world.time + 15
return
//transit tube dispenser
@@ -216,7 +210,7 @@ Nah
return 1
usr.set_machine(src)
src.add_fingerprint(usr)
if(!wait)
if(wait < world.time)
if(href_list["tube"])
var/tube_type = text2num(href_list["tube"])
var/obj/structure/C
@@ -241,7 +235,5 @@ Nah
C = new /obj/structure/c_transit_tube_pod(loc)
if(C)
C.add_fingerprint(usr)
wait = 1
spawn(15)
wait = 0
wait = world.time + 15
return
@@ -1102,4 +1102,4 @@
if(target == user || target == get_turf(src))
return
target_turf = get_turf(target)
fire_helper(target_turf)
fire_helper(user)
+13 -20
View File
@@ -49,9 +49,7 @@
/obj/structure/emergency_shield/take_damage(damage, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
if(.) //damage was dealt
set_opacity(1)
spawn(20)
set_opacity(0)
new /obj/effect/temp_visual/impact_effect/ion(loc)
/obj/structure/emergency_shield/sanguine
name = "sanguine barrier"
@@ -86,23 +84,24 @@
req_access = list(GLOB.access_engine)
max_integrity = 100
obj_integrity = 100
var/active = 0
var/list/deployed_shields = list()
var/active = FALSE
var/list/deployed_shields
var/locked = 0
var/shield_range = 4
/obj/machinery/shieldgen/Destroy()
for(var/obj/structure/emergency_shield/ES in deployed_shields)
qdel(ES)
/obj/machinery/shieldgen/Initialize(mapload)
. = ..()
deployed_shields = list()
if(mapload && active && anchored)
shields_up()
/obj/machinery/shieldgen/Destroy()
QDEL_LIST(deployed_shields)
return ..()
/obj/machinery/shieldgen/proc/shields_up()
if(active)
return 0 //If it's already turned on, how did this get called?
active = 1
active = TRUE
update_icon()
for(var/turf/target_tile in range(shield_range, src))
@@ -111,15 +110,9 @@
deployed_shields += new /obj/structure/emergency_shield(target_tile)
/obj/machinery/shieldgen/proc/shields_down()
if(!active)
return 0 //If it's already off, how did this get called?
active = 0
active = FALSE
update_icon()
for(var/obj/structure/emergency_shield/ES in deployed_shields)
qdel(ES)
deployed_shields.Cut()
QDEL_LIST(deployed_shields)
/obj/machinery/shieldgen/process()
if((stat & BROKEN) && active)
+3 -1
View File
@@ -45,12 +45,14 @@
// register for radio system
/obj/machinery/status_display/Initialize()
..()
. = ..()
GLOB.ai_status_displays.Add(src)
SSradio.add_object(src, frequency)
/obj/machinery/status_display/Destroy()
if(SSradio)
SSradio.remove_object(src,frequency)
GLOB.ai_status_displays.Remove(src)
return ..()
// timed process
@@ -68,8 +68,7 @@
message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Wormhole Generator in [ADMIN_COORDJMP(T)]",0,1)
log_game("[key_name(chassis.occupant)] used a Wormhole Generator in [COORD(T)]")
src = null
spawn(rand(150,300))
qdel(P)
QDEL_IN(P, rand(150,300))
return 1
+4 -4
View File
@@ -12,8 +12,8 @@
var/poster_type
var/obj/structure/sign/poster/poster_structure
/obj/item/weapon/poster/New(loc, obj/structure/sign/poster/new_poster_structure)
..()
/obj/item/weapon/poster/Initialize(mapload, obj/structure/sign/poster/new_poster_structure)
. = ..()
poster_structure = new_poster_structure
if(!new_poster_structure && poster_type)
poster_structure = new poster_type(src)
@@ -58,8 +58,8 @@
var/poster_item_desc = "This hypothetical poster item should not exist, let's be honest here."
var/poster_item_icon_state = "rolled_poster"
/obj/structure/sign/poster/New()
..()
/obj/structure/sign/poster/Initialize()
. = ..()
if(random_basetype)
randomise(random_basetype)
if(!ruined)
+14 -6
View File
@@ -30,27 +30,35 @@
layer = HIGH_OBJ_LAYER //Harder to hide
do_icon_rotate = FALSE //These are designed to always face south, so no rotation please.
var/datum/gang/gang
var/obj/item/device/gangtool/linked_tool
var/datum/mind/user_mind
var/area/territory
/obj/effect/decal/cleanable/crayon/gang/Initialize(mapload, var/datum/gang/G, var/e_name = "gang tag", var/rotation = 0, var/mob/user)
if(!type || !G)
qdel(src)
user_mind = user.mind
territory = get_area(src)
gang = G
var/newcolor = G.color_hex
icon_state = G.name
G.territory_new |= list(territory.type = territory.name)
linked_tool = locate(/obj/item/device/gangtool) in user.contents
if(linked_tool)
linked_tool.tags += src
//If this isn't tagged by a specific gangster there's no bonus income.
set_mind_owner(user_mind)
..(mapload, newcolor, icon_state, e_name, rotation)
/obj/effect/decal/cleanable/crayon/gang/proc/set_mind_owner(datum/mind/mind)
if(istype(user_mind) && istype(gang) && islist(gang.tags_by_mind[user_mind])) //Clear us out of old ownership
gang.tags_by_mind[user_mind] -= src
if(istype(mind))
if(!islist(gang.tags_by_mind[mind]))
gang.tags_by_mind[mind] = list()
gang.tags_by_mind[mind] += src
user_mind = mind
/obj/effect/decal/cleanable/crayon/gang/Destroy()
if(linked_tool)
linked_tool.tags -= src
if(gang)
gang.territory -= territory.type
set_mind_owner(null)
gang.territory_new -= territory.type
gang.territory_lost |= list(territory.type = territory.name)
return ..()
+1 -1
View File
@@ -182,7 +182,7 @@
/obj/effect/landmark/latejoin/Initialize(mapload)
..()
GLOB.latejoin += loc
SSjob.latejoin_trackers += loc
qdel(src)
// carp.
+2 -2
View File
@@ -127,8 +127,8 @@
var/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0)
spawn(0)
new /obj/effect/hallucination/delusion(victim.loc,victim,force_kind="demon",duration=duration,skip_nearby=0)
new /obj/effect/hallucination/delusion(victim.loc,victim,"demon",duration,0)
var/obj/item/weapon/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
chainsaw.flags |= NODROP
victim.drop_all_held_items()
+30 -1
View File
@@ -54,6 +54,35 @@
/obj/item/trash/sosjerky = 1,
/obj/item/trash/syndi_cakes = 1)
/obj/effect/spawner/lootdrop/three_course_meal
name = "three course meal spawner"
lootcount = 3
lootdoubles = FALSE
var/soups = list(
/obj/item/weapon/reagent_containers/food/snacks/soup/beet,
/obj/item/weapon/reagent_containers/food/snacks/soup/sweetpotato,
/obj/item/weapon/reagent_containers/food/snacks/soup/stew,
/obj/item/weapon/reagent_containers/food/snacks/soup/hotchili,
/obj/item/weapon/reagent_containers/food/snacks/soup/nettle,
/obj/item/weapon/reagent_containers/food/snacks/soup/meatball)
var/salads = list(
/obj/item/weapon/reagent_containers/food/snacks/salad/herbsalad,
/obj/item/weapon/reagent_containers/food/snacks/salad/validsalad,
/obj/item/weapon/reagent_containers/food/snacks/salad/fruit,
/obj/item/weapon/reagent_containers/food/snacks/salad/jungle,
/obj/item/weapon/reagent_containers/food/snacks/salad/aesirsalad)
var/mains = list(
/obj/item/weapon/reagent_containers/food/snacks/bearsteak,
/obj/item/weapon/reagent_containers/food/snacks/enchiladas,
/obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat,
/obj/item/weapon/reagent_containers/food/snacks/burger/bigbite,
/obj/item/weapon/reagent_containers/food/snacks/burger/superbite,
/obj/item/weapon/reagent_containers/food/snacks/burger/fivealarm)
/obj/effect/spawner/lootdrop/three_course_meal/Initialize(mapload)
loot = list(pick(soups) = 1,pick(salads) = 1,pick(mains) = 1)
. = ..()
/obj/effect/spawner/lootdrop/maintenance
name = "maintenance loot spawner"
// see code/_globalvars/lists/maintenance_loot.dm for loot table
@@ -85,7 +114,7 @@
/obj/item/organ/heart/gland/spiderman = 5,
/obj/item/organ/heart/gland/ventcrawling = 1,
/obj/item/organ/body_egg/alien_embryo = 1,
/obj/item/organ/hivelord_core = 2)
/obj/item/organ/regenerative_core = 2)
lootcount = 3
/obj/effect/spawner/lootdrop/two_percent_xeno_egg_spawner
@@ -169,7 +169,9 @@
/obj/effect/temp_visual/fire
icon = 'icons/effects/fire.dmi'
icon_state = "3"
duration = 20
light_range = 3
light_color = LIGHT_COLOR_FIRE
duration = 10
/obj/effect/temp_visual/revenant
name = "spooky lights"
+5 -6
View File
@@ -1,19 +1,18 @@
/obj/item/weapon/poster/wanted
icon_state = "rolled_poster"
/obj/item/weapon/poster/wanted/New(turf/loc, icon/person_icon, wanted_name, description)
var/obj/structure/sign/poster/wanted/wanted_poster = new(person_icon, wanted_name, description)
..(loc, wanted_poster)
/obj/item/weapon/poster/wanted/Initialize(mapload, icon/person_icon, wanted_name, description)
. = ..(mapload, new /obj/structure/sign/poster/wanted(src, person_icon, wanted_name, description))
name = "wanted poster ([wanted_name])"
desc = "A wanted poster for [wanted_name]."
/obj/structure/sign/poster/wanted
var/wanted_name
/obj/structure/sign/poster/wanted/New(var/icon/person_icon, var/person_name, var/description)
/obj/structure/sign/poster/wanted/Initialize(mapload, icon/person_icon, person_name, description)
. = ..()
if(!person_icon)
qdel(src)
return
return INITIALIZE_HINT_QDEL
name = "wanted poster ([person_name])"
wanted_name = person_name
desc = description
+11 -2
View File
@@ -10,9 +10,9 @@
// add an entry in change_appearance() if you add to here
var/list/possible_appearances = list("Assistant", "Clown", "Mime",
"Traitor", "Nuke Op", "Cultist", "Clockwork Cultist",
"Revolutionary", "Wizard", "Shadowling", "Xenomorph", "Swarmer",
"Revolutionary", "Wizard", "Shadowling", "Xenomorph", "Xenomorph Maid", "Swarmer",
"Ash Walker", "Deathsquad Officer", "Ian", "Slaughter Demon",
"Laughter Demon")
"Laughter Demon", "Private Security Officer")
var/pushed_over = FALSE //If the cutout is pushed over and has to be righted
var/deceptive = FALSE //If the cutout actually appears as what it portray and not a discolored version
@@ -142,6 +142,10 @@
icon_state = "cutout_fukken_xeno"
if(prob(25))
alpha = 75 //Spooky sneaking!
if("Xenomorph Maid")
name = "lusty xenomorph maid ([rand(1, 999)])"
desc = "A cardboard cutout of a xenomorph maid."
icon_state = "cutout_lusty"
if("Swarmer")
name = "Swarmer ([rand(1, 999)])"
desc = "A cardboard cutout of a swarmer."
@@ -168,6 +172,11 @@
desc = "A cardboard cutout of a laughter demon."
icon = 'icons/mob/mob.dmi'
icon_state = "bowmon"
if("Private Security Officer")
name = "Private Security Officer"
desc = "A cardboard cutout of a private security officer."
icon = 'icons/mob/mob.dmi'
icon_state = "cutout_ntsec"
return 1
/obj/item/cardboard_cutout/setDir(newdir)
@@ -90,7 +90,7 @@
name = ""
desc = ""
density = 0
var/can_move = 1
var/can_move = 0
var/obj/item/device/chameleon/master = null
/obj/effect/dummy/chameleon/proc/activate(mob/M, saved_appearance, obj/item/device/chameleon/C)
@@ -126,19 +126,21 @@
if(isspaceturf(loc) || !direction)
return //No magical space movement!
if(can_move)
can_move = 0
if(can_move < world.time)
var/amount
switch(user.bodytemperature)
if(300 to INFINITY)
spawn(10) can_move = 1
amount = 10
if(295 to 300)
spawn(13) can_move = 1
amount = 13
if(280 to 295)
spawn(16) can_move = 1
amount = 16
if(260 to 280)
spawn(20) can_move = 1
amount = 20
else
spawn(25) can_move = 1
amount = 25
can_move = world.time + amount
step(src, direction)
return
+4 -8
View File
@@ -111,7 +111,7 @@
"<span class='warning'>You bop [M] on the head!</span>")
playsound(loc, 'sound/weapons/tap.ogg', 50, 1, -1)
if(2)
if(!scooldown)
if(scooldown < world.time)
if(M.health >= 0)
if(ishuman(M)||ismonkey(M))
M.electrocute_act(5, "[user]", safety = 1)
@@ -128,11 +128,9 @@
"<span class='danger'>You shock [M] to no effect.</span>")
playsound(loc, 'sound/effects/sparks2.ogg', 50, 1, -1)
user.cell.charge -= 500
scooldown = TRUE
spawn(20)
scooldown = FALSE
scooldown = world.time + 20
if(3)
if(!ccooldown)
if(ccooldown < world.time)
if(M.health >= 0)
if(ishuman(M))
user.visible_message("<span class='userdanger'>[user] crushes [M] in their grip!</span>", \
@@ -143,9 +141,7 @@
playsound(loc, 'sound/weapons/smash.ogg', 50, 1, -1)
M.adjustBruteLoss(15)
user.cell.charge -= 300
ccooldown = TRUE
spawn(10)
ccooldown = FALSE
ccooldown = world.time + 10
/obj/item/borg/cyborghug/peacekeeper
shockallowed = TRUE
@@ -60,6 +60,7 @@
origin_tech = "bluespace=6;materials=3"
materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT)
attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed")
novariants = TRUE
var/crystal_type = /obj/item/weapon/ore/bluespace_crystal/refined
/obj/item/stack/sheet/bluespace_crystal/attack_self(mob/user)// to prevent the construction menu from ever happening
@@ -5,11 +5,13 @@
amount = 6
max_amount = 6
w_class = WEIGHT_CLASS_TINY
full_w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
resistance_flags = FLAMMABLE
obj_integrity = 40
max_integrity = 40
novariants = FALSE
var/heal_brute = 0
var/heal_burn = 0
var/stop_bleeding = 0
+1
View File
@@ -20,6 +20,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
max_amount = 50
attack_verb = list("hit", "bludgeoned", "whacked")
hitsound = 'sound/weapons/grenadelaunch.ogg'
novariants = TRUE
/obj/item/stack/rods/Initialize(mapload, new_amount, merge = TRUE)
..()
@@ -2,12 +2,14 @@
name = "hide"
desc = "Something went wrong."
origin_tech = "biotech=3"
novariants = TRUE
/obj/item/stack/sheet/animalhide/human
name = "human skin"
desc = "The by-product of human farming."
singular_name = "human skin piece"
icon_state = "sheet-hide"
novariants = FALSE
GLOBAL_LIST_INIT(human_recipes, list( \
new/datum/stack_recipe("bloated human costume", /obj/item/clothing/suit/hooded/bloated_human, 5, on_floor = 1), \
@@ -22,6 +24,7 @@ GLOBAL_LIST_INIT(human_recipes, list( \
desc = "A piece of skin."
singular_name = "skin piece"
icon_state = "sheet-hide"
novariants = FALSE
/obj/item/stack/sheet/animalhide/corgi
name = "corgi hide"
@@ -87,6 +90,7 @@ GLOBAL_LIST_INIT(xeno_recipes, list ( \
icon = 'icons/mob/alien.dmi'
icon_state = "chitin"
origin_tech = null
novariants = TRUE
/obj/item/xenos_claw
name = "alien claw"
@@ -153,6 +157,7 @@ GLOBAL_LIST_INIT(leather_recipes, list ( \
singular_name = "watcher sinew"
icon_state = "sinew"
origin_tech = "biotech=4"
novariants = TRUE
GLOBAL_LIST_INIT(sinew_recipes, list ( \
@@ -166,23 +171,27 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \
/*
* Plates
*/
/obj/item/stack/sheet/animalhide/goliath_hide
name = "goliath hide plates"
desc = "Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna."
icon = 'icons/obj/mining.dmi'
icon_state = "goliath_hide"
singular_name = "hide plate"
max_amount = 6
novariants = FALSE
flags = NOBLUDGEON
w_class = WEIGHT_CLASS_NORMAL
layer = MOB_LAYER
/obj/item/stack/sheet/animalhide/ashdrake
name = "ash drake hide"
desc = "The strong, scaled hide of an ash drake."
icon = 'icons/obj/mining.dmi'
icon_state = "dragon_hide"
singular_name = "drake plate"
max_amount = 10
novariants = FALSE
flags = NOBLUDGEON
w_class = WEIGHT_CLASS_NORMAL
layer = MOB_LAYER
@@ -68,6 +68,7 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
singular_name = "sandbag"
layer = LOW_ITEM_LAYER
origin_tech = "materials=2"
novariants = TRUE
GLOBAL_LIST_INIT(sandbag_recipes, list ( \
new/datum/stack_recipe("sandbags", /obj/structure/barricade/sandbags, 1, time = 25, one_per_turf = 1, on_floor = 1), \
@@ -104,6 +105,7 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \
origin_tech = "materials=6"
sheettype = "diamond"
materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT)
novariants = TRUE
GLOBAL_LIST_INIT(diamond_recipes, list ( \
new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \
@@ -127,6 +129,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
origin_tech = "materials=5"
sheettype = "uranium"
materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT)
novariants = TRUE
GLOBAL_LIST_INIT(uranium_recipes, list ( \
new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \
@@ -237,6 +240,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
origin_tech = "materials=4"
sheettype = "clown"
materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT)
novariants = TRUE
GLOBAL_LIST_INIT(clown_recipes, list ( \
new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
@@ -355,6 +359,7 @@ GLOBAL_LIST_INIT(adamantine_recipes, list(
icon_state = "sheet-mythril"
singular_name = "mythril sheet"
origin_tech = "materials=4"
novariants = TRUE
/*
* Alien Alloy
@@ -162,6 +162,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0)
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/sheet/mineral/wood
novariants = TRUE
/obj/item/stack/sheet/mineral/wood/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.wood_recipes
@@ -239,6 +240,7 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
origin_tech = "materials=1"
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/sheet/cardboard
novariants = TRUE
/obj/item/stack/sheet/cardboard/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.cardboard_recipes
@@ -268,6 +270,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
icon = 'icons/obj/items.dmi'
sheettype = "runed"
merge_type = /obj/item/stack/sheet/runed_metal
novariants = TRUE
/obj/item/stack/sheet/runed_metal/ratvar_act()
new /obj/item/stack/tile/brass(loc, amount)
@@ -322,6 +325,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
throw_speed = 1
throw_range = 3
turf_type = /turf/open/floor/clockwork
novariants = FALSE
/obj/item/stack/tile/brass/narsie_act()
new /obj/item/stack/sheet/runed_metal(loc, amount)
@@ -339,6 +343,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
singular_name = "lesser gem"
icon_state = "sheet-lessergem"
origin_tech = "materials=4"
novariants = TRUE
/obj/item/stack/sheet/greatergem
@@ -347,6 +352,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
singular_name = "greater gem"
icon_state = "sheet-greatergem"
origin_tech = "materials=7"
novariants = TRUE
/*
* Bones
@@ -359,6 +365,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
desc = "Someone's been drinking their milk."
force = 7
throwforce = 5
max_amount = 12
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 1
throw_range = 3
@@ -1,11 +1,12 @@
/obj/item/stack/sheet
name = "sheet"
w_class = WEIGHT_CLASS_NORMAL
full_w_class = WEIGHT_CLASS_NORMAL
force = 5
throwforce = 5
max_amount = 50
throw_speed = 1
throw_range = 3
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
novariants = FALSE
var/perunit = MINERAL_MATERIAL_AMOUNT
var/sheettype = null //this is used for girders in the creation of walls/false walls
+26
View File
@@ -18,6 +18,8 @@
var/datum/robot_energy_storage/source
var/cost = 1 // How much energy from storage it costs
var/merge_type = null // This path and its children should merge with this stack, defaults to src.type
var/full_w_class = WEIGHT_CLASS_NORMAL //The weight class the stack should have at amount > 2/3rds max_amount
var/novariants = TRUE //Determines whether the item should update it's sprites based on amount.
/obj/item/stack/Initialize(mapload, new_amount=null , merge = TRUE)
..()
@@ -29,6 +31,28 @@
for(var/obj/item/stack/S in loc)
if(S.merge_type == merge_type)
merge(S)
update_weight()
update_icon()
/obj/item/stack/proc/update_weight()
if(amount <= (max_amount * (1/3)))
w_class = Clamp(full_w_class-2, WEIGHT_CLASS_TINY, full_w_class)
else if (amount <= (max_amount * (2/3)))
w_class = Clamp(full_w_class-1, WEIGHT_CLASS_TINY, full_w_class)
else
w_class = full_w_class
/obj/item/stack/update_icon()
if(novariants)
return ..()
if(amount <= (max_amount * (1/3)))
icon_state = initial(icon_state)
else if (amount <= (max_amount * (2/3)))
icon_state = "[initial(icon_state)]_2"
else
icon_state = "[initial(icon_state)]_3"
..()
/obj/item/stack/Destroy()
if (usr && usr.machine==src)
@@ -188,6 +212,7 @@
amount -= used
zero_amount()
update_icon()
update_weight()
return 1
/obj/item/stack/proc/zero_amount()
@@ -204,6 +229,7 @@
else
src.amount += amount
update_icon()
update_weight()
/obj/item/stack/proc/merge(obj/item/stack/S) //Merge src into S, as much as possible
if(QDELETED(S) || QDELETED(src) || S == src) //amusingly this can cause a stack to consume itself, let's not allow that.
@@ -12,6 +12,7 @@
origin_tech = "materials=1"
var/turf_type = null
var/mineralType = null
novariants = TRUE
/obj/item/stack/tile/Initialize(mapload, amount)
. = ..()
@@ -106,6 +107,14 @@
turf_type = /turf/open/floor/carpet
resistance_flags = FLAMMABLE
/obj/item/stack/tile/carpet/black
name = "black carpet"
icon_state = "tile-carpet-black"
turf_type = /turf/open/floor/carpet/black
/obj/item/stack/tile/carpet/black/fifty
amount = 50
/obj/item/stack/tile/fakespace
name = "astral carpet"
@@ -92,6 +92,13 @@
if(mapload && access_txt)
access = text2access(access_txt)
/obj/item/weapon/card/id/vv_edit_var(var_name, var_value)
. = ..()
if(.)
switch(var_name)
if("assignment","registered_name")
update_label()
/obj/item/weapon/card/id/attack_self(mob/user)
user.visible_message("<span class='notice'>[user] shows you: \icon[src] [src.name].</span>", \
"<span class='notice'>You show \the [src.name].</span>")
-1
View File
@@ -273,7 +273,6 @@
force = 0
throwforce = 6
w_class = WEIGHT_CLASS_BULKY
flags = NODROP
var/revivecost = 1000
var/cooldown = 0
@@ -103,7 +103,7 @@
to_chat(user, "<span class='warning'>You need one length of coil to wire the assembly!</span>")
return
else if(stage == READY && istype(I, /obj/item/weapon/wirecutters))
else if(stage == READY && istype(I, /obj/item/weapon/wirecutters) && !active)
stage_change(WIRED)
to_chat(user, "<span class='notice'>You unlock the [initial(name)] assembly.</span>")
@@ -185,17 +185,6 @@
maxWeightClass = 7
gasPerThrow = 5
/datum/crafting_recipe/improvised_pneumatic_cannon //Pretty easy to obtain but
name = "Pneumatic Cannon"
result = /obj/item/weapon/pneumatic_cannon/ghetto
tools = list(/obj/item/weapon/weldingtool,
/obj/item/weapon/wrench)
reqs = list(/obj/item/stack/sheet/metal = 4,
/obj/item/stack/packageWrap = 8,
/obj/item/pipe = 2)
time = 300
category = CAT_WEAPON
/obj/item/weapon/pneumatic_cannon/proc/updateTank(obj/item/weapon/tank/internals/thetank, removing = 0, mob/living/carbon/human/user)
if(removing)
if(!src.tank)
@@ -200,10 +200,10 @@
/obj/item/weapon/storage/pill_bottle,
/obj/item/weapon/ore,
/obj/item/weapon/reagent_containers/food/drinks,
/obj/item/organ/hivelord_core,
/obj/item/organ/regenerative_core,
/obj/item/device/wormhole_jaunter,
/obj/item/weapon/storage/bag/plants,
/obj/item/stack/marker_beacon
)
@@ -247,10 +247,10 @@
)
/obj/item/weapon/storage/belt/military
name = "chest rig"
desc = "A set of tactical webbing worn by Syndicate boarding parties."
icon_state = "explorer1"
item_state = "explorer1"
name = "chest rig"
desc = "A set of tactical webbing worn by Syndicate boarding parties."
icon_state = "militarywebbing"
item_state = "militarywebbing"
max_w_class = WEIGHT_CLASS_SMALL
/obj/item/weapon/storage/belt/military/abductor
@@ -405,10 +405,9 @@
if(iscyborg(user))
return //Robots can't interact with storage items.
if(contents.len >= storage_slots) //don't use items on the backpack if they don't fit
return 1
if(!can_be_inserted(W, 0 , user))
if(contents.len >= storage_slots) //don't use items on the backpack if they don't fit
return 1
return 0
handle_item_insertion(W, 0 , user)
@@ -151,7 +151,7 @@
new /obj/item/weapon/weldingtool/experimental/brass(src)
/obj/item/weapon/storage/toolbox/brass/prefilled/ratvar
var/slab_type = /obj/item/clockwork/slab/scarab
var/slab_type = /obj/item/clockwork/slab
/obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/PopulateContents()
..()
+1 -53
View File
@@ -698,56 +698,4 @@
sharpness = IS_SHARP
/obj/item/weapon/twohanded/bonespear/update_icon()
icon_state = "bone_spear[wielded]"
/*
* Sky Bulge (Gae Bolg, tradtional dragoon lance from many FF games.)
*/
/obj/item/weapon/twohanded/skybulge //Copy+paste job from bonespear because no explosions.
icon_state = "sky_bulge0"
name = "Sky Bulge"
desc = "A legendary stick with a very pointy tip. Looks to be used for throwing. And jumping. Can be stubborn if you throw too much." //TODO: Be funnier.
force = 10 //This thing aint for robusting.
w_class = WEIGHT_CLASS_BULKY
slot_flags = SLOT_BACK
force_unwielded = 10
force_wielded = 18 //Same as regular spear. This is a utility weapon.
throwforce = 24 //And that utility is throwing. 24 so it takes 5 hits instead of 4.
throw_speed = 4
embedded_impact_pain_multiplier = 0 //If you somehow embed this, it's not going to hurt.
armour_penetration = 15 //Same as Bone Spear
embed_chance = 0 //Would ruin the whole theme of the thing.
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "poked", "jabbed", "torn", "gored", "lanced") //Added lanced for flavour.
sharpness = IS_SHARP
var/maxdist = 16
var/throw_cooldown = 0 //Should equate to half a second. Not supposed to be varedited.
/obj/item/weapon/twohanded/skybulge/update_icon()
icon_state = "sky_bulge[wielded]"
/obj/item/weapon/twohanded/skybulge/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) //Throw cooldown and offhand-proofing.
if(throw_cooldown > world.time)
var/mob/user = thrownby
user.put_in_hands(src)
return
unwield(src)
..()
/obj/item/weapon/twohanded/skybulge/throw_impact(atom/target) //Praise be the ratvar spear for showing me how to use this proc.
var/turf/turfhit = get_turf(target)
var/mob/user = thrownby
var/turf/source = get_turf(thrownby)
if(source.z == ZLEVEL_STATION && get_dist(turfhit, source) < maxdist || source.z != ZLEVEL_STATION)
..()
if(do_after_mob(user, src, 5, uninterruptible = 1, progress = 0))
if(QDELETED(src))
return
var/turf/landing = get_turf(src)
if (loc != landing)
return
user.forceMove(landing)
throw_cooldown = world.time + 5 //Half a second between throws.
user.put_in_hands(src)
playsound(src, 'sound/weapons/laser2.ogg', 20, 1)
icon_state = "bone_spear[wielded]"
+3
View File
@@ -193,3 +193,6 @@
..()
if(unique_rename)
to_chat(user, "<span class='notice'>Use a pen on it to rename it or change its description.</span>")
/obj/proc/gang_contraband_value()
return 0
@@ -25,7 +25,7 @@
return ..()
/obj/structure/chair/proc/RemoveFromLatejoin()
GLOB.latejoin -= src //These may be here due to the arrivals shuttle
SSjob.latejoin_trackers -= src //These may be here due to the arrivals shuttle
/obj/structure/chair/deconstruct()
// If we have materials, and don't have the NOCONSTRUCT flag
@@ -64,6 +64,7 @@
new /obj/item/clothing/gloves/color/black(src)
new /obj/item/clothing/head/soft/purple(src)
new /obj/item/weapon/paint/paint_remover(src)
new /obj/item/weapon/melee/flyswatter(src)
new /obj/item/device/flashlight(src)
for(var/i in 1 to 3)
new /obj/item/weapon/caution(src)
+15
View File
@@ -3,6 +3,7 @@
* Morgue
* Morgue tray
* Crematorium
* Creamatorium
* Crematorium tray
* Crematorium button
*/
@@ -223,6 +224,20 @@ GLOBAL_LIST_EMPTY(crematoriums)
update_icon()
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) //you horrible people
/obj/structure/bodycontainer/crematorium/creamatorium
name = "creamatorium"
desc = "A human incinerator. Works well during ice cream socials."
/obj/structure/bodycontainer/crematorium/creamatorium/cremate(mob/user)
var/list/icecreams = new()
for(var/mob/living/i_scream in GetAllContents())
var/obj/item/weapon/reagent_containers/food/snacks/icecream/IC = new()
IC.set_cone_type("waffle")
IC.add_mob_flavor(i_scream)
icecreams += IC
. = ..()
for(var/obj/IC in icecreams)
IC.forceMove(src)
/*
* Generic Tray
@@ -61,6 +61,14 @@
to_chat(user, "<span class='notice'>You start adding [S] to [src]...</span>")
if(do_after(user, 20, target = src) && S.use(1))
make_new_table(/obj/structure/table/optable)
else if(istype(I, /obj/item/stack/tile/carpet/black))
var/obj/item/stack/tile/carpet/black/C = I
if(C.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one black carpet sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [C] to [src]...</span>")
if(do_after(user, 20, target = src) && C.use(1))
make_new_table(/obj/structure/table/wood/fancy/black)
else if(istype(I, /obj/item/stack/tile/carpet))
var/obj/item/stack/tile/carpet/C = I
if(C.get_amount() < 1)
+9 -1
View File
@@ -271,12 +271,20 @@
frame = /obj/structure/table_frame
framestack = /obj/item/stack/rods
buildstack = /obj/item/stack/tile/carpet
canSmoothWith = list(/obj/structure/table/wood/fancy)
canSmoothWith = list(/obj/structure/table/wood/fancy,/obj/structure/table/wood/fancy/black)
/obj/structure/table/wood/fancy/New()
icon = 'icons/obj/smooth_structures/fancy_table.dmi' //so that the tables place correctly in the map editor
..()
/obj/structure/table/wood/fancy/black
icon_state = "fancy_table_black"
buildstack = /obj/item/stack/tile/carpet/black
/obj/structure/table/wood/fancy/black/New()
..()
icon = 'icons/obj/smooth_structures/fancy_table_black.dmi'
/*
* Reinforced tables
*/
+55 -5
View File
@@ -11,10 +11,10 @@
var/mob/living/swirlie = null //the mob being given a swirlie
/obj/structure/toilet/New()
/obj/structure/toilet/Initialize()
. = ..()
open = round(rand(0, 1))
update_icon()
..()
/obj/structure/toilet/attack_hand(mob/living/user)
@@ -104,6 +104,21 @@
else
return ..()
/obj/structure/toilet/secret
var/obj/item/secret
var/secret_type = null
/obj/structure/toilet/secret/Initialize(mapload)
. = ..()
if (secret_type)
secret = new secret_type(src)
secret.desc += " It's a secret!"
w_items += secret.w_class
contents += secret
/obj/structure/urinal
name = "urinal"
desc = "The HU-452, an experimental urinal. Comes complete with experimental urinal cake."
@@ -239,7 +254,7 @@
qdel(mymist)
if(on)
add_overlay(mutable_appearance('icons/obj/watercloset.dmi', "water", MOB_LAYER + 1))
add_overlay(mutable_appearance('icons/obj/watercloset.dmi', "water", ABOVE_MOB_LAYER))
if(watertemp == "freezing")
return
if(!ismist)
@@ -552,7 +567,7 @@
icon_state = "open"
color = "#ACD1E9" //Default color, didn't bother hardcoding other colors, mappers can and should easily change it.
alpha = 200 //Mappers can also just set this to 255 if they want curtains that can't be seen through
layer = WALL_OBJ_LAYER
layer = SIGN_LAYER
anchored = 1
opacity = 0
density = 0
@@ -575,13 +590,48 @@
density = 0
open = TRUE
/obj/structure/curtain/attackby(obj/item/W, mob/user)
if (istype(W, /obj/item/toy/crayon))
color = input(user,"Choose Color") as color
else if(istype(W, /obj/item/weapon/screwdriver))
if(anchored)
playsound(src.loc, W.usesound, 100, 1)
user.visible_message("<span class='warning'>[user] unscrews [src] from the floor.</span>", "<span class='notice'>You start to unscrew [src] from the floor...</span>", "You hear rustling noises.")
if(do_after(user, 50*W.toolspeed, target = src))
if(!anchored)
return
anchored = FALSE
to_chat(user, "<span class='notice'>You unscrew [src] from the floor.</span>")
else
playsound(src.loc, W.usesound, 100, 1)
user.visible_message("<span class='warning'>[user] screws [src] to the floor.</span>", "<span class='notice'>You start to screw [src] to the floor...</span>", "You hear rustling noises.")
if(do_after(user, 50*W.toolspeed, target = src))
if(anchored)
return
anchored = TRUE
to_chat(user, "<span class='notice'>You screw [src] to the floor.</span>")
else if(istype(W, /obj/item/weapon/wirecutters))
if(!anchored)
playsound(src.loc, W.usesound, 100, 1)
user.visible_message("<span class='warning'>[user] cuts apart [src].</span>", "<span class='notice'>You start to cut apart [src].</span>", "You hear cutting.")
if(do_after(user, 50*W.toolspeed, target = src))
if(anchored)
return
to_chat(user, "<span class='notice'>You cut apart [src].</span>")
deconstruct()
else
. = ..()
/obj/structure/curtain/attack_hand(mob/user)
playsound(loc, 'sound/effects/curtain.ogg', 50, 1)
toggle()
..()
/obj/structure/curtain/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/cloth (loc, 3)
new /obj/item/stack/sheet/cloth (loc, 2)
new /obj/item/stack/sheet/plastic (loc, 2)
new /obj/item/stack/rods (loc, 1)
qdel(src)
/obj/structure/curtain/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)

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