Merge branch 'master' into upstream-merge-33627
This commit is contained in:
@@ -705,15 +705,17 @@
|
||||
|
||||
/datum/admins/proc/output_all_devil_info()
|
||||
var/devil_number = 0
|
||||
for(var/D in SSticker.mode.devils)
|
||||
for(var/datum/mind/D in SSticker.mode.devils)
|
||||
devil_number++
|
||||
to_chat(usr, "Devil #[devil_number]:<br><br>" + SSticker.mode.printdevilinfo(D))
|
||||
var/datum/antagonist/devil/devil = D.has_antag_datum(/datum/antagonist/devil)
|
||||
to_chat(usr, "Devil #[devil_number]:<br><br>" + devil.printdevilinfo())
|
||||
if(!devil_number)
|
||||
to_chat(usr, "<b>No Devils located</b>" )
|
||||
|
||||
/datum/admins/proc/output_devil_info(mob/living/M)
|
||||
if(is_devil(M))
|
||||
to_chat(usr, SSticker.mode.printdevilinfo(M))
|
||||
var/datum/antagonist/devil/devil = M.mind.has_antag_datum(/datum/antagonist/devil)
|
||||
to_chat(usr, devil.printdevilinfo())
|
||||
else
|
||||
to_chat(usr, "<b>[M] is not a devil.")
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ GLOBAL_LIST(round_end_notifiees)
|
||||
return "Unable to run query, another admin proc call is in progress. Try again later."
|
||||
GLOB.AdminProcCaller = "CHAT_[sender]" //_ won't show up in ckeys so it'll never match with a real admin
|
||||
var/list/results = world.SDQL2_query(params, GLOB.AdminProcCaller, GLOB.AdminProcCaller)
|
||||
GLOB.AdminProcCaller = null
|
||||
if(!results)
|
||||
return "Query produced no output"
|
||||
var/list/text_res = results.Copy(1, 3)
|
||||
|
||||
@@ -384,9 +384,10 @@
|
||||
dat += "<BR><span class='userdanger'>[other_players] players in invalid state or the statistics code is bugged!</span>"
|
||||
dat += "<BR>"
|
||||
|
||||
if(SSticker.mode.syndicates.len)
|
||||
var/list/nukeops = get_antagonists(/datum/antagonist/nukeop)
|
||||
if(nukeops.len)
|
||||
dat += "<br><table cellspacing=5><tr><td><B>Syndicates</B></td><td></td></tr>"
|
||||
for(var/datum/mind/N in SSticker.mode.syndicates)
|
||||
for(var/datum/mind/N in nukeops)
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
@@ -523,7 +524,7 @@
|
||||
|
||||
if(SSticker.mode.brother_teams.len > 0)
|
||||
dat += "<br><table cellspacing=5><tr><td><B>Brothers</B></td><td></td><td></td></tr>"
|
||||
for(var/datum/objective_team/brother_team/team in SSticker.mode.brother_teams)
|
||||
for(var/datum/team/brother_team/team in SSticker.mode.brother_teams)
|
||||
for(var/datum/mind/brother in team.members)
|
||||
var/mob/M = brother.current
|
||||
if(M)
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
var/new_volume = input(user, "Choose a volume.", "Sound Emitter", sound_volume) as null|num
|
||||
if(isnull(new_volume))
|
||||
return
|
||||
new_volume = Clamp(new_volume, 0, 100)
|
||||
new_volume = CLAMP(new_volume, 0, 100)
|
||||
sound_volume = new_volume
|
||||
to_chat(user, "<span class='notice'>Volume set to [sound_volume]%.</span>")
|
||||
if(href_list["edit_mode"])
|
||||
@@ -115,7 +115,7 @@
|
||||
var/new_radius = input(user, "Choose a radius.", "Sound Emitter", sound_volume) as null|num
|
||||
if(isnull(new_radius))
|
||||
return
|
||||
new_radius = Clamp(new_radius, 0, 127)
|
||||
new_radius = CLAMP(new_radius, 0, 127)
|
||||
play_radius = new_radius
|
||||
to_chat(user, "<span class='notice'>Audible radius set to [play_radius].</span>")
|
||||
if(href_list["play"])
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
var/nsd = CONFIG_GET(number/note_stale_days)
|
||||
var/nfd = CONFIG_GET(number/note_fresh_days)
|
||||
if (agegate && type == "note" && isnum(nsd) && isnum(nfd) && nsd > nfd)
|
||||
var/alpha = Clamp(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100)
|
||||
var/alpha = CLAMP(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100)
|
||||
if (alpha < 100)
|
||||
if (alpha <= 15)
|
||||
if (skipped)
|
||||
|
||||
@@ -1943,7 +1943,7 @@
|
||||
return
|
||||
|
||||
var/list/offset = splittext(href_list["offset"],",")
|
||||
var/number = Clamp(text2num(href_list["object_count"]), 1, 100)
|
||||
var/number = CLAMP(text2num(href_list["object_count"]), 1, 100)
|
||||
var/X = offset.len > 0 ? text2num(offset[1]) : 0
|
||||
var/Y = offset.len > 1 ? text2num(offset[2]) : 0
|
||||
var/Z = offset.len > 2 ? text2num(offset[3]) : 0
|
||||
|
||||
@@ -435,7 +435,7 @@
|
||||
else if(expression[start + 1] == "\[" && islist(v))
|
||||
var/list/L = v
|
||||
var/index = SDQL_expression(source, expression[start + 2])
|
||||
if(isnum(index) && (!IsInteger(index) || L.len < index))
|
||||
if(isnum(index) && (!ISINTEGER(index) || L.len < index))
|
||||
to_chat(usr, "<span class='danger'>Invalid list index: [index]</span>")
|
||||
return null
|
||||
return L[index]
|
||||
|
||||
@@ -107,6 +107,8 @@ GLOBAL_VAR(LastAdminCalledTarget)
|
||||
GLOBAL_PROTECT(LastAdminCalledTarget)
|
||||
GLOBAL_VAR(LastAdminCalledProc)
|
||||
GLOBAL_PROTECT(LastAdminCalledProc)
|
||||
GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention)
|
||||
GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
|
||||
/proc/WrapAdminProcCall(target, procname, list/arguments)
|
||||
var/current_caller = GLOB.AdminProcCaller
|
||||
@@ -114,9 +116,14 @@ GLOBAL_PROTECT(LastAdminCalledProc)
|
||||
if(!ckey)
|
||||
CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]")
|
||||
if(current_caller && current_caller != ckey)
|
||||
to_chat(usr, "<span class='adminnotice'>Another set of admin called procs are still running, your proc will be run after theirs finish.</span>")
|
||||
UNTIL(!GLOB.AdminProcCaller)
|
||||
to_chat(usr, "<span class='adminnotice'>Running your proc</span>")
|
||||
if(!GLOB.AdminProcCallSpamPrevention[ckey])
|
||||
to_chat(usr, "<span class='adminnotice'>Another set of admin called procs are still running, your proc will be run after theirs finish.</span>")
|
||||
GLOB.AdminProcCallSpamPrevention[ckey] = TRUE
|
||||
UNTIL(!GLOB.AdminProcCaller)
|
||||
to_chat(usr, "<span class='adminnotice'>Running your proc</span>")
|
||||
GLOB.AdminProcCallSpamPrevention -= ckey
|
||||
else
|
||||
UNTIL(!GLOB.AdminProcCaller)
|
||||
GLOB.LastAdminCalledProc = procname
|
||||
if(target != GLOBAL_PROC)
|
||||
GLOB.LastAdminCalledTargetRef = "[REF(target)]"
|
||||
@@ -735,7 +742,7 @@ GLOBAL_PROTECT(LastAdminCalledProc)
|
||||
if(Rad.anchored)
|
||||
if(!Rad.loaded_tank)
|
||||
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
|
||||
ASSERT_GAS(/datum/gas/plasma, Plasma.air_contents)
|
||||
Plasma.air_contents.assert_gas(/datum/gas/plasma)
|
||||
Plasma.air_contents.gases[/datum/gas/plasma][MOLES] = 70
|
||||
Rad.drainratio = 0
|
||||
Rad.loaded_tank = Plasma
|
||||
|
||||
@@ -45,7 +45,8 @@ GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
|
||||
/client/proc/manipulate_organs,
|
||||
/client/proc/start_line_profiling,
|
||||
/client/proc/stop_line_profiling,
|
||||
/client/proc/show_line_profiling
|
||||
/client/proc/show_line_profiling,
|
||||
/client/proc/create_mapping_job_icons
|
||||
))
|
||||
|
||||
/obj/effect/debugging/mapfix_marker
|
||||
@@ -265,3 +266,31 @@ GLOBAL_VAR_INIT(say_disabled, FALSE)
|
||||
message_admins("[src.ckey] used 'Disable all communication verbs', killing all communication methods.")
|
||||
else
|
||||
message_admins("[src.ckey] used 'Disable all communication verbs', restoring all communication methods.")
|
||||
|
||||
//This generates the icon states for job starting location landmarks.
|
||||
/client/proc/create_mapping_job_icons()
|
||||
set name = "Generate job landmarks icons"
|
||||
set category = "Mapping"
|
||||
var/icon/final = icon()
|
||||
var/mob/living/carbon/human/dummy/D = new(locate(1,1,1)) //spawn on 1,1,1 so we don't have runtimes when items are deleted
|
||||
D.setDir(SOUTH)
|
||||
for(var/job in subtypesof(/datum/job))
|
||||
var/datum/job/JB = new job
|
||||
switch(JB.title)
|
||||
if("AI")
|
||||
final.Insert(icon('icons/mob/ai.dmi', "ai", SOUTH, 1), "AI")
|
||||
if("Cyborg")
|
||||
final.Insert(icon('icons/mob/robots.dmi', "robot", SOUTH, 1), "Cyborg")
|
||||
else
|
||||
for(var/obj/item/I in D)
|
||||
qdel(I)
|
||||
randomize_human(D)
|
||||
JB.equip(D, TRUE, FALSE)
|
||||
COMPILE_OVERLAYS(D)
|
||||
var/icon/I = icon(getFlatIcon(D), frame = 1)
|
||||
final.Insert(I, JB.title)
|
||||
qdel(D)
|
||||
//Also add the x
|
||||
for(var/x_number in 1 to 4)
|
||||
final.Insert(icon('icons/mob/screen_gen.dmi', "x[x_number == 1 ? "" : x_number]"), "x[x_number == 1 ? "" : x_number]")
|
||||
fcopy(final, "icons/mob/landmarks.dmi")
|
||||
@@ -213,7 +213,9 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
.["class"] = null
|
||||
return
|
||||
.["type"] = type
|
||||
.["value"] = new type()
|
||||
var/atom/newguy = new type()
|
||||
newguy.var_edited = TRUE
|
||||
.["value"] = newguy
|
||||
|
||||
if (VV_NEW_DATUM)
|
||||
var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
|
||||
@@ -221,7 +223,9 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
.["class"] = null
|
||||
return
|
||||
.["type"] = type
|
||||
.["value"] = new type()
|
||||
var/datum/newguy = new type()
|
||||
newguy.var_edited = TRUE
|
||||
.["value"] = newguy
|
||||
|
||||
if (VV_NEW_TYPE)
|
||||
var/type = current_value
|
||||
@@ -237,7 +241,10 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
.["class"] = null
|
||||
return
|
||||
.["type"] = type
|
||||
.["value"] = new type()
|
||||
var/datum/newguy = new type()
|
||||
if(istype(newguy))
|
||||
newguy.var_edited = TRUE
|
||||
.["value"] = newguy
|
||||
|
||||
|
||||
if (VV_NEW_LIST)
|
||||
|
||||
@@ -238,26 +238,17 @@
|
||||
if(agentcount < 3)
|
||||
return 0
|
||||
|
||||
var/nuke_code = random_nukecode()
|
||||
|
||||
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list
|
||||
if(nuke)
|
||||
nuke.r_code = nuke_code
|
||||
|
||||
//Let's find the spawn locations
|
||||
var/leader_chosen = FALSE
|
||||
var/spawnpos = 1 //Decides where they'll spawn. 1=leader.
|
||||
|
||||
var/datum/team/nuclear/nuke_team
|
||||
for(var/mob/c in chosen)
|
||||
if(spawnpos > GLOB.nukeop_start.len)
|
||||
spawnpos = 1 //Ran out of spawns. Let's loop back to the first non-leader position
|
||||
var/mob/living/carbon/human/new_character=makeBody(c)
|
||||
if(!leader_chosen)
|
||||
leader_chosen = TRUE
|
||||
new_character.mind.make_Nuke(pick(GLOB.nukeop_leader_start), nuke_code, TRUE)
|
||||
var/datum/antagonist/nukeop/N = new_character.mind.add_antag_datum(/datum/antagonist/nukeop/leader)
|
||||
nuke_team = N.nuke_team
|
||||
else
|
||||
new_character.mind.make_Nuke(GLOB.nukeop_start[spawnpos], nuke_code)
|
||||
spawnpos++
|
||||
new_character.mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
@@ -317,12 +308,15 @@
|
||||
//Assign antag status and the mission
|
||||
SSticker.mode.traitors += Commando.mind
|
||||
Commando.mind.special_role = "deathsquad"
|
||||
|
||||
var/datum/objective/missionobj = new
|
||||
missionobj.owner = Commando.mind
|
||||
missionobj.explanation_text = mission
|
||||
missionobj.completed = 1
|
||||
Commando.mind.objectives += missionobj
|
||||
|
||||
Commando.mind.add_antag_datum(/datum/antagonist/auto_custom)
|
||||
|
||||
//Greet the commando
|
||||
to_chat(Commando, "<B><font size=3 color=red>You are the [numagents==1?"Deathsquad Officer":"Death Commando"].</font></B>")
|
||||
var/missiondesc = "Your squad is being sent on a mission to [station_name()] by Nanotrasen's Security Division."
|
||||
@@ -369,12 +363,15 @@
|
||||
//Assign antag status and the mission
|
||||
SSticker.mode.traitors += newmob.mind
|
||||
newmob.mind.special_role = "official"
|
||||
|
||||
var/datum/objective/missionobj = new
|
||||
missionobj.owner = newmob.mind
|
||||
missionobj.explanation_text = mission
|
||||
missionobj.completed = 1
|
||||
newmob.mind.objectives += missionobj
|
||||
|
||||
newmob.mind.add_antag_datum(/datum/antagonist/auto_custom)
|
||||
|
||||
if(CONFIG_GET(flag/enforce_human_authority))
|
||||
newmob.set_species(/datum/species/human)
|
||||
|
||||
@@ -474,12 +471,15 @@
|
||||
//Assign antag status and the mission
|
||||
SSticker.mode.traitors += ERTOperative.mind
|
||||
ERTOperative.mind.special_role = "ERT"
|
||||
|
||||
var/datum/objective/missionobj = new
|
||||
missionobj.owner = ERTOperative.mind
|
||||
missionobj.explanation_text = mission
|
||||
missionobj.completed = 1
|
||||
ERTOperative.mind.objectives += missionobj
|
||||
|
||||
ERTOperative.mind.add_antag_datum(/datum/antagonist/auto_custom)
|
||||
|
||||
//Greet the commando
|
||||
to_chat(ERTOperative, "<B><font size=3 color=red>You are [numagents==1?"the Emergency Response Team Commander":"an Emergency Response Officer"].</font></B>")
|
||||
var/missiondesc = "Your squad is being sent on a Code [alert] mission to [station_name()] by Nanotrasen's Security Division."
|
||||
|
||||
@@ -28,6 +28,7 @@ GLOBAL_VAR_INIT(highlander, FALSE)
|
||||
/mob/living/carbon/human/proc/make_scottish()
|
||||
SSticker.mode.traitors += mind
|
||||
mind.special_role = "highlander"
|
||||
|
||||
dna.species.species_traits |= NOGUNS //nice try jackass
|
||||
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
@@ -40,6 +41,8 @@ GLOBAL_VAR_INIT(highlander, FALSE)
|
||||
hijack_objective.owner = mind
|
||||
mind.objectives += hijack_objective
|
||||
|
||||
mind.add_antag_datum(/datum/antagonist/auto_custom)
|
||||
|
||||
mind.announce_objectives()
|
||||
|
||||
for(var/obj/item/I in get_equipped_items())
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/vol = input(usr, "What volume would you like the sound to play at?",, 100) as null|num
|
||||
if(!vol)
|
||||
return
|
||||
vol = Clamp(vol, 1, 100)
|
||||
vol = CLAMP(vol, 1, 100)
|
||||
|
||||
var/sound/admin_sound = new()
|
||||
admin_sound.file = S
|
||||
@@ -80,14 +80,32 @@
|
||||
to_chat(src, "<span class='warning'>For youtube-dl shortcuts like ytsearch: please use the appropriate full url from the website.</span>")
|
||||
return
|
||||
var/shell_scrubbed_input = shell_url_scrub(web_sound_input)
|
||||
var/list/output = world.shelleo("[ytdl] --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height<=360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --get-url \"[shell_scrubbed_input]\"")
|
||||
var/list/output = world.shelleo("[ytdl] --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height<=360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --dump-single-json --no-playlist -- \"[shell_scrubbed_input]\"")
|
||||
var/errorlevel = output[SHELLEO_ERRORLEVEL]
|
||||
var/stdout = output[SHELLEO_STDOUT]
|
||||
var/stderr = output[SHELLEO_STDERR]
|
||||
if(!errorlevel)
|
||||
var/static/regex/content_url_regex = regex("https?://\\S+")
|
||||
if(content_url_regex.Find(stdout))
|
||||
web_sound_url = content_url_regex.match
|
||||
var/list/data
|
||||
try
|
||||
data = json_decode(stdout)
|
||||
catch(var/exception/e)
|
||||
to_chat(src, "<span class='boldwarning'>Youtube-dl JSON parsing FAILED:</span>")
|
||||
to_chat(src, "<span class='warning'>[e]: [stdout]</span>")
|
||||
return
|
||||
|
||||
if (data["url"])
|
||||
web_sound_url = data["url"]
|
||||
var/title = "[data["title"]]"
|
||||
var/webpage_url = title
|
||||
if (data["webpage_url"])
|
||||
webpage_url = "<a href=\"[data["webpage_url"]]\">[title]</a>"
|
||||
|
||||
var/res = alert(usr, "Show the title of and link to this song to the players?\n[title]",, "No", "Yes", "Cancel")
|
||||
switch(res)
|
||||
if("Yes")
|
||||
to_chat(world, "<span class='boldannounce'>An admin played: [webpage_url]</span>")
|
||||
if("Cancel")
|
||||
return
|
||||
|
||||
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
|
||||
pitch = pick(0.5, 0.7, 0.8, 0.85, 0.9, 0.95, 1.1, 1.2, 1.4, 1.6, 2.0, 2.5)
|
||||
|
||||
@@ -386,7 +386,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
A.equip_wizard()
|
||||
if("Syndicate")
|
||||
new_character.forceMove(pick(GLOB.nukeop_start))
|
||||
call(/datum/game_mode/proc/equip_syndicate)(new_character)
|
||||
var/datum/antagonist/nukeop/N = new_character.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)
|
||||
N.equip_op()
|
||||
if("Space Ninja")
|
||||
var/list/ninja_spawn = list()
|
||||
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
||||
@@ -1206,7 +1207,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
if(!holder)
|
||||
return
|
||||
|
||||
var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_FIREBALL)
|
||||
var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_ROD)
|
||||
|
||||
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
|
||||
|
||||
@@ -1228,6 +1229,12 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
bluespace_artillery(target)
|
||||
if(ADMIN_PUNISHMENT_FIREBALL)
|
||||
new /obj/effect/temp_visual/target(get_turf(target))
|
||||
if(ADMIN_PUNISHMENT_ROD)
|
||||
var/turf/T = get_turf(target)
|
||||
var/startside = pick(GLOB.cardinals)
|
||||
var/turf/startT = spaceDebrisStartLoc(startside, T.z)
|
||||
var/turf/endT = spaceDebrisFinishLoc(startside, T.z)
|
||||
new /obj/effect/immovablerod(startT, endT,target)
|
||||
|
||||
var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]."
|
||||
message_admins(msg)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
holder.update_icon()
|
||||
|
||||
/obj/item/device/assembly/flash/proc/clown_check(mob/living/carbon/human/user)
|
||||
if(user.disabilities & CLUMSY && prob(50))
|
||||
if(user.has_disability(CLUMSY) && prob(50))
|
||||
flash_carbon(user, user, 15, 0)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
+142
-142
@@ -1,142 +1,142 @@
|
||||
/obj/item/device/assembly/mousetrap
|
||||
name = "mousetrap"
|
||||
desc = "A handy little spring-loaded trap for catching pesty rodents."
|
||||
icon_state = "mousetrap"
|
||||
materials = list(MAT_METAL=100)
|
||||
attachable = 1
|
||||
var/armed = 0
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/examine(mob/user)
|
||||
..()
|
||||
if(armed)
|
||||
to_chat(user, "The mousetrap is armed!")
|
||||
else
|
||||
to_chat(user, "The mousetrap is not armed.")
|
||||
|
||||
/obj/item/device/assembly/mousetrap/activate()
|
||||
if(..())
|
||||
armed = !armed
|
||||
if(!armed)
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/user = usr
|
||||
if((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY && prob(50))
|
||||
to_chat(user, "<span class='warning'>Your hand slips, setting off the trigger!</span>")
|
||||
pulse(0)
|
||||
update_icon()
|
||||
if(usr)
|
||||
playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
|
||||
|
||||
/obj/item/device/assembly/mousetrap/describe()
|
||||
return "The pressure switch is [armed?"primed":"safe"]."
|
||||
|
||||
/obj/item/device/assembly/mousetrap/update_icon()
|
||||
if(armed)
|
||||
icon_state = "mousetraparmed"
|
||||
else
|
||||
icon_state = "mousetrap"
|
||||
if(holder)
|
||||
holder.update_icon()
|
||||
|
||||
/obj/item/device/assembly/mousetrap/proc/triggered(mob/target, type = "feet")
|
||||
if(!armed)
|
||||
return
|
||||
var/obj/item/bodypart/affecting = null
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(PIERCEIMMUNE in H.dna.species.species_traits)
|
||||
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
|
||||
armed = 0
|
||||
update_icon()
|
||||
pulse(0)
|
||||
return 0
|
||||
switch(type)
|
||||
if("feet")
|
||||
if(!H.shoes)
|
||||
affecting = H.get_bodypart(pick("l_leg", "r_leg"))
|
||||
H.Knockdown(60)
|
||||
if("l_hand", "r_hand")
|
||||
if(!H.gloves)
|
||||
affecting = H.get_bodypart(type)
|
||||
H.Stun(60)
|
||||
if(affecting)
|
||||
if(affecting.receive_damage(1, 0))
|
||||
H.update_damage_overlays()
|
||||
else if(ismouse(target))
|
||||
var/mob/living/simple_animal/mouse/M = target
|
||||
visible_message("<span class='boldannounce'>SPLAT!</span>")
|
||||
M.splat()
|
||||
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
|
||||
armed = 0
|
||||
update_icon()
|
||||
pulse(0)
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/attack_self(mob/living/carbon/human/user)
|
||||
if(!armed)
|
||||
to_chat(user, "<span class='notice'>You arm [src].</span>")
|
||||
else
|
||||
if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50))
|
||||
var/which_hand = "l_hand"
|
||||
if(!(user.active_hand_index % 2))
|
||||
which_hand = "r_hand"
|
||||
triggered(user, which_hand)
|
||||
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking their fingers.</span>", \
|
||||
"<span class='warning'>You accidentally trigger [src]!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You disarm [src].</span>")
|
||||
armed = !armed
|
||||
update_icon()
|
||||
playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user)
|
||||
if(armed)
|
||||
if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50))
|
||||
var/which_hand = "l_hand"
|
||||
if(!(user.active_hand_index % 2))
|
||||
which_hand = "r_hand"
|
||||
triggered(user, which_hand)
|
||||
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking their fingers.</span>", \
|
||||
"<span class='warning'>You accidentally trigger [src]!</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/Crossed(atom/movable/AM as mob|obj)
|
||||
if(armed)
|
||||
if(ismob(AM))
|
||||
var/mob/MM = AM
|
||||
if(!(MM.movement_type & FLYING))
|
||||
if(ishuman(AM))
|
||||
var/mob/living/carbon/H = AM
|
||||
if(H.m_intent == MOVE_INTENT_RUN)
|
||||
triggered(H)
|
||||
H.visible_message("<span class='warning'>[H] accidentally steps on [src].</span>", \
|
||||
"<span class='warning'>You accidentally step on [src]</span>")
|
||||
else if(ismouse(MM))
|
||||
triggered(MM)
|
||||
else if(AM.density) // For mousetrap grenades, set off by anything heavy
|
||||
triggered(AM)
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/on_found(mob/finder)
|
||||
if(armed)
|
||||
finder.visible_message("<span class='warning'>[finder] accidentally sets off [src], breaking their fingers.</span>", \
|
||||
"<span class='warning'>You accidentally trigger [src]!</span>")
|
||||
triggered(finder, (finder.active_hand_index % 2 == 0) ? "r_hand" : "l_hand")
|
||||
return 1 //end the search!
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/hitby(A as mob|obj)
|
||||
if(!armed)
|
||||
return ..()
|
||||
visible_message("<span class='warning'>[src] is triggered by [A].</span>")
|
||||
triggered(null)
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/armed
|
||||
icon_state = "mousetraparmed"
|
||||
armed = TRUE
|
||||
/obj/item/device/assembly/mousetrap
|
||||
name = "mousetrap"
|
||||
desc = "A handy little spring-loaded trap for catching pesty rodents."
|
||||
icon_state = "mousetrap"
|
||||
materials = list(MAT_METAL=100)
|
||||
attachable = 1
|
||||
var/armed = 0
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/examine(mob/user)
|
||||
..()
|
||||
if(armed)
|
||||
to_chat(user, "The mousetrap is armed!")
|
||||
else
|
||||
to_chat(user, "The mousetrap is not armed.")
|
||||
|
||||
/obj/item/device/assembly/mousetrap/activate()
|
||||
if(..())
|
||||
armed = !armed
|
||||
if(!armed)
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/user = usr
|
||||
if((user.has_disability(DUMB) || user.has_disability(CLUMSY)) && prob(50))
|
||||
to_chat(user, "<span class='warning'>Your hand slips, setting off the trigger!</span>")
|
||||
pulse(0)
|
||||
update_icon()
|
||||
if(usr)
|
||||
playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
|
||||
|
||||
/obj/item/device/assembly/mousetrap/describe()
|
||||
return "The pressure switch is [armed?"primed":"safe"]."
|
||||
|
||||
/obj/item/device/assembly/mousetrap/update_icon()
|
||||
if(armed)
|
||||
icon_state = "mousetraparmed"
|
||||
else
|
||||
icon_state = "mousetrap"
|
||||
if(holder)
|
||||
holder.update_icon()
|
||||
|
||||
/obj/item/device/assembly/mousetrap/proc/triggered(mob/target, type = "feet")
|
||||
if(!armed)
|
||||
return
|
||||
var/obj/item/bodypart/affecting = null
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(PIERCEIMMUNE in H.dna.species.species_traits)
|
||||
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
|
||||
armed = 0
|
||||
update_icon()
|
||||
pulse(0)
|
||||
return 0
|
||||
switch(type)
|
||||
if("feet")
|
||||
if(!H.shoes)
|
||||
affecting = H.get_bodypart(pick("l_leg", "r_leg"))
|
||||
H.Knockdown(60)
|
||||
if("l_hand", "r_hand")
|
||||
if(!H.gloves)
|
||||
affecting = H.get_bodypart(type)
|
||||
H.Stun(60)
|
||||
if(affecting)
|
||||
if(affecting.receive_damage(1, 0))
|
||||
H.update_damage_overlays()
|
||||
else if(ismouse(target))
|
||||
var/mob/living/simple_animal/mouse/M = target
|
||||
visible_message("<span class='boldannounce'>SPLAT!</span>")
|
||||
M.splat()
|
||||
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
|
||||
armed = 0
|
||||
update_icon()
|
||||
pulse(0)
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/attack_self(mob/living/carbon/human/user)
|
||||
if(!armed)
|
||||
to_chat(user, "<span class='notice'>You arm [src].</span>")
|
||||
else
|
||||
if((user.has_disability(DUMB) || user.has_disability(CLUMSY)) && prob(50))
|
||||
var/which_hand = "l_hand"
|
||||
if(!(user.active_hand_index % 2))
|
||||
which_hand = "r_hand"
|
||||
triggered(user, which_hand)
|
||||
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking their fingers.</span>", \
|
||||
"<span class='warning'>You accidentally trigger [src]!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You disarm [src].</span>")
|
||||
armed = !armed
|
||||
update_icon()
|
||||
playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user)
|
||||
if(armed)
|
||||
if((user.has_disability(DUMB) || user.has_disability(CLUMSY)) && prob(50))
|
||||
var/which_hand = "l_hand"
|
||||
if(!(user.active_hand_index % 2))
|
||||
which_hand = "r_hand"
|
||||
triggered(user, which_hand)
|
||||
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking their fingers.</span>", \
|
||||
"<span class='warning'>You accidentally trigger [src]!</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/Crossed(atom/movable/AM as mob|obj)
|
||||
if(armed)
|
||||
if(ismob(AM))
|
||||
var/mob/MM = AM
|
||||
if(!(MM.movement_type & FLYING))
|
||||
if(ishuman(AM))
|
||||
var/mob/living/carbon/H = AM
|
||||
if(H.m_intent == MOVE_INTENT_RUN)
|
||||
triggered(H)
|
||||
H.visible_message("<span class='warning'>[H] accidentally steps on [src].</span>", \
|
||||
"<span class='warning'>You accidentally step on [src]</span>")
|
||||
else if(ismouse(MM))
|
||||
triggered(MM)
|
||||
else if(AM.density) // For mousetrap grenades, set off by anything heavy
|
||||
triggered(AM)
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/on_found(mob/finder)
|
||||
if(armed)
|
||||
finder.visible_message("<span class='warning'>[finder] accidentally sets off [src], breaking their fingers.</span>", \
|
||||
"<span class='warning'>You accidentally trigger [src]!</span>")
|
||||
triggered(finder, (finder.active_hand_index % 2 == 0) ? "r_hand" : "l_hand")
|
||||
return 1 //end the search!
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/hitby(A as mob|obj)
|
||||
if(!armed)
|
||||
return ..()
|
||||
visible_message("<span class='warning'>[src] is triggered by [A].</span>")
|
||||
triggered(null)
|
||||
|
||||
|
||||
/obj/item/device/assembly/mousetrap/armed
|
||||
icon_state = "mousetraparmed"
|
||||
armed = 1
|
||||
|
||||
@@ -37,14 +37,24 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
|
||||
reaction_results = new
|
||||
|
||||
//listmos procs
|
||||
//use the macros in performance intensive areas. for their definitions, refer to code/__DEFINES/atmospherics.dm
|
||||
|
||||
// The following procs used to live here: thermal_energy(), assert_gas() and add_gas(). They have been moved into defines in code/__DEFINES/atmospherics.dm
|
||||
//assert_gas(gas_id) - used to guarantee that the gas list for this id exists in gas_mixture.gases.
|
||||
//Must be used before adding to a gas. May be used before reading from a gas.
|
||||
/datum/gas_mixture/proc/assert_gas(gas_id)
|
||||
ASSERT_GAS(gas_id, src)
|
||||
|
||||
//assert_gases(args) - shorthand for calling ASSERT_GAS() once for each gas type.
|
||||
/datum/gas_mixture/proc/assert_gases()
|
||||
for(var/id in args)
|
||||
ASSERT_GAS(id, src)
|
||||
|
||||
//add_gas(gas_id) - similar to assert_gas(), but does not check for an existing
|
||||
//gas list for this id. This can clobber existing gases.
|
||||
//Used instead of assert_gas() when you know the gas does not exist. Faster than assert_gas().
|
||||
/datum/gas_mixture/proc/add_gas(gas_id)
|
||||
ADD_GAS(gas_id, gases)
|
||||
|
||||
//add_gases(args) - shorthand for calling add_gas() once for each gas_type.
|
||||
/datum/gas_mixture/proc/add_gases()
|
||||
var/cached_gases = gases
|
||||
@@ -101,6 +111,9 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
|
||||
/datum/gas_mixture/proc/return_volume() //liters
|
||||
return max(0, volume)
|
||||
|
||||
/datum/gas_mixture/proc/thermal_energy() //joules
|
||||
return THERMAL_ENERGY(src) //see code/__DEFINES/atmospherics.dm; use the define in performance critical areas
|
||||
|
||||
/datum/gas_mixture/proc/archive()
|
||||
//Update archived versions of variables
|
||||
//Returns: 1 in all cases
|
||||
@@ -399,7 +412,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
|
||||
return ""
|
||||
|
||||
/datum/gas_mixture/react(turf/open/dump_location)
|
||||
. = 0
|
||||
. = NO_REACTION
|
||||
|
||||
reaction_results = new
|
||||
|
||||
@@ -423,6 +436,22 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
|
||||
continue reaction_loop
|
||||
//at this point, all minimum requirements for the reaction are satisfied.
|
||||
|
||||
/* currently no reactions have maximum requirements, so we can leave the checks commented out for a slight performance boost
|
||||
PLEASE DO NOT REMOVE THIS CODE. the commenting is here only for a performance increase.
|
||||
enabling these checks should be as easy as possible and the fact that they are disabled should be as clear as possible
|
||||
|
||||
var/list/max_reqs = reaction.max_requirements.Copy()
|
||||
if((max_reqs["TEMP"] && temp > max_reqs["TEMP"]) \
|
||||
|| (max_reqs["ENER"] && ener > max_reqs["ENER"]))
|
||||
continue
|
||||
max_reqs -= "TEMP"
|
||||
max_reqs -= "ENER"
|
||||
for(var/id in max_reqs)
|
||||
if(cached_gases[id] && cached_gases[id][MOLES] > max_reqs[id])
|
||||
continue reaction_loop
|
||||
//at this point, all requirements for the reaction are satisfied. we can now react()
|
||||
*/
|
||||
|
||||
. |= reaction.react(src, dump_location)
|
||||
if (. & STOP_REACTIONS)
|
||||
break
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
|
||||
//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting.
|
||||
/datum/gas_reaction/fusion
|
||||
exclude = FALSE
|
||||
exclude = TRUE
|
||||
priority = 2
|
||||
name = "Plasmic Fusion"
|
||||
id = "fusion"
|
||||
|
||||
@@ -185,13 +185,13 @@ Acts like a normal vent, but has an input AND output.
|
||||
pump_direction = 1
|
||||
|
||||
if("set_input_pressure" in signal.data)
|
||||
input_pressure_min = Clamp(text2num(signal.data["set_input_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
input_pressure_min = CLAMP(text2num(signal.data["set_input_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("set_output_pressure" in signal.data)
|
||||
output_pressure_max = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
output_pressure_max = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("set_external_pressure" in signal.data)
|
||||
external_pressure_bound = Clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
external_pressure_bound = CLAMP(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("status" in signal.data)
|
||||
spawn(2)
|
||||
|
||||
@@ -127,7 +127,7 @@ Passive gate is similar to the regular pump except:
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
|
||||
update_icon()
|
||||
|
||||
@@ -149,7 +149,7 @@ Passive gate is similar to the regular pump except:
|
||||
on = !on
|
||||
|
||||
if("set_output_pressure" in signal.data)
|
||||
target_pressure = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
target_pressure = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if(on != old_on)
|
||||
investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS)
|
||||
|
||||
@@ -133,9 +133,8 @@ Thus, the two variables affect pump operation are set in New():
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("Pump, [src.name], was set to [target_pressure] kPa by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
|
||||
message_admins("Pump, [src.name], was set to [target_pressure] kPa by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
|
||||
target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/atmosinit()
|
||||
@@ -156,7 +155,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
on = !on
|
||||
|
||||
if("set_output_pressure" in signal.data)
|
||||
target_pressure = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
target_pressure = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if(on != old_on)
|
||||
investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS)
|
||||
|
||||
@@ -133,9 +133,8 @@ Thus, the two variables affect pump operation are set in New():
|
||||
rate = text2num(rate)
|
||||
. = TRUE
|
||||
if(.)
|
||||
transfer_rate = Clamp(rate, 0, MAX_TRANSFER_RATE)
|
||||
investigate_log("Volume Pump, [src.name], was set to [transfer_rate] L/s by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
|
||||
message_admins("Volume Pump, [src.name], was set to [transfer_rate] L/s by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
|
||||
transfer_rate = CLAMP(rate, 0, MAX_TRANSFER_RATE)
|
||||
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", INVESTIGATE_ATMOS)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/receive_signal(datum/signal/signal)
|
||||
@@ -152,7 +151,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
|
||||
if("set_transfer_rate" in signal.data)
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
transfer_rate = Clamp(text2num(signal.data["set_transfer_rate"]),0,air1.volume)
|
||||
transfer_rate = CLAMP(text2num(signal.data["set_transfer_rate"]),0,air1.volume)
|
||||
|
||||
if(on != old_on)
|
||||
investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS)
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
var/datum/gas_mixture/filtered_out = new
|
||||
|
||||
filtered_out.temperature = removed.temperature
|
||||
ASSERT_GAS(filter_type, filtered_out)
|
||||
filtered_out.add_gas(filter_type)
|
||||
filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES]
|
||||
|
||||
removed.gases[filter_type][MOLES] = 0
|
||||
@@ -162,7 +162,7 @@
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
|
||||
if("filter")
|
||||
filter_type = null
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
|
||||
if("node1")
|
||||
var/value = text2num(params["concentration"])
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
if("set_volume_rate" in signal.data)
|
||||
var/number = text2num(signal.data["set_volume_rate"])
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
volume_rate = Clamp(number, 0, air_contents.volume)
|
||||
volume_rate = CLAMP(number, 0, air_contents.volume)
|
||||
|
||||
if("status" in signal.data)
|
||||
spawn(2)
|
||||
@@ -180,7 +180,7 @@
|
||||
rate = text2num(rate)
|
||||
. = TRUE
|
||||
if(.)
|
||||
volume_rate = Clamp(rate, 0, MAX_TRANSFER_RATE)
|
||||
volume_rate = CLAMP(rate, 0, MAX_TRANSFER_RATE)
|
||||
investigate_log("was set to [volume_rate] L/s by [key_name(usr)]", INVESTIGATE_ATMOS)
|
||||
update_icon()
|
||||
broadcast_status()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
air_contents.volume = volume
|
||||
air_contents.temperature = T20C
|
||||
if(gas_type)
|
||||
ASSERT_GAS(gas_type, air_contents)
|
||||
air_contents.assert_gas(gas_type)
|
||||
air_contents.gases[gas_type][MOLES] = AIR_CONTENTS
|
||||
name = "[name] ([air_contents.gases[gas_type][GAS_META][META_GAS_NAME]])"
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
target = text2num(target)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_temperature = Clamp(target, min_temperature, max_temperature)
|
||||
target_temperature = CLAMP(target, min_temperature, max_temperature)
|
||||
investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS)
|
||||
|
||||
update_icon()
|
||||
|
||||
@@ -244,10 +244,10 @@
|
||||
pump_direction = text2num(signal.data["direction"])
|
||||
|
||||
if("set_internal_pressure" in signal.data)
|
||||
internal_pressure_bound = Clamp(text2num(signal.data["set_internal_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
internal_pressure_bound = CLAMP(text2num(signal.data["set_internal_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("set_external_pressure" in signal.data)
|
||||
external_pressure_bound = Clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
external_pressure_bound = CLAMP(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("reset_external_pressure" in signal.data)
|
||||
external_pressure_bound = ONE_ATMOSPHERE
|
||||
@@ -256,10 +256,10 @@
|
||||
internal_pressure_bound = 0
|
||||
|
||||
if("adjust_internal_pressure" in signal.data)
|
||||
internal_pressure_bound = Clamp(internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
internal_pressure_bound = CLAMP(internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("adjust_external_pressure" in signal.data)
|
||||
external_pressure_bound = Clamp(external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
external_pressure_bound = CLAMP(external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("init" in signal.data)
|
||||
name = signal.data["init"]
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
filtered_out.temperature = removed.temperature
|
||||
|
||||
for(var/gas in filter_types & removed_gases)
|
||||
ADD_GAS(gas, filtered_gases)
|
||||
filtered_out.add_gas(gas)
|
||||
filtered_gases[gas][MOLES] = removed_gases[gas][MOLES]
|
||||
removed_gases[gas][MOLES] = 0
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
if(!isopenturf(O))
|
||||
return FALSE
|
||||
var/datum/gas_mixture/merger = new
|
||||
ASSERT_GAS(spawn_id, merger)
|
||||
merger.assert_gas(spawn_id)
|
||||
merger.gases[spawn_id][MOLES] = (spawn_mol)
|
||||
merger.temperature = spawn_temp
|
||||
O.assume_air(merger)
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
if(initialize_directions & dir)
|
||||
return ..()
|
||||
if((NORTH|EAST) & dir)
|
||||
user.ventcrawl_layer = Clamp(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
|
||||
user.ventcrawl_layer = CLAMP(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
|
||||
if((SOUTH|WEST) & dir)
|
||||
user.ventcrawl_layer = Clamp(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
|
||||
user.ventcrawl_layer = CLAMP(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
|
||||
to_chat(user, "You align yourself with the [user.ventcrawl_layer]\th output.")
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proc/create_gas()
|
||||
if(gas_type)
|
||||
ADD_GAS(gas_type, air_contents.gases)
|
||||
air_contents.add_gas(gas_type)
|
||||
if(starter_temp)
|
||||
air_contents.temperature = starter_temp
|
||||
air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
@@ -411,7 +411,7 @@
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
release_pressure = Clamp(round(pressure), can_min_release_pressure, can_max_release_pressure)
|
||||
release_pressure = CLAMP(round(pressure), can_min_release_pressure, can_max_release_pressure)
|
||||
investigate_log("was set to [release_pressure] kPa by [key_name(usr)].", INVESTIGATE_ATMOS)
|
||||
if("valve")
|
||||
var/logmsg
|
||||
@@ -455,7 +455,7 @@
|
||||
var/N = text2num(user_input)
|
||||
if(!N)
|
||||
return
|
||||
timer_set = Clamp(N,minimum_timer_set,maximum_timer_set)
|
||||
timer_set = CLAMP(N,minimum_timer_set,maximum_timer_set)
|
||||
log_admin("[key_name(usr)] has activated a prototype valve timer")
|
||||
. = TRUE
|
||||
if("toggle_timer")
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
pump.target_pressure = Clamp(round(pressure), PUMP_MIN_PRESSURE, PUMP_MAX_PRESSURE)
|
||||
pump.target_pressure = CLAMP(round(pressure), PUMP_MIN_PRESSURE, PUMP_MAX_PRESSURE)
|
||||
investigate_log("was set to [pump.target_pressure] kPa by [key_name(usr)].", INVESTIGATE_ATMOS)
|
||||
if("eject")
|
||||
if(holding)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
filtered.temperature = filtering.temperature
|
||||
for(var/gas in filtering.gases & scrubbing)
|
||||
ADD_GAS(gas, filtered.gases)
|
||||
filtered.add_gas(gas)
|
||||
filtered.gases[gas][MOLES] = filtering.gases[gas][MOLES] // Shuffle the "bad" gasses to the filtered mixture.
|
||||
filtering.gases[gas][MOLES] = 0
|
||||
filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture.
|
||||
|
||||
@@ -115,9 +115,11 @@
|
||||
to_chat(user, "The Wish Granter punishes you for your wickedness, claiming your soul and warping your body to match the darkness in your heart.")
|
||||
SSticker.mode.traitors += user.mind
|
||||
user.mind.special_role = "traitor"
|
||||
|
||||
var/datum/objective/hijack/hijack = new
|
||||
hijack.owner = user.mind
|
||||
user.mind.objectives += hijack
|
||||
user.mind.add_antag_datum(/datum/antagonist/auto_custom)
|
||||
to_chat(user, "<B>Your inhibitions are swept away, the bonds of loyalty broken, you are free to murder as you please!</B>")
|
||||
user.mind.announce_objectives()
|
||||
user.set_species(/datum/species/shadow)
|
||||
|
||||
@@ -86,7 +86,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
|
||||
|
||||
/datum/export/process()
|
||||
..()
|
||||
cost *= GLOB.E**(k_elasticity * (1/30))
|
||||
cost *= NUM_E**(k_elasticity * (1/30))
|
||||
if(cost > init_cost)
|
||||
cost = init_cost
|
||||
|
||||
@@ -94,7 +94,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
|
||||
/datum/export/proc/get_cost(obj/O, contr = 0, emag = 0)
|
||||
var/amount = get_amount(O, contr, emag)
|
||||
if(k_elasticity!=0)
|
||||
return round((cost/k_elasticity) * (1 - GLOB.E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function
|
||||
return round((cost/k_elasticity) * (1 - NUM_E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function
|
||||
else
|
||||
return round(cost * amount) //alternative form derived from L'Hopital to avoid division by 0
|
||||
|
||||
@@ -131,7 +131,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
|
||||
else
|
||||
total_amount += amount
|
||||
|
||||
cost *= GLOB.E**(-1*k_elasticity*amount) //marginal cost modifier
|
||||
cost *= NUM_E**(-1*k_elasticity*amount) //marginal cost modifier
|
||||
SSblackbox.record_feedback("nested tally", "export_sold_cost", 1, list("[O.type]", "[the_cost]"))
|
||||
|
||||
// Total printout for the cargo console.
|
||||
|
||||
@@ -372,3 +372,39 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
var/meter = icon('icons/obj/atmospherics/pipes/simple.dmi', "meterX", SOUTH, frame, movement_states)
|
||||
if(meter)
|
||||
register_asset(sanitize_filename("[prefix].south.meterX.png"), fcopy_rsc(meter))
|
||||
|
||||
// Representative icons for each research design
|
||||
/datum/asset/simple/research_designs/register()
|
||||
for (var/path in subtypesof(/datum/design))
|
||||
var/datum/design/D = path
|
||||
|
||||
// construct the icon and slap it into the resource cache
|
||||
var/atom/item = initial(D.build_path)
|
||||
if (!ispath(item, /atom))
|
||||
// biogenerator outputs to beakers by default
|
||||
if (initial(D.build_type) & BIOGENERATOR)
|
||||
item = /obj/item/reagent_containers/glass/beaker/large
|
||||
else
|
||||
continue // shouldn't happen, but just in case
|
||||
|
||||
// circuit boards become their resulting machines or computers
|
||||
if (ispath(item, /obj/item/circuitboard))
|
||||
var/obj/item/circuitboard/C = item
|
||||
var/machine = initial(C.build_path)
|
||||
if (machine)
|
||||
item = machine
|
||||
var/icon_file = initial(item.icon)
|
||||
var/icon/I = icon(icon_file, initial(item.icon_state), SOUTH)
|
||||
|
||||
// computers (and snowflakes) get their screen and keyboard sprites
|
||||
if (ispath(item, /obj/machinery/computer) || ispath(item, /obj/machinery/power/solar_control))
|
||||
var/obj/machinery/computer/C = item
|
||||
var/screen = initial(C.icon_screen)
|
||||
var/keyboard = initial(C.icon_keyboard)
|
||||
if (screen)
|
||||
I.Blend(icon(icon_file, screen, SOUTH), ICON_OVERLAY)
|
||||
if (keyboard)
|
||||
I.Blend(icon(icon_file, keyboard, SOUTH), ICON_OVERLAY)
|
||||
|
||||
assets["design_[initial(D.id)].png"] = I
|
||||
return ..()
|
||||
|
||||
@@ -68,3 +68,6 @@
|
||||
|
||||
var/datum/chatOutput/chatOutput
|
||||
|
||||
var/list/credits //lazy list of all credit object bound to this client
|
||||
|
||||
var/datum/player_details/player_details //these persist between logins/logouts during the same round.
|
||||
|
||||
@@ -152,7 +152,7 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
#if (PRELOAD_RSC == 0)
|
||||
var/static/next_external_rsc = 0
|
||||
if(external_rsc_urls && external_rsc_urls.len)
|
||||
next_external_rsc = Wrap(next_external_rsc+1, 1, external_rsc_urls.len+1)
|
||||
next_external_rsc = WRAP(next_external_rsc+1, 1, external_rsc_urls.len+1)
|
||||
preload_rsc = external_rsc_urls[next_external_rsc]
|
||||
#endif
|
||||
|
||||
@@ -199,9 +199,7 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
prefs.parent = src
|
||||
prefs.last_ip = address //these are gonna be used for banning
|
||||
prefs.last_id = computer_id //these are gonna be used for banning
|
||||
if(world.byond_version >= 511 && byond_version >= 511 && prefs.clientfps)
|
||||
vars["fps"] = prefs.clientfps
|
||||
sethotkeys(1) //set hoykeys from preferences (from_pref = 1)
|
||||
fps = prefs.clientfps
|
||||
|
||||
log_access("Login: [key_name(src)] from [address ? address : "localhost"]-[computer_id] || BYOND v[byond_version]")
|
||||
var/alert_mob_dupe_login = FALSE
|
||||
@@ -227,6 +225,13 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
message_admins("<font color='red'><B>Notice: </B><font color='blue'>[key_name_admin(src)] has the same [matches] as [key_name_admin(C)] (no longer logged in). </font>")
|
||||
log_access("Notice: [key_name(src)] has the same [matches] as [key_name(C)] (no longer logged in).")
|
||||
|
||||
if(GLOB.player_details[ckey])
|
||||
player_details = GLOB.player_details[ckey]
|
||||
else
|
||||
player_details = new
|
||||
GLOB.player_details[ckey] = player_details
|
||||
|
||||
|
||||
. = ..() //calls mob.Login()
|
||||
|
||||
chatOutput.start() // Starts the chat
|
||||
@@ -673,6 +678,13 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
return TRUE
|
||||
. = ..()
|
||||
|
||||
/client/proc/rescale_view(change, min, max)
|
||||
var/viewscale = getviewsize(view)
|
||||
var/x = viewscale[1]
|
||||
var/y = viewscale[2]
|
||||
x = CLAMP(x+change, min, max)
|
||||
y = CLAMP(y+change, min,max)
|
||||
change_view("[x]x[y]")
|
||||
|
||||
/client/proc/change_view(new_size)
|
||||
if (isnull(new_size))
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/datum/player_details
|
||||
var/list/player_actions = list()
|
||||
@@ -1282,16 +1282,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
preferred_map = maplist[pickedmap]
|
||||
|
||||
if ("clientfps")
|
||||
var/version_message
|
||||
if (user.client && user.client.byond_version < 511)
|
||||
version_message = "\nYou need to be using byond version 511 or later to take advantage of this feature, your version of [user.client.byond_version] is too low"
|
||||
if (world.byond_version < 511)
|
||||
version_message += "\nThis server does not currently support client side fps. You can set now for when it does."
|
||||
var/desiredfps = input(user, "Choose your desired fps.[version_message]\n(0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num
|
||||
var/desiredfps = input(user, "Choose your desired fps. (0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num
|
||||
if (!isnull(desiredfps))
|
||||
clientfps = desiredfps
|
||||
if (world.byond_version >= 511 && user.client && user.client.byond_version >= 511)
|
||||
user.client.vars["fps"] = clientfps
|
||||
parent.fps = desiredfps
|
||||
if("ui")
|
||||
var/pickedui = input(user, "Choose your UI style.", "Character Preference") as null|anything in list("Midnight", "Plasmafire", "Retro", "Slimecore", "Operative", "Clockwork")
|
||||
if(pickedui)
|
||||
@@ -1596,12 +1590,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
toggles ^= MIDROUND_ANTAG
|
||||
|
||||
if("parallaxup")
|
||||
parallax = Wrap(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
|
||||
parallax = WRAP(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
|
||||
if (parent && parent.mob && parent.mob.hud_used)
|
||||
parent.mob.hud_used.update_parallax_pref(parent.mob)
|
||||
|
||||
if("parallaxdown")
|
||||
parallax = Wrap(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
|
||||
parallax = WRAP(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
|
||||
if (parent && parent.mob && parent.mob.hud_used)
|
||||
parent.mob.hud_used.update_parallax_pref(parent.mob)
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
/obj/item/clothing/glasses/proc/thermal_overload()
|
||||
if(ishuman(src.loc))
|
||||
var/mob/living/carbon/human/H = src.loc
|
||||
if(!(H.disabilities & BLIND))
|
||||
if(!(H.has_disability(BLIND)))
|
||||
if(H.glasses == src)
|
||||
to_chat(H, "<span class='danger'>[src] overloads and blinds you!</span>")
|
||||
H.flash_act(visual = 1)
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
assembled = TRUE
|
||||
boost_chargerate *= cap
|
||||
boost_drain -= manip
|
||||
powersetting_high = Clamp(laser, 0, 3)
|
||||
powersetting_high = CLAMP(laser, 0, 3)
|
||||
emp_disable_threshold = bin*1.25
|
||||
stabilizer_decay_amount = scan*3.5
|
||||
airbrake_decay_amount = manip*8
|
||||
@@ -194,15 +194,15 @@
|
||||
/obj/item/device/flightpack/proc/adjust_momentum(amountx, amounty, reduce_amount_total = 0)
|
||||
if(reduce_amount_total != 0)
|
||||
if(momentum_x > 0)
|
||||
momentum_x = Clamp(momentum_x - reduce_amount_total, 0, momentum_max)
|
||||
momentum_x = CLAMP(momentum_x - reduce_amount_total, 0, momentum_max)
|
||||
else if(momentum_x < 0)
|
||||
momentum_x = Clamp(momentum_x + reduce_amount_total, -momentum_max, 0)
|
||||
momentum_x = CLAMP(momentum_x + reduce_amount_total, -momentum_max, 0)
|
||||
if(momentum_y > 0)
|
||||
momentum_y = Clamp(momentum_y - reduce_amount_total, 0, momentum_max)
|
||||
momentum_y = CLAMP(momentum_y - reduce_amount_total, 0, momentum_max)
|
||||
else if(momentum_y < 0)
|
||||
momentum_y = Clamp(momentum_y + reduce_amount_total, -momentum_max, 0)
|
||||
momentum_x = Clamp(momentum_x + amountx, -momentum_max, momentum_max)
|
||||
momentum_y = Clamp(momentum_y + amounty, -momentum_max, momentum_max)
|
||||
momentum_y = CLAMP(momentum_y + reduce_amount_total, -momentum_max, 0)
|
||||
momentum_x = CLAMP(momentum_x + amountx, -momentum_max, momentum_max)
|
||||
momentum_y = CLAMP(momentum_y + amounty, -momentum_max, momentum_max)
|
||||
calculate_momentum_speed()
|
||||
|
||||
/obj/item/device/flightpack/intercept_user_move(dir, mob, newLoc, oldLoc)
|
||||
@@ -314,7 +314,7 @@
|
||||
|
||||
/obj/item/device/flightpack/proc/handle_damage()
|
||||
if(emp_damage)
|
||||
emp_damage = Clamp(emp_damage-emp_heal_amount, 0, emp_disable_threshold * 10)
|
||||
emp_damage = CLAMP(emp_damage-emp_heal_amount, 0, emp_disable_threshold * 10)
|
||||
if(emp_damage >= emp_disable_threshold)
|
||||
emp_disabled = TRUE
|
||||
if(emp_disabled && (emp_damage <= 0.5))
|
||||
@@ -347,11 +347,11 @@
|
||||
|
||||
/obj/item/device/flightpack/proc/handle_boost()
|
||||
if(boost)
|
||||
boost_charge = Clamp(boost_charge-boost_drain, 0, boost_maxcharge)
|
||||
boost_charge = CLAMP(boost_charge-boost_drain, 0, boost_maxcharge)
|
||||
if(boost_charge < 1)
|
||||
deactivate_booster()
|
||||
if(boost_charge < boost_maxcharge)
|
||||
boost_charge = Clamp(boost_charge+boost_chargerate, 0, boost_maxcharge)
|
||||
boost_charge = CLAMP(boost_charge+boost_chargerate, 0, boost_maxcharge)
|
||||
|
||||
/obj/item/device/flightpack/proc/cycle_power()
|
||||
powersetting < powersetting_high? (powersetting++) : (powersetting = 1)
|
||||
|
||||
@@ -654,7 +654,7 @@
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/shielded/process()
|
||||
if(world.time > recharge_cooldown && current_charges < max_charges)
|
||||
current_charges = Clamp((current_charges + recharge_rate), 0, max_charges)
|
||||
current_charges = CLAMP((current_charges + recharge_rate), 0, max_charges)
|
||||
playsound(loc, 'sound/magic/charge.ogg', 50, 1)
|
||||
if(current_charges == max_charges)
|
||||
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
|
||||
@@ -1,48 +1,49 @@
|
||||
/obj/item/clothing/suit/toggle/labcoat
|
||||
name = "labcoat"
|
||||
desc = "A suit that protects against minor chemical spills."
|
||||
icon_state = "labcoat"
|
||||
item_state = "labcoat"
|
||||
blood_overlay_type = "coat"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
allowed = list(/obj/item/device/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/device/healthanalyzer, /obj/item/device/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/soap, /obj/item/device/sensor_device, /obj/item/tank/internals/emergency_oxygen)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0, fire = 50, acid = 50)
|
||||
togglename = "buttons"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/cmo
|
||||
name = "chief medical officer's labcoat"
|
||||
desc = "Bluer than the standard model."
|
||||
icon_state = "labcoat_cmo"
|
||||
item_state = "labcoat_cmo"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/emt
|
||||
name = "EMT's jacket"
|
||||
desc = "A dark blue jacket with reflective strips for emergency medical technicians."
|
||||
icon_state = "labcoat_emt"
|
||||
item_state = "labcoat_cmo"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/mad
|
||||
name = "\improper The Mad's labcoat"
|
||||
desc = "It makes you look capable of konking someone on the noggin and shooting them into space."
|
||||
icon_state = "labgreen"
|
||||
item_state = "labgreen"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/genetics
|
||||
name = "geneticist labcoat"
|
||||
desc = "A suit that protects against minor chemical spills. Has a blue stripe on the shoulder."
|
||||
icon_state = "labcoat_gen"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/chemist
|
||||
name = "chemist labcoat"
|
||||
desc = "A suit that protects against minor chemical spills. Has an orange stripe on the shoulder."
|
||||
icon_state = "labcoat_chem"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/virologist
|
||||
name = "virologist labcoat"
|
||||
desc = "A suit that protects against minor chemical spills. Offers slightly more protection against biohazards than the standard model. Has a green stripe on the shoulder."
|
||||
icon_state = "labcoat_vir"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/science
|
||||
name = "scientist labcoat"
|
||||
desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder."
|
||||
icon_state = "labcoat_tox"
|
||||
/obj/item/clothing/suit/toggle/labcoat
|
||||
name = "labcoat"
|
||||
desc = "A suit that protects against minor chemical spills."
|
||||
icon_state = "labcoat"
|
||||
item_state = "labcoat"
|
||||
blood_overlay_type = "coat"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
allowed = list(/obj/item/device/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/device/healthanalyzer, /obj/item/device/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/soap, /obj/item/device/sensor_device, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0, fire = 50, acid = 50)
|
||||
togglename = "buttons"
|
||||
species_exception = list(/datum/species/golem)
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/cmo
|
||||
name = "chief medical officer's labcoat"
|
||||
desc = "Bluer than the standard model."
|
||||
icon_state = "labcoat_cmo"
|
||||
item_state = "labcoat_cmo"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/emt
|
||||
name = "EMT's jacket"
|
||||
desc = "A dark blue jacket with reflective strips for emergency medical technicians."
|
||||
icon_state = "labcoat_emt"
|
||||
item_state = "labcoat_cmo"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/mad
|
||||
name = "\improper The Mad's labcoat"
|
||||
desc = "It makes you look capable of konking someone on the noggin and shooting them into space."
|
||||
icon_state = "labgreen"
|
||||
item_state = "labgreen"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/genetics
|
||||
name = "geneticist labcoat"
|
||||
desc = "A suit that protects against minor chemical spills. Has a blue stripe on the shoulder."
|
||||
icon_state = "labcoat_gen"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/chemist
|
||||
name = "chemist labcoat"
|
||||
desc = "A suit that protects against minor chemical spills. Has an orange stripe on the shoulder."
|
||||
icon_state = "labcoat_chem"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/virologist
|
||||
name = "virologist labcoat"
|
||||
desc = "A suit that protects against minor chemical spills. Offers slightly more protection against biohazards than the standard model. Has a green stripe on the shoulder."
|
||||
icon_state = "labcoat_vir"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/science
|
||||
name = "scientist labcoat"
|
||||
desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder."
|
||||
icon_state = "labcoat_tox"
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
"<span class='notice'>You pin \the [src] on [M]'s chest.</span>")
|
||||
if(input)
|
||||
SSblackbox.record_feedback("associative", "commendation", 1, list("commender" = "[user.real_name]", "commendee" = "[M.real_name]", "medal" = "[src]", "reason" = input))
|
||||
GLOB.commendations += "[user.real_name] awarded <b>[M.real_name]</b> the <font color='blue'>[name]</font>! \n- [input]"
|
||||
GLOB.commendations += "[user.real_name] awarded <b>[M.real_name]</b> the <span class='medaltext'>[name]</span>! \n- [input]"
|
||||
commended = TRUE
|
||||
log_game("<b>[key_name(M)]</b> was given the following commendation by <b>[key_name(user)]</b>: [input]")
|
||||
message_admins("<b>[key_name(M)]</b> was given the following commendation by <b>[key_name(user)]</b>: [input]")
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
else
|
||||
if(istype(I, /obj/item/reagent_containers))
|
||||
var/obj/item/reagent_containers/RC = I
|
||||
if(RC.container_type & OPENCONTAINER_1)
|
||||
if(RC.is_drainable())
|
||||
for(var/datum/reagent/A in RC.reagents.reagent_list)
|
||||
.[A.type] += A.volume
|
||||
.[I.type] += 1
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "rag"
|
||||
flags_1 = NOBLUDGEON_1
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
amount_per_transfer_from_this = 5
|
||||
possible_transfer_amounts = list()
|
||||
volume = 5
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
|
||||
/datum/round_event_control/New()
|
||||
if(config && !wizardevent) // Magic is unaffected by configs
|
||||
earliest_start = Ceiling(earliest_start * CONFIG_GET(number/events_min_time_mul))
|
||||
min_players = Ceiling(min_players * CONFIG_GET(number/events_min_players_mul))
|
||||
earliest_start = CEILING(earliest_start * CONFIG_GET(number/events_min_time_mul), 1)
|
||||
min_players = CEILING(min_players * CONFIG_GET(number/events_min_players_mul), 1)
|
||||
|
||||
/datum/round_event_control/wizard
|
||||
wizardevent = 1
|
||||
|
||||
@@ -67,12 +67,12 @@
|
||||
|
||||
kill()
|
||||
return
|
||||
if(IsMultiple(activeFor, 4))
|
||||
if(ISMULTIPLE(activeFor, 4))
|
||||
var/obj/machinery/vending/rebel = pick(vendingMachines)
|
||||
vendingMachines.Remove(rebel)
|
||||
infectedMachines.Add(rebel)
|
||||
rebel.shut_up = 0
|
||||
rebel.shoot_inventory = 1
|
||||
|
||||
if(IsMultiple(activeFor, 8))
|
||||
if(ISMULTIPLE(activeFor, 8))
|
||||
originMachine.speak(pick(rampant_speeches))
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
var/virus_type
|
||||
|
||||
var/max_severity = 3
|
||||
|
||||
|
||||
/datum/round_event/disease_outbreak/announce(fake)
|
||||
priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg')
|
||||
@@ -17,8 +19,14 @@
|
||||
/datum/round_event/disease_outbreak/setup()
|
||||
announceWhen = rand(15, 30)
|
||||
|
||||
|
||||
/datum/round_event/disease_outbreak/start()
|
||||
if(!virus_type)
|
||||
var/advanced_virus = FALSE
|
||||
max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes
|
||||
if(prob(20 + (10 * max_severity)))
|
||||
advanced_virus = TRUE
|
||||
|
||||
if(!virus_type && !advanced_virus)
|
||||
virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis)
|
||||
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
|
||||
@@ -41,16 +49,48 @@
|
||||
continue
|
||||
|
||||
var/datum/disease/D
|
||||
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
|
||||
if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst.
|
||||
continue
|
||||
D = new virus_type()
|
||||
var/datum/disease/dnaspread/DS = D
|
||||
DS.strain_data["name"] = H.real_name
|
||||
DS.strain_data["UI"] = H.dna.uni_identity
|
||||
DS.strain_data["SE"] = H.dna.struc_enzymes
|
||||
if(!advanced_virus)
|
||||
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
|
||||
if(!H.dna || (H.has_disability(BLIND))) //A blindness disease would be the worst.
|
||||
continue
|
||||
D = new virus_type()
|
||||
var/datum/disease/dnaspread/DS = D
|
||||
DS.strain_data["name"] = H.real_name
|
||||
DS.strain_data["UI"] = H.dna.uni_identity
|
||||
DS.strain_data["SE"] = H.dna.struc_enzymes
|
||||
else
|
||||
D = new virus_type()
|
||||
else
|
||||
D = new virus_type()
|
||||
D = make_virus(max_severity, max_severity)
|
||||
D.carrier = TRUE
|
||||
H.AddDisease(D)
|
||||
break
|
||||
|
||||
if(advanced_virus)
|
||||
var/datum/disease/advance/A = D
|
||||
var/list/name_symptoms = list() //for feedback
|
||||
for(var/datum/symptom/S in A.symptoms)
|
||||
name_symptoms += S.name
|
||||
message_admins("An event has triggered a random advanced virus outbreak on [key_name_admin(H)]! It has these symptoms: [english_list(name_symptoms)]")
|
||||
log_game("An event has triggered a random advanced virus outbreak on [key_name(H)]! It has these symptoms: [english_list(name_symptoms)]")
|
||||
break
|
||||
|
||||
/datum/round_event/disease_outbreak/proc/make_virus(max_symptoms, max_level)
|
||||
if(max_symptoms > SYMPTOM_LIMIT)
|
||||
max_symptoms = SYMPTOM_LIMIT
|
||||
var/datum/disease/advance/A = new(FALSE, null)
|
||||
A.symptoms = list()
|
||||
var/list/datum/symptom/possible_symptoms = list()
|
||||
for(var/symptom in subtypesof(/datum/symptom))
|
||||
var/datum/symptom/S = symptom
|
||||
if(initial(S.level) > max_level)
|
||||
continue
|
||||
if(initial(S.level) <= 0) //unobtainable symptoms
|
||||
continue
|
||||
possible_symptoms += S
|
||||
for(var/i in 1 to max_symptoms)
|
||||
var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms)
|
||||
if(chosen_symptom)
|
||||
var/datum/symptom/S = new chosen_symptom
|
||||
A.symptoms += S
|
||||
A.Refresh() //just in case someone already made and named the same disease
|
||||
return A
|
||||
|
||||
@@ -45,19 +45,26 @@
|
||||
to_chat(L, "<span class='warning'><B>You didn't get a date! They're all having fun without you! you'll show them though...</B></span>")
|
||||
var/datum/objective/martyr/normiesgetout = new
|
||||
normiesgetout.owner = L.mind
|
||||
L.mind.special_role = "heartbreaker"
|
||||
SSticker.mode.traitors |= L.mind
|
||||
L.mind.objectives += normiesgetout
|
||||
|
||||
L.mind.add_antag_datum(/datum/antagonist/auto_custom)
|
||||
|
||||
/proc/forge_valentines_objective(mob/living/lover,mob/living/date)
|
||||
|
||||
SSticker.mode.traitors |= lover.mind
|
||||
lover.mind.special_role = "valentine"
|
||||
|
||||
|
||||
var/datum/objective/protect/protect_objective = new /datum/objective/protect
|
||||
protect_objective.owner = lover.mind
|
||||
protect_objective.target = date.mind
|
||||
protect_objective.explanation_text = "Protect [date.real_name], your date."
|
||||
lover.mind.objectives += protect_objective
|
||||
|
||||
lover.mind.add_antag_datum(/datum/antagonist/auto_custom)
|
||||
|
||||
to_chat(lover, "<span class='warning'><B>You're on a date with [date]! Protect them at all costs. This takes priority over all other loyalties.</B></span>")
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
/datum/round_event_control/treevenge
|
||||
name = "Treevenge (Christmas)"
|
||||
holidayID = CHRISTMAS
|
||||
typepath = /datum/round_event/treevenge
|
||||
max_occurrences = 1
|
||||
weight = 20
|
||||
|
||||
/datum/round_event/treevenge/start()
|
||||
for(var/obj/structure/flora/tree/pine/xmas in world)
|
||||
var/mob/living/simple_animal/hostile/tree/evil_tree = new /mob/living/simple_animal/hostile/tree(xmas.loc)
|
||||
evil_tree.icon_state = xmas.icon_state
|
||||
evil_tree.icon_living = evil_tree.icon_state
|
||||
evil_tree.icon_dead = evil_tree.icon_state
|
||||
evil_tree.icon_gib = evil_tree.icon_state
|
||||
qdel(xmas) //b-but I don't want to delete xmas...
|
||||
|
||||
//this is an example of a possible round-start event
|
||||
/datum/round_event_control/presents
|
||||
name = "Presents under Trees (Christmas)"
|
||||
@@ -24,12 +8,11 @@
|
||||
earliest_start = 0
|
||||
|
||||
/datum/round_event/presents/start()
|
||||
for(var/obj/structure/flora/tree/pine/xmas in world)
|
||||
for(var/obj/structure/flora/tree/pine/xmas/xmas in world)
|
||||
if(!(xmas.z in GLOB.station_z_levels))
|
||||
continue
|
||||
for(var/turf/open/floor/T in orange(1,xmas))
|
||||
for(var/i=1,i<=rand(1,5),i++)
|
||||
new /obj/item/a_gift(T)
|
||||
xmas.icon_state = "pinepresents"
|
||||
xmas.gifts_under_tree = TRUE
|
||||
for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_living_list)
|
||||
Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
|
||||
for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in GLOB.machines)
|
||||
@@ -98,7 +81,7 @@
|
||||
name = "Santa is coming to town! (Christmas)"
|
||||
holidayID = CHRISTMAS
|
||||
typepath = /datum/round_event/santa
|
||||
weight = 150
|
||||
weight = 20
|
||||
max_occurrences = 1
|
||||
earliest_start = 20000
|
||||
|
||||
|
||||
@@ -12,6 +12,16 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
typepath = /datum/round_event/immovable_rod
|
||||
min_players = 15
|
||||
max_occurrences = 5
|
||||
var/atom/special_target
|
||||
|
||||
|
||||
/datum/round_event_control/immovable_rod/admin_setup()
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/aimed = alert("Aimed at current location?","Sniperod", "Yes", "No")
|
||||
if(aimed == "Yes")
|
||||
special_target = get_turf(usr)
|
||||
|
||||
/datum/round_event/immovable_rod
|
||||
announceWhen = 5
|
||||
@@ -20,10 +30,11 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
priority_announce("What the fuck was that?!", "General Alert")
|
||||
|
||||
/datum/round_event/immovable_rod/start()
|
||||
var/datum/round_event_control/immovable_rod/C = control
|
||||
var/startside = pick(GLOB.cardinals)
|
||||
var/turf/startT = spaceDebrisStartLoc(startside, ZLEVEL_STATION_PRIMARY)
|
||||
var/turf/endT = spaceDebrisFinishLoc(startside, ZLEVEL_STATION_PRIMARY)
|
||||
new /obj/effect/immovablerod(startT, endT)
|
||||
new /obj/effect/immovablerod(startT, endT, C.special_target)
|
||||
|
||||
/obj/effect/immovablerod
|
||||
name = "immovable rod"
|
||||
@@ -36,18 +47,28 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
var/z_original = 0
|
||||
var/destination
|
||||
var/notify = TRUE
|
||||
var/atom/special_target
|
||||
|
||||
/obj/effect/immovablerod/New(atom/start, atom/end)
|
||||
/obj/effect/immovablerod/New(atom/start, atom/end, aimed_at)
|
||||
..()
|
||||
SSaugury.register_doom(src, 2000)
|
||||
z_original = z
|
||||
destination = end
|
||||
special_target = aimed_at
|
||||
if(notify)
|
||||
notify_ghosts("\A [src] is inbound!",
|
||||
enter_link="<a href=?src=[REF(src)];orbit=1>(Click to orbit)</a>",
|
||||
source=src, action=NOTIFY_ORBIT)
|
||||
GLOB.poi_list += src
|
||||
if(end && end.z==z_original)
|
||||
|
||||
var/special_target_valid = FALSE
|
||||
if(special_target)
|
||||
var/turf/T = get_turf(special_target)
|
||||
if(T.z == z_original)
|
||||
special_target_valid = TRUE
|
||||
if(special_target_valid)
|
||||
walk_towards(src, special_target, 1)
|
||||
else if(end && end.z==z_original)
|
||||
walk_towards(src, destination, 1)
|
||||
|
||||
/obj/effect/immovablerod/Topic(href, href_list)
|
||||
@@ -60,11 +81,20 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
GLOB.poi_list -= src
|
||||
. = ..()
|
||||
|
||||
/obj/effect/immovablerod/Move()
|
||||
/obj/effect/immovablerod/Moved()
|
||||
if((z != z_original) || (loc == destination))
|
||||
qdel(src)
|
||||
if(special_target && loc == get_turf(special_target))
|
||||
complete_trajectory()
|
||||
return ..()
|
||||
|
||||
/obj/effect/immovablerod/proc/complete_trajectory()
|
||||
//We hit what we wanted to hit, time to go
|
||||
special_target = null
|
||||
destination = get_edge_target_turf(src, dir)
|
||||
walk(src,0)
|
||||
walk_towards(src, destination, 1)
|
||||
|
||||
/obj/effect/immovablerod/ex_act(severity, target)
|
||||
return 0
|
||||
|
||||
@@ -83,6 +113,9 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
x = clong.x
|
||||
y = clong.y
|
||||
|
||||
if(special_target && clong == special_target)
|
||||
complete_trajectory()
|
||||
|
||||
if(isturf(clong) || isobj(clong))
|
||||
if(clong.density)
|
||||
clong.ex_act(EXPLODE_HEAVY)
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/ai/meteors.ogg')
|
||||
|
||||
/datum/round_event/meteor_wave/tick()
|
||||
if(IsMultiple(activeFor, 3))
|
||||
if(ISMULTIPLE(activeFor, 3))
|
||||
spawn_meteors(5, wave_type) //meteor list types defined in gamemode/meteor/meteors.dm
|
||||
|
||||
/datum/round_event_control/meteor_wave/threatening
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
player_mind.assigned_role = "Nightmare"
|
||||
player_mind.special_role = "Nightmare"
|
||||
SSticker.mode.traitors += player_mind
|
||||
player_mind.add_antag_datum(/datum/antagonist/auto_custom)
|
||||
S.set_species(/datum/species/shadow/nightmare)
|
||||
playsound(S, 'sound/magic/ethereal_exit.ogg', 50, 1, -1)
|
||||
message_admins("[key_name_admin(S)] has been made into a Nightmare by an event.")
|
||||
|
||||
@@ -27,31 +27,13 @@
|
||||
A.copy_to(operative)
|
||||
operative.dna.update_dna_identity()
|
||||
|
||||
operative.equipOutfit(/datum/outfit/syndicate/full)
|
||||
|
||||
var/datum/mind/Mind = new /datum/mind(selected.key)
|
||||
Mind.assigned_role = "Lone Operative"
|
||||
Mind.special_role = "Lone Operative"
|
||||
SSticker.mode.traitors |= Mind
|
||||
Mind.active = 1
|
||||
|
||||
var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.machines
|
||||
if(nuke)
|
||||
var/nuke_code
|
||||
if(!nuke.r_code || nuke.r_code == "ADMIN")
|
||||
nuke_code = random_nukecode()
|
||||
nuke.r_code = nuke_code
|
||||
else
|
||||
nuke_code = nuke.r_code
|
||||
|
||||
Mind.store_memory("<B>Station Self-Destruct Device Code</B>: [nuke_code]", 0, 0)
|
||||
to_chat(Mind.current, "The nuclear authorization code is: <B>[nuke_code]</B>")
|
||||
|
||||
var/datum/objective/nuclear/O = new()
|
||||
O.owner = Mind
|
||||
Mind.objectives += O
|
||||
|
||||
Mind.transfer_to(operative)
|
||||
Mind.add_antag_datum(/datum/antagonist/nukeop/lone)
|
||||
|
||||
message_admins("[key_name_admin(operative)] has been made into lone operative by an event.")
|
||||
log_game("[key_name(operative)] was spawned as a lone operative by an event.")
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
T = safepick(get_area_turfs(pick(station_areas)))
|
||||
hostiles_spawn += T
|
||||
|
||||
next_boss_spawn = startWhen + Ceiling(2 * number_of_hostiles / number_of_bosses)
|
||||
next_boss_spawn = startWhen + CEILING(2 * number_of_hostiles / number_of_bosses, 1)
|
||||
|
||||
/datum/round_event/portal_storm/announce(fake)
|
||||
set waitfor = 0
|
||||
@@ -117,14 +117,14 @@
|
||||
/datum/round_event/portal_storm/proc/spawn_hostile()
|
||||
if(!hostile_types || !hostile_types.len)
|
||||
return 0
|
||||
return IsMultiple(activeFor, 2)
|
||||
return ISMULTIPLE(activeFor, 2)
|
||||
|
||||
/datum/round_event/portal_storm/proc/spawn_boss()
|
||||
if(!boss_types || !boss_types.len)
|
||||
return 0
|
||||
|
||||
if(activeFor == next_boss_spawn)
|
||||
next_boss_spawn += Ceiling(number_of_hostiles / number_of_bosses)
|
||||
next_boss_spawn += CEILING(number_of_hostiles / number_of_bosses, 1)
|
||||
return 1
|
||||
|
||||
/datum/round_event/portal_storm/proc/time_to_end()
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
citizens += H
|
||||
SSticker.mode.traitors += M
|
||||
M.special_role = "separatist"
|
||||
M.add_antag_datum(/datum/antagonist/auto_custom)
|
||||
H.log_message("<font color='red'>Was made into a separatist, long live [nation]!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
to_chat(H, "<B>You are a separatist! [nation] forever! Protect the sovereignty of your newfound land with your comrades in arms!</B>")
|
||||
if(citizens.len)
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
O.completed = 1 //YES!
|
||||
O.owner = new_holder.mind
|
||||
new_holder.mind.objectives += O
|
||||
new_holder.mind.add_antag_datum(/datum/antagonist/auto_custom)
|
||||
new_holder.log_message("<font color='green'>Won with greentext!!!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
color_altered_mobs -= new_holder
|
||||
resistance_flags |= ON_FIRE
|
||||
|
||||
@@ -80,6 +80,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list(
|
||||
|
||||
/obj/effect/hallucination
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
anchored = TRUE
|
||||
var/mob/living/carbon/target = null
|
||||
|
||||
/obj/effect/hallucination/simple
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
icon_state = null
|
||||
lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
var/gulp_size = 5 //This is now officially broken ... need to think of a nice way to fix it.
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,50)
|
||||
volume = 50
|
||||
@@ -30,7 +30,7 @@
|
||||
if(!canconsume(M, user))
|
||||
return 0
|
||||
|
||||
if (!is_open_container())
|
||||
if (!is_drainable())
|
||||
to_chat(user, "<span class='warning'>[src]'s lid hasn't been opened!</span>")
|
||||
return 0
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
if(!reagents || !reagents.total_volume)
|
||||
return // The drink might be empty after the delay, such as by spam-feeding
|
||||
M.visible_message("<span class='danger'>[user] feeds the contents of [src] to [M].</span>", "<span class='userdanger'>[user] feeds the contents of [src] to [M].</span>")
|
||||
add_logs(user, M, "fed", reagentlist(src))
|
||||
add_logs(user, M, "fed", reagents.log_list())
|
||||
|
||||
var/fraction = min(gulp_size/reagents.total_volume, 1)
|
||||
checkLiked(fraction, M)
|
||||
@@ -56,31 +56,16 @@
|
||||
/obj/item/reagent_containers/food/drinks/afterattack(obj/target, mob/user , proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us.
|
||||
|
||||
if (!is_open_container())
|
||||
to_chat(user, "<span class='warning'>[target]'s tab isn't open!</span>")
|
||||
return
|
||||
|
||||
if(!target.reagents.total_volume)
|
||||
to_chat(user, "<span class='warning'>[target] is empty.</span>")
|
||||
return
|
||||
|
||||
if(reagents.total_volume >= reagents.maximum_volume)
|
||||
to_chat(user, "<span class='warning'>[src] is full.</span>")
|
||||
return
|
||||
|
||||
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
|
||||
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the contents of [target].</span>")
|
||||
|
||||
else if(target.is_open_container()) //Something like a glass. Player probably wants to transfer TO it.
|
||||
if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
|
||||
if(!reagents.total_volume)
|
||||
to_chat(user, "<span class='warning'>[src] is empty.</span>")
|
||||
return
|
||||
|
||||
if(target.reagents.total_volume >= target.reagents.maximum_volume)
|
||||
if(target.reagents.holder_full())
|
||||
to_chat(user, "<span class='warning'>[target] is full.</span>")
|
||||
return
|
||||
|
||||
var/refill = reagents.get_master_reagent_id()
|
||||
var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
|
||||
to_chat(user, "<span class='notice'>You transfer [trans] units of the solution to [target].</span>")
|
||||
@@ -90,13 +75,29 @@
|
||||
bro.cell.use(30)
|
||||
addtimer(CALLBACK(reagents, /datum/reagents.proc/add_reagent, refill, trans), 600)
|
||||
|
||||
else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
|
||||
if (!is_refillable())
|
||||
to_chat(user, "<span class='warning'>[src]'s tab isn't open!</span>")
|
||||
return
|
||||
|
||||
if(!target.reagents.total_volume)
|
||||
to_chat(user, "<span class='warning'>[target] is empty.</span>")
|
||||
return
|
||||
|
||||
if(reagents.holder_full())
|
||||
to_chat(user, "<span class='warning'>[src] is full.</span>")
|
||||
return
|
||||
|
||||
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
|
||||
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the contents of [target].</span>")
|
||||
|
||||
else
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/attackby(obj/item/I, mob/user, params)
|
||||
if(I.is_hot())
|
||||
var/added_heat = (I.is_hot() / 100) //ishot returns a temperature
|
||||
if(reagents)
|
||||
reagents.chem_temp += added_heat
|
||||
to_chat(user, "<span class='notice'>You heat [src] with [I].</span>")
|
||||
reagents.handle_reactions()
|
||||
var/hotness = I.is_hot()
|
||||
if(hotness && reagents)
|
||||
reagents.expose_temperature(hotness)
|
||||
to_chat(user, "<span class='notice'>You heat [name] with [I]!</span>")
|
||||
..()
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/throw_impact(atom/target, mob/thrower)
|
||||
@@ -142,7 +143,7 @@
|
||||
possible_transfer_amounts = list()
|
||||
volume = 5
|
||||
flags_1 = CONDUCT_1
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
spillable = TRUE
|
||||
resistance_flags = FIRE_PROOF
|
||||
isGlass = FALSE
|
||||
@@ -406,9 +407,9 @@
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/soda_cans/attack_self(mob/user)
|
||||
if(!is_open_container())
|
||||
if(!is_drainable())
|
||||
to_chat(user, "You pull back the tab of \the [src] with a satisfying pop.") //Ahhhhhhhh
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
playsound(src, "can_open", 50, 1)
|
||||
spillable = TRUE
|
||||
return
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/obj/item/reagent_containers/food
|
||||
possible_transfer_amounts = list()
|
||||
volume = 50 //Sets the default container amount for all food items.
|
||||
container_type = INJECTABLE_1
|
||||
container_type = INJECTABLE
|
||||
resistance_flags = FLAMMABLE
|
||||
var/foodtype = NONE
|
||||
var/last_check_time
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
desc = "Just your average condiment container."
|
||||
icon = 'icons/obj/food/containers.dmi'
|
||||
icon_state = "emptycondiment"
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
possible_transfer_amounts = list(1, 5, 10, 15, 20, 25, 30, 50)
|
||||
volume = 50
|
||||
//Possible_states has the reagent id as key and a list of, in order, the icon_state, the name and the desc as values. Used in the on_reagent_change(changetype) to change names, descs and sprites.
|
||||
@@ -45,7 +45,7 @@
|
||||
if(!reagents || !reagents.total_volume)
|
||||
return // The condiment might be empty after the delay.
|
||||
user.visible_message("<span class='warning'>[user] feeds [M] from [src].</span>")
|
||||
add_logs(user, M, "fed", reagentlist(src))
|
||||
add_logs(user, M, "fed", reagents.log_list())
|
||||
|
||||
var/fraction = min(10/reagents.total_volume, 1)
|
||||
reagents.reaction(M, INGEST, fraction)
|
||||
@@ -70,7 +70,7 @@
|
||||
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the contents of [target].</span>")
|
||||
|
||||
//Something like a glass or a food item. Player probably wants to transfer TO it.
|
||||
else if(target.is_open_container() || istype(target, /obj/item/reagent_containers/food/snacks))
|
||||
else if(target.is_drainable() || istype(target, /obj/item/reagent_containers/food/snacks))
|
||||
if(!reagents.total_volume)
|
||||
to_chat(user, "<span class='warning'>[src] is empty!</span>")
|
||||
return
|
||||
|
||||
@@ -291,7 +291,7 @@
|
||||
desc = "A simple bowl, used for soups and salads."
|
||||
icon = 'icons/obj/food/soupsalad.dmi'
|
||||
icon_state = "bowl"
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
materials = list(MAT_GLASS = 500)
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
if(!do_mob(user, M))
|
||||
return
|
||||
add_logs(user, M, "fed", reagentlist(src))
|
||||
add_logs(user, M, "fed", reagents.log_list())
|
||||
M.visible_message("<span class='danger'>[user] forces [M] to eat [src].</span>", \
|
||||
"<span class='userdanger'>[user] forces [M] to eat [src].</span>")
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2)
|
||||
tastes = list("pie" = 1)
|
||||
foodtype = GRAIN | DAIRY | SUGAR
|
||||
var/stunning = TRUE
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pie/cream/throw_impact(atom/hit_atom)
|
||||
. = ..()
|
||||
@@ -46,15 +47,18 @@
|
||||
creamoverlay.icon_state = "creampie_lizard"
|
||||
else
|
||||
creamoverlay.icon_state = "creampie_human"
|
||||
H.Knockdown(20) //splat!
|
||||
if(stunning)
|
||||
H.Knockdown(20) //splat!
|
||||
H.adjust_blurriness(1)
|
||||
H.visible_message("<span class='warning'>[H] is creamed by [src]!</span>", "<span class='userdanger'>You've been creamed by [src]!</span>")
|
||||
playsound(H, "desceration", 50, TRUE)
|
||||
if (!H.creamed) // one layer at a time
|
||||
if(!H.creamed) // one layer at a time
|
||||
H.add_overlay(creamoverlay)
|
||||
H.creamed = TRUE
|
||||
qdel(src)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pie/cream/nostun
|
||||
stunning = FALSE
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pie/berryclafoutis
|
||||
name = "berry clafoutis"
|
||||
|
||||
@@ -29,7 +29,7 @@ God bless America.
|
||||
anchored = TRUE
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 5
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
var/obj/item/reagent_containers/food/snacks/deepfryholder/frying //What's being fried RIGHT NOW?
|
||||
var/cook_time = 0
|
||||
var/oil_use = 0.05 //How much cooking oil is used per tick
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
var/portion = 10
|
||||
var/selected_drink
|
||||
var/list/stored_food = list()
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
var/obj/item/reagent_containers/mixer
|
||||
|
||||
/obj/machinery/food_cart/Initialize()
|
||||
@@ -100,7 +100,7 @@
|
||||
stored_food[sanitize(S.name)]++
|
||||
else
|
||||
stored_food[sanitize(S.name)] = 1
|
||||
else if(O.is_open_container())
|
||||
else if(O.is_drainable())
|
||||
return
|
||||
else
|
||||
. = ..()
|
||||
@@ -123,7 +123,7 @@
|
||||
break
|
||||
|
||||
if(href_list["portion"])
|
||||
portion = Clamp(input("How much drink do you want to dispense per glass?") as num, 0, 50)
|
||||
portion = CLAMP(input("How much drink do you want to dispense per glass?") as num, 0, 50)
|
||||
|
||||
if(href_list["pour"] || href_list["m_pour"])
|
||||
if(glasses-- <= 0)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/obj/machinery/gibber
|
||||
name = "gibber"
|
||||
desc = "The name isn't descriptive enough?"
|
||||
@@ -12,10 +11,10 @@
|
||||
circuit = /obj/item/circuitboard/machine/gibber
|
||||
|
||||
var/operating = FALSE //Is it on?
|
||||
var/dirty = 0 // Does it need cleaning?
|
||||
var/dirty = FALSE // Does it need cleaning?
|
||||
var/gibtime = 40 // Time from starting until meat appears
|
||||
var/meat_produced = 0
|
||||
var/ignore_clothing = 0
|
||||
var/ignore_clothing = FALSE
|
||||
|
||||
|
||||
/obj/machinery/gibber/Initialize()
|
||||
@@ -30,7 +29,7 @@
|
||||
gib_time -= 5 * M.rating
|
||||
gibtime = gib_time
|
||||
if(M.rating >= 2)
|
||||
ignore_clothing = 1
|
||||
ignore_clothing = TRUE
|
||||
|
||||
/obj/machinery/gibber/update_icon()
|
||||
cut_overlays()
|
||||
@@ -61,6 +60,10 @@
|
||||
to_chat(user, "<span class='danger'>It's locked and running.</span>")
|
||||
return
|
||||
|
||||
if(!anchored)
|
||||
to_chat(user, "<span class='notice'>[src] cannot be used unless bolted to the ground.</span>")
|
||||
return
|
||||
|
||||
if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
|
||||
var/mob/living/L = user.pulling
|
||||
if(!iscarbon(L))
|
||||
@@ -70,12 +73,17 @@
|
||||
if(C.buckled ||C.has_buckled_mobs())
|
||||
to_chat(user, "<span class='warning'>[C] is attached to something!</span>")
|
||||
return
|
||||
if(C.abiotic(1) && !ignore_clothing)
|
||||
to_chat(user, "<span class='danger'>Subject may not have abiotic items on.</span>")
|
||||
return
|
||||
|
||||
if(!ignore_clothing)
|
||||
for(var/obj/item/I in C.held_items + C.get_equipped_items())
|
||||
if(!(I.flags_1 & NODROP_1))
|
||||
to_chat(user, "<span class='danger'>Subject may not have abiotic items on.</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='danger'>[user] starts to put [C] into the gibber!</span>")
|
||||
src.add_fingerprint(user)
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if(do_after(user, gibtime, target = src))
|
||||
if(C && user.pulling == C && !C.buckled && !C.has_buckled_mobs() && !occupant)
|
||||
user.visible_message("<span class='danger'>[user] stuffs [C] into the gibber!</span>")
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
anchored = FALSE
|
||||
use_power = NO_POWER_USE
|
||||
layer = BELOW_OBJ_LAYER
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
max_integrity = 300
|
||||
var/list/product_types = list()
|
||||
var/dispense_flavour = ICECREAM_VANILLA
|
||||
@@ -112,7 +112,7 @@
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[O] already has ice cream in it.</span>")
|
||||
return 1
|
||||
else if(O.is_open_container())
|
||||
else if(O.is_drainable())
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
src.icon_state = "mw"
|
||||
src.broken = 0 // Fix it!
|
||||
src.dirty = 0 // just to be sure
|
||||
src.container_type = OPENCONTAINER_1
|
||||
src.container_type = OPENCONTAINER
|
||||
return 0 //to use some fuel
|
||||
else
|
||||
to_chat(user, "<span class='warning'>It's broken!</span>")
|
||||
@@ -98,7 +98,7 @@
|
||||
src.dirty = 0 // It's clean!
|
||||
src.broken = 0 // just to be sure
|
||||
src.icon_state = "mw"
|
||||
src.container_type = OPENCONTAINER_1
|
||||
src.container_type = OPENCONTAINER
|
||||
src.updateUsrDialog()
|
||||
return 1 // Disables the after-attack so we don't spray the floor/user.
|
||||
else
|
||||
@@ -119,7 +119,7 @@
|
||||
src.dirty = 0 // It's clean!
|
||||
src.broken = 0 // just to be sure
|
||||
src.icon_state = "mw"
|
||||
src.container_type = OPENCONTAINER_1
|
||||
src.container_type = OPENCONTAINER
|
||||
|
||||
else if(src.dirty==100) // The microwave is all dirty so can't be used!
|
||||
to_chat(user, "<span class='warning'>It's dirty!</span>")
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
return
|
||||
else
|
||||
bomb_timer = input(user, "Set the [bomb] timer from [BOMB_TIMER_MIN] to [BOMB_TIMER_MAX].", bomb, bomb_timer) as num
|
||||
bomb_timer = Clamp(Ceiling(bomb_timer / 2), BOMB_TIMER_MIN, BOMB_TIMER_MAX)
|
||||
bomb_timer = CLAMP(CEILING(bomb_timer / 2, 1), BOMB_TIMER_MIN, BOMB_TIMER_MAX)
|
||||
bomb_defused = FALSE
|
||||
|
||||
var/message = "[ADMIN_LOOKUPFLW(user)] has trapped a [src] with [bomb] set to [bomb_timer * 2] seconds."
|
||||
|
||||
@@ -132,7 +132,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
|
||||
/datum/chatOutput/proc/setMusicVolume(volume = "")
|
||||
if(volume)
|
||||
adminMusicVolume = Clamp(text2num(volume), 0, 100)
|
||||
adminMusicVolume = CLAMP(text2num(volume), 0, 100)
|
||||
|
||||
//Sends client connection details to the chat to handle and save
|
||||
/datum/chatOutput/proc/sendClientData()
|
||||
|
||||
@@ -13,7 +13,7 @@ body {
|
||||
background: #fff;
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 9pt;
|
||||
line-height: 1.4;
|
||||
line-height: 1.2;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
word-wrap: break-word;
|
||||
@@ -399,6 +399,9 @@ h1.alert, h2.alert {color: #000000;}
|
||||
|
||||
.love {color: #FF69Bf;}
|
||||
.lovebold {color: #FF69Bf; font-weight: bold;}
|
||||
.monkeyhive {color: #774704;}
|
||||
.monkeylead {color: #774704; font-size: 2;}
|
||||
|
||||
|
||||
.connectionClosed, .fatalError {background: red; color: white; padding: 5px;}
|
||||
.connectionClosed.restored {background: green;}
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
<div class="sub" id="subOptions">
|
||||
<a href="#" class="subCell decreaseFont topCell" id="decreaseFont"><span>Decrease font size</span> <i class="icon-font">-</i></a>
|
||||
<a href="#" class="subCell increaseFont" id="increaseFont"><span>Increase font size</span> <i class="icon-font">+</i></a>
|
||||
<a href="#" class="subCell decreaseLineHeight" id="decreaseLineHeight"><span>Decrease line height</span> <i class="icon-text-height">-</i></a>
|
||||
<a href="#" class="subCell increaseLineHeight" id="increaseLineHeight"><span>Increase line height</span> <i class="icon-text-height">+</i></a>
|
||||
<a href="#" class="subCell togglePing" id="togglePing"><span>Toggle ping display</span> <i class="icon-circle"></i></a>
|
||||
<a href="#" class="subCell highlightTerm" id="highlightTerm"><span>Highlight string</span> <i class="icon-tag"></i></a>
|
||||
<a href="#" class="subCell saveLog" id="saveLog"><span>Save chat log</span> <i class="icon-save"></i></a>
|
||||
|
||||
@@ -593,6 +593,7 @@ $(function() {
|
||||
******************************************/
|
||||
var savedConfig = {
|
||||
'sfontSize': getCookie('fontsize'),
|
||||
'slineHeight': getCookie('lineheight'),
|
||||
'spingDisabled': getCookie('pingdisabled'),
|
||||
'shighlightTerms': getCookie('highlightterms'),
|
||||
'shighlightColor': getCookie('highlightcolor'),
|
||||
@@ -604,6 +605,10 @@ $(function() {
|
||||
$messages.css('font-size', savedConfig.sfontSize);
|
||||
internalOutput('<span class="internal boldnshit">Loaded font size setting of: '+savedConfig.sfontSize+'</span>', 'internal');
|
||||
}
|
||||
if (savedConfig.slineHeight) {
|
||||
$("body").css('line-height', savedConfig.slineHeight);
|
||||
internalOutput('<span class="internal boldnshit">Loaded line height setting of: '+savedConfig.slineHeight+'</span>', 'internal');
|
||||
}
|
||||
if (savedConfig.spingDisabled) {
|
||||
if (savedConfig.spingDisabled == 'true') {
|
||||
opts.pingDisabled = true;
|
||||
@@ -843,6 +848,28 @@ $(function() {
|
||||
internalOutput('<span class="internal boldnshit">Font size set to '+fontSize+'</span>', 'internal');
|
||||
});
|
||||
|
||||
$('#decreaseLineHeight').click(function(e) {
|
||||
var Heightline = parseFloat($("body").css('line-height'));
|
||||
var Sizefont = parseFloat($("body").css('font-size'));
|
||||
var lineheightvar = Heightline / Sizefont
|
||||
lineheightvar -= 0.1;
|
||||
lineheightvar = lineheightvar.toFixed(1)
|
||||
$("body").css({'line-height': lineheightvar});
|
||||
setCookie('lineheight', lineheightvar, 365);
|
||||
internalOutput('<span class="internal boldnshit">Line height set to '+lineheightvar+'</span>', 'internal');
|
||||
});
|
||||
|
||||
$('#increaseLineHeight').click(function(e) {
|
||||
var Heightline = parseFloat($("body").css('line-height'));
|
||||
var Sizefont = parseFloat($("body").css('font-size'));
|
||||
var lineheightvar = Heightline / Sizefont
|
||||
lineheightvar += 0.1;
|
||||
lineheightvar = lineheightvar.toFixed(1)
|
||||
$("body").css({'line-height': lineheightvar});
|
||||
setCookie('lineheight', lineheightvar, 365);
|
||||
internalOutput('<span class="internal boldnshit">Line height set to '+lineheightvar+'</span>', 'internal');
|
||||
});
|
||||
|
||||
$('#togglePing').click(function(e) {
|
||||
if (opts.pingDisabled) {
|
||||
$('#ping').slideDown('fast');
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
var/begin_weekday = FALSE //If set to a weekday, then this will trigger the holiday on the above week
|
||||
var/always_celebrate = FALSE // for christmas neverending, or testing.
|
||||
|
||||
var/obj/item/drone_hat //If this is defined, drones without a default hat will spawn with this one during the holiday; check drones_as_items.dm to see this used
|
||||
|
||||
// This proc gets run before the game starts when the holiday is activated. Do festive shit here.
|
||||
/datum/holiday/proc/celebrate()
|
||||
return
|
||||
@@ -172,11 +174,13 @@
|
||||
name = "Labor Day"
|
||||
begin_day = 1
|
||||
begin_month = MAY
|
||||
drone_hat = /obj/item/clothing/head/hardhat
|
||||
|
||||
/datum/holiday/firefighter
|
||||
name = "Firefighter's Day"
|
||||
begin_day = 4
|
||||
begin_month = MAY
|
||||
drone_hat = /obj/item/clothing/head/hardhat/red
|
||||
|
||||
/datum/holiday/firefighter/getStationPrefix()
|
||||
return pick("Burning","Blazing","Plasma","Fire")
|
||||
@@ -190,6 +194,7 @@
|
||||
name = "Doctor's Day"
|
||||
begin_day = 1
|
||||
begin_month = JULY
|
||||
drone_hat = /obj/item/clothing/head/nursehat
|
||||
|
||||
/datum/holiday/UFO
|
||||
name = "UFO Day"
|
||||
@@ -221,6 +226,7 @@
|
||||
name = "Talk-Like-a-Pirate Day"
|
||||
begin_day = 19
|
||||
begin_month = SEPTEMBER
|
||||
drone_hat = /obj/item/clothing/head/pirate
|
||||
|
||||
/datum/holiday/pirate/greet()
|
||||
return "Ye be talkin' like a pirate today or else ye'r walkin' tha plank, matey!"
|
||||
@@ -321,6 +327,7 @@
|
||||
begin_week = 4
|
||||
begin_month = NOVEMBER
|
||||
begin_weekday = THURSDAY
|
||||
drone_hat = /obj/item/clothing/head/that //This is the closest we can get to a pilgrim's hat
|
||||
|
||||
/datum/holiday/thanksgiving/canada
|
||||
name = "Thanksgiving in Canada"
|
||||
@@ -384,12 +391,14 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and
|
||||
name = "Mayan Doomsday Anniversary"
|
||||
begin_day = 21
|
||||
begin_month = DECEMBER
|
||||
drone_hat = /obj/item/clothing/mask/rat/tribal
|
||||
|
||||
/datum/holiday/xmas
|
||||
name = CHRISTMAS
|
||||
begin_day = 23
|
||||
begin_day = 22
|
||||
begin_month = DECEMBER
|
||||
end_day = 25
|
||||
end_day = 27
|
||||
drone_hat = /obj/item/clothing/head/santa
|
||||
|
||||
/datum/holiday/xmas/greet()
|
||||
return "Have a merry Christmas!"
|
||||
@@ -399,6 +408,7 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and
|
||||
begin_day = 1
|
||||
begin_month = DECEMBER
|
||||
end_day = 31
|
||||
drone_hat = /obj/item/clothing/head/santa
|
||||
|
||||
/datum/holiday/festive_season/greet()
|
||||
return "Have a nice festive season!"
|
||||
@@ -421,6 +431,7 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and
|
||||
|
||||
/datum/holiday/easter
|
||||
name = EASTER
|
||||
drone_hat = /obj/item/clothing/head/rabbitears
|
||||
var/const/days_early = 1 //to make editing the holiday easier
|
||||
var/const/days_extra = 1
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
for(var/obj/item/stock_parts/micro_laser/ML in component_parts)
|
||||
var/wratemod = ML.rating * 2.5
|
||||
min_wrate = Floor(10-wratemod,1) // 7,5,2,0 Clamps at 0 and 10 You want this low
|
||||
min_wrate = FLOOR(10-wratemod,1) // 7,5,2,0 Clamps at 0 and 10 You want this low
|
||||
min_wchance = 67-(ML.rating*16) // 48,35,19,3 Clamps at 0 and 67 You want this low
|
||||
for(var/obj/item/circuitboard/machine/plantgenes/vaultcheck in component_parts)
|
||||
if(istype(vaultcheck, /obj/item/circuitboard/machine/plantgenes/vault)) // DUMB BOTANY TUTS
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
for(var/datum/plant_gene/trait/T in seed.genes)
|
||||
T.on_new(src, loc)
|
||||
seed.prepare_result(src)
|
||||
transform *= TransformUsingVariable(seed.potency, 100, 0.5) //Makes the resulting produce's sprite larger or smaller based on potency!
|
||||
transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 //Makes the resulting produce's sprite larger or smaller based on potency!
|
||||
add_juice()
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/on_grind()
|
||||
var/nutriment = reagents.get_reagent_amount("nutriment")
|
||||
if(grind_results.len)
|
||||
if(grind_results&&grind_results.len)
|
||||
for(var/i in 1 to grind_results.len)
|
||||
grind_results[grind_results[i]] = nutriment
|
||||
reagents.del_reagent("nutriment")
|
||||
@@ -154,7 +154,7 @@
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/on_juice()
|
||||
var/nutriment = reagents.get_reagent_amount("nutriment")
|
||||
if(juice_results.len)
|
||||
if(juice_results&&juice_results.len)
|
||||
for(var/i in 1 to juice_results.len)
|
||||
juice_results[juice_results[i]] = nutriment
|
||||
reagents.del_reagent("nutriment")
|
||||
|
||||
@@ -154,8 +154,8 @@
|
||||
if(!click_params || !click_params["icon-x"] || !click_params["icon-y"])
|
||||
return
|
||||
//Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf)
|
||||
W.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2)
|
||||
W.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2)
|
||||
W.pixel_x = CLAMP(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2)
|
||||
W.pixel_y = CLAMP(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
if(istype(src, seed.product)) // no adding reagents if it is just a trash item
|
||||
seed.prepare_result(src)
|
||||
transform *= TransformUsingVariable(seed.potency, 100, 0.5)
|
||||
transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5
|
||||
add_juice()
|
||||
|
||||
|
||||
|
||||
@@ -24,12 +24,6 @@
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
volume = 100
|
||||
container_type = OPENCONTAINER_1
|
||||
slot_flags = SLOT_BELT
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throw_speed = 3
|
||||
throw_range = 10
|
||||
|
||||
/obj/item/reagent_containers/spray/weedspray/Initialize()
|
||||
. = ..()
|
||||
@@ -48,12 +42,6 @@
|
||||
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
|
||||
volume = 100
|
||||
container_type = OPENCONTAINER_1
|
||||
slot_flags = SLOT_BELT
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throw_speed = 3
|
||||
throw_range = 10
|
||||
|
||||
/obj/item/reagent_containers/spray/pestspray/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -712,8 +712,8 @@
|
||||
else if(transfer_amount) // Droppers, cans, beakers, what have you.
|
||||
visi_msg="[user] uses [reagent_source] on [target]"
|
||||
irrigate = 1
|
||||
// Beakers, bottles, buckets, etc. Can't use is_open_container though.
|
||||
if(istype(reagent_source, /obj/item/reagent_containers/glass/))
|
||||
// Beakers, bottles, buckets, etc.
|
||||
if(reagent_source.is_drainable())
|
||||
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
|
||||
|
||||
if(irrigate && transfer_amount > 30 && reagent_source.reagents.total_volume >= 30 && using_irrigation)
|
||||
@@ -881,26 +881,26 @@
|
||||
|
||||
/// Tray Setters - The following procs adjust the tray or plants variables, and make sure that the stat doesn't go out of bounds.///
|
||||
/obj/machinery/hydroponics/proc/adjustNutri(adjustamt)
|
||||
nutrilevel = Clamp(nutrilevel + adjustamt, 0, maxnutri)
|
||||
nutrilevel = CLAMP(nutrilevel + adjustamt, 0, maxnutri)
|
||||
|
||||
/obj/machinery/hydroponics/proc/adjustWater(adjustamt)
|
||||
waterlevel = Clamp(waterlevel + adjustamt, 0, maxwater)
|
||||
waterlevel = CLAMP(waterlevel + adjustamt, 0, maxwater)
|
||||
|
||||
if(adjustamt>0)
|
||||
adjustToxic(-round(adjustamt/4))//Toxicity dilutation code. The more water you put in, the lesser the toxin concentration.
|
||||
|
||||
/obj/machinery/hydroponics/proc/adjustHealth(adjustamt)
|
||||
if(myseed && !dead)
|
||||
plant_health = Clamp(plant_health + adjustamt, 0, myseed.endurance)
|
||||
plant_health = CLAMP(plant_health + adjustamt, 0, myseed.endurance)
|
||||
|
||||
/obj/machinery/hydroponics/proc/adjustToxic(adjustamt)
|
||||
toxic = Clamp(toxic + adjustamt, 0, 100)
|
||||
toxic = CLAMP(toxic + adjustamt, 0, 100)
|
||||
|
||||
/obj/machinery/hydroponics/proc/adjustPests(adjustamt)
|
||||
pestlevel = Clamp(pestlevel + adjustamt, 0, 10)
|
||||
pestlevel = CLAMP(pestlevel + adjustamt, 0, 10)
|
||||
|
||||
/obj/machinery/hydroponics/proc/adjustWeeds(adjustamt)
|
||||
weedlevel = Clamp(weedlevel + adjustamt, 0, 10)
|
||||
weedlevel = CLAMP(weedlevel + adjustamt, 0, 10)
|
||||
|
||||
/obj/machinery/hydroponics/proc/spawnplant() // why would you put strange reagent in a hydro tray you monster I bet you also feed them blood
|
||||
var/list/livingplants = list(/mob/living/simple_animal/hostile/tree, /mob/living/simple_animal/hostile/killertomato)
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
/// Setters procs ///
|
||||
/obj/item/seeds/proc/adjust_yield(adjustamt)
|
||||
if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable
|
||||
yield = Clamp(yield + adjustamt, 0, 10)
|
||||
yield = CLAMP(yield + adjustamt, 0, 10)
|
||||
|
||||
if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism))
|
||||
yield = 1 // Mushrooms always have a minimum yield of 1.
|
||||
@@ -179,39 +179,39 @@
|
||||
C.value = yield
|
||||
|
||||
/obj/item/seeds/proc/adjust_lifespan(adjustamt)
|
||||
lifespan = Clamp(lifespan + adjustamt, 10, 100)
|
||||
lifespan = CLAMP(lifespan + adjustamt, 10, 100)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan)
|
||||
if(C)
|
||||
C.value = lifespan
|
||||
|
||||
/obj/item/seeds/proc/adjust_endurance(adjustamt)
|
||||
endurance = Clamp(endurance + adjustamt, 10, 100)
|
||||
endurance = CLAMP(endurance + adjustamt, 10, 100)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance)
|
||||
if(C)
|
||||
C.value = endurance
|
||||
|
||||
/obj/item/seeds/proc/adjust_production(adjustamt)
|
||||
if(yield != -1)
|
||||
production = Clamp(production + adjustamt, 1, 10)
|
||||
production = CLAMP(production + adjustamt, 1, 10)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production)
|
||||
if(C)
|
||||
C.value = production
|
||||
|
||||
/obj/item/seeds/proc/adjust_potency(adjustamt)
|
||||
if(potency != -1)
|
||||
potency = Clamp(potency + adjustamt, 0, 100)
|
||||
potency = CLAMP(potency + adjustamt, 0, 100)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency)
|
||||
if(C)
|
||||
C.value = potency
|
||||
|
||||
/obj/item/seeds/proc/adjust_weed_rate(adjustamt)
|
||||
weed_rate = Clamp(weed_rate + adjustamt, 0, 10)
|
||||
weed_rate = CLAMP(weed_rate + adjustamt, 0, 10)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate)
|
||||
if(C)
|
||||
C.value = weed_rate
|
||||
|
||||
/obj/item/seeds/proc/adjust_weed_chance(adjustamt)
|
||||
weed_chance = Clamp(weed_chance + adjustamt, 0, 67)
|
||||
weed_chance = CLAMP(weed_chance + adjustamt, 0, 67)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance)
|
||||
if(C)
|
||||
C.value = weed_chance
|
||||
@@ -220,7 +220,7 @@
|
||||
|
||||
/obj/item/seeds/proc/set_yield(adjustamt)
|
||||
if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable
|
||||
yield = Clamp(adjustamt, 0, 10)
|
||||
yield = CLAMP(adjustamt, 0, 10)
|
||||
|
||||
if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism))
|
||||
yield = 1 // Mushrooms always have a minimum yield of 1.
|
||||
@@ -229,39 +229,39 @@
|
||||
C.value = yield
|
||||
|
||||
/obj/item/seeds/proc/set_lifespan(adjustamt)
|
||||
lifespan = Clamp(adjustamt, 10, 100)
|
||||
lifespan = CLAMP(adjustamt, 10, 100)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan)
|
||||
if(C)
|
||||
C.value = lifespan
|
||||
|
||||
/obj/item/seeds/proc/set_endurance(adjustamt)
|
||||
endurance = Clamp(adjustamt, 10, 100)
|
||||
endurance = CLAMP(adjustamt, 10, 100)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance)
|
||||
if(C)
|
||||
C.value = endurance
|
||||
|
||||
/obj/item/seeds/proc/set_production(adjustamt)
|
||||
if(yield != -1)
|
||||
production = Clamp(adjustamt, 1, 10)
|
||||
production = CLAMP(adjustamt, 1, 10)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production)
|
||||
if(C)
|
||||
C.value = production
|
||||
|
||||
/obj/item/seeds/proc/set_potency(adjustamt)
|
||||
if(potency != -1)
|
||||
potency = Clamp(adjustamt, 0, 100)
|
||||
potency = CLAMP(adjustamt, 0, 100)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency)
|
||||
if(C)
|
||||
C.value = potency
|
||||
|
||||
/obj/item/seeds/proc/set_weed_rate(adjustamt)
|
||||
weed_rate = Clamp(adjustamt, 0, 10)
|
||||
weed_rate = CLAMP(adjustamt, 0, 10)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate)
|
||||
if(C)
|
||||
C.value = weed_rate
|
||||
|
||||
/obj/item/seeds/proc/set_weed_chance(adjustamt)
|
||||
weed_chance = Clamp(adjustamt, 0, 67)
|
||||
weed_chance = CLAMP(adjustamt, 0, 67)
|
||||
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance)
|
||||
if(C)
|
||||
C.value = weed_chance
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
var/charge_tick = FALSE
|
||||
var/charge_delay = 4
|
||||
var/use_cyborg_cell = TRUE
|
||||
max_integrity = 50
|
||||
armor = list(melee = 50, bullet = 70, laser = 70, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 0, acid = 0)
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/check_interactivity(mob/user)
|
||||
return user.canUseTopic(src,be_close = TRUE)
|
||||
@@ -30,8 +32,6 @@
|
||||
START_PROCESSING(SScircuit, src)
|
||||
materials[MAT_METAL] = round((max_complexity + max_components) / 4) * SScircuit.cost_multiplier
|
||||
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/Destroy()
|
||||
STOP_PROCESSING(SScircuit, src)
|
||||
return ..()
|
||||
@@ -273,22 +273,9 @@
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity)
|
||||
for(var/obj/item/integrated_circuit/input/sensor/S in assembly_components)
|
||||
if(!proximity)
|
||||
if(istype(S,/obj/item/integrated_circuit/input/sensor/ranged)||(!user))
|
||||
if(user.client)
|
||||
if(!(target in view(user.client)))
|
||||
continue
|
||||
else
|
||||
if(!(target in view(user)))
|
||||
continue
|
||||
else
|
||||
continue
|
||||
S.set_pin_data(IC_OUTPUT, 1, WEAKREF(target))
|
||||
S.check_then_do_work()
|
||||
S.scan(target)
|
||||
|
||||
visible_message("<span class='notice'> [user] waves [src] around [target].</span>")
|
||||
for(var/obj/item/integrated_circuit/input/S in assembly_components)
|
||||
if(S.sense(target,user,proximity))
|
||||
visible_message("<span class='notice'> [user] waves [src] around [target].</span>")
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/screwdriver_act(mob/living/user, obj/item/S)
|
||||
@@ -326,8 +313,11 @@
|
||||
interact(user)
|
||||
return TRUE
|
||||
else
|
||||
for(var/obj/item/integrated_circuit/input/S in assembly_components)
|
||||
S.attackby_react(I,user,user.a_intent)
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/attack_self(mob/user)
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
@@ -391,7 +381,6 @@
|
||||
/obj/item/device/electronic_assembly/proc/get_object()
|
||||
return src
|
||||
|
||||
|
||||
// Returns the location to be used for dropping items.
|
||||
// Same as the regular drop_location(), but with checks being run on acting_object if necessary.
|
||||
/obj/item/integrated_circuit/drop_location()
|
||||
@@ -406,6 +395,7 @@
|
||||
/obj/item/device/electronic_assembly/default //The /default electronic_assemblys are to allow the introduction of the new naming scheme without breaking old saves.
|
||||
name = "type-a electronic assembly"
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/calc
|
||||
name = "type-b electronic assembly"
|
||||
icon_state = "setup_small_calc"
|
||||
@@ -507,4 +497,4 @@
|
||||
/obj/item/device/electronic_assembly/drone/arms
|
||||
name = "type-b electronic drone"
|
||||
icon_state = "setup_drone_arms"
|
||||
desc = "It's a case, for building mobile electronics with. This one is armed and dangerous."
|
||||
desc = "It's a case, for building mobile electronics with. This one is armed and dangerous."
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
data_to_show = A.name
|
||||
to_chat(user, "<span class='notice'>You write '[data_to_write ? data_to_show : "NULL"]' to the '[io]' pin of \the [io.holder].</span>")
|
||||
else if(io.io_type == PULSE_CHANNEL)
|
||||
io.holder.check_then_do_work(ignore_power = TRUE)
|
||||
io.holder.check_then_do_work(io.ord,ignore_power = TRUE)
|
||||
to_chat(user, "<span class='notice'>You pulse \the [io.holder]'s [io].</span>")
|
||||
|
||||
io.holder.interact(user) // This is to update the UI.
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
io_type_override = io_list_copy[io_entry]
|
||||
|
||||
if(io_type_override)
|
||||
io_list.Add(new io_type_override(src, io_entry, default_data, pin_type))
|
||||
io_list.Add(new io_type_override(src, io_entry, default_data, pin_type,i))
|
||||
else
|
||||
io_list.Add(new io_type(src, io_entry, default_data, pin_type))
|
||||
io_list.Add(new io_type(src, io_entry, default_data, pin_type,i))
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/proc/set_pin_data(pin_type, pin_number, datum/new_data)
|
||||
|
||||
@@ -58,6 +58,12 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
/obj/item/integrated_circuit/proc/any_examine(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/attackby_react(var/atom/movable/A,mob/user)
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/sense(var/atom/movable/A,mob/user,prox)
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/check_interactivity(mob/user)
|
||||
if(assembly)
|
||||
return assembly.check_interactivity(user)
|
||||
@@ -291,17 +297,18 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
return TRUE // Battery has enough.
|
||||
return FALSE // Not enough power.
|
||||
|
||||
/obj/item/integrated_circuit/proc/check_then_do_work(var/ignore_power = FALSE)
|
||||
/obj/item/integrated_circuit/proc/check_then_do_work(ord,var/ignore_power = FALSE)
|
||||
if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam.
|
||||
return
|
||||
return FALSE
|
||||
if(power_draw_per_use && !ignore_power)
|
||||
if(!check_power())
|
||||
power_fail()
|
||||
return
|
||||
return FALSE
|
||||
next_use = world.time + cooldown_per_use
|
||||
do_work()
|
||||
do_work(ord)
|
||||
return TRUE
|
||||
|
||||
/obj/item/integrated_circuit/proc/do_work()
|
||||
/obj/item/integrated_circuit/proc/do_work(ord)
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/disconnect_all()
|
||||
@@ -369,4 +376,3 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -25,14 +25,16 @@ D [1]/ ||
|
||||
var/list/linked = list()
|
||||
var/io_type = DATA_CHANNEL
|
||||
var/pin_type // IC_INPUT, IC_OUTPUT, IC_ACTIVATOR - used in saving assembly wiring
|
||||
var/ord
|
||||
|
||||
|
||||
/datum/integrated_io/New(loc, _name, _data, _pin_type)
|
||||
/datum/integrated_io/New(loc, _name, _data, _pin_type,_ord)
|
||||
name = _name
|
||||
if(_data)
|
||||
data = _data
|
||||
if(_pin_type)
|
||||
pin_type = _pin_type
|
||||
if(_ord)
|
||||
ord = _ord
|
||||
|
||||
holder = loc
|
||||
|
||||
@@ -148,7 +150,7 @@ D [1]/ ||
|
||||
/datum/integrated_io/activate/push_data()
|
||||
for(var/k in 1 to linked.len)
|
||||
var/datum/integrated_io/io = linked[k]
|
||||
io.holder.check_then_do_work()
|
||||
io.holder.check_then_do_work(io.ord)
|
||||
|
||||
/datum/integrated_io/proc/pull_data()
|
||||
for(var/k in 1 to linked.len)
|
||||
@@ -207,7 +209,7 @@ D [1]/ ||
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/activate/ask_for_pin_data(mob/user) // This just pulses the pin.
|
||||
holder.check_then_do_work(ignore_power = TRUE)
|
||||
holder.check_then_do_work(ord,ignore_power = TRUE)
|
||||
to_chat(user, "<span class='notice'>You pulse \the [holder]'s [src] pin.</span>")
|
||||
|
||||
/datum/integrated_io/activate
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// These pins can only contain integer numbers between 1 and IC_MAX_LIST_LENGTH. Null is not allowed.
|
||||
// These pins can only contain integer numbers between 0 and IC_MAX_LIST_LENGTH. Null is allowed.
|
||||
/datum/integrated_io/index
|
||||
name = "index pin"
|
||||
data = 1
|
||||
@@ -11,10 +11,10 @@
|
||||
|
||||
/datum/integrated_io/index/write_data_to_pin(new_data)
|
||||
if(isnull(new_data))
|
||||
new_data = 1
|
||||
new_data = 0
|
||||
|
||||
if(isnum(new_data))
|
||||
data = Clamp(round(new_data), 1, IC_MAX_LIST_LENGTH)
|
||||
data = CLAMP(round(new_data), 0, IC_MAX_LIST_LENGTH)
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/index/display_pin_type()
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
icon_state = "chemical_cell"
|
||||
extended_desc = "This is effectively an internal beaker. It will consume and produce power from plasma, slime jelly, welding fuel, carbon,\
|
||||
ethanol, nutriments and blood , in order of decreasing efficiency. It will consume fuel only if the battery can take more energy."
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_REF)
|
||||
|
||||
@@ -30,10 +30,9 @@
|
||||
/obj/item/integrated_circuit/arithmetic/addition/do_work()
|
||||
var/result = 0
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result + I.data
|
||||
var/I = get_pin_data(IC_INPUT, k)
|
||||
if(isnum(I))
|
||||
result += I
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
@@ -56,13 +55,10 @@
|
||||
return
|
||||
var/result = A.data
|
||||
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
if(I == A)
|
||||
continue
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result - I.data
|
||||
for(var/k in 2 to inputs.len)
|
||||
var/I = get_pin_data(IC_INPUT, k)
|
||||
if(isnum(I))
|
||||
result -= I
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
@@ -85,13 +81,10 @@
|
||||
if(!isnum(A.data))
|
||||
return
|
||||
var/result = A.data
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
if(I == A)
|
||||
continue
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result * I.data
|
||||
for(var/k in 2 to inputs.len)
|
||||
var/I = get_pin_data(IC_INPUT, k)
|
||||
if(isnum(I))
|
||||
result *= I
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
@@ -114,13 +107,12 @@
|
||||
return
|
||||
var/result = A.data
|
||||
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
if(I == A)
|
||||
continue
|
||||
I.pull_data()
|
||||
if(isnum(I.data) && I.data != 0) //No runtimes here.
|
||||
result = result / I.data
|
||||
|
||||
for(var/k in 2 to inputs.len)
|
||||
var/I = get_pin_data(IC_INPUT, k)
|
||||
if(isnum(I) && (I != 0))
|
||||
result /= I
|
||||
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
@@ -228,12 +220,11 @@
|
||||
/obj/item/integrated_circuit/arithmetic/average/do_work()
|
||||
var/result = 0
|
||||
var/inputs_used = 0
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
for(var/k in 2 to inputs.len)
|
||||
var/I = get_pin_data(IC_INPUT, k)
|
||||
if(isnum(I))
|
||||
inputs_used++
|
||||
result = result + I.data
|
||||
result += I
|
||||
|
||||
if(inputs_used)
|
||||
result = result / inputs_used
|
||||
@@ -288,11 +279,10 @@
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/square_root/do_work()
|
||||
var/result = 0
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = sqrt(I.data)
|
||||
for(var/k in 2 to inputs.len)
|
||||
var/I = get_pin_data(IC_INPUT, k)
|
||||
if(isnum(I))
|
||||
result += sqrt(I)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
|
||||
@@ -160,10 +160,10 @@
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenator/do_work()
|
||||
var/result = null
|
||||
for(var/datum/integrated_io/I in inputs)
|
||||
I.pull_data()
|
||||
if(!isnull(I.data))
|
||||
result = result + I.data
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/I = get_pin_data(IC_INPUT, k)
|
||||
if(!isnull(I))
|
||||
result = result + I
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
@@ -265,7 +265,7 @@
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = ToDegrees(incoming)
|
||||
result = TODEGREES(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
@@ -283,7 +283,7 @@
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = ToRadians(incoming)
|
||||
result = TORADIANS(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/do_work()
|
||||
var/output_index = get_pin_data(IC_INPUT, 1)
|
||||
|
||||
if(output_index == Clamp(output_index, 1, number_of_pins))
|
||||
if(output_index == CLAMP(output_index, 1, number_of_pins))
|
||||
activate_pin(round(output_index + 1 ,1))
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/medium
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
|
||||
if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
|
||||
var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100
|
||||
var/missing_health = H.getMaxHealth() - H.health
|
||||
|
||||
@@ -143,6 +143,49 @@
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/slime_scanner
|
||||
name = "slime_scanner"
|
||||
desc = "A very small version of the xenobio analyser. This allows the machine to know every needed properties of slime."
|
||||
icon_state = "medscan_adv"
|
||||
complexity = 12
|
||||
inputs = list("\<REF\> target")
|
||||
outputs = list(
|
||||
"colour" = IC_PINTYPE_STRING,
|
||||
"adult" = IC_PINTYPE_BOOLEAN,
|
||||
"nutrition" = IC_PINTYPE_NUMBER,
|
||||
"charge" = IC_PINTYPE_NUMBER,
|
||||
"health" = IC_PINTYPE_NUMBER,
|
||||
"possible mutation" = IC_PINTYPE_LIST,
|
||||
"genetic destability"= IC_PINTYPE_NUMBER,
|
||||
"slime core amount" = IC_PINTYPE_NUMBER,
|
||||
"Growth progress" = IC_PINTYPE_NUMBER,
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 80
|
||||
|
||||
/obj/item/integrated_circuit/input/slime_scanner/do_work()
|
||||
var/mob/living/simple_animal/slime/T = get_pin_data_as_type(IC_INPUT, 1, /mob/living/simple_animal/slime)
|
||||
if(!isslime(T)) //Invalid input
|
||||
return
|
||||
if(T in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, T.colour)
|
||||
set_pin_data(IC_OUTPUT, 2, T.is_adult)
|
||||
set_pin_data(IC_OUTPUT, 3, T.nutrition/T.get_max_nutrition())
|
||||
set_pin_data(IC_OUTPUT, 4, T.powerlevel)
|
||||
set_pin_data(IC_OUTPUT, 5, round(T.health/T.maxHealth,0.01)*100)
|
||||
set_pin_data(IC_OUTPUT, 6, uniqueList(T.slime_mutation))
|
||||
set_pin_data(IC_OUTPUT, 7, T.mutation_chance)
|
||||
set_pin_data(IC_OUTPUT, 8, T.cores)
|
||||
set_pin_data(IC_OUTPUT, 9, T.amount_grown/SLIME_EVOLUTION_THRESHOLD)
|
||||
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/plant_scanner
|
||||
name = "integrated plant analyzer"
|
||||
desc = "A very small version of the plant analyser. This allows the machine to know all valuable params of plants in trays. \
|
||||
@@ -180,7 +223,7 @@
|
||||
return
|
||||
for(var/i=1, i<=outputs.len, i++)
|
||||
set_pin_data(IC_OUTPUT, i, null)
|
||||
if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
|
||||
if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
|
||||
if(H.myseed)
|
||||
set_pin_data(IC_OUTPUT, 1, H.myseed.plantname)
|
||||
set_pin_data(IC_OUTPUT, 2, H.age)
|
||||
@@ -228,7 +271,7 @@
|
||||
return
|
||||
for(var/i=1, i<=outputs.len, i++)
|
||||
set_pin_data(IC_OUTPUT, i, null)
|
||||
if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
|
||||
if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
|
||||
if(H.myseed)
|
||||
for(var/datum/plant_gene/reagent/G in H.myseed.genes)
|
||||
greagents.Add(G.get_name())
|
||||
@@ -373,7 +416,7 @@
|
||||
var/rad = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(isnum(rad))
|
||||
rad = Clamp(rad, 0, 8)
|
||||
rad = CLAMP(rad, 0, 8)
|
||||
radius = rad
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator_list/do_work()
|
||||
@@ -426,7 +469,7 @@
|
||||
/obj/item/integrated_circuit/input/advanced_locator/on_data_written()
|
||||
var/rad = get_pin_data(IC_INPUT, 2)
|
||||
if(isnum(rad))
|
||||
rad = Clamp(rad, 0, 8)
|
||||
rad = CLAMP(rad, 0, 8)
|
||||
radius = rad
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator/do_work()
|
||||
@@ -671,12 +714,15 @@
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 120
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor/proc/scan(var/atom/A)
|
||||
/obj/item/integrated_circuit/input/sensor/sense(var/atom/A,mob/user,prox)
|
||||
if(!prox)
|
||||
return FALSE
|
||||
if(!check_then_do_work())
|
||||
return FALSE
|
||||
var/ignore_bags = get_pin_data(IC_INPUT, 1)
|
||||
if(ignore_bags)
|
||||
if(istype(A, /obj/item/storage))
|
||||
return FALSE
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
@@ -694,6 +740,52 @@
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 120
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor/ranged/sense(var/atom/A,mob/user)
|
||||
if(!user)
|
||||
return FALSE
|
||||
if(user.client)
|
||||
if(!(A in view(user.client)))
|
||||
return FALSE
|
||||
else
|
||||
if(!(A in view(user)))
|
||||
return FALSE
|
||||
if(!check_then_do_work())
|
||||
return FALSE
|
||||
var/ignore_bags = get_pin_data(IC_INPUT, 1)
|
||||
if(ignore_bags)
|
||||
if(istype(A, /obj/item/storage))
|
||||
return FALSE
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/integrated_circuit/input/objscaner
|
||||
name = "scaner"
|
||||
desc = "Scans and obtains a reference for any objects you use on assembly."
|
||||
extended_desc = "If 'put down' pin is set to true, assembly will take scanned object from your hands to it's location.\
|
||||
useful for interaction with grabber. Scaner works only with help intent."
|
||||
icon_state = "recorder"
|
||||
complexity = 4
|
||||
inputs = list("put down" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list("scanned" = IC_PINTYPE_REF)
|
||||
activators = list("on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/input/objscaner/attackby_react(var/atom/A,var/mob/user,intent)
|
||||
if(intent!=INTENT_HELP)
|
||||
return FALSE
|
||||
if(!check_then_do_work())
|
||||
return FALSE
|
||||
var/pu = get_pin_data(IC_INPUT, 1)
|
||||
if(pu)
|
||||
user.transferItemToLoc(A,drop_location())
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/integrated_circuit/input/internalbm
|
||||
name = "internal battery monitor"
|
||||
desc = "This monitors the charge level of an internal battery."
|
||||
@@ -760,3 +852,38 @@
|
||||
activate_pin(2)
|
||||
push_data()
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/input/ntnetsc
|
||||
name = "NTnet scaner"
|
||||
desc = "This can return NTnet id of component insi given object, if there is any."
|
||||
icon_state = "signalsc"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
complexity = 2
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"id" = IC_PINTYPE_STRING
|
||||
)
|
||||
activators = list("read" = IC_PINTYPE_PULSE_IN, "found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/ntnetsc/do_work()
|
||||
|
||||
var/atom/AM = get_pin_data_as_type(IC_INPUT, 1, /atom)
|
||||
var/list/processing_list = list(AM)
|
||||
var/datum/component/ntnet_interface/net = null
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
while(processing_list.len && !net)
|
||||
var/atom/A = processing_list[1]
|
||||
processing_list.Cut(1, 2)
|
||||
//Byond does not allow things to be in multiple contents, or double parent-child hierarchies, so only += is needed
|
||||
//This is also why we don't need to check against assembled as we go along
|
||||
processing_list += A.contents
|
||||
net = A.GetComponent(/datum/component/ntnet_interface)
|
||||
if(net)
|
||||
set_pin_data(IC_OUTPUT, 1, net.hardware_id)
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
push_data()
|
||||
return
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "logic gate"
|
||||
desc = "This tiny chip will decide for you!"
|
||||
extended_desc = "Logic circuits will treat a null, 0, and a \"\" string value as FALSE and anything else as TRUE."
|
||||
complexity = 3
|
||||
complexity = 1
|
||||
outputs = list("result")
|
||||
activators = list("compare" = IC_PINTYPE_PULSE_IN)
|
||||
category_text = "Logic"
|
||||
|
||||
@@ -93,8 +93,8 @@
|
||||
yo.data = round(yo.data, 1)
|
||||
|
||||
var/turf/T = get_turf(assembly)
|
||||
var/target_x = Clamp(T.x + xo.data, 0, world.maxx)
|
||||
var/target_y = Clamp(T.y + yo.data, 0, world.maxy)
|
||||
var/target_x = CLAMP(T.x + xo.data, 0, world.maxx)
|
||||
var/target_y = CLAMP(T.y + yo.data, 0, world.maxy)
|
||||
|
||||
shootAt(locate(target_x, target_y, T.z))
|
||||
|
||||
@@ -155,9 +155,11 @@
|
||||
if(isnum(wanted_dir.data))
|
||||
if(step(assembly, wanted_dir.data))
|
||||
activate_pin(2)
|
||||
return
|
||||
else
|
||||
activate_pin(3)
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade
|
||||
name = "grenade primer"
|
||||
@@ -210,7 +212,7 @@
|
||||
var/datum/integrated_io/detonation_time = inputs[1]
|
||||
var/dt
|
||||
if(isnum(detonation_time.data) && detonation_time.data > 0)
|
||||
dt = Clamp(detonation_time.data, 1, 12)*10
|
||||
dt = CLAMP(detonation_time.data, 1, 12)*10
|
||||
else
|
||||
dt = 15
|
||||
addtimer(CALLBACK(attached_grenade, /obj/item/grenade.proc/prime), dt)
|
||||
@@ -247,9 +249,14 @@
|
||||
/obj/item/integrated_circuit/manipulation/plant_module/do_work()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/machinery/hydroponics/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics)
|
||||
if(!istype(AM)) //Invalid input
|
||||
var/obj/OM = get_pin_data_as_type(IC_INPUT, 1, /obj)
|
||||
if(istype(OM,/obj/structure/spacevine) && get_pin_data(IC_INPUT, 2) == 2)
|
||||
qdel(OM)
|
||||
activate_pin(2)
|
||||
return
|
||||
var/obj/machinery/hydroponics/AM = OM
|
||||
if(!istype(AM)) //Invalid input
|
||||
return FALSE
|
||||
var/mob/living/M = get_turf(AM)
|
||||
if(!M.Adjacent(T))
|
||||
return //Can't reach
|
||||
@@ -276,6 +283,7 @@
|
||||
qdel(AM.myseed)
|
||||
AM.myseed = null
|
||||
AM.weedlevel = 0 //Has a side effect of cleaning up those nasty weeds
|
||||
AM.dead = 0
|
||||
AM.update_icon()
|
||||
else
|
||||
activate_pin(2)
|
||||
@@ -284,7 +292,7 @@
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber
|
||||
name = "grabber"
|
||||
desc = "A circuit with it's own inventory for small/medium items, used to grab and store things."
|
||||
desc = "A circuit with it's own inventory for tiny/small items, used to grab and store things."
|
||||
icon_state = "grabber"
|
||||
extended_desc = "The circuit accepts a reference to thing to be grabbed. It can store up to 10 things. Modes: 1 for grab. 0 for eject the first thing. -1 for eject all."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
@@ -307,7 +315,7 @@
|
||||
var/mode = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(mode == 1)
|
||||
if(check_target(AM, exclude_contents = TRUE))
|
||||
if(check_target(AM))
|
||||
if((contents.len < max_items) && (!max_w_class || AM.w_class <= max_w_class))
|
||||
AM.forceMove(src)
|
||||
if(mode == 0)
|
||||
@@ -389,9 +397,9 @@
|
||||
if(!M.temporarilyRemoveItemFromInventory(A))
|
||||
return
|
||||
|
||||
var/x_abs = Clamp(T.x + target_x_rel, 0, world.maxx)
|
||||
var/y_abs = Clamp(T.y + target_y_rel, 0, world.maxy)
|
||||
var/range = round(Clamp(sqrt(target_x_rel*target_x_rel+target_y_rel*target_y_rel),0,8),1)
|
||||
var/x_abs = CLAMP(T.x + target_x_rel, 0, world.maxx)
|
||||
var/y_abs = CLAMP(T.y + target_y_rel, 0, world.maxy)
|
||||
var/range = round(CLAMP(sqrt(target_x_rel*target_x_rel+target_y_rel*target_y_rel),0,8),1)
|
||||
|
||||
A.forceMove(drop_location())
|
||||
A.throw_at(locate(x_abs, y_abs, T.z), range, 3)
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
var/brightness = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(new_color && isnum(brightness))
|
||||
brightness = Clamp(brightness, 0, 6)
|
||||
brightness = CLAMP(brightness, 0, 6)
|
||||
light_rgb = new_color
|
||||
light_brightness = brightness
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
var/selected_sound = sounds[ID]
|
||||
if(!selected_sound)
|
||||
return
|
||||
vol = Clamp(vol ,0 , 100)
|
||||
vol = CLAMP(vol ,0 , 100)
|
||||
playsound(get_turf(src), selected_sound, vol, freq, -1)
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/on_data_written()
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define IC_SMOKE_REAGENTS_MINIMUM_UNITS 10
|
||||
|
||||
/obj/item/integrated_circuit/reagent
|
||||
category_text = "Reagent"
|
||||
resistance_flags = UNACIDABLE | FIRE_PROOF
|
||||
@@ -7,8 +9,11 @@
|
||||
. = ..()
|
||||
if(volume)
|
||||
create_reagents(volume)
|
||||
push_vol()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/proc/push_vol()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke
|
||||
name = "smoke generator"
|
||||
@@ -17,7 +22,7 @@
|
||||
extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \
|
||||
into the smoke clouds when activated. The reagents are consumed when smoke is made."
|
||||
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
volume = 100
|
||||
|
||||
complexity = 20
|
||||
@@ -29,7 +34,8 @@
|
||||
)
|
||||
activators = list(
|
||||
"create smoke" = IC_PINTYPE_PULSE_IN,
|
||||
"on smoked" = IC_PINTYPE_PULSE_OUT
|
||||
"on smoked" = IC_PINTYPE_PULSE_OUT,
|
||||
"push ref" = IC_PINTYPE_PULSE_IN
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 20
|
||||
@@ -40,24 +46,27 @@
|
||||
//reset warning only if we have reagents now
|
||||
if(changetype == ADD_REAGENT)
|
||||
notified = FALSE
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/do_work()
|
||||
var/location = get_turf(src)
|
||||
var/datum/effect_system/smoke_spread/chem/S = new
|
||||
S.attach(location)
|
||||
playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
if(S)
|
||||
S.set_up(reagents, smoke_radius, location, notified)
|
||||
if(!notified)
|
||||
notified = TRUE
|
||||
S.start()
|
||||
|
||||
if(reagents)
|
||||
reagents.clear_reagents()
|
||||
activate_pin(2)
|
||||
push_vol()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/do_work(ord)
|
||||
switch(ord)
|
||||
if(1)
|
||||
if(!reagents || (reagents.total_volume < IC_SMOKE_REAGENTS_MINIMUM_UNITS))
|
||||
return
|
||||
var/location = get_turf(src)
|
||||
var/datum/effect_system/smoke_spread/chem/S = new
|
||||
S.attach(location)
|
||||
playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
if(S)
|
||||
S.set_up(reagents, smoke_radius, location, notified)
|
||||
if(!notified)
|
||||
notified = TRUE
|
||||
S.start()
|
||||
reagents.clear_reagents()
|
||||
activate_pin(2)
|
||||
if(3)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector
|
||||
name = "integrated hypo-injector"
|
||||
@@ -66,7 +75,7 @@
|
||||
extended_desc = "This autoinjector can push reagents into another container or someone else outside of the machine. The target \
|
||||
must be adjacent to the machine, and if it is a person, they cannot be wearing thick clothing. Negative given amount makes injector suck out reagents."
|
||||
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
volume = 30
|
||||
|
||||
complexity = 20
|
||||
@@ -85,7 +94,9 @@
|
||||
activators = list(
|
||||
"inject" = IC_PINTYPE_PULSE_IN,
|
||||
"on injected" = IC_PINTYPE_PULSE_OUT,
|
||||
"on fail" = IC_PINTYPE_PULSE_OUT
|
||||
"on fail" = IC_PINTYPE_PULSE_OUT,
|
||||
"push ref" = IC_PINTYPE_PULSE_IN
|
||||
|
||||
)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 15
|
||||
@@ -93,15 +104,8 @@
|
||||
var/transfer_amount = 10
|
||||
var/busy = FALSE
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/on_reagent_change(changetype)
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
push_vol()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/on_data_written()
|
||||
var/new_amount = get_pin_data(IC_INPUT, 2)
|
||||
@@ -111,7 +115,7 @@
|
||||
else
|
||||
direction_mode = SYRINGE_INJECT
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, volume)
|
||||
new_amount = CLAMP(new_amount, 0, volume)
|
||||
transfer_amount = new_amount
|
||||
|
||||
// Hydroponics trays have no reagents holder and handle reagents in their own snowflakey way.
|
||||
@@ -127,7 +131,15 @@
|
||||
temp_reagents.clear_reagents()
|
||||
qdel(temp_reagents)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/do_work()
|
||||
/obj/item/integrated_circuit/reagent/injector/do_work(ord)
|
||||
switch(ord)
|
||||
if(1)
|
||||
inject()
|
||||
if(4)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/proc/inject()
|
||||
set waitfor = FALSE // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
var/atom/movable/acting_object = get_object()
|
||||
@@ -145,7 +157,7 @@
|
||||
return
|
||||
|
||||
if(direction_mode == SYRINGE_INJECT)
|
||||
if(!reagents.total_volume || !AM.is_injectable() || AM.reagents.total_volume >= AM.reagents.maximum_volume)
|
||||
if(!reagents.total_volume || !AM.is_injectable() || AM.reagents.holder_full())
|
||||
activate_pin(3)
|
||||
return
|
||||
|
||||
@@ -156,12 +168,8 @@
|
||||
return
|
||||
|
||||
//Always log attemped injections for admins
|
||||
var/list/rinject = list()
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
rinject += R.name
|
||||
var/contained = english_list(rinject)
|
||||
|
||||
add_logs(src, L, "attemped to inject", addition="which had [contained]") //TODO: proper logging (maybe last touched and assembled)
|
||||
var/contained = reagents.log_list()
|
||||
add_logs(src, L, "attemped to inject", addition="which had [contained]")
|
||||
L.visible_message("<span class='danger'>[acting_object] is trying to inject [L]!</span>", \
|
||||
"<span class='userdanger'>[acting_object] is trying to inject you!</span>")
|
||||
busy = TRUE
|
||||
@@ -169,6 +177,7 @@
|
||||
var/fraction = min(transfer_amount/reagents.total_volume, 1)
|
||||
reagents.reaction(L, INJECT, fraction)
|
||||
reagents.trans_to(L, transfer_amount)
|
||||
add_logs(src, L, "injected", addition="which had [contained]")
|
||||
L.visible_message("<span class='danger'>[acting_object] injects [L] with its needle!</span>", \
|
||||
"<span class='userdanger'>[acting_object] injects you with its needle!</span>")
|
||||
else
|
||||
@@ -184,7 +193,7 @@
|
||||
activate_pin(3)
|
||||
return
|
||||
|
||||
var/tramount = Clamp(transfer_amount, 0, reagents.total_volume)
|
||||
var/tramount = CLAMP(transfer_amount, 0, reagents.total_volume)
|
||||
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
@@ -235,7 +244,7 @@
|
||||
else
|
||||
direction_mode = SYRINGE_INJECT
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, 50)
|
||||
new_amount = CLAMP(new_amount, 0, 50)
|
||||
transfer_amount = new_amount
|
||||
|
||||
/obj/item/integrated_circuit/reagent/pump/do_work()
|
||||
@@ -263,8 +272,7 @@
|
||||
activate_pin(2)
|
||||
return
|
||||
|
||||
// FALSE in those procs makes mobs invalid targets.
|
||||
if(!source.is_drawable(FALSE) || !target.is_injectable(FALSE))
|
||||
if(!source.is_drainable() || !target.is_refillable())
|
||||
return
|
||||
|
||||
source.reagents.trans_to(target, transfer_amount)
|
||||
@@ -276,7 +284,7 @@
|
||||
icon_state = "reagent_storage"
|
||||
extended_desc = "This is effectively an internal beaker."
|
||||
|
||||
container_type = OPENCONTAINER_1
|
||||
container_type = OPENCONTAINER
|
||||
volume = 60
|
||||
|
||||
complexity = 4
|
||||
@@ -285,17 +293,15 @@
|
||||
"volume used" = IC_PINTYPE_NUMBER,
|
||||
"self reference" = IC_PINTYPE_REF
|
||||
)
|
||||
activators = list()
|
||||
activators = list("push ref" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/interact(mob/user)
|
||||
/obj/item/integrated_circuit/reagent/storage/do_work()
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/on_reagent_change(changetype)
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
push_vol()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/cryo
|
||||
name = "cryo reagent storage"
|
||||
@@ -310,6 +316,7 @@
|
||||
. = ..()
|
||||
reagents.set_reacting(FALSE)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/big
|
||||
name = "big reagent storage"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 180u."
|
||||
@@ -321,6 +328,99 @@
|
||||
complexity = 16
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/grinder
|
||||
name = "reagent grinder"
|
||||
desc = "This is reagent grinder.It accepts ref to something and refines it into reagents. Can store up to 100u."
|
||||
icon_state = "blender"
|
||||
extended_desc = ""
|
||||
inputs = list(
|
||||
"target" = IC_PINTYPE_REF,
|
||||
)
|
||||
outputs = list(
|
||||
"volume used" = IC_PINTYPE_NUMBER,
|
||||
"self reference" = IC_PINTYPE_REF
|
||||
)
|
||||
activators = list(
|
||||
"grind" = IC_PINTYPE_PULSE_IN,
|
||||
"on grind" = IC_PINTYPE_PULSE_OUT,
|
||||
"on fail" = IC_PINTYPE_PULSE_OUT,
|
||||
"push ref" = IC_PINTYPE_PULSE_IN
|
||||
)
|
||||
volume = 100
|
||||
power_draw_per_use = 150
|
||||
complexity = 16
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/grinder/do_work(ord)
|
||||
switch(ord)
|
||||
if(1)
|
||||
grind()
|
||||
if(4)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/grinder/proc/grind()
|
||||
if(reagents.total_volume >= reagents.maximum_volume)
|
||||
activate_pin(3)
|
||||
return FALSE
|
||||
var/obj/item/I = get_pin_data_as_type(IC_INPUT, 1, /obj/item)
|
||||
if(istype(I)&&(I.grind_results)&&check_target(I)&&(I.on_grind(src) != -1))
|
||||
reagents.add_reagent_list(I.grind_results)
|
||||
if(I.reagents)
|
||||
I.reagents.trans_to(src, I.reagents.total_volume)
|
||||
qdel(I)
|
||||
activate_pin(2)
|
||||
return TRUE
|
||||
activate_pin(3)
|
||||
return FALSE
|
||||
|
||||
obj/item/integrated_circuit/reagent/storage/juicer
|
||||
name = "reagent juicer"
|
||||
desc = "This is reagent juicer.It accepts ref to something and refines it into reagents. Can store up to 100u."
|
||||
icon_state = "blender"
|
||||
extended_desc = ""
|
||||
inputs = list(
|
||||
"target" = IC_PINTYPE_REF,
|
||||
)
|
||||
outputs = list(
|
||||
"volume used" = IC_PINTYPE_NUMBER,
|
||||
"self reference" = IC_PINTYPE_REF
|
||||
)
|
||||
activators = list(
|
||||
"juice" = IC_PINTYPE_PULSE_IN,
|
||||
"on juice" = IC_PINTYPE_PULSE_OUT,
|
||||
"on fail" = IC_PINTYPE_PULSE_OUT,
|
||||
"push ref" = IC_PINTYPE_PULSE_IN
|
||||
)
|
||||
volume = 100
|
||||
power_draw_per_use = 150
|
||||
complexity = 16
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/juicer/do_work(ord)
|
||||
switch(ord)
|
||||
if(1)
|
||||
juice()
|
||||
if(4)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/juicer/proc/juice()
|
||||
if(reagents.total_volume >= reagents.maximum_volume)
|
||||
activate_pin(3)
|
||||
return FALSE
|
||||
var/obj/item/I = get_pin_data_as_type(IC_INPUT, 1, /obj/item)
|
||||
if(istype(I)&&check_target(I)&&(I.juice_results)&&(I.on_juice() != -1))
|
||||
reagents.add_reagent_list(I.juice_results)
|
||||
qdel(I)
|
||||
activate_pin(2)
|
||||
return TRUE
|
||||
activate_pin(3)
|
||||
return FALSE
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/scan
|
||||
name = "reagent scanner"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. On pulse this beaker will send list of contained reagents."
|
||||
@@ -334,17 +434,22 @@
|
||||
"list of reagents" = IC_PINTYPE_LIST
|
||||
)
|
||||
activators = list(
|
||||
"scan" = IC_PINTYPE_PULSE_IN
|
||||
"scan" = IC_PINTYPE_PULSE_IN,
|
||||
"push ref" = IC_PINTYPE_PULSE_IN
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/scan/do_work()
|
||||
var/cont[0]
|
||||
for(var/datum/reagent/RE in reagents.reagent_list)
|
||||
cont += RE.id
|
||||
set_pin_data(IC_OUTPUT, 3, cont)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/scan/do_work(ord)
|
||||
switch(ord)
|
||||
if(1)
|
||||
var/cont[0]
|
||||
for(var/datum/reagent/RE in reagents.reagent_list)
|
||||
cont += RE.id
|
||||
set_pin_data(IC_OUTPUT, 3, cont)
|
||||
push_data()
|
||||
if(2)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/filter
|
||||
name = "reagent filter"
|
||||
@@ -383,7 +488,7 @@
|
||||
else
|
||||
direction_mode = SYRINGE_INJECT
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, 50)
|
||||
new_amount = CLAMP(new_amount, 0, 50)
|
||||
transfer_amount = new_amount
|
||||
|
||||
/obj/item/integrated_circuit/reagent/filter/do_work()
|
||||
@@ -415,3 +520,45 @@
|
||||
activate_pin(2)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/heater
|
||||
name = "chemical heater"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. Will heat or freeze reagents \
|
||||
to target temperature, when turned on."
|
||||
icon_state = "heater"
|
||||
container_type = OPENCONTAINER
|
||||
complexity = 8
|
||||
inputs = list(
|
||||
"target temperature" = IC_PINTYPE_NUMBER,
|
||||
"on" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
inputs_default = list("1" = 300)
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF,"temperature" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
var/heater_coefficient = 0.1
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/heater/on_data_written()
|
||||
if(get_pin_data(IC_INPUT, 2))
|
||||
power_draw_idle = 30
|
||||
else
|
||||
power_draw_idle = 0
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/heater/Initialize()
|
||||
.=..()
|
||||
START_PROCESSING(SScircuit, src)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/heater/Destroy()
|
||||
STOP_PROCESSING(SScircuit, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/heater/process()
|
||||
if(power_draw_idle)
|
||||
var/target_temperature = get_pin_data(IC_INPUT, 1)
|
||||
if(reagents.chem_temp > target_temperature)
|
||||
reagents.chem_temp += min(-1, (target_temperature - reagents.chem_temp) * heater_coefficient)
|
||||
if(reagents.chem_temp < target_temperature)
|
||||
reagents.chem_temp += max(1, (target_temperature - reagents.chem_temp) * heater_coefficient)
|
||||
|
||||
reagents.chem_temp = round(reagents.chem_temp)
|
||||
reagents.handle_reactions()
|
||||
set_pin_data(IC_OUTPUT, 3, reagents.chem_temp)
|
||||
push_data()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user