Merge branch 'master' into upstream-merge-31044

This commit is contained in:
LetterJay
2017-09-30 14:53:08 -04:00
committed by GitHub
346 changed files with 9273 additions and 7009 deletions

View File

@@ -214,8 +214,6 @@ GLOBAL_PROTECT(admin_ranks)
var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use
if(!D)
continue //will occur if an invalid rank is provided
if(D.rank.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
D.associate(GLOB.directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum
else
if(!SSdbcore.Connect())

View File

@@ -34,6 +34,8 @@ GLOBAL_PROTECT(href_token)
admin_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
href_token = GenerateToken()
GLOB.admin_datums[ckey] = src
if(R.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
/proc/GenerateToken()
. = ""

View File

@@ -317,7 +317,7 @@
dat += "Replacement Game Mode: <B>[SSticker.mode.replacementmode.name]</B><BR>"
else
dat += "Current Game Mode: <B>[SSticker.mode.name]</B><BR>"
dat += "Round Duration: <B>[round(world.time / 36000)]:[add_zero("[world.time / 600 % 60]", 2)]:[world.time / 100 % 6][world.time / 100 % 10]</B><BR>"
dat += "Round Duration: <B>[DisplayTimeText(world.time - SSticker.round_start_time)]</B><BR>"
dat += "<B>Emergency shuttle</B><BR>"
if(EMERGENCY_IDLE_OR_RECALLED)
dat += "<a href='?_src_=holder;[HrefToken()];call_shuttle=1'>Call Shuttle</a><br>"

View File

@@ -114,7 +114,7 @@
end_time -= start_time
to_chat(usr, "<span class='admin'>SDQL query results: [query_text]</span>")
to_chat(usr, "<span class='admin'>SDQL query completed: [objs_all] objects selected by path, and [objs_eligible] objects executed on after WHERE filtering if applicable.</span>")
to_chat(usr, "<span class='admin'>SDQL query took [end_time/10] seconds to complete.</span>")
to_chat(usr, "<span class='admin'>SDQL query took [DisplayTimeText(end_time)] to complete.</span>")
/proc/SDQL_qdel_datum(datum/d)
qdel(d)

View File

@@ -399,9 +399,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
dat += "</b>[GLOB.TAB][TicketHref("Refresh", ref_src)][GLOB.TAB][TicketHref("Re-Title", ref_src, "retitle")]"
if(state != AHELP_ACTIVE)
dat += "[GLOB.TAB][TicketHref("Reopen", ref_src, "reopen")]"
dat += "<br><br>Opened at: [gameTimestamp(wtime = opened_at)] (Approx [(world.time - opened_at) / 600] minutes ago)"
dat += "<br><br>Opened at: [gameTimestamp(wtime = opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)"
if(closed_at)
dat += "<br>Closed at: [gameTimestamp(wtime = closed_at)] (Approx [(world.time - closed_at) / 600] minutes ago)"
dat += "<br>Closed at: [gameTimestamp(wtime = closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)"
dat += "<br><br>"
if(initiator)
dat += "<b>Actions:</b> [FullMonty(ref_src)]<br>"

View File

@@ -1,18 +1,11 @@
/client/proc/cinematic(cinematic as anything in list("explosion",null))
set name = "cinematic"
set category = "Fun"
set desc = "Shows a cinematic." // Intended for testing but I thought it might be nice for events on the rare occasion Feel free to comment it out if it's not wanted.
set hidden = 1
if(!SSticker)
return
switch(cinematic)
if("explosion")
var/parameter = input(src,"station_missed = ?","Enter Parameter",0) as num
var/override
switch(parameter)
if(1)
override = input(src,"mode = ?","Enter Parameter",null) as anything in list("nuclear emergency","gang war","fake","no override")
if(0)
override = input(src,"mode = ?","Enter Parameter",null) as anything in list("blob","nuclear emergency","AI malfunction","no override")
SSticker.station_explosion_cinematic(parameter,override)
return
/client/proc/cinematic()
set name = "cinematic"
set category = "Fun"
set desc = "Shows a cinematic." // Intended for testing but I thought it might be nice for events on the rare occasion Feel free to comment it out if it's not wanted.
set hidden = 1
if(!SSticker)
return
var/datum/cinematic/choice = input(src,"Cinematic","Choose",null) as anything in subtypesof(/datum/cinematic)
if(choice)
Cinematic(initial(choice.id),world,null)

View File

@@ -96,10 +96,16 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
to_chat(usr, .)
SSblackbox.add_details("admin_verb","Advanced ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
GLOBAL_VAR_INIT(AdminProcCaller, null)
GLOBAL_VAR(AdminProcCaller)
GLOBAL_PROTECT(AdminProcCaller)
GLOBAL_VAR_INIT(AdminProcCallCount, 0)
GLOBAL_PROTECT(AdminProcCallCount)
GLOBAL_VAR(LastAdminCalledTargetRef)
GLOBAL_PROTECT(LastAdminCalledTargetRef)
GLOBAL_VAR(LastAdminCalledTarget)
GLOBAL_PROTECT(LastAdminCalledTarget)
GLOBAL_VAR(LastAdminCalledProc)
GLOBAL_PROTECT(LastAdminCalledProc)
/proc/WrapAdminProcCall(target, procname, list/arguments)
var/current_caller = GLOB.AdminProcCaller
@@ -108,6 +114,9 @@ GLOBAL_PROTECT(AdminProcCallCount)
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>")
GLOB.LastAdminCalledProc = procname
if(target != GLOBAL_PROC)
GLOB.LastAdminCalledTargetRef = "\ref[target]"
GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you
++GLOB.AdminProcCallCount
. = world.WrapAdminProcCall(target, procname, arguments)

View File

@@ -43,8 +43,8 @@
log_admin("DEBUG: [key_name(M)] next_move = [M.next_move] lastDblClick = [M.next_click] world.time = [world.time]")
M.next_move = 1
M.next_click = 0
message_admins("[key_name_admin(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [largest_move_time/10] seconds!")
message_admins("[key_name_admin(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!")
message_admins("[key_name_admin(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [DisplayTimeText(largest_move_time)]!")
message_admins("[key_name_admin(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [DisplayTimeText(largest_click_time)]!")
message_admins("world.time = [world.time]")
SSblackbox.add_details("admin_verb","Unfreeze Everyone") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return

View File

@@ -92,6 +92,7 @@
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)
to_chat(src, "You feel the Honkmother messing with your song...")
SSblackbox.add_details("played_url", web_sound_input)
log_admin("[key_name(src)] played web sound: [web_sound_input]")
message_admins("[key_name(src)] played web sound: [web_sound_input]")
else

View File

@@ -34,6 +34,11 @@ Pipelines + Other Objects -> Pipe network
var/device_type = 0
var/list/obj/machinery/atmospherics/nodes
/obj/machinery/atmospherics/examine(mob/living/user)
..()
if(is_type_in_list(src, GLOB.ventcrawl_machinery) && user.ventcrawler)
to_chat(user, "<span class='notice'>Alt-click to crawl through it.</span>")
/obj/machinery/atmospherics/New(loc, process = TRUE)
nodes = new(device_type)
if (!armor)
@@ -300,4 +305,3 @@ Pipelines + Other Objects -> Pipe network
//Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it.
/obj/machinery/atmospherics/proc/can_see_pipes()
return TRUE

View File

@@ -33,7 +33,7 @@
var/escape_in_progress = FALSE
var/message_cooldown
var/breakout_time = 0.5
var/breakout_time = 300
/obj/machinery/atmospherics/components/unary/cryo_cell/Initialize()
. = ..()
@@ -246,9 +246,9 @@
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the glass of [src]!</span>", \
"<span class='notice'>You struggle inside [src], kicking the release with your foot... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
"<span class='notice'>You struggle inside [src], kicking the release with your foot... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear a thump from [src].</span>")
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
if(do_after(user,(breakout_time), target = src))
if(!user || user.stat != CONSCIOUS || user.loc != src )
return
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \

View File

@@ -210,7 +210,7 @@
return
if(user.ckey in team_members)
if(user.ckey in recently_dead_ckeys)
to_chat(user, "It must be more than [respawn_cooldown/10] seconds from your last death to respawn!")
to_chat(user, "It must be more than [DisplayTimeText(respawn_cooldown)] from your last death to respawn!")
return
var/client/new_team_member = user.client
if(user.mind && user.mind.current)

View File

@@ -123,7 +123,7 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
to_chat(user, "<span class='notice'>Error: No destination found.</span>")
return
if(world.time < wait)
to_chat(user, "<span class='notice'>Error: Warpspace triangulation in progress. Estimated time to completion: [round(((wait - world.time) / 10) / 60)] minutes.</span>")
to_chat(user, "<span class='notice'>Error: Warpspace triangulation in progress. Estimated time to completion: [DisplayTimeText(wait - world.time)].</span>")
return
for(var/obj/machinery/gateway/G in linked)

View File

@@ -211,6 +211,13 @@
var/datum/action/item_action/chameleon/change/chameleon_action
/obj/item/clothing/under/chameleon/ratvar
name = "ratvarian engineer's jumpsuit"
desc = "A tough jumpsuit woven from alloy threads. It can take on the appearance of other jumpsuits."
icon_state = "engine"
item_state = "engi_suit"
item_color = "engine"
/obj/item/clothing/under/chameleon/New()
..()
chameleon_action = new(src)

View File

@@ -1,11 +1,10 @@
//Ears: currently only used for headsets and earmuffs
/obj/item/clothing/ears
name = "ears"
w_class = WEIGHT_CLASS_TINY
throwforce = 0
slot_flags = SLOT_EARS
resistance_flags = 0
resistance_flags = NONE
/obj/item/clothing/ears/earmuffs
name = "earmuffs"
@@ -15,7 +14,7 @@
strip_delay = 15
equip_delay_other = 25
resistance_flags = FLAMMABLE
flags_2 = BANG_PROTECT_2|HEALS_EARS_2
flags_2 = BANG_PROTECT_2|HEALS_EARS_2
/obj/item/clothing/ears/headphones
name = "headphones"
@@ -43,4 +42,4 @@
H.update_inv_ears()
H.update_inv_neck()
H.update_inv_head()
to_chat(owner, "<span class='notice'>You turn the music [headphones_on? "on. Untz Untz Untz!" : "off."]</span>")
to_chat(owner, "<span class='notice'>You turn the music [headphones_on? "on. Untz Untz Untz!" : "off."]</span>")

View File

@@ -3,6 +3,11 @@
materials = list(MAT_GLASS = 250)
var/glass_colour_type = null //colors your vision when worn
/obj/item/clothing/glasses/examine(mob/user)
..()
if(glass_colour_type && ishuman(user))
to_chat(user, "<span class='notice'>Alt-click to toggle its colors.</span>")
/obj/item/clothing/glasses/visor_toggling()
..()
if(visor_vars_to_toggle & VISOR_VISIONFLAGS)

View File

@@ -82,6 +82,10 @@
pockets = /obj/item/storage/internal/pocket/small/detective
dog_fashion = /datum/dog_fashion/head/detective
/obj/item/clothing/head/fedora/det_hat/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to take a candy corn.</span>")
/obj/item/clothing/head/fedora/det_hat/AltClick()
..()
if(ismob(loc))
@@ -172,4 +176,4 @@
/obj/item/clothing/head/fedora/curator
name = "treasure hunter's fedora"
desc = "You got red text today kid, but it doesn't mean you have to like it."
icon_state = "curator"
icon_state = "curator"

View File

@@ -23,7 +23,7 @@
icon_state = initial(icon_state)
desc = initial(desc)
/obj/item/evidencebag/proc/evidencebagEquip(obj/item/I, mob/user)
/obj/item/evidencebag/proc/evidencebagEquip(obj/item/I, mob/user)
if(!istype(I) || I.anchored == 1)
return
@@ -43,9 +43,7 @@
if(istype(I.loc, /obj/item/storage)) //in a container.
var/obj/item/storage/U = I.loc
U.remove_from_storage(I, src)
if(user.is_holding(I))
user.dropItemToGround(I)
else
if(!user.dropItemToGround(I))
return
user.visible_message("[user] puts [I] into [src].", "<span class='notice'>You put [I] inside [src].</span>",\
@@ -62,7 +60,7 @@
add_overlay("evidence") //should look nicer for transparent stuff. not really that important, but hey.
desc = "An evidence bag containing [I]. [I.desc]"
I.loc = src
I.forceMove(src)
w_class = I.w_class
return 1

View File

@@ -88,7 +88,7 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0)
if(usrinfo) //If this info isn't null, it hasn't been added yet
desclines.Add(usrinfo)
if(silencing)
desclines += " (This error will now be silenced for [configured_error_silence_time / 600] minutes)"
desclines += " (This error will now be silenced for [DisplayTimeText(configured_error_silence_time)])"
if(GLOB.error_cache)
GLOB.error_cache.log_error(E, desclines)

View File

@@ -28,7 +28,6 @@
var/triggering //admin cancellation
/datum/round_event_control/New()
..()
if(config && !wizardevent) // Magic is unaffected by configs
earliest_start = Ceiling(earliest_start * config.events_min_time_mul)
min_players = Ceiling(min_players * config.events_min_players_mul)

View File

@@ -3,9 +3,7 @@
typepath = /datum/round_event/ghost_role/abductor
weight = 10
max_occurrences = 1
min_players = 20
gamemode_blacklist = list("nuclear","wizard","revolution","abduction")
/datum/round_event/ghost_role/abductor
@@ -17,40 +15,17 @@
if(candidates.len < 2)
return NOT_ENOUGH_PLAYERS
//Oh god why we can't have static functions
// I feel your pain, bro
var/number = SSticker.mode.abductor_teams + 1
var/datum/game_mode/abduction/temp
var/datum/game_mode/abduction/GM
if(SSticker.mode.config_tag == "abduction")
temp = SSticker.mode
GM = SSticker.mode
else
temp = new
GM = new
var/agent_mind = pick_n_take(candidates)
var/scientist_mind = pick_n_take(candidates)
var/mob/living/carbon/human/agent = makeBody(pick_n_take(candidates))
var/mob/living/carbon/human/scientist = makeBody(pick_n_take(candidates))
var/mob/living/carbon/human/agent = makeBody(agent_mind)
var/mob/living/carbon/human/scientist = makeBody(scientist_mind)
agent_mind = agent.mind
scientist_mind = scientist.mind
temp.scientists.len = number
temp.agents.len = number
temp.abductors.len = 2*number
temp.team_objectives.len = number
temp.team_names.len = number
temp.scientists[number] = scientist_mind
temp.agents[number] = agent_mind
temp.abductors |= list(agent_mind,scientist_mind)
temp.make_abductor_team(number,preset_scientist=scientist_mind,preset_agent=agent_mind)
temp.post_setup_team(number)
SSticker.mode.abductor_teams++
if(SSticker.mode.config_tag != "abduction")
SSticker.mode.abductors |= temp.abductors
GM.post_setup_team(GM.make_abductor_team(agent.mind, scientist.mind))
spawned_mobs += list(agent, scientist)
return SUCCESSFUL_SPAWN

View File

@@ -7,4 +7,5 @@
/datum/round_event/wizard/fake_explosion/start()
sound_to_playing_players('sound/machines/alarm.ogg')
addtimer(CALLBACK(SSticker, /datum/controller/subsystem/ticker/.proc/station_explosion_cinematic, 1, "fake"), 100) //:o)
sleep(100)
Cinematic(CINEMATIC_NUKE_FAKE,world)

View File

@@ -30,6 +30,7 @@
//Processing
var/process_inner_turfs = FALSE //Don't do this unless it's absolutely necessary
var/process_edge_turfs = FALSE //Don't do this either unless it's absolutely necessary, you can just track what things are inside manually or on the initial setup.
var/requires_processing = FALSE
var/setup_edge_turfs = FALSE //Setup edge turfs/all field turfs. Set either or both to ON when you need it, it's defaulting to off unless you do to save CPU.
var/setup_field_turfs = FALSE
var/use_host_turf = FALSE //For fields from items carried on mobs to check turf instead of loc...
@@ -41,6 +42,7 @@
/datum/proximity_monitor/advanced/Destroy()
full_cleanup()
STOP_PROCESSING(SSfields, src)
return ..()
/datum/proximity_monitor/advanced/proc/assume_params(list/field_params)
@@ -76,6 +78,10 @@
/datum/proximity_monitor/advanced/proc/process_edge_turf(turf/T)
/datum/proximity_monitor/advanced/New()
if(requires_processing)
START_PROCESSING(SSfields, src)
/datum/proximity_monitor/advanced/proc/Initialize()
setup_field()
post_setup_field()
@@ -250,11 +256,6 @@
setup_field_turfs = TRUE
setup_edge_turfs = TRUE
/datum/proximity_monitor/advanced/debug/recalculate_field()
..()
/datum/proximity_monitor/advanced/debug/post_setup_field()
..()
/datum/proximity_monitor/advanced/debug/setup_edge_turf(turf/T)
T.color = set_edgeturf_color

View File

@@ -5,6 +5,7 @@
name = "\improper Hyperkinetic Dampener Field"
setup_edge_turfs = TRUE
setup_field_turfs = TRUE
requires_processing = TRUE
field_shape = FIELD_SHAPE_RADIUS_SQUARE
var/static/image/edgeturf_south = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_south")
var/static/image/edgeturf_north = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_north")
@@ -21,13 +22,11 @@
use_host_turf = TRUE
/datum/proximity_monitor/advanced/peaceborg_dampener/New()
START_PROCESSING(SSfields, src)
tracked = list()
staging = list()
..()
/datum/proximity_monitor/advanced/peaceborg_dampener/Destroy()
STOP_PROCESSING(SSfields, src)
return ..()
/datum/proximity_monitor/advanced/peaceborg_dampener/process()

View File

@@ -0,0 +1,131 @@
/obj/effect/timestop
anchored = TRUE
name = "chronofield"
desc = "ZA WARUDO"
icon = 'icons/effects/160x160.dmi'
icon_state = "time"
layer = FLY_LAYER
pixel_x = -64
pixel_y = -64
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/list/immune = list() // the one who creates the timestop is immune
var/turf/target
var/freezerange = 2
var/duration = 140
var/datum/proximity_monitor/advanced/timestop/chronofield
alpha = 125
/obj/effect/timestop/Initialize(mapload, radius, time, list/immune_atoms, start = TRUE) //Immune atoms assoc list atom = TRUE
. = ..()
if(immune_atoms)
immune = immune_atoms.Copy()
if(!isnull(time))
duration = time
if(!isnull(radius))
freezerange = radius
for(var/mob/living/L in GLOB.player_list)
if(locate(/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop) in L.mind.spell_list) //People who can stop time are immune to its effects
immune[L] = TRUE
if(start)
timestop()
/obj/effect/timestop/Destroy()
qdel(chronofield)
playsound(src, 'sound/magic/timeparadox2.ogg', 75, TRUE, frequency = -1) //reverse!
return ..()
/obj/effect/timestop/proc/timestop()
target = get_turf(src)
playsound(src, 'sound/magic/timeparadox2.ogg', 75, 1, -1)
chronofield = make_field(/datum/proximity_monitor/advanced/timestop, list("current_range" = freezerange, "host" = src, "immune" = immune))
QDEL_IN(src, duration)
/obj/effect/timestop/wizard
duration = 100
/datum/proximity_monitor/advanced/timestop
name = "chronofield"
setup_field_turfs = TRUE
field_shape = FIELD_SHAPE_RADIUS_SQUARE
requires_processing = TRUE
var/list/immune = list()
var/list/mob/living/frozen_mobs = list()
var/list/obj/item/projectile/frozen_projectiles = list()
var/list/atom/movable/frozen_throws = list()
/datum/proximity_monitor/advanced/timestop/Destroy()
unfreeze_all()
return ..()
/datum/proximity_monitor/advanced/timestop/field_turf_crossed(atom/movable/AM)
freeze_atom(AM)
/datum/proximity_monitor/advanced/timestop/proc/freeze_atom(atom/movable/A)
if(immune[A] || !istype(A))
return FALSE
if(A.throwing)
freeze_throwing(A)
if(isliving(A))
freeze_mob(A)
else if(istype(A, /obj/item/projectile))
freeze_projectile(A)
else
return FALSE
return TRUE
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_all()
for(var/i in frozen_projectiles)
unfreeze_projectile(i)
for(var/i in frozen_mobs)
unfreeze_mob(i)
for(var/i in frozen_throws)
unfreeze_throw(i)
/datum/proximity_monitor/advanced/timestop/proc/freeze_throwing(atom/movable/AM)
var/datum/thrownthing/T = AM.throwing
T.paused = TRUE
frozen_throws[AM] = T
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_throw(atom/movable/AM)
var/datum/thrownthing/T = frozen_throws[AM]
T.paused = FALSE
frozen_throws -= AM
/datum/proximity_monitor/advanced/timestop/process()
for(var/i in frozen_mobs)
var/mob/living/m = i
if(get_dist(get_turf(m), get_turf(host)) > current_range)
unfreeze_mob(m)
else
m.Stun(20, 1, 1)
/datum/proximity_monitor/advanced/timestop/setup_field_turf(turf/T)
for(var/i in T.contents)
freeze_atom(i)
return ..()
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_projectile(obj/item/projectile/P)
frozen_projectiles -= P
P.paused = FALSE
/datum/proximity_monitor/advanced/timestop/proc/freeze_projectile(obj/item/projectile/P)
frozen_projectiles[P] = TRUE
P.paused = TRUE
/datum/proximity_monitor/advanced/timestop/proc/freeze_mob(mob/living/L)
L.Stun(20, 1, 1)
frozen_mobs[L] = L.anchored
L.anchored = TRUE
if(ishostile(L))
var/mob/living/simple_animal/hostile/H = L
H.AIStatus = AI_OFF
H.LoseTarget()
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mob(mob/living/L)
L.AdjustStun(-20, 1, 1)
L.anchored = frozen_mobs[L]
frozen_mobs -= L
if(ishostile(L))
var/mob/living/simple_animal/hostile/H = L
H.AIStatus = initial(H.AIStatus)

View File

@@ -185,6 +185,37 @@
icon_state = ""
bitesize = 2
/obj/item/reagent_containers/food/snacks/deepfryholder/proc/fry(obj/item/frying, datum/reagents/reagents, cook_time = 30)
if(istype(frying, /obj/item/reagent_containers/))
var/obj/item/reagent_containers/food = frying
food.reagents.trans_to(src, food.reagents.total_volume)
icon = frying.icon
overlays = frying.overlays
icon_state = frying.icon_state
desc = frying.desc
w_class = frying.w_class
reagents.trans_to(src, 2*(cook_time/15))
switch(cook_time)
if(0 to 15)
add_atom_colour(rgb(166,103,54), FIXED_COLOUR_PRIORITY)
name = "lightly-fried [frying.name]"
if(16 to 49)
add_atom_colour(rgb(103,63,24), FIXED_COLOUR_PRIORITY)
name = "fried [frying.name]"
if(50 to 59)
add_atom_colour(rgb(63,23,4), FIXED_COLOUR_PRIORITY)
name = "deep-fried [frying.name]"
if(60 to INFINITY)
add_atom_colour(rgb(33,19,9), FIXED_COLOUR_PRIORITY)
name = "the physical manifestation of the very concept of fried foods"
desc = "A heavily fried...something. Who can tell anymore?"
filling_color = color
foodtype |= FRIED
if(istype(frying, /obj/item/reagent_containers/food/snacks/))
qdel(frying)
else
frying.forceMove(src)
/obj/item/reagent_containers/food/snacks/butteredtoast
name = "buttered toast"
desc = "Butter lightly spread over a piece of toast."

View File

@@ -82,36 +82,7 @@ insert ascii eagle on american flag background here
if(frying.loc == src)
to_chat(user, "<span class='notice'>You eject [frying] from [src].</span>")
var/obj/item/reagent_containers/food/snacks/deepfryholder/S = new(get_turf(src))
if(istype(frying, /obj/item/reagent_containers/))
var/obj/item/reagent_containers/food = frying
food.reagents.trans_to(S, food.reagents.total_volume)
S.icon = frying.icon
S.overlays = frying.overlays
S.icon_state = frying.icon_state
S.desc = frying.desc
S.w_class = frying.w_class
reagents.trans_to(S, 2*(cook_time/15))
switch(cook_time)
if(0 to 15)
S.add_atom_colour(rgb(166,103,54), FIXED_COLOUR_PRIORITY)
S.name = "lightly-fried [frying.name]"
if(16 to 49)
S.add_atom_colour(rgb(103,63,24), FIXED_COLOUR_PRIORITY)
S.name = "fried [frying.name]"
if(50 to 59)
S.add_atom_colour(rgb(63,23,4), FIXED_COLOUR_PRIORITY)
S.name = "deep-fried [frying.name]"
if(60 to INFINITY)
S.add_atom_colour(rgb(33,19,9), FIXED_COLOUR_PRIORITY)
S.name = "the physical manifestation of the very concept of fried foods"
S.desc = "A heavily fried...something. Who can tell anymore?"
S.filling_color = S.color
S.foodtype |= FRIED
if(istype(frying, /obj/item/reagent_containers/food/snacks/))
qdel(frying)
else
frying.forceMove(S)
S.fry(frying, reagents, cook_time)
icon_state = "fryer_off"
user.put_in_hands(S)
frying = null

View File

@@ -104,12 +104,14 @@
var/buffertext = "A funny bit of text."
/obj/item/toy/cards/singlecard/cas/examine(mob/user)
..()
if (flipped)
to_chat(user, "<span class='notice'>The card is face down.</span>")
else if (blank)
to_chat(user, "<span class='notice'>The card is blank. Write on it with a pen.</span>")
else
to_chat(user, "<span class='notice'>The card reads: [name]</span>")
to_chat(user, "<span class='notice'>Alt-click to flip it.</span>")
/obj/item/toy/cards/singlecard/cas/Flip()
set name = "Flip Card"
@@ -145,4 +147,4 @@
return
name = cardtext
buffertext = cardtext
blank = 0
blank = 0

View File

@@ -353,6 +353,8 @@ h1.alert, h2.alert {color: #000000;}
.borer {color: #543354; font-style: italic;}
.changeling {color: #800080; font-style: italic;}
.spider {color: #4d004d;}
.interface {color: #330033;}
.sans {font-family: "Comic Sans MS", cursive, sans-serif;}

View File

@@ -184,7 +184,7 @@
/obj/structure/closet/crate/secure/loot/AltClick(mob/living/user)
if(!user.canUseTopic(src))
return
attack_hand(user)
attack_hand(user) //this helps you not blow up so easily by overriding unlocking which results in an immediate boom.
/obj/structure/closet/crate/secure/loot/attackby(obj/item/W, mob/user)
if(locked)

View File

@@ -8,6 +8,7 @@
density = TRUE
anchored = TRUE
circuit = /obj/item/circuitboard/machine/mining_equipment_vendor
var/icon_deny = "mining-deny"
var/obj/item/card/id/inserted_id
var/list/prize_list = list( //if you add something to this, please, for the love of god, use tabs and not spaces.
new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10),
@@ -108,6 +109,7 @@
if(href_list["choice"])
if(istype(inserted_id))
if(href_list["choice"] == "eject")
to_chat(usr, "<span class='notice'>You eject the ID from [src]'s card slot.</span>")
inserted_id.loc = loc
inserted_id.verb_pickup()
inserted_id = null
@@ -118,20 +120,31 @@
return
I.loc = src
inserted_id = I
else to_chat(usr, "<span class='danger'>No valid ID.</span>")
to_chat(usr, "<span class='notice'>You insert the ID into [src]'s card slot.</span>")
else
to_chat(usr, "<span class='warning'>Error: No valid ID!</span>")
flick(icon_deny, src)
if(href_list["purchase"])
if(istype(inserted_id))
var/datum/data/mining_equipment/prize = locate(href_list["purchase"])
if (!prize || !(prize in prize_list))
to_chat(usr, "<span class='warning'>Error: Invalid choice!</span>")
flick(icon_deny, src)
return
if(prize.cost > inserted_id.mining_points)
to_chat(usr, "<span class='warning'>Error: Insufficent points for [prize.equipment_name]!</span>")
flick(icon_deny, src)
else
inserted_id.mining_points -= prize.cost
to_chat(usr, "<span class='notice'>[src] clanks to life briefly before vending [prize.equipment_name]!</span>")
new prize.equipment_path(src.loc)
SSblackbox.add_details("mining_equipment_bought",
"[src.type]|[prize.equipment_path]")
// Add src.type to keep track of free golem purchases
// separately.
else
to_chat(usr, "<span class='warning'>Error: Please insert a valid ID!</span>")
flick(icon_deny, src)
updateUsrDialog()
return
@@ -146,6 +159,7 @@
return
C.loc = src
inserted_id = C
to_chat(usr, "<span class='notice'>You insert the ID into [src]'s card slot.</span>")
interact(user)
return
if(default_deconstruction_screwdriver(user, "mining-open", "mining", I))

View File

@@ -32,10 +32,10 @@
new_player_panel()
client.playtitlemusic()
if(SSticker.current_state < GAME_STATE_SETTING_UP)
var/tl = round(SSticker.GetTimeLeft(), 1)/10
var/tl = SSticker.GetTimeLeft()
var/postfix
if(tl >= 0)
postfix = "in about [tl] seconds"
if(tl > 0)
postfix = "in about [DisplayTimeText(tl)]"
else
postfix = "soon"
to_chat(src, "Please set up your character and select \"Ready\". The game will start [postfix].")

View File

@@ -392,12 +392,7 @@
/mob/dead/new_player/proc/LateChoices()
var/mills = world.time - SSticker.round_start_time // 1/10 of a second, not real milliseconds but whatever
//var/secs = ((mills % 36000) % 600) / 10 //Not really needed, but I'll leave it here for refrence.. or something
var/mins = (mills % 36000) / 600
var/hours = mills / 36000
var/dat = "<div class='notice'>Round Duration: [round(hours)]h [round(mins)]m</div>"
var/dat = "<div class='notice'>Round Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]</div>"
if(SSshuttle.emergency)
switch(SSshuttle.emergency.mode)

View File

@@ -67,30 +67,317 @@
/datum/sprite_accessory/hair
icon = 'icons/mob/human_face.dmi' // default icon for all hairs
/datum/sprite_accessory/hair/short
name = "Short Hair" // try to capatilize the names please~ // try to spell
icon_state = "hair_a" // you do not need to define _s or _l sub-states, game automatically does this for you
//Place in order by major style E.G "Afro, Bun, Ponytail"
//Place different versions under the same style E.G "Bun > Large Bun, Ponytail > Long Ponytail"
//A
/datum/sprite_accessory/hair/shorthair2
name = "Short Hair 2"
icon_state = "hair_shorthair2"
/datum/sprite_accessory/hair/afro
name = "Afro" // try to capatilize the names please~ // try to spell
icon_state = "hair_afro" // you do not need to define _s or _l sub-states, game automatically does this for you
/datum/sprite_accessory/hair/shorthair3
name = "Short Hair 3"
icon_state = "hair_shorthair3"
/datum/sprite_accessory/hair/afro2
name = "Afro 2"
icon_state = "hair_afro2"
/datum/sprite_accessory/hair/afro_large
name = "Big Afro"
icon_state = "hair_bigafro"
/datum/sprite_accessory/hair/antenna
name = "Ahoge"
icon_state = "hair_antenna"
//B
/datum/sprite_accessory/hair/bald
name = "Bald"
icon_state = null
/datum/sprite_accessory/hair/balding
name = "Balding Hair"
icon_state = "hair_e"
/datum/sprite_accessory/hair/longbangs
name = "Long Bangs"
icon_state = "hair_lbangs"
/datum/sprite_accessory/hair/bedhead
name = "Bedhead"
icon_state = "hair_bedhead"
/datum/sprite_accessory/hair/bedhead2
name = "Bedhead 2"
icon_state = "hair_bedheadv2"
/datum/sprite_accessory/hair/bedhead3
name = "Bedhead 3"
icon_state = "hair_bedheadv3"
/datum/sprite_accessory/hair/beehive
name = "Beehive"
icon_state = "hair_beehive"
/datum/sprite_accessory/hair/beehive2
name = "Beehive 2"
icon_state = "hair_beehivev2"
/datum/sprite_accessory/hair/bob
name = "Bob"
icon_state = "hair_bobcut"
/datum/sprite_accessory/hair/bobcurl
name = "Bobcurl"
icon_state = "hair_bobcurl"
/datum/sprite_accessory/hair/bob
name = "Bob Hair"
icon_state = "hair_bob"
/datum/sprite_accessory/hair/bob2
name = "Bob Hair 2"
icon_state = "hair_bob2"
/datum/sprite_accessory/hair/boddicker
name = "Boddicker"
icon_state = "hair_boddicker"
/datum/sprite_accessory/hair/bowl
name = "Bowl"
icon_state = "hair_bowlcut"
/datum/sprite_accessory/hair/braided
name = "Braided"
icon_state = "hair_braided"
/datum/sprite_accessory/hair/front_braid
name = "Braided front"
icon_state = "hair_braidfront"
/datum/sprite_accessory/hair/braidtail
name = "Braided Tail"
icon_state = "hair_braidtail"
/datum/sprite_accessory/hair/lowbraid
name = "Low Braid"
icon_state = "hair_hbraid"
/datum/sprite_accessory/hair/not_floorlength_braid
name = "High Braid"
icon_state = "hair_braid2"
/datum/sprite_accessory/hair/shortbraid
name = "Short Braid"
icon_state = "hair_shortbraid"
/datum/sprite_accessory/hair/braid
name = "Floorlength Braid"
icon_state = "hair_braid"
/datum/sprite_accessory/hair/business
name = "Business Hair"
icon_state = "hair_business"
/datum/sprite_accessory/hair/business2
name = "Business Hair 2"
icon_state = "hair_business2"
/datum/sprite_accessory/hair/business3
name = "Business Hair 3"
icon_state = "hair_business3"
/datum/sprite_accessory/hair/business4
name = "Business Hair 4"
icon_state = "hair_business4"
/datum/sprite_accessory/hair/bun
name = "Bun Head"
icon_state = "hair_bun"
/datum/sprite_accessory/hair/bun2
name = "Bun Head 2"
icon_state = "hair_bunhead2"
/datum/sprite_accessory/hair/largebun
name = "Large Bun"
icon_state = "hair_largebun"
/datum/sprite_accessory/hair/buzz
name = "Buzzcut"
icon_state = "hair_buzzcut"
//C
/datum/sprite_accessory/hair/crew
name = "Crewcut"
icon_state = "hair_crewcut"
/datum/sprite_accessory/hair/combover
name = "Combover"
icon_state = "hair_combover"
/datum/sprite_accessory/hair/curls
name = "Curls"
icon_state = "hair_curls"
//D
/datum/sprite_accessory/hair/devillock
name = "Devil Lock"
icon_state = "hair_devilock"
/datum/sprite_accessory/hair/dreadlocks
name = "Dreadlocks"
icon_state = "hair_dreads"
/datum/sprite_accessory/hair/drillhair
name = "Drill Hair"
icon_state = "hair_drillhair"
//E
/datum/sprite_accessory/hair/emo
name = "Emo"
icon_state = "hair_emo"
/datum/sprite_accessory/hair/longemo
name = "Long Emo"
icon_state = "hair_longemo"
//F
/datum/sprite_accessory/hair/feather
name = "Feather"
icon_state = "hair_feather"
/datum/sprite_accessory/hair/sargeant
name = "Flat Top"
icon_state = "hair_sargeant"
/datum/sprite_accessory/hair/bigflattop
name = "Big Flat Top"
icon_state = "hair_bigflattop"
/datum/sprite_accessory/hair/fag
name = "Flow Hair"
icon_state = "hair_f"
/datum/sprite_accessory/hair/longfringe
name = "Long Fringe"
icon_state = "hair_longfringe"
/datum/sprite_accessory/hair/longestalt
name = "Longer Fringe"
icon_state = "hair_vlongfringe"
//G
/datum/sprite_accessory/hair/gelled
name = "Gelled Back"
icon_state = "hair_gelled"
/datum/sprite_accessory/hair/gentle
name = "Gentle"
icon_state = "hair_gentle"
//H
/datum/sprite_accessory/hair/cut
name = "Cut Hair"
icon_state = "hair_c"
/datum/sprite_accessory/hair/long
name = "Shoulder-length Hair"
icon_state = "hair_b"
/datum/sprite_accessory/hair/halfbang
name = "Half-banged Hair"
icon_state = "hair_halfbang"
/datum/sprite_accessory/hair/halfbang2
name = "Half-banged Hair 2"
icon_state = "hair_halfbang2"
/datum/sprite_accessory/hair/hedgehog
name = "Hedgehog Hair"
icon_state = "hair_hedgehog"
/datum/sprite_accessory/hair/hitop
name = "Hitop"
icon_state = "hair_hitop"
/datum/sprite_accessory/hair/himecut
name = "Hime Cut"
icon_state = "hair_himecut"
/datum/sprite_accessory/hair/himecut2
name = "Hime Cut 2"
icon_state = "hair_himecut2"
/datum/sprite_accessory/hair/himeup
name = "Hime Updo"
icon_state = "hair_himeup"
//I
//J
/datum/sprite_accessory/hair/jensen
name = "Jensen Hair"
icon_state = "hair_jensen"
//K
/datum/sprite_accessory/hair/keanu
name = "Keanu Hair"
icon_state = "hair_keanu"
/datum/sprite_accessory/hair/kusangi
name = "Kusanagi Hair"
icon_state = "hair_kusanagi"
//L
/datum/sprite_accessory/hair/longer
name = "Long Hair"
icon_state = "hair_vlong"
/datum/sprite_accessory/hair/long
name = "Long Hair 1"
icon_state = "hair_long"
/datum/sprite_accessory/hair/long2
name = "Long Hair 2"
icon_state = "hair_long2"
/datum/sprite_accessory/hair/longest
name = "Very Long Hair"
icon_state = "hair_longest"
//M
/datum/sprite_accessory/hair/megaeyebrows
name = "Mega Eyebrows"
icon_state = "hair_megaeyebrows"
/datum/sprite_accessory/hair/messy
name = "Messy"
icon_state = "hair_messy"
/datum/sprite_accessory/hair/mohawk
name = "Mohawk"
icon_state = "hair_d"
/datum/sprite_accessory/hair/reversemohawk
name = "Reverse Mohawk"
icon_state = "hair_reversemohawk"
//N
//O
/datum/sprite_accessory/hair/odango
name = "Odango"
icon_state = "hair_odango"
/datum/sprite_accessory/hair/ombre
name = "Ombre"
icon_state = "hair_ombre"
/datum/sprite_accessory/hair/over_eye
name = "Over Eye"
icon_state = "hair_shortovereye"
@@ -103,29 +390,39 @@
name = "Very Long Over Eye"
icon_state = "hair_longest2"
/datum/sprite_accessory/hair/longest
name = "Very Long Hair"
icon_state = "hair_longest"
//P
/datum/sprite_accessory/hair/longfringe
name = "Long Fringe"
icon_state = "hair_longfringe"
/datum/sprite_accessory/hair/parted
name = "Parted"
icon_state = "hair_parted"
/datum/sprite_accessory/hair/longestalt
name = "Longer Fringe"
icon_state = "hair_vlongfringe"
/datum/sprite_accessory/hair/sidepartlongalt
name = "Long Side Part"
icon_state = "hair_longsidepart"
/datum/sprite_accessory/hair/gentle
name = "Gentle"
icon_state = "hair_gentle"
/datum/sprite_accessory/hair/kagami
name = "Pigtails"
icon_state = "hair_kagami"
/datum/sprite_accessory/hair/halfbang
name = "Half-banged Hair"
icon_state = "hair_halfbang"
/datum/sprite_accessory/hair/pigtail
name = "Pigtails 2"
icon_state = "hair_pigtails"
/datum/sprite_accessory/hair/halfbang2
name = "Half-banged Hair 2"
icon_state = "hair_halfbang2"
/datum/sprite_accessory/hair/pigtail
name = "Pigtails 3"
icon_state = "hair_pigtails2"
/datum/sprite_accessory/hair/pixie
name = "Pixie Cut"
icon_state = "hair_pixie"
/datum/sprite_accessory/hair/pompadour
name = "Pompadour"
icon_state = "hair_pompadour"
/datum/sprite_accessory/hair/bigpompadour
name = "Big Pompadour"
icon_state = "hair_bigpompadour"
/datum/sprite_accessory/hair/ponytail1
name = "Ponytail"
@@ -147,6 +444,36 @@
name = "Ponytail 5"
icon_state = "hair_ponytail5"
/datum/sprite_accessory/hair/highponytail
name = "High Ponytail"
icon_state = "hair_highponytail"
/datum/sprite_accessory/hair/longponytail
name = "Long Ponytail"
icon_state = "hair_longstraightponytail"
//Q
/datum/sprite_accessory/hair/quiff
name = "Quiff"
icon_state = "hair_quiff"
//R
//S
/datum/sprite_accessory/hair/oneshoulder
name = "One Shoulder"
icon_state = "hair_oneshoulder"
/datum/sprite_accessory/hair/tressshoulder
name = "Tress Shoulder"
icon_state = "hair_tressshoulder"
/datum/sprite_accessory/hair/sidecut
name = "Sidecut"
icon_state = "hair_sidecut"
/datum/sprite_accessory/hair/sidetail
name = "Side Pony"
@@ -164,141 +491,33 @@
name = "Side Pony 4"
icon_state = "hair_sidetail4"
/datum/sprite_accessory/hair/oneshoulder
name = "One Shoulder"
icon_state = "hair_oneshoulder"
/datum/sprite_accessory/hair/short
name = "Short Hair"
icon_state = "hair_a"
/datum/sprite_accessory/hair/tressshoulder
name = "Tress Shoulder"
icon_state = "hair_tressshoulder"
/datum/sprite_accessory/hair/shorthair2
name = "Short Hair 2"
icon_state = "hair_shorthair2"
/datum/sprite_accessory/hair/shorthair3
name = "Short Hair 3"
icon_state = "hair_shorthair3"
/datum/sprite_accessory/hair/long
name = "Shoulder-length Hair"
icon_state = "hair_b"
/datum/sprite_accessory/hair/parted
name = "Parted"
icon_state = "hair_parted"
name = "Side Part"
icon_state = "hair_part"
/datum/sprite_accessory/hair/pompadour
name = "Pompadour"
icon_state = "hair_pompadour"
/datum/sprite_accessory/hair/skinhead
name = "Skinhead"
icon_state = "hair_skinhead"
/datum/sprite_accessory/hair/bigpompadour
name = "Big Pompadour"
icon_state = "hair_bigpompadour"
/datum/sprite_accessory/hair/quiff
name = "Quiff"
icon_state = "hair_quiff"
/datum/sprite_accessory/hair/bedhead
name = "Bedhead"
icon_state = "hair_bedhead"
/datum/sprite_accessory/hair/bedhead2
name = "Bedhead 2"
icon_state = "hair_bedheadv2"
/datum/sprite_accessory/hair/bedhead3
name = "Bedhead 3"
icon_state = "hair_bedheadv3"
/datum/sprite_accessory/hair/messy
name = "Messy"
icon_state = "hair_messy"
/datum/sprite_accessory/hair/beehive
name = "Beehive"
icon_state = "hair_beehive"
/datum/sprite_accessory/hair/beehive2
name = "Beehive 2"
icon_state = "hair_beehivev2"
/datum/sprite_accessory/hair/bobcurl
name = "Bobcurl"
icon_state = "hair_bobcurl"
/datum/sprite_accessory/hair/bob
name = "Bob"
icon_state = "hair_bobcut"
/datum/sprite_accessory/hair/bowl
name = "Bowl"
icon_state = "hair_bowlcut"
/datum/sprite_accessory/hair/buzz
name = "Buzzcut"
icon_state = "hair_buzzcut"
/datum/sprite_accessory/hair/crew
name = "Crewcut"
icon_state = "hair_crewcut"
/datum/sprite_accessory/hair/combover
name = "Combover"
icon_state = "hair_combover"
/datum/sprite_accessory/hair/devillock
name = "Devil Lock"
icon_state = "hair_devilock"
/datum/sprite_accessory/hair/dreadlocks
name = "Dreadlocks"
icon_state = "hair_dreads"
/datum/sprite_accessory/hair/curls
name = "Curls"
icon_state = "hair_curls"
/datum/sprite_accessory/hair/afro
name = "Afro"
icon_state = "hair_afro"
/datum/sprite_accessory/hair/afro2
name = "Afro 2"
icon_state = "hair_afro2"
/datum/sprite_accessory/hair/afro_large
name = "Big Afro"
icon_state = "hair_bigafro"
/datum/sprite_accessory/hair/sargeant
name = "Flat Top"
icon_state = "hair_sargeant"
/datum/sprite_accessory/hair/emo
name = "Emo"
icon_state = "hair_emo"
/datum/sprite_accessory/hair/longemo
name = "Long Emo"
icon_state = "hair_longemo"
/datum/sprite_accessory/hair/fag
name = "Flow Hair"
icon_state = "hair_f"
/datum/sprite_accessory/hair/feather
name = "Feather"
icon_state = "hair_feather"
/datum/sprite_accessory/hair/hitop
name = "Hitop"
icon_state = "hair_hitop"
/datum/sprite_accessory/hair/mohawk
name = "Mohawk"
icon_state = "hair_d"
/datum/sprite_accessory/hair/reversemohawk
name = "Reverse Mohawk"
icon_state = "hair_reversemohawk"
/datum/sprite_accessory/hair/jensen
name = "Jensen Hair"
icon_state = "hair_jensen"
/datum/sprite_accessory/hair/gelled
name = "Gelled Back"
icon_state = "hair_gelled"
/datum/sprite_accessory/hair/protagonist
name = "Slightly Long"
icon_state = "hair_protagonist"
/datum/sprite_accessory/hair/spiky
name = "Spiky"
@@ -312,122 +531,6 @@
name = "Spiky 3"
icon_state = "hair_spiky2"
/datum/sprite_accessory/hair/protagonist
name = "Slightly Long"
icon_state = "hair_protagonist"
/datum/sprite_accessory/hair/kusangi
name = "Kusanagi Hair"
icon_state = "hair_kusanagi"
/datum/sprite_accessory/hair/kagami
name = "Pigtails"
icon_state = "hair_kagami"
/datum/sprite_accessory/hair/pigtail
name = "Pigtails 2"
icon_state = "hair_pigtails"
/datum/sprite_accessory/hair/pigtail
name = "Pigtails 3"
icon_state = "hair_pigtails2"
/datum/sprite_accessory/hair/himecut
name = "Hime Cut"
icon_state = "hair_himecut"
/datum/sprite_accessory/hair/himecut2
name = "Hime Cut 2"
icon_state = "hair_himecut2"
/datum/sprite_accessory/hair/himeup
name = "Hime Updo"
icon_state = "hair_himeup"
/datum/sprite_accessory/hair/antenna
name = "Ahoge"
icon_state = "hair_antenna"
/datum/sprite_accessory/hair/front_braid
name = "Braided front"
icon_state = "hair_braidfront"
/datum/sprite_accessory/hair/lowbraid
name = "Low Braid"
icon_state = "hair_hbraid"
/datum/sprite_accessory/hair/not_floorlength_braid
name = "High Braid"
icon_state = "hair_braid2"
/datum/sprite_accessory/hair/shortbraid
name = "Short Braid"
icon_state = "hair_shortbraid"
/datum/sprite_accessory/hair/braid
name = "Floorlength Braid"
icon_state = "hair_braid"
/datum/sprite_accessory/hair/odango
name = "Odango"
icon_state = "hair_odango"
/datum/sprite_accessory/hair/ombre
name = "Ombre"
icon_state = "hair_ombre"
/datum/sprite_accessory/hair/updo
name = "Updo"
icon_state = "hair_updo"
/datum/sprite_accessory/hair/skinhead
name = "Skinhead"
icon_state = "hair_skinhead"
/datum/sprite_accessory/hair/longbangs
name = "Long Bangs"
icon_state = "hair_lbangs"
/datum/sprite_accessory/hair/balding
name = "Balding Hair"
icon_state = "hair_e"
/datum/sprite_accessory/hair/bald
name = "Bald"
icon_state = null
/datum/sprite_accessory/hair/parted
name = "Side Part"
icon_state = "hair_part"
/datum/sprite_accessory/hair/braided
name = "Braided"
icon_state = "hair_braided"
/datum/sprite_accessory/hair/bun
name = "Bun Head"
icon_state = "hair_bun"
/datum/sprite_accessory/hair/bun2
name = "Bun Head 2"
icon_state = "hair_bunhead2"
/datum/sprite_accessory/hair/braidtail
name = "Braided Tail"
icon_state = "hair_braidtail"
/datum/sprite_accessory/hair/bigflattop
name = "Big Flat Top"
icon_state = "hair_bigflattop"
/datum/sprite_accessory/hair/drillhair
name = "Drill Hair"
icon_state = "hair_drillhair"
/datum/sprite_accessory/hair/keanu
name = "Keanu Hair"
icon_state = "hair_keanu"
/datum/sprite_accessory/hair/swept
name = "Swept Back Hair"
icon_state = "hair_swept"
@@ -436,73 +539,24 @@
name = "Swept Back Hair 2"
icon_state = "hair_swept2"
/datum/sprite_accessory/hair/business
name = "Business Hair"
icon_state = "hair_business"
//T
/datum/sprite_accessory/hair/business2
name = "Business Hair 2"
icon_state = "hair_business2"
//U
/datum/sprite_accessory/hair/business3
name = "Business Hair 3"
icon_state = "hair_business3"
/datum/sprite_accessory/hair/updo
name = "Updo"
icon_state = "hair_updo"
/datum/sprite_accessory/hair/business4
name = "Business Hair 4"
icon_state = "hair_business4"
//V
/datum/sprite_accessory/hair/hedgehog
name = "Hedgehog Hair"
icon_state = "hair_hedgehog"
//W
/datum/sprite_accessory/hair/bob
name = "Bob Hair"
icon_state = "hair_bob"
//X
/datum/sprite_accessory/hair/bob2
name = "Bob Hair 2"
icon_state = "hair_bob2"
//Y
/datum/sprite_accessory/hair/boddicker
name = "Boddicker"
icon_state = "hair_boddicker"
//Z
/datum/sprite_accessory/hair/long
name = "Long Hair 1"
icon_state = "hair_long"
/datum/sprite_accessory/hair/long2
name = "Long Hair 2"
icon_state = "hair_long2"
/datum/sprite_accessory/hair/pixie
name = "Pixie Cut"
icon_state = "hair_pixie"
/datum/sprite_accessory/hair/megaeyebrows
name = "Mega Eyebrows"
icon_state = "hair_megaeyebrows"
/datum/sprite_accessory/hair/highponytail
name = "High Ponytail"
icon_state = "hair_highponytail"
/datum/sprite_accessory/hair/longponytail
name = "Long Ponytail"
icon_state = "hair_longstraightponytail"
/datum/sprite_accessory/hair/sidepartlongalt
name = "Long Side Part"
icon_state = "hair_longsidepart"
/datum/sprite_accessory/hair/sidecut
name = "Sidecut"
icon_state = "hair_sidecut"
/datum/sprite_accessory/hair/largebun
name = "Large Bun"
icon_state = "hair_largebun"
/////////////////////////////
// Facial Hair Definitions //
@@ -516,82 +570,81 @@
icon_state = null
gender = NEUTER
/datum/sprite_accessory/facial_hair/watson
name = "Watson Mustache"
icon_state = "facial_watson"
/datum/sprite_accessory/facial_hair/hogan
name = "Hulk Hogan Mustache"
icon_state = "facial_hogan" //-Neek
/datum/sprite_accessory/facial_hair/vandyke
name = "Van Dyke Mustache"
icon_state = "facial_vandyke"
/datum/sprite_accessory/facial_hair/chaplin
name = "Square Mustache"
icon_state = "facial_chaplin"
/datum/sprite_accessory/facial_hair/selleck
name = "Selleck Mustache"
icon_state = "facial_selleck"
/datum/sprite_accessory/facial_hair/neckbeard
name = "Neckbeard"
icon_state = "facial_neckbeard"
/datum/sprite_accessory/facial_hair/fullbeard
name = "Full Beard"
icon_state = "facial_fullbeard"
/datum/sprite_accessory/facial_hair/longbeard
name = "Long Beard"
icon_state = "facial_longbeard"
/datum/sprite_accessory/facial_hair/vlongbeard
name = "Very Long Beard"
icon_state = "facial_wise"
/datum/sprite_accessory/facial_hair/elvis
name = "Elvis Sideburns"
icon_state = "facial_elvis"
/datum/sprite_accessory/facial_hair/abe
name = "Abraham Lincoln Beard"
icon_state = "facial_abe"
/datum/sprite_accessory/facial_hair/brokenman
name = "Broken Man"
icon_state = "facial_brokenman"
/datum/sprite_accessory/facial_hair/chinstrap
name = "Chinstrap"
icon_state = "facial_chin"
/datum/sprite_accessory/facial_hair/dwarf
name = "Dwarf Beard"
icon_state = "facial_dwarf"
/datum/sprite_accessory/facial_hair/elvis
name = "Elvis Sideburns"
icon_state = "facial_elvis"
/datum/sprite_accessory/facial_hair/fiveoclock
name = "Five o Clock Shadow"
icon_state = "facial_fiveoclock"
/datum/sprite_accessory/facial_hair/fullbeard
name = "Full Beard"
icon_state = "facial_fullbeard"
/datum/sprite_accessory/facial_hair/fu
name = "Fu Manchu"
icon_state = "facial_fumanchu"
/datum/sprite_accessory/facial_hair/gt
name = "Goatee"
icon_state = "facial_gt"
/datum/sprite_accessory/facial_hair/hip
name = "Hipster Beard"
icon_state = "facial_hip"
/datum/sprite_accessory/facial_hair/gt
name = "Goatee"
icon_state = "facial_gt"
/datum/sprite_accessory/facial_hair/hogan
name = "Hulk Hogan Mustache"
icon_state = "facial_hogan" //-Neek
/datum/sprite_accessory/facial_hair/jensen
name = "Jensen Beard"
icon_state = "facial_jensen"
/datum/sprite_accessory/facial_hair/dwarf
name = "Dwarf Beard"
icon_state = "facial_dwarf"
/datum/sprite_accessory/facial_hair/fiveoclock
name = "Five o Clock Shadow"
icon_state = "facial_fiveoclock"
/datum/sprite_accessory/facial_hair/fu
name = "Fu Manchu"
icon_state = "facial_fumanchu"
/datum/sprite_accessory/facial_hair/brokenman
name = "Broken Man"
icon_state = "facial_brokenman"
/datum/sprite_accessory/facial_hair/longbeard
name = "Long Beard"
icon_state = "facial_longbeard"
/datum/sprite_accessory/facial_hair/neckbeard
name = "Neckbeard"
icon_state = "facial_neckbeard"
/datum/sprite_accessory/facial_hair/selleck
name = "Selleck Mustache"
icon_state = "facial_selleck"
/datum/sprite_accessory/facial_hair/chaplin
name = "Square Mustache"
icon_state = "facial_chaplin"
/datum/sprite_accessory/facial_hair/vandyke
name = "Van Dyke Mustache"
icon_state = "facial_vandyke"
/datum/sprite_accessory/facial_hair/vlongbeard
name = "Very Long Beard"
icon_state = "facial_wise"
/datum/sprite_accessory/facial_hair/watson
name = "Watson Mustache"
icon_state = "facial_watson"
///////////////////////////
// Underwear Definitions //

View File

@@ -13,6 +13,7 @@
var/obj/item/organ/brain/brain = null //The actual brain
var/datum/ai_laws/laws = new()
var/force_replace_ai_name = FALSE
var/overrides_aicore_laws = FALSE // Whether the laws on the MMI, if any, override possible pre-existing laws loaded on the AI core.
/obj/item/device/mmi/update_icon()
if(brain)
@@ -198,13 +199,16 @@
else
to_chat(user, "<span class='notice'>The MMI indicates the brain is active.</span>")
/obj/item/device/mmi/relaymove()
return //so that the MMI won't get a warning about not being able to move if it tries to move
/obj/item/device/mmi/syndie
name = "Syndicate Man-Machine Interface"
desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs and AIs created with it."
origin_tech = "biotech=4;programming=4;syndicate=2"
overrides_aicore_laws = TRUE
/obj/item/device/mmi/syndie/New()
..()
/obj/item/device/mmi/syndie/Initialize()
. = ..()
laws = new /datum/ai_laws/syndicate_override()
radio.on = 0

View File

@@ -10,15 +10,15 @@ Doesn't work on other aliens/AI.*/
name = "Alien Power"
panel = "Alien"
var/plasma_cost = 0
var/check_turf = 0
var/has_action = 1
var/datum/action/spell_action/alien/action = null
var/action_icon = 'icons/mob/actions/actions_xeno.dmi'
var/action_icon_state = "spell_default"
var/action_background_icon_state = "bg_alien"
var/check_turf = FALSE
has_action = TRUE
datum/action/spell_action/alien/action
action_icon = 'icons/mob/actions/actions_xeno.dmi'
action_icon_state = "spell_default"
action_background_icon_state = "bg_alien"
/obj/effect/proc_holder/alien/New()
..()
/obj/effect/proc_holder/alien/Initialize()
. = ..()
action = new(src)
/obj/effect/proc_holder/alien/Click()
@@ -30,15 +30,20 @@ Doesn't work on other aliens/AI.*/
user.adjustPlasma(-plasma_cost)
return 1
/obj/effect/proc_holder/alien/proc/on_gain(mob/living/carbon/user)
/obj/effect/proc_holder/alien/on_gain(mob/living/carbon/user)
return
/obj/effect/proc_holder/alien/proc/on_lose(mob/living/carbon/user)
/obj/effect/proc_holder/alien/on_lose(mob/living/carbon/user)
return
/obj/effect/proc_holder/alien/proc/fire(mob/living/carbon/user)
/obj/effect/proc_holder/alien/fire(mob/living/carbon/user)
return 1
/obj/effect/proc_holder/alien/get_panel_text()
. = ..()
if(plasma_cost > 0)
return "[plasma_cost]"
/obj/effect/proc_holder/alien/proc/cost_check(check_turf=0,mob/living/carbon/user,silent = 0)
if(user.stat)
if(!silent)
@@ -168,7 +173,6 @@ Doesn't work on other aliens/AI.*/
if(user.getPlasma() > A.plasma_cost && A.corrode(O))
user.adjustPlasma(-A.plasma_cost)
/obj/effect/proc_holder/alien/neurotoxin
name = "Spit Neurotoxin"
desc = "Spits neurotoxin at someone, paralyzing them for a short time."
@@ -179,7 +183,7 @@ Doesn't work on other aliens/AI.*/
var/message
if(active)
message = "<span class='notice'>You empty your neurotoxin gland.</span>"
remove_ranged_ability(user,message)
remove_ranged_ability(message)
else
message = "<span class='notice'>You prepare your neurotoxin gland. <B>Left-click to fire at a target!</B></span>"
add_ranged_ability(user, message, TRUE)
@@ -193,7 +197,7 @@ Doesn't work on other aliens/AI.*/
return
var/p_cost = 50
if(!iscarbon(ranged_ability_user) || ranged_ability_user.lying || ranged_ability_user.stat)
remove_ranged_ability(ranged_ability_user)
remove_ranged_ability()
return
var/mob/living/carbon/user = ranged_ability_user
@@ -219,8 +223,7 @@ Doesn't work on other aliens/AI.*/
return TRUE
/obj/effect/proc_holder/alien/neurotoxin/on_lose(mob/living/carbon/user)
if(user.ranged_ability == src)
user.ranged_ability = null
remove_ranged_ability()
/obj/effect/proc_holder/alien/neurotoxin/add_ranged_ability(mob/living/user, msg)
..()
@@ -328,7 +331,3 @@ Doesn't work on other aliens/AI.*/
return 1
return 0
/proc/cmp_abilities_cost(obj/effect/proc_holder/alien/a, obj/effect/proc_holder/alien/b)
return b.plasma_cost - a.plasma_cost

View File

@@ -34,6 +34,7 @@
if(L.handcuffed || L.legcuffed) // Cuffing larvas ? Eh ?
to_chat(user, "<span class='danger'>You cannot evolve when you are cuffed.</span>")
return
if(L.amount_grown >= L.max_grown) //TODO ~Carn
to_chat(L, "<span class='name'>You are growing into a beautiful alien! It is time to choose a caste.</span>")

View File

@@ -302,10 +302,9 @@
return
I.being_removed = TRUE
breakouttime = I.breakouttime
var/displaytime = breakouttime / 600
if(!cuff_break)
visible_message("<span class='warning'>[src] attempts to remove [I]!</span>")
to_chat(src, "<span class='notice'>You attempt to remove [I]... (This will take around [displaytime] minutes and you need to stand still.)</span>")
to_chat(src, "<span class='notice'>You attempt to remove [I]... (This will take around [DisplayTimeText(breakouttime)] and you need to stand still.)</span>")
if(do_after(src, breakouttime, 0, target = src))
clear_cuffs(I, cuff_break)
else
@@ -426,23 +425,6 @@
var/turf/target = get_turf(loc)
I.throw_at(target,I.throw_range,I.throw_speed,src)
/mob/living/carbon/proc/AddAbility(obj/effect/proc_holder/alien/A)
abilities.Add(A)
A.on_gain(src)
if(A.has_action)
A.action.Grant(src)
sortInsert(abilities, /proc/cmp_abilities_cost, 0)
/mob/living/carbon/proc/RemoveAbility(obj/effect/proc_holder/alien/A)
abilities.Remove(A)
A.on_lose(src)
if(A.action)
A.action.Remove(src)
/mob/living/carbon/proc/add_abilities_to_panel()
for(var/obj/effect/proc_holder/alien/A in abilities)
statpanel("[A.panel]",A.plasma_cost > 0?"([A.plasma_cost])":"",A)
/mob/living/carbon/Stat()
..()
if(statpanel("Status"))

View File

@@ -35,7 +35,6 @@
has_limbs = 1
var/obj/item/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab
var/list/obj/effect/proc_holder/alien/abilities = list()
var/gib_type = /obj/effect/decal/cleanable/blood/gibs
var/rotate_on_lying = 1

View File

@@ -311,7 +311,7 @@
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH, /obj/item/organ/cyberimp/eyes/hud/medical))
var/cyberimp_detect
for(var/obj/item/organ/cyberimp/CI in internal_organs)
if(CI.status == ORGAN_ROBOTIC)
if(CI.status == ORGAN_ROBOTIC && !CI.syndicate_implant)
cyberimp_detect += "[name] is modified with a [CI.name].<br>"
if(cyberimp_detect)
msg += "Detected cybernetic modifications:<br>"

View File

@@ -235,7 +235,7 @@
if(!I || I.loc != src) //no item, no limb, or item is not in limb or in the person anymore
return
var/time_taken = I.embedded_unsafe_removal_time*I.w_class
usr.visible_message("<span class='warning'>[usr] attempts to remove [I] from their [L.name].</span>","<span class='notice'>You attempt to remove [I] from your [L.name]... (It will take [time_taken/10] seconds.)</span>")
usr.visible_message("<span class='warning'>[usr] attempts to remove [I] from their [L.name].</span>","<span class='notice'>You attempt to remove [I] from your [L.name]... (It will take [DisplayTimeText(time_taken)].)</span>")
if(do_after(usr, time_taken, needhand = 1, target = src))
if(!I || !L || I.loc != src || !(I in L.embedded_objects))
return
@@ -941,3 +941,124 @@
riding_datum.unequip_buckle_inhands(M)
riding_datum.restore_position(M)
. = ..(M, force)
/mob/living/carbon/human/species
var/race = null
/mob/living/carbon/human/species/Initialize()
. = ..()
set_species(race)
/mob/living/carbon/human/species/abductor
race = /datum/species/abductor
/mob/living/carbon/human/species/android
race = /datum/species/android
/mob/living/carbon/human/species/angel
race = /datum/species/angel
/mob/living/carbon/human/species/corporate
race = /datum/species/corporate
/mob/living/carbon/human/species/fly
race = /datum/species/fly
/mob/living/carbon/human/species/golem
race = /datum/species/golem
/mob/living/carbon/human/species/golem/random
race = /datum/species/golem/random
/mob/living/carbon/human/species/golem/adamantine
race = /datum/species/golem/adamantine
/mob/living/carbon/human/species/golem/plasma
race = /datum/species/golem/plasma
/mob/living/carbon/human/species/golem/diamond
race = /datum/species/golem/diamond
/mob/living/carbon/human/species/golem/gold
race = /datum/species/golem/gold
/mob/living/carbon/human/species/golem/silver
race = /datum/species/golem/silver
/mob/living/carbon/human/species/golem/plasteel
race = /datum/species/golem/plasteel
/mob/living/carbon/human/species/golem/titanium
race = /datum/species/golem/titanium
/mob/living/carbon/human/species/golem/plastitanium
race = /datum/species/golem/plastitanium
/mob/living/carbon/human/species/golem/alien_alloy
race = /datum/species/golem/alloy
/mob/living/carbon/human/species/golem/wood
race = /datum/species/golem/wood
/mob/living/carbon/human/species/golem/uranium
race = /datum/species/golem/uranium
/mob/living/carbon/human/species/golem/sand
race = /datum/species/golem/sand
/mob/living/carbon/human/species/golem/glass
race = /datum/species/golem/glass
/mob/living/carbon/human/species/golem/bluespace
race = /datum/species/golem/bluespace
/mob/living/carbon/human/species/golem/bananium
race = /datum/species/golem/bananium
/mob/living/carbon/human/species/golem/blood_cult
race = /datum/species/golem/runic
/mob/living/carbon/human/species/golem/cloth
race = /datum/species/golem/cloth
/mob/living/carbon/human/species/golem/plastic
race = /datum/species/golem/plastic
/mob/living/carbon/human/species/jelly
race = /datum/species/jelly
/mob/living/carbon/human/species/jelly/slime
race = /datum/species/jelly/slime
/mob/living/carbon/human/species/lizard
race = /datum/species/lizard
/mob/living/carbon/human/species/lizard/ashwalker
race = /datum/species/lizard/ashwalker
/mob/living/carbon/human/species/plasma
race = /datum/species/plasmaman
/mob/living/carbon/human/species/pod
race = /datum/species/pod
/mob/living/carbon/human/species/shadow
race = /datum/species/shadow
/mob/living/carbon/human/species/skeleton
race = /datum/species/skeleton
/mob/living/carbon/human/species/synth
race = /datum/species/synth
/mob/living/carbon/human/species/synth/military
race = /datum/species/synth/military
/mob/living/carbon/human/species/zombie
race = /datum/species/zombie
/mob/living/carbon/human/species/zombie/infectious
race = /datum/species/zombie/infectious
/mob/living/carbon/human/species/zombie/krokodil_addict
race = /datum/species/krokodil_addict

View File

@@ -2,12 +2,10 @@
name = "Abductor"
id = "abductor"
say_mod = "gibbers"
sexes = 0
sexes = FALSE
species_traits = list(NOBLOOD,NOBREATH,VIRUSIMMUNE,NOGUNS,NOHUNGER)
mutanttongue = /obj/item/organ/tongue/abductor
var/scientist = 0 // vars to not pollute spieces list with castes
var/team = 1
var/scientist = FALSE // vars to not pollute spieces list with castes
/datum/species/abductor/copy_properties_from(datum/species/abductor/old_species)
scientist = old_species.scientist
team = old_species.team

View File

@@ -636,7 +636,7 @@
has_corpse = TRUE
blacklisted = TRUE
dangerous_existence = TRUE
/datum/species/golem/cloth
name = "Cloth Golem"
id = "cloth golem"

View File

@@ -412,8 +412,9 @@
liver_failure()
else
liver.failing = FALSE
if(((!(NOLIVER in dna.species.species_traits)) && (!liver)))
else
if((dna && dna.species && (NOLIVER in dna.species.species_traits)))
return
liver_failure()
/mob/living/carbon/proc/undergoing_liver_failure()

View File

@@ -982,3 +982,19 @@
client.move_delay = world.time + movement_delay()
lying_prev = lying
return canmove
/mob/living/proc/AddAbility(obj/effect/proc_holder/A)
abilities.Add(A)
A.on_gain(src)
if(A.has_action)
A.action.Grant(src)
/mob/living/proc/RemoveAbility(obj/effect/proc_holder/A)
abilities.Remove(A)
A.on_lose(src)
if(A.action)
A.action.Remove(src)
/mob/living/proc/add_abilities_to_panel()
for(var/obj/effect/proc_holder/A in abilities)
statpanel("[A.panel]",A.get_panel_text(),A)

View File

@@ -77,3 +77,5 @@
var/datum/language/selected_default_language
var/last_words //used for database logging
var/list/obj/effect/proc_holder/abilities = list()

View File

@@ -97,7 +97,7 @@
/mob/living/silicon/ai/proc/announcement()
var/static/announcing_vox = 0 // Stores the time of the last announcement
if(announcing_vox > world.time)
to_chat(src, "<span class='notice'>Please wait [round((announcing_vox - world.time) / 10)] seconds.</span>")
to_chat(src, "<span class='notice'>Please wait [DisplayTimeText(announcing_vox - world.time)].</span>")
return
var/message = input(src, "WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", src.last_announcement) as text

View File

@@ -810,7 +810,35 @@
cell = null
qdel(src)
/mob/living/silicon/robot/syndicate
/mob/living/silicon/robot/modules
var/set_module = null
/mob/living/silicon/robot/modules/Initialize()
. = ..()
module.transform_to(set_module)
/mob/living/silicon/robot/modules/standard
set_module = /obj/item/robot_module/standard
/mob/living/silicon/robot/modules/medical
set_module = /obj/item/robot_module/medical
/mob/living/silicon/robot/modules/engineering
set_module = /obj/item/robot_module/engineering
/mob/living/silicon/robot/modules/security
set_module = /obj/item/robot_module/security
/mob/living/silicon/robot/modules/peacekeeper
set_module = /obj/item/robot_module/peacekeeper
/mob/living/silicon/robot/modules/miner
set_module = /obj/item/robot_module/miner
/mob/living/silicon/robot/modules/janitor
set_module = /obj/item/robot_module/janitor
/mob/living/silicon/robot/modules/syndicate
icon_state = "syndie_bloodhound"
faction = list("syndicate")
bubble_icon = "syndibot"
@@ -822,25 +850,24 @@
<b>You are armed with powerful offensive tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \
Your cyborg LMG will slowly produce ammunition from your power supply, and your operative pinpointer will find and locate fellow nuclear operatives. \
<i>Help the operatives secure the disk at all costs!</i></b>"
var/set_module = /obj/item/robot_module/syndicate
set_module = /obj/item/robot_module/syndicate
/mob/living/silicon/robot/syndicate/Initialize()
/mob/living/silicon/robot/modules/syndicate/Initialize()
. = ..()
cell.maxcharge = 25000
cell.charge = 25000
radio = new /obj/item/device/radio/borg/syndicate(src)
module.transform_to(set_module)
laws = new /datum/ai_laws/syndicate_override()
addtimer(CALLBACK(src, .proc/show_playstyle), 5)
/mob/living/silicon/robot/syndicate/proc/show_playstyle()
/mob/living/silicon/robot/modules/syndicate/proc/show_playstyle()
if(playstyle_string)
to_chat(src, playstyle_string)
/mob/living/silicon/robot/syndicate/ResetModule()
/mob/living/silicon/robot/modules/syndicate/ResetModule()
return
/mob/living/silicon/robot/syndicate/medical
/mob/living/silicon/robot/modules/syndicate/medical
icon_state = "syndi-medi"
playstyle_string = "<span class='userdanger'>You are a Syndicate medical cyborg!</span><br>\
<b>You are armed with powerful medical tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,9 @@
/mob/living/silicon/forceMove(atom/destination)
. = ..()
update_camera_location(destination)
//Only bother updating the camera if we actually managed to move
if(.)
update_camera_location(destination)
/mob/living/silicon/proc/do_camera_update(oldLoc)
if(!QDELETED(builtInCamera) && oldLoc != get_turf(src))

View File

@@ -27,7 +27,7 @@
del_on_death = 1
/mob/living/simple_animal/cockroach/death(gibbed)
if(SSticker.cinematic) //If the nuke is going off, then cockroaches are invincible. Keeps the nuke from killing them, cause cockroaches are immune to nukes.
if(SSticker.mode && SSticker.mode.station_was_nuked) //If the nuke is going off, then cockroaches are invincible. Keeps the nuke from killing them, cause cockroaches are immune to nukes.
return
..()

View File

@@ -130,9 +130,9 @@
hacked = TRUE
visualAppearence = CLOCKDRONE
can_be_held = FALSE
flavortext = "<span class='heavy_brass'>You are a cogscarab</span><b>, a clockwork creation of Ratvar. As a cogscarab, you have low health, an inbuilt fabricator that can convert brass \
to power, a set of relatively fast tools, </b><span class='heavy_brass'>can communicate over the Hierophant Network with :b</span><b>, and are immune to extreme \
temperatures and pressures. \nYour goal is to serve the Justiciar and his servants by repairing and defending all they create.</b>"
flavortext = "<b><span class='nezbere'>You are a cogscarab,</span> a tiny building construct of Ratvar. While you're weak and can't recite scripture, \
you have a set of quick tools, as well as a replica fabricator that can create brass and convert objects.<br><br>Work with the servants of Ratvar \
to construct and maintain defenses at the City of Cogs. If there are no servants, use this time to experiment with base designs!"
/mob/living/simple_animal/drone/cogscarab/ratvar //a subtype for spawning when ratvar is alive, has a slab that it can use and a normal fabricator
default_storage = /obj/item/storage/toolbox/brass/prefilled/ratvar

View File

@@ -159,7 +159,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
resulthealth = round((summoner.health / summoner.maxHealth) * 100, 0.5)
stat(null, "Summoner Health: [resulthealth]%")
if(cooldown >= world.time)
stat(null, "Manifest/Recall Cooldown Remaining: [max(round((cooldown - world.time)*0.1, 0.1), 0)] seconds")
stat(null, "Manifest/Recall Cooldown Remaining: [DisplayTimeText(cooldown - world.time)]")
/mob/living/simple_animal/hostile/guardian/Move() //Returns to summoner if they move out of range
. = ..()

View File

@@ -30,7 +30,7 @@
..()
if(statpanel("Status"))
if(stealthcooldown >= world.time)
stat(null, "Stealth Cooldown Remaining: [max(round((stealthcooldown - world.time)*0.1, 0.1), 0)] seconds")
stat(null, "Stealth Cooldown Remaining: [DisplayTimeText(stealthcooldown - world.time)]")
/mob/living/simple_animal/hostile/guardian/assassin/AttackingTarget()
. = ..()
@@ -79,7 +79,7 @@
updatestealthalert()
toggle = TRUE
else if(!forced)
to_chat(src, "<span class='danger'><B>You cannot yet enter stealth, wait another [max(round((stealthcooldown - world.time)*0.1, 0.1), 0)] seconds!</span></B>")
to_chat(src, "<span class='danger'><B>You cannot yet enter stealth, wait another [DisplayTimeText(stealthcooldown - world.time)]!</span></B>")
/mob/living/simple_animal/hostile/guardian/assassin/proc/updatestealthalert()
if(stealthcooldown <= world.time)

View File

@@ -14,7 +14,7 @@
..()
if(statpanel("Status"))
if(bomb_cooldown >= world.time)
stat(null, "Bomb Cooldown Remaining: [max(round((bomb_cooldown - world.time)*0.1, 0.1), 0)] seconds")
stat(null, "Bomb Cooldown Remaining: [DisplayTimeText(bomb_cooldown - world.time)]")
/mob/living/simple_animal/hostile/guardian/bomb/AttackingTarget()
. = ..()

View File

@@ -24,7 +24,7 @@
..()
if(statpanel("Status"))
if(beacon_cooldown >= world.time)
stat(null, "Beacon Cooldown Remaining: [max(round((beacon_cooldown - world.time)*0.1, 0.1), 0)] seconds")
stat(null, "Beacon Cooldown Remaining: [DisplayTimeText(beacon_cooldown - world.time)]")
/mob/living/simple_animal/hostile/guardian/healer/AttackingTarget()
. = ..()

View File

@@ -49,6 +49,17 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
var/playable_spider = FALSE
devourable = TRUE
var/datum/action/innate/spider/lay_web/lay_web
var/directive = "" //Message passed down to children, to relay the creator's orders
/mob/living/simple_animal/hostile/poison/giant_spider/Initialize()
. = ..()
lay_web = new
lay_web.Grant(src)
/mob/living/simple_animal/hostile/poison/giant_spider/Destroy()
QDEL_NULL(lay_web)
return ..()
/mob/living/simple_animal/hostile/poison/giant_spider/Topic(href, href_list)
if(href_list["activate"])
@@ -56,6 +67,12 @@
if(istype(ghost) && playable_spider)
humanize_spider(ghost)
/mob/living/simple_animal/hostile/poison/giant_spider/Login()
..()
if(directive)
to_chat(src, "<span class='notice'>Your mother left you a directive! Follow it at all costs.</span>")
to_chat(src, "<span class='spider'><b>[directive]</b></span>")
/mob/living/simple_animal/hostile/poison/giant_spider/attack_ghost(mob/user)
if(!humanize_spider(user))
return ..()
@@ -87,8 +104,26 @@
poison_per_bite = 3
var/atom/movable/cocoon_target
var/fed = 0
var/obj/effect/proc_holder/wrap/wrap
var/datum/action/innate/spider/lay_eggs/lay_eggs
var/datum/action/innate/spider/set_directive/set_directive
var/static/list/consumed_mobs = list() //the tags of mobs that have been consumed by nurse spiders to lay eggs
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/Initialize()
. = ..()
wrap = new
AddAbility(wrap)
lay_eggs = new
lay_eggs.Grant(src)
set_directive = new
set_directive.Grant(src)
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/Destroy()
RemoveAbility(wrap)
QDEL_NULL(lay_eggs)
QDEL_NULL(set_directive)
return ..()
//hunters have the most poison and move the fastest, so they can find prey
/mob/living/simple_animal/hostile/poison/giant_spider/hunter
desc = "Furry and black, it makes you shudder to look at it. This one has sparkling purple eyes."
@@ -117,6 +152,7 @@
move_to_delay = 4
poison_type = "venom" //all in venom, glass cannon. you bite 5 times and they are DEFINITELY dead, but 40 health and you are extremely obvious. Ambush, maybe?
speed = 1
gold_core_spawnable = 0
//tarantulas are really tanky, regenerating (maybe), hulky monster but are also extremely slow, so.
/mob/living/simple_animal/hostile/poison/giant_spider/tarantula
@@ -134,6 +170,7 @@
speed = 7
status_flags = NONE
mob_size = MOB_SIZE_LARGE
gold_core_spawnable = 0
/mob/living/simple_animal/hostile/poison/giant_spider/tarantula/movement_delay()
var/turf/T = get_turf(src)
@@ -153,12 +190,16 @@
maxHealth = 40
health = 40
var/datum/action/innate/spider/comm/letmetalkpls
gold_core_spawnable = 0
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/midwife/Initialize()
. = ..()
letmetalkpls = new
letmetalkpls.Grant(src)
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/midwife/Destroy()
QDEL_NULL(letmetalkpls)
return ..()
/mob/living/simple_animal/hostile/poison/giant_spider/ice //spiders dont usually like tempatures of 140 kelvin who knew
name = "giant ice spider"
@@ -222,11 +263,11 @@
//second, spin a sticky spiderweb on this tile
var/obj/structure/spider/stickyweb/W = locate() in get_turf(src)
if(!W)
Web()
lay_web.Activate()
else
//third, lay an egg cluster there
if(fed)
LayEggs()
lay_eggs.Activate()
else
//fourthly, cocoon any nearby items so those pesky pinkskins can't use them
for(var/obj/O in can_see)
@@ -244,62 +285,28 @@
else if(busy == MOVING_TO_TARGET && cocoon_target)
if(get_dist(src, cocoon_target) <= 1)
Wrap()
cocoon()
else
busy = SPIDER_IDLE
stop_automated_movement = FALSE
/mob/living/simple_animal/hostile/poison/giant_spider/verb/Web()
set name = "Lay Web"
set category = "Spider"
set desc = "Spread a sticky web to slow down prey."
var/T = src.loc
if(stat == DEAD)
return
if(busy != SPINNING_WEB)
busy = SPINNING_WEB
src.visible_message("<span class='notice'>\the [src] begins to secrete a sticky substance.</span>")
stop_automated_movement = 1
if(do_after(src, 40, target = T))
if(busy == SPINNING_WEB && src.loc == T)
new /obj/structure/spider/stickyweb(T)
busy = SPIDER_IDLE
stop_automated_movement = FALSE
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/verb/Wrap()
set name = "Wrap"
set category = "Spider"
set desc = "Wrap up prey to feast upon and objects for safe keeping."
if(stat == DEAD)
return
if(!cocoon_target)
var/list/choices = list()
for(var/mob/living/L in view(1,src))
if(L == src || L.anchored)
continue
if(istype(L, /mob/living/simple_animal/hostile/poison/giant_spider))
continue
if(Adjacent(L))
choices += L
for(var/obj/O in src.loc)
if(O.anchored)
continue
if(Adjacent(O))
choices += O
var/temp_input = input(src,"What do you wish to cocoon?") in null|choices
if(temp_input && !cocoon_target)
cocoon_target = temp_input
if(stat != DEAD && cocoon_target && Adjacent(cocoon_target) && !cocoon_target.anchored)
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/proc/cocoon()
if(stat != DEAD && cocoon_target && !cocoon_target.anchored)
if(cocoon_target == src)
to_chat(src, "<span class='warning'>You can't wrap yourself!</span>")
return
if(istype(cocoon_target, /mob/living/simple_animal/hostile/poison/giant_spider))
to_chat(src, "<span class='warning'>You can't wrap other spiders!</span>")
return
if(!Adjacent(cocoon_target))
to_chat(src, "<span class='warning'>You can't reach [cocoon_target]!</span>")
return
if(busy == SPINNING_COCOON)
to_chat(src, "<span class='warning'>You're already spinning a cocoon!</span>")
return //we're already doing this, don't cancel out or anything
busy = SPINNING_COCOON
visible_message("<span class='notice'>\the [src] begins to secrete a sticky substance around \the [cocoon_target].</span>")
visible_message("<span class='notice'>[src] begins to secrete a sticky substance around [cocoon_target].</span>","<span class='notice'>You begin wrapping [cocoon_target] into a cocoon.</span>")
stop_automated_movement = TRUE
walk(src,0)
if(do_after(src, 50, target = cocoon_target))
@@ -310,7 +317,8 @@
if(L.blood_volume && (L.stat != DEAD || !consumed_mobs[L.tag])) //if they're not dead, you can consume them anyway
consumed_mobs[L.tag] = TRUE
fed++
visible_message("<span class='danger'>\the [src] sticks a proboscis into \the [L] and sucks a viscous substance out.</span>")
lay_eggs.UpdateButtonIcon(TRUE)
visible_message("<span class='danger'>[src] sticks a proboscis into [L] and sucks a viscous substance out.</span>","<span class='notice'>You suck the nutriment out of [L], feeding you enough to lay a cluster of eggs.</span>")
L.death() //you just ate them, they're dead.
else
to_chat(src, "<span class='warning'>[L] cannot sate your hunger!</span>")
@@ -322,35 +330,155 @@
busy = SPIDER_IDLE
stop_automated_movement = FALSE
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/verb/LayEggs()
set name = "Lay Eggs"
set category = "Spider"
set desc = "Lay a clutch of eggs, but you must wrap a creature for feeding first."
/datum/action/innate/spider
icon_icon = 'icons/mob/actions/actions_animal.dmi'
background_icon_state = "bg_alien"
var/obj/structure/spider/eggcluster/E = locate() in get_turf(src)
if(stat == DEAD)
/datum/action/innate/spider/lay_web
name = "Spin Web"
desc = "Spin a web to slow down potential prey."
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "lay_web"
/datum/action/innate/spider/lay_web/Activate()
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
return
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/S = owner
if(!isturf(S.loc))
return
var/turf/T = get_turf(S)
var/obj/structure/spider/stickyweb/W = locate() in T
if(W)
to_chat(S, "<span class='warning'>There's already a web here!</span>")
return
if(S.busy != SPINNING_WEB)
S.busy = SPINNING_WEB
S.visible_message("<span class='notice'>[S] begins to secrete a sticky substance.</span>","<span class='notice'>You begin to lay a web.</span>")
S.stop_automated_movement = TRUE
if(do_after(S, 40, target = T))
if(S.busy == SPINNING_WEB && S.loc == T)
new /obj/structure/spider/stickyweb(T)
S.busy = SPIDER_IDLE
S.stop_automated_movement = FALSE
else
to_chat(S, "<span class='warning'>You're already spinning a web!</span>")
/obj/effect/proc_holder/wrap
name = "Wrap"
panel = "Spider"
active = FALSE
datum/action/spell_action/action = null
desc = "Wrap something or someone in a cocoon. If it's a living being, you'll also consume them, allowing you to lay eggs."
ranged_mousepointer = 'icons/effects/wrap_target.dmi'
action_icon = 'icons/mob/actions/actions_animal.dmi'
action_icon_state = "wrap_0"
action_background_icon_state = "bg_alien"
/obj/effect/proc_holder/wrap/Initialize()
. = ..()
action = new(src)
/obj/effect/proc_holder/wrap/update_icon()
action.button_icon_state = "wrap_[active]"
action.UpdateButtonIcon()
/obj/effect/proc_holder/wrap/Click()
if(!istype(usr, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
return TRUE
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/user = usr
activate(user)
return TRUE
/obj/effect/proc_holder/wrap/proc/activate(mob/living/user)
var/message
if(active)
message = "<span class='notice'>You no longer prepare to wrap something in a cocoon.</span>"
remove_ranged_ability(message)
else
message = "<span class='notice'>You prepare to wrap something in a cocoon. <B>Left-click your target to start wrapping!</B></span>"
add_ranged_ability(user, message, TRUE)
return 1
/obj/effect/proc_holder/wrap/InterceptClickOn(mob/living/caller, params, atom/target)
if(..())
return
if(ranged_ability_user.incapacitated() || !istype(ranged_ability_user, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
remove_ranged_ability()
return
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/user = ranged_ability_user
if(user.Adjacent(target) && (ismob(target) || isobj(target)))
var/atom/movable/target_atom = target
if(target_atom.anchored)
return
user.cocoon_target = target_atom
INVOKE_ASYNC(user, /mob/living/simple_animal/hostile/poison/giant_spider/nurse/.proc/cocoon)
remove_ranged_ability()
return TRUE
/obj/effect/proc_holder/wrap/on_lose(mob/living/carbon/user)
remove_ranged_ability()
/datum/action/innate/spider/lay_eggs
name = "Lay Eggs"
desc = "Lay a cluster of eggs, which will soon grow into more spiders. You must wrap a living being to do this."
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "lay_eggs"
/datum/action/innate/spider/lay_eggs/IsAvailable()
if(..())
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
return 0
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/S = owner
if(S.fed)
return 1
return 0
/datum/action/innate/spider/lay_eggs/Activate()
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
return
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/S = owner
var/obj/structure/spider/eggcluster/E = locate() in get_turf(S)
if(E)
to_chat(src, "<span class='warning'>There is already a cluster of eggs here!</span>")
else if(!fed)
to_chat(src, "<span class='warning'>You are too hungry to do this!</span>")
else if(busy != LAYING_EGGS)
busy = LAYING_EGGS
src.visible_message("<span class='notice'>\the [src] begins to lay a cluster of eggs.</span>")
stop_automated_movement = 1
if(do_after(src, 50, target = src.loc))
if(busy == LAYING_EGGS)
E = locate() in get_turf(src)
if(!E)
var/obj/structure/spider/eggcluster/C = new /obj/structure/spider/eggcluster(src.loc)
if(ckey)
C.player_spiders = 1
C.poison_type = poison_type
C.poison_per_bite = poison_per_bite
C.faction = faction.Copy()
fed--
busy = SPIDER_IDLE
stop_automated_movement = FALSE
to_chat(S, "<span class='warning'>There is already a cluster of eggs here!</span>")
else if(!S.fed)
to_chat(S, "<span class='warning'>You are too hungry to do this!</span>")
else if(S.busy != LAYING_EGGS)
S.busy = LAYING_EGGS
S.visible_message("<span class='notice'>[S] begins to lay a cluster of eggs.</span>","<span class='notice'>You begin to lay a cluster of eggs.</span>")
S.stop_automated_movement = TRUE
if(do_after(S, 50, target = get_turf(S)))
if(S.busy == LAYING_EGGS)
E = locate() in get_turf(S)
if(!E || !isturf(S.loc))
var/obj/structure/spider/eggcluster/C = new /obj/structure/spider/eggcluster(get_turf(S))
if(S.ckey)
C.player_spiders = TRUE
C.directive = S.directive
C.poison_type = S.poison_type
C.poison_per_bite = S.poison_per_bite
C.faction = S.faction.Copy()
S.fed--
UpdateButtonIcon(TRUE)
S.busy = SPIDER_IDLE
S.stop_automated_movement = FALSE
/datum/action/innate/spider/set_directive
name = "Set Directive"
desc = "Set a directive for your children to follow."
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "directive"
/datum/action/innate/spider/set_directive/Activate()
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
return
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/S = owner
S.directive = stripped_input(S, "Enter the new directive", "Create directive", "[S.directive]", MAX_MESSAGE_LEN)
/mob/living/simple_animal/hostile/poison/giant_spider/Login()
. = ..()
@@ -362,7 +490,8 @@
/datum/action/innate/spider/comm
name = "Command"
button_icon_state = "cult_comms"
desc = "Send a command to all living spiders."
button_icon_state = "command"
/datum/action/innate/spider/comm/IsAvailable()
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse/midwife))
@@ -370,19 +499,22 @@
return TRUE
/datum/action/innate/spider/comm/Trigger()
var/input = stripped_input(usr, "Input a message for your legions to follow.", "Command", "")
var/input = stripped_input(owner, "Input a command for your legions to follow.", "Command", "")
if(QDELETED(src) || !input || !IsAvailable())
return FALSE
spider_command(usr, input)
spider_command(owner, input)
return TRUE
/datum/action/innate/spider/comm/proc/spider_command(mob/living/user, message)
if(!message)
return
var/my_message
my_message = "<FONT size = 3><b>COMMAND FROM SPIDER QUEEN:</b> [message]</FONT>"
my_message = "<span class='spider'><b>Command from [user]:</b> [message]</span>"
for(var/mob/living/simple_animal/hostile/poison/giant_spider/M in GLOB.spidermobs)
to_chat(M, my_message)
for(var/M in GLOB.dead_mob_list)
var/link = FOLLOW_LINK(M, user)
to_chat(M, "[link] [my_message]")
log_talk(user, "SPIDERCOMMAND: [key_name(user)] : [message]",LOGSAY)
/mob/living/simple_animal/hostile/poison/giant_spider/handle_temperature_damage()

View File

@@ -164,6 +164,7 @@ Difficulty: Medium
hitsound = 'sound/weapons/sear.ogg'
var/storm_type = /datum/weather/ash_storm
var/storm_cooldown = 0
var/static/list/excluded_areas = list(/area/reebe/city_of_cogs)
/obj/item/staff/storm/attack_self(mob/user)
if(storm_cooldown > world.time)
@@ -171,6 +172,9 @@ Difficulty: Medium
return
var/area/user_area = get_area(user)
if(user_area.type in excluded_areas)
to_chat(user, "<span class='warning'>Something is preventing you from using the staff here.</span>")
return
var/datum/weather/A
for(var/V in SSweather.existing_weather)
var/datum/weather/W = V

View File

@@ -144,44 +144,42 @@
return TRUE
/proc/UnlockMedal(medal,client/player)
set waitfor = FALSE
if(!player || !medal)
return
if(global.medal_hub && global.medal_pass && global.medals_enabled)
spawn()
var/result = world.SetMedal(medal, player, global.medal_hub, global.medal_pass)
if(isnull(result))
global.medals_enabled = FALSE
log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.ckey]")
message_admins("Error! Failed to contact hub to award [medal] medal to [player.ckey]!")
else if (result)
to_chat(player, "<span class='greenannounce'><B>Achievement unlocked: [medal]!</B></span>")
var/result = world.SetMedal(medal, player, global.medal_hub, global.medal_pass)
if(isnull(result))
global.medals_enabled = FALSE
log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.ckey]")
message_admins("Error! Failed to contact hub to award [medal] medal to [player.ckey]!")
else if (result)
to_chat(player, "<span class='greenannounce'><B>Achievement unlocked: [medal]!</B></span>")
/proc/SetScore(score,client/player,increment,force)
set waitfor = FALSE
if(!score || !player)
return
if(global.medal_hub && global.medal_pass && global.medals_enabled)
spawn()
var/list/oldscore = GetScore(score,player,1)
var/list/oldscore = GetScore(score,player,1)
if(increment)
if(!oldscore[score])
oldscore[score] = 1
else
oldscore[score] = (text2num(oldscore[score]) + 1)
if(increment)
if(!oldscore[score])
oldscore[score] = 1
else
oldscore[score] = force
oldscore[score] = (text2num(oldscore[score]) + 1)
else
oldscore[score] = force
var/newscoreparam = list2params(oldscore)
var/newscoreparam = list2params(oldscore)
var/result = world.SetScores(player.ckey, newscoreparam, global.medal_hub, global.medal_pass)
var/result = world.SetScores(player.ckey, newscoreparam, global.medal_hub, global.medal_pass)
if(isnull(result))
global.medals_enabled = FALSE
log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.ckey]")
message_admins("Error! Failed to contact hub to set [score] score for [player.ckey]!")
if(isnull(result))
global.medals_enabled = FALSE
log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.ckey]")
message_admins("Error! Failed to contact hub to set [score] score for [player.ckey]!")
/proc/GetScore(score,client/player,returnlist)

View File

@@ -21,6 +21,11 @@
var/w_class_open = WEIGHT_CLASS_BULKY
var/slowdown_open = TRUE
/obj/item/device/modular_computer/laptop/examine(mob/user)
..()
if(screen_on)
to_chat(user, "<span class='notice'>Alt-click to close it.</span>")
/obj/item/device/modular_computer/laptop/Initialize()
. = ..()

View File

@@ -44,6 +44,10 @@
desc = "A stationary computer. This one comes preloaded with research programs."
_has_ai = 1
/obj/machinery/modular_computer/console/preset/research/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to eject the intelliCard.</span>")
/obj/machinery/modular_computer/console/preset/research/install_programs()
var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor())
@@ -59,6 +63,10 @@
_has_id_slot = 1
_has_printer = 1
/obj/machinery/modular_computer/console/preset/command/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click [src] to eject the identification card.</span>")
/obj/machinery/modular_computer/console/preset/command/install_programs()
var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
hard_drive.store_file(new/datum/computer_file/program/chatclient())
@@ -72,4 +80,4 @@
/obj/machinery/modular_computer/console/preset/civilian/install_programs()
var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
hard_drive.store_file(new/datum/computer_file/program/chatclient())
hard_drive.store_file(new/datum/computer_file/program/nttransfer())
hard_drive.store_file(new/datum/computer_file/program/nttransfer())

View File

@@ -170,12 +170,19 @@
t = replacetext(t, "\[td\]", "<td>")
t = replacetext(t, "\[cell\]", "<td>")
t = replacetext(t, "\[tab\]", "&nbsp;&nbsp;&nbsp;&nbsp;")
t = parsemarkdown_basic(t)
return t
/datum/computer_file/program/filemanager/proc/prepare_printjob(t) // Additional stuff to parse if we want to print it and make a happy Head of Personnel. Forms FTW.
t = replacetext(t, "\[field\]", "<span class=\"paper_field\"></span>")
t = replacetext(t, "\[sign\]", "<span class=\"paper_field\"></span>")
t = parse_tags(t)
t = replacetext(t, regex("(?:%s(?:ign)|%f(?:ield))(?=\\s|$)", "ig"), "<span class=\"paper_field\"></span>")
return t
/datum/computer_file/program/filemanager/ui_data(mob/user)

View File

@@ -71,13 +71,9 @@ Contents:
var/datum/antagonist/ninja/ninjadatum = add_ninja(Ninja)
ninjadatum.equip_space_ninja()
Ninja.internal = Ninja.s_store
Ninja.update_internals_hud_icon(1)
if(Ninja.mind != Mind) //something has gone wrong!
throw EXCEPTION("Ninja created with incorrect mind")
SSticker.mode.update_ninja_icons_added(Ninja)
spawned_mobs += Ninja
message_admins("[key_name_admin(Ninja)] has been made into a ninja by an event.")

View File

@@ -0,0 +1,25 @@
/datum/outfit/ninja
name = "Space Ninja"
uniform = /obj/item/clothing/under/color/black
suit = /obj/item/clothing/suit/space/space_ninja
glasses = /obj/item/clothing/glasses/night
mask = /obj/item/clothing/mask/gas/space_ninja
head = /obj/item/clothing/head/helmet/space/space_ninja
ears = /obj/item/device/radio/headset
shoes = /obj/item/clothing/shoes/space_ninja
gloves = /obj/item/clothing/gloves/space_ninja
back = /obj/item/tank/jetpack/carbondioxide
l_pocket = /obj/item/grenade/plastic/x4
r_pocket = /obj/item/tank/internals/emergency_oxygen
internals_slot = slot_r_store
belt = /obj/item/dash/energy_katana
implants = list(/obj/item/implant/explosive)
/datum/outfit/ninja/post_equip(mob/living/carbon/human/H)
if(istype(H.wear_suit, suit))
var/obj/item/clothing/suit/space/space_ninja/S = H.wear_suit
if(istype(H.belt, belt))
S.energyKatana = H.belt
S.randomize_param()

View File

@@ -64,6 +64,8 @@
/obj/item/paper/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to fold it.</span>")
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/paper)
assets.send(user)
@@ -79,7 +81,7 @@
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)]<HR>[stamps]</BODY></HTML>", "window=[name]")
onclose(user, "[name]")
else
to_chat(user, "<span class='notice'>It is too far away.</span>")
to_chat(user, "<span class='warning'>You're too far away to read it!</span>")
/obj/item/paper/verb/rename()
@@ -101,10 +103,12 @@
name = "paper[(n_name ? text("- '[n_name]'") : null)]"
add_fingerprint(usr)
/obj/item/paper/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] scratches a grid on [user.p_their()] wrist with the paper! It looks like [user.p_theyre()] trying to commit sudoku...</span>")
return (BRUTELOSS)
/obj/item/paper/attack_self(mob/user)
user.examinate(src)
if(rigged && (SSevents.holidays && SSevents.holidays[APRIL_FOOLS]))
@@ -187,47 +191,15 @@
if(length(t) < 1) //No input means nothing needs to be parsed
return
// t = copytext(sanitize(t),1,MAX_MESSAGE_LEN)
t = replacetext(t, "\[center\]", "<center>")
t = replacetext(t, "\[/center\]", "</center>")
t = replacetext(t, "\[br\]", "<BR>")
t = replacetext(t, "\n", "<BR>")
t = replacetext(t, "\[b\]", "<B>")
t = replacetext(t, "\[/b\]", "</B>")
t = replacetext(t, "\[i\]", "<I>")
t = replacetext(t, "\[/i\]", "</I>")
t = replacetext(t, "\[u\]", "<U>")
t = replacetext(t, "\[/u\]", "</U>")
t = replacetext(t, "\[large\]", "<font size=\"4\">")
t = replacetext(t, "\[/large\]", "</font>")
t = replacetext(t, "\[sign\]", "<font face=\"[SIGNFONT]\"><i>[user.real_name]</i></font>")
t = replacetext(t, "\[field\]", "<span class=\"paper_field\"></span>")
t = replacetext(t, "\[tab\]", "&nbsp;&nbsp;&nbsp;&nbsp;")
t = parsemarkdown(t, user, iscrayon)
if(!iscrayon)
t = replacetext(t, "\[*\]", "<li>")
t = replacetext(t, "\[hr\]", "<HR>")
t = replacetext(t, "\[small\]", "<font size = \"1\">")
t = replacetext(t, "\[/small\]", "</font>")
t = replacetext(t, "\[list\]", "<ul>")
t = replacetext(t, "\[/list\]", "</ul>")
t = "<font face=\"[P.font]\" color=[P.colour]>[t]</font>"
else // If it is a crayon, and he still tries to use these, make them empty!
else
var/obj/item/toy/crayon/C = P
t = replacetext(t, "\[*\]", "")
t = replacetext(t, "\[hr\]", "")
t = replacetext(t, "\[small\]", "")
t = replacetext(t, "\[/small\]", "")
t = replacetext(t, "\[list\]", "")
t = replacetext(t, "\[/list\]", "")
t = "<font face=\"[CRAYON_FONT]\" color=[C.paint_color]><b>[t]</b></font>"
// t = replacetext(t, "#", "") // Junk converted to nothing!
//Count the fields
// Count the fields
var/laststart = 1
while(1)
var/i = findtext(t, "<span class=\"paper_field\">", laststart)
@@ -253,22 +225,23 @@
/obj/item/paper/proc/openhelp(mob/user)
user << browse({"<HTML><HEAD><TITLE>Paper Help</TITLE></HEAD>
<BODY>
You can use backslash (\\) to escape special characters.<br>
<br>
<b><center>Crayon&Pen commands</center></b><br>
<br>
\[br\] : Creates a linebreak.<br>
\[center\] - \[/center\] : Centers the text.<br>
\[b\] - \[/b\] : Makes the text <b>bold</b>.<br>
\[i\] - \[/i\] : Makes the text <i>italic</i>.<br>
\[u\] - \[/u\] : Makes the text <u>underlined</u>.<br>
\[large\] - \[/large\] : Increases the <font size = \"4\">size</font> of the text.<br>
\[sign\] : Inserts a signature of your name in a foolproof way.<br>
\[field\] : Inserts an invisible field which lets you start type from there. Useful for forms.<br>
# text : Defines a header.<br>
|text| : Centers the text.<br>
**text** : Makes the text <b>bold</b>.<br>
*text* : Makes the text <i>italic</i>.<br>
^text^ : Increases the <font size = \"4\">size</font> of the text.<br>
%s : Inserts a signature of your name in a foolproof way.<br>
%f : Inserts an invisible field which lets you start type from there. Useful for forms.<br>
<br>
<b><center>Pen exclusive commands</center></b><br>
\[small\] - \[/small\] : Decreases the <font size = \"1\">size</font> of the text.<br>
\[list\] - \[/list\] : A list.<br>
\[*\] : A dot used for lists.<br>
\[hr\] : Adds a horizontal rule.
((text)) : Decreases the <font size = \"1\">size</font> of the text.<br>
* item : An unordered list item.<br>
&nbsp;&nbsp;* item: An unordered list child item.<br>
--- : Adds a horizontal rule.
</BODY></HTML>"}, "window=paper_help")
@@ -399,4 +372,5 @@
return
/obj/item/paper/crumpled/bloody
icon_state = "scrap_bloodied"
icon_state = "scrap_bloodied"

View File

@@ -84,6 +84,7 @@
var/beenhit = 0 // used for counting how many times it has been hit, used for Aliens at the moment
var/mob/living/silicon/ai/occupier = null
var/transfer_in_progress = FALSE //Is there an AI being transferred out of us?
var/obj/item/clockwork/integration_cog/integration_cog //Is there a cog siphoning power?
var/longtermpower = 10
var/auto_name = 0
var/failure_timer = 0
@@ -215,6 +216,8 @@
else
to_chat(user, "It's [ !terminal ? "not" : "" ] wired up.")
to_chat(user, "The electronics are[!has_electronics?"n't":""] installed.")
if(user.Adjacent(src) && integration_cog)
to_chat(user, "<span class='warning'>[src]'s innards have been replaced by strange brass machinery!</span>")
else
if (stat & MAINT)
@@ -224,6 +227,8 @@
else
to_chat(user, "The cover is closed.")
if(integration_cog && is_servant_of_ratvar(user))
to_chat(user, "<span class='brass'>There is an integration cog installed!</span>")
// update the APC icon to show the three base states
// also add overlays for indicator lights
@@ -408,6 +413,17 @@
"<span class='notice'>You remove the power control board.</span>")
new /obj/item/electronics/apc(loc)
return
else if(integration_cog)
user.visible_message("<span class='notice'>[user] starts prying [integration_cog] from [src]...</span>", \
"<span class='notice'>You painstakingly start tearing [integration_cog] out of [src]'s guts...</span>")
playsound(src, W.usesound, 50, TRUE)
if(!do_after(user, 100 * W.toolspeed, target = src))
return
user.visible_message("<span class='notice'>[user] destroys [integration_cog] in [src]!</span>", \
"<span class='notice'>[integration_cog] comes free with a clank and snaps in two as the machinery returns to normal!</span>")
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
QDEL_NULL(integration_cog)
return
else if (opened!=2) //cover isn't removed
opened = 0
coverlocked = TRUE //closing cover relocks it
@@ -625,6 +641,33 @@
if (opened==2)
opened = 1
update_icon()
else if(istype(W, /obj/item/clockwork/integration_cog) && is_servant_of_ratvar(user))
if(integration_cog)
to_chat(user, "<span class='warning'>This APC already has a cog.</span>")
return
if(!opened)
user.visible_message("<span class='warning'>[user] slices [src]'s cover lock, and it swings wide open!</span>", \
"<span class='alloy'>You slice [src]'s cover lock apart with [W], and the cover swings open.</span>")
opened = TRUE
update_icon()
else
user.visible_message("<span class='warning'>[user] presses [W] into [src]!</span>", \
"<span class='alloy'>You hold [W] in place within [src], and it slowly begins to warm up...</span>")
playsound(src, 'sound/machines/click.ogg', 50, TRUE)
if(!do_after(user, 70, target = src))
return
user.visible_message("<span class='warning'>[user] installs [W] in [src]!</span>", \
"<span class='alloy'>Replicant alloy rapidly covers the APC's innards, replacing the machinery.</span><br>\
<span class='brass'>This APC will now passively provide power for the cult!</span>")
playsound(user, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE)
user.transferItemToLoc(W, src)
integration_cog = W
START_PROCESSING(SSfastprocess, W)
playsound(src, 'sound/machines/clockcult/steam_whoosh.ogg', 50, FALSE)
opened = FALSE
locked = FALSE
update_icon()
return
else if(panel_open && !opened && is_wire_tool(W))
wires.interact(user)
else
@@ -695,7 +738,7 @@
/obj/machinery/power/apc/ui_data(mob/user)
var/list/data = list(
"locked" = locked,
"locked" = integration_cog ? !is_servant_of_ratvar(user) : locked,
"failTime" = failure_timer,
"isOperating" = operating,
"externalPower" = main_status,

View File

@@ -73,7 +73,6 @@
resolved = TRUE
sound_to_playing_players('sound/machines/alarm.ogg')
addtimer(CALLBACK(GLOBAL_PROC, .proc/cult_ending_helper), 120)
addtimer(CALLBACK(GLOBAL_PROC, .proc/ending_helper), 220)
/obj/singularity/narsie/large/cult/Destroy()
GLOB.cult_narsie = null
@@ -83,7 +82,7 @@
SSticker.force_ending = 1
/proc/cult_ending_helper(var/no_explosion = 0)
SSticker.station_explosion_cinematic(no_explosion, "cult", null)
Cinematic(CINEMATIC_CULT,world,CALLBACK(GLOBAL_PROC,.ending_helper))
/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob)

View File

@@ -204,8 +204,8 @@
/obj/machinery/particle_accelerator/control_box/proc/toggle_power()
active = !active
investigate_log("turned [active?"<font color='green'>ON</font>":"<font color='red'>OFF</font>"] by [usr ? key_name(usr) : "outside forces"]", INVESTIGATE_SINGULO)
message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? key_name_admin(usr) : "outside forces"](<A HREF='?_src_=holder;[HrefToken()];adminmoreinfo=\ref[usr]'>?</A>) (<A HREF='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[usr]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? "[key_name(usr)]" : "outside forces"] in ([x],[y],[z])")
message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? key_name_admin(usr) : "outside forces"][ADMIN_QUE(usr)] [ADMIN_FLW(usr)] in [ADMIN_COORDJMP(src)]",0,1)
log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? "[key_name(usr)]" : "outside forces"] in [COORD(src)]")
if(active)
use_power = ACTIVE_POWER_USE
for(var/CP in connected_parts)

View File

@@ -537,7 +537,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
to_chat(user, "<span class='notice'>You carefully begin to scrape \the [src] with \the [W]...</span>")
if(do_after(user, 60 * W.toolspeed, TRUE, src))
to_chat(user, "<span class='notice'>You extract a sliver from \the [src]. \The [src] begins to react violently!</span>")
new /obj/item/nuke_core/supermatter_sliver(user.loc)
new /obj/item/nuke_core/supermatter_sliver(drop_location())
matter_power += 200
else if(user.dropItemToGround(W))
user.visible_message("<span class='danger'>As [user] touches \the [src] with \a [W], silence fills the room...</span>",\

View File

@@ -136,13 +136,27 @@
boolets += magazine.ammo_count()
return boolets
#define BRAINS_BLOWN_THROW_RANGE 3
#define BRAINS_BLOWN_THROW_SPEED 1
/obj/item/gun/ballistic/suicide_act(mob/user)
if (chambered && chambered.BB && can_trigger_gun(user) && !chambered.BB.nodamage)
var/obj/item/organ/brain/B = user.getorganslot("brain")
if (B && chambered && chambered.BB && can_trigger_gun(user) && !chambered.BB.nodamage)
user.visible_message("<span class='suicide'>[user] is putting the barrel of [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!</span>")
sleep(25)
if(user.is_holding(src))
var/turf/T = get_turf(user)
process_fire(user, user, 0, zone_override = "head")
user.visible_message("<span class='suicide'>[user] blows [user.p_their()] brain[user.p_s()] out with [src]!</span>")
var/turf/target = get_ranged_target_turf(user, turn(user.dir, 180), BRAINS_BLOWN_THROW_RANGE)
B.Remove(user)
B.forceMove(T)
var/datum/dna/user_dna
if(iscarbon(user))
var/mob/living/carbon/C = user
user_dna = C.dna
B.add_blood(user_dna)
var/datum/callback/gibspawner = CALLBACK(GLOBAL_PROC, /proc/spawn_atom_to_turf, /obj/effect/gibspawner/generic, B, 1, FALSE, list(user_dna))
B.throw_at(target, BRAINS_BLOWN_THROW_RANGE, BRAINS_BLOWN_THROW_SPEED, callback=gibspawner)
return(BRUTELOSS)
else
user.visible_message("<span class='suicide'>[user] panics and starts choking to death!</span>")
@@ -151,8 +165,8 @@
user.visible_message("<span class='suicide'>[user] is pretending to blow [user.p_their()] brain[user.p_s()] out with [src]! It looks like [user.p_theyre()] trying to commit suicide!</b></span>")
playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1)
return (OXYLOSS)
#undef BRAINS_BLOWN_THROW_SPEED
#undef BRAINS_BLOWN_THROW_RANGE
/obj/item/gun/ballistic/proc/sawoff(mob/user)
if(sawn_state == SAWN_OFF)

View File

@@ -213,6 +213,10 @@
var/toggled = FALSE
var/obj/item/ammo_box/magazine/internal/shot/alternate_magazine
/obj/item/gun/ballistic/shotgun/automatic/dual_tube/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to pump it.</span>")
/obj/item/gun/ballistic/shotgun/automatic/dual_tube/Initialize()
. = ..()
if (!alternate_magazine)

View File

@@ -139,9 +139,9 @@
if("syndiborg")
var/path
if(prob(50))
path = /mob/living/silicon/robot/syndicate
path = /mob/living/silicon/robot/modules/syndicate
else
path = /mob/living/silicon/robot/syndicate/medical
path = /mob/living/silicon/robot/modules/syndicate/medical
new_mob = new path(M.loc)
if("drone")
new_mob = new /mob/living/simple_animal/drone/polymorphed(M.loc)

View File

@@ -151,6 +151,12 @@
for(var/i in 1 to 4 + rand(1,2))
var/chosen = pick(borks)
var/obj/B = new chosen(T)
if(prob(5))//Fry it!
var/obj/item/reagent_containers/food/snacks/deepfryholder/D = new(T)
var/datum/reagents/reagents = new(25)
reagents.add_reagent("nutriment", 25)
D.fry(B, reagents)
B = D
if(prob(50))
for(var/j in 1 to rand(1, 3))
step(B, pick(NORTH,SOUTH,EAST,WEST))
@@ -173,6 +179,7 @@
/obj/item/reagent_containers/food/snacks/soup,
/obj/item/reagent_containers/food/snacks/grown,
/obj/item/reagent_containers/food/snacks/grown/mushroom,
/obj/item/reagent_containers/food/snacks/deepfryholder
)
blocked |= typesof(/obj/item/reagent_containers/food/snacks/customizable)

View File

@@ -542,84 +542,6 @@
log_admin("[key_name(G)] was made a golem by [key_name(user)].")
qdel(src)
/obj/effect/timestop
anchored = TRUE
name = "chronofield"
desc = "ZA WARUDO"
icon = 'icons/effects/160x160.dmi'
icon_state = "time"
layer = FLY_LAYER
pixel_x = -64
pixel_y = -64
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/mob/living/immune = list() // the one who creates the timestop is immune
var/list/stopped_atoms = list()
var/freezerange = 2
var/duration = 140
alpha = 125
/obj/effect/timestop/Initialize()
. = ..()
for(var/mob/living/L in GLOB.player_list)
if(locate(/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop) in L.mind.spell_list) //People who can stop time are immune to its effects
immune += L
timestop()
/obj/effect/timestop/proc/timestop()
set waitfor = FALSE
playsound(src, 'sound/magic/timeparadox2.ogg', 75, 1, -1)
for(var/i in 1 to duration-1)
for(var/atom/A in orange (freezerange, src.loc))
if(isliving(A))
var/mob/living/M = A
if(M in immune)
continue
M.Stun(200, 1, 1)
M.anchored = TRUE
if(ishostile(M))
var/mob/living/simple_animal/hostile/H = M
H.AIStatus = AI_OFF
H.LoseTarget()
stopped_atoms |= M
else if(istype(A, /obj/item/projectile))
var/obj/item/projectile/P = A
P.paused = TRUE
stopped_atoms |= P
for(var/mob/living/M in stopped_atoms)
if(get_dist(get_turf(M),get_turf(src)) > freezerange) //If they lagged/ran past the timestop somehow, just ignore them
unfreeze_mob(M)
stopped_atoms -= M
stoplag()
//End
playsound(src, 'sound/magic/timeparadox2.ogg', 75, TRUE, frequency = -1) //reverse!
for(var/mob/living/M in stopped_atoms)
unfreeze_mob(M)
for(var/obj/item/projectile/P in stopped_atoms)
P.paused = FALSE
qdel(src)
return
/obj/effect/timestop/proc/unfreeze_mob(mob/living/M)
M.AdjustStun(-200, 1, 1)
M.anchored = FALSE
if(ishostile(M))
var/mob/living/simple_animal/hostile/H = M
H.AIStatus = initial(H.AIStatus)
/obj/effect/timestop/wizard
duration = 100
/obj/item/stack/tile/bluespace
name = "bluespace floor tile"
singular_name = "floor tile"

View File

@@ -70,7 +70,8 @@
/obj/item/stack/medical/gauze = /datum/species/golem/cloth,
/obj/item/stack/sheet/cloth = /datum/species/golem/cloth,
/obj/item/stack/sheet/mineral/adamantine = /datum/species/golem/adamantine,
/obj/item/stack/sheet/plastic = /datum/species/golem/plastic)
/obj/item/stack/sheet/plastic = /datum/species/golem/plastic,
/obj/item/stack/tile/brass = /datum/species/golem/clockwork)
if(istype(I, /obj/item/stack))
var/obj/item/stack/O = I

View File

@@ -1,7 +1,6 @@
/obj/machinery/computer/camera_advanced/shuttle_docker
name = "navigation computer"
desc = "Used to designate a precise transit location for a spacecraft."
z_lock = ZLEVEL_STATION_PRIMARY
jump_action = null
var/datum/action/innate/shuttledocker_rotate/rotate_action = new
var/datum/action/innate/shuttledocker_place/place_action = new
@@ -133,7 +132,7 @@
if(!V)
continue
var/obj/docking_port/stationary/S = V
if(z_lock && (S.z != z_lock))
if(z_lock.len && !(S.z in z_lock))
continue
if((S.id == shuttlePortId) || jumpto_ports[S.id])
continue
@@ -222,7 +221,7 @@
if(!V)
continue
var/obj/docking_port/stationary/S = V
if(console.z_lock && (S.z != console.z_lock))
if(console.z_lock.len && !(S.z in console.z_lock))
continue
if(console.jumpto_ports[S.id])
L[S.name] = S

View File

@@ -20,7 +20,7 @@
if(href_list["move"])
var/obj/item/circuitboard/computer/syndicate_shuttle/board = circuit
if(board.challenge && world.time < SYNDICATE_CHALLENGE_TIMER)
to_chat(usr, "<span class='warning'>You've issued a combat challenge to the station! You've got to give them at least [round(((SYNDICATE_CHALLENGE_TIMER - world.time) / 10) / 60)] more minutes to allow them to prepare.</span>")
to_chat(usr, "<span class='warning'>You've issued a combat challenge to the station! You've got to give them at least [DisplayTimeText(SYNDICATE_CHALLENGE_TIMER - world.time)] more to allow them to prepare.</span>")
return 0
board.moved = TRUE
..()
@@ -47,8 +47,8 @@
desc = "Used to designate a precise transit location for the syndicate shuttle."
icon_screen = "syndishuttle"
icon_keyboard = "syndie_key"
z_lock = ZLEVEL_STATION_PRIMARY
shuttleId = "syndicate"
station_lock_override = TRUE
shuttlePortId = "syndicate_custom"
shuttlePortName = "custom location"
jumpto_ports = list("syndicate_ne" = 1, "syndicate_nw" = 1, "syndicate_n" = 1, "syndicate_se" = 1, "syndicate_sw" = 1, "syndicate_s" = 1)

View File

@@ -8,6 +8,28 @@
var/ranged_mousepointer
var/mob/living/ranged_ability_user
var/ranged_clickcd_override = -1
var/has_action = TRUE
var/datum/action/spell_action/action = null
var/action_icon = 'icons/mob/actions/actions_spells.dmi'
var/action_icon_state = "spell_default"
var/action_background_icon_state = "bg_spell"
/obj/effect/proc_holder/Initialize()
. = ..()
if(has_action)
action = new(src)
/obj/effect/proc_holder/proc/on_gain(mob/living/user)
return
/obj/effect/proc_holder/proc/on_lose(mob/living/user)
return
/obj/effect/proc_holder/proc/fire(mob/living/user)
return TRUE
/obj/effect/proc_holder/proc/get_panel_text()
return ""
GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for the badmin verb for now
@@ -118,10 +140,10 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
var/critfailchance = 0
var/centcom_cancast = 1 //Whether or not the spell should be allowed on z2
var/action_icon = 'icons/mob/actions/actions_spells.dmi'
var/action_icon_state = "spell_default"
var/action_background_icon_state = "bg_spell"
var/datum/action/spell_action/action
action_icon = 'icons/mob/actions/actions_spells.dmi'
action_icon_state = "spell_default"
action_background_icon_state = "bg_spell"
datum/action/spell_action/spell/action
/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = 0,mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell

View File

@@ -82,7 +82,7 @@ a.updated {
mystocks = S.shareholders[logged_in]
dat += "<hr /><div class='stock'><span class='company'>[S.name]</span> <span class='s_company'>([S.short_name])</span>[S.bankrupt ? " <b style='color:red'>BANKRUPT</b>" : null]<br>"
if (S.last_unification)
dat += "<b>Unified shares</b> [(world.time - S.last_unification) / 600] minutes ago.<br>"
dat += "<b>Unified shares</b> [DisplayTimeText(world.time - S.last_unification)] ago.<br>"
dat += "<b>Current value per share:</b> [S.current_value] | <a href='?src=\ref[src];viewhistory=\ref[S]'>View history</a><br><br>"
dat += "You currently own <b>[mystocks]</b> shares in this company. There are [S.available_shares] purchasable shares on the market currently.<br>"
if (S.bankrupt)

View File

@@ -61,7 +61,7 @@
else
cooldown = revive_cost + world.time
reviving = FALSE
to_chat(owner, "<span class='notice'>Your reviver implant shuts down and starts recharging. It will be ready again in [revive_cost/10] seconds.</span>")
to_chat(owner, "<span class='notice'>Your reviver implant shuts down and starts recharging. It will be ready again in [DisplayTimeText(revive_cost)].</span>")
return
if(cooldown > world.time)

View File

@@ -39,3 +39,8 @@
desc = "These cybernetic eye implants will display a security HUD over everything you see."
origin_tech = "materials=4;programming=4;biotech=3;combat=3"
HUD_type = DATA_HUD_SECURITY_ADVANCED
/obj/item/organ/cyberimp/eyes/hud/security/syndicate
name = "Contraband Security HUD Implant"
desc = "A Cybersun Industries brand Security HUD Implant. These illicit cybernetic eye implants will display a security HUD over everything you see."
syndicate_implant = TRUE

View File

@@ -6,6 +6,7 @@
status = ORGAN_ROBOTIC
var/implant_color = "#FFFFFF"
var/implant_overlay
var/syndicate_implant = FALSE //Makes the implant invisible to health analyzers and medical HUDs.
/obj/item/organ/cyberimp/New(var/mob/M = null)
if(iscarbon(M))

View File

@@ -85,10 +85,9 @@
var/obj/item/organ/tongue/T = H.getorganslot("tongue")
if(!T || T.type != type)
continue
else if(H.dna && H.dna.species.id == "abductor" && user.dna && user.dna.species.id == "abductor")
var/datum/species/abductor/Ayy = user.dna.species
var/datum/species/abductor/Byy = H.dna.species
if(Ayy.team != Byy.team)
if(H.dna && H.dna.species.id == "abductor" && user.dna && user.dna.species.id == "abductor")
var/datum/antagonist/abductor/A = user.mind.has_antag_datum(ANTAG_DATUM_ABDUCTOR)
if(!A || !(H.mind in A.team.members))
continue
to_chat(H, rendered)
for(var/mob/M in GLOB.dead_mob_list)

View File

@@ -91,7 +91,7 @@
. = ..()
if(!IsAvailable())
if(world.time < cords.next_command)
to_chat(owner, "<span class='notice'>You must wait [(cords.next_command - world.time)/10] seconds before Speaking again.</span>")
to_chat(owner, "<span class='notice'>You must wait [DisplayTimeText(cords.next_command - world.time)] before Speaking again.</span>")
return
var/command = input(owner, "Speak with the Voice of God", "Command")
if(QDELETED(src) || QDELETED(owner))
@@ -102,7 +102,7 @@
/obj/item/organ/vocal_cords/colossus/can_speak_with()
if(world.time < next_command)
to_chat(owner, "<span class='notice'>You must wait [(next_command - world.time)/10] seconds before Speaking again.</span>")
to_chat(owner, "<span class='notice'>You must wait [DisplayTimeText(next_command - world.time)] before Speaking again.</span>")
return FALSE
if(!owner)
return FALSE

View File

@@ -65,6 +65,10 @@ Notes:
else if (!title && content)
content = "<p>[content]</p>"
// Strip macros from item names
title = replacetext(title, "\proper", "")
title = replacetext(title, "\improper", "")
//Make our dumb param object
params = {"{ "cursor": "[params]", "screenLoc": "[thing.screen_loc]" }"}

View File

@@ -31,12 +31,133 @@
/datum/uplink_item/dangerous/antitank
name = "Anti Tank Pistol"
desc = "Essentially amounting to a sniper rifle with no stock and barrel (or indeed, any rifling at all),\
this extremely dubious pistol is guaranteed to dislocate your wrists and hit the broad side of a barn!\
Uses sniper ammo.\
desc = "Essentially amounting to a sniper rifle with no stock and barrel (or indeed, any rifling at all), \
this extremely dubious pistol is guaranteed to dislocate your wrists and hit the broad side of a barn! \
Uses sniper ammo. \
Bullets tend to veer off-course. We are not responsible for any unintentional damage or injury resulting from inaacuracy."
item = /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate
refundable = TRUE
cost = 14
surplus = 25
include_modes = list(/datum/game_mode/nuclear)
/* Commented out due to introduction of reskinnable stetchkins. May still have a niche if people decide it somehow has value.
/datum/uplink_item/dangerous/stealthpistol
name = "Stealth Pistol"
desc = "A compact, easily concealable bullpup pistol that fires 10mm auto rounds in 8 round magazines. \
Has an integrated suppressor."
item = /obj/item/gun/ballistic/automatic/pistol/stealth
cost = 10
surplus = 30
*/
///Soporific 10mm mags///
/datum/uplink_item/ammo/pistolzzz
name = "10mm Soporific Magazine"
desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with soporific rounds that put the target to sleep. \
NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require two shots to take effect."
item = /obj/item/ammo_box/magazine/m10mm/soporific
cost = 2
///flechette memes///
/datum/uplink_item/dangerous/flechettegun
name = "Flechette Launcher"
desc = "A compact bullpup that fires micro-flechettes.\
Flechettes have very poor performance idividually, but can be very deadly in numbers. \
Pre-loaded with armor piercing flechettes that are capable of puncturing most kinds of armor."
item = /obj/item/gun/ballistic/automatic/flechette
cost = 12
surplus = 30
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/flechetteap
name = "Armor Piercing Flechette Magazine"
desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \
Loaded with armor piercing flechettes that very nearly ignore armor, but are not very effective agaisnt flesh."
item = /obj/item/ammo_box/magazine/flechette
cost = 2
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/flechettes
name = "Serrated Flechette Magazine"
desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \
Loaded with serrated flechettes that shreds flesh, but is stopped dead in its tracks by armor. \
These flechettes are highly likely to sever arteries, and even limbs."
item = /obj/item/ammo_box/magazine/flechette/s
cost = 2
include_modes = list(/datum/game_mode/nuclear)
///shredder///
/datum/uplink_item/nukeoffer/shredder
name = "Shredder bundle"
desc = "A truly horrific weapon designed simply to maim its victim, the CX Shredder is banned by several intergalactic treaties. \
You'll get two of them with this. And spare ammo to boot. And we'll throw in an extra elite hardsuit and chest rig to hold them all!"
item = /obj/item/storage/backpack/duffelbag/syndie/shredderbundle
cost = 30 // normally 41
///Modular Pistols///
/datum/uplink_item/bundle/modular
name="Modular Pistol Kit"
desc="A heavy briefcase containing one modular pistol (chambered in 10mm), one supressor, and spare ammunition, including a box of soporific ammo. \
Includes a suit jacket that is padded with a robust liner."
item = /obj/item/storage/briefcase/modularbundle
cost = 12
//////Bundle stuff//////
///bundle category///
/datum/uplink_item/bundle
category = "Bundles"
surplus = 0
cant_discount = TRUE
///place bundle storage items here I guess///
/obj/item/storage/briefcase/modularbundle
name = "briefcase"
desc = "It's label reads genuine hardened Captain leather, but suspiciously has no other tags or branding."
icon_state = "briefcase"
flags_1 = CONDUCT_1
force = 10
hitsound = "swing_hit"
throw_speed = 2
throw_range = 4
w_class = WEIGHT_CLASS_BULKY
max_w_class = WEIGHT_CLASS_NORMAL
max_combined_w_class = 21
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked")
resistance_flags = FLAMMABLE
max_integrity = 150
/obj/item/storage/briefcase/modularbundle/PopulateContents()
new /obj/item/gun/ballistic/automatic/pistol/modular(src)
new /obj/item/suppressor(src)
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/ammo_box/magazine/m10mm/soporific(src)
new /obj/item/ammo_box/c10mm/soporific(src)
new /obj/item/clothing/under/lawyer/blacksuit(src)
new /obj/item/clothing/accessory/waistcoat(src)
new /obj/item/clothing/suit/toggle/lawyer/black/syndie(src)
/obj/item/clothing/suit/toggle/lawyer/black/syndie
desc = "A snappy dress jacket. Suspiciously has no tags or branding."
armor = list(melee = 10, bullet = 10, laser = 10, energy = 10, bomb = 10)
/obj/item/storage/backpack/duffelbag/syndie/shredderbundle
desc = "A large duffel bag containing two CX Shredders, some magazines, an elite hardsuit, and a chest rig."
/obj/item/storage/backpack/duffelbag/syndie/shredderbundle/PopulateContents()
new /obj/item/ammo_box/magazine/flechette/shredder(src)
new /obj/item/ammo_box/magazine/flechette/shredder(src)
new /obj/item/ammo_box/magazine/flechette/shredder(src)
new /obj/item/ammo_box/magazine/flechette/shredder(src)
new /obj/item/gun/ballistic/automatic/flechette/shredder(src)
new /obj/item/gun/ballistic/automatic/flechette/shredder(src)
new /obj/item/storage/belt/military(src)
new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src)
///End of Bundle stuff///