Merge branch 'master' into digileg-runtime

This commit is contained in:
Poojawa
2018-03-17 20:16:21 -05:00
committed by GitHub
112 changed files with 1640 additions and 581 deletions

View File

@@ -226,8 +226,8 @@ GLOBAL_PROTECT(protected_ranks)
dbfail = 1
else
while(query_load_admins.NextRow())
var/admin_ckey = query_load_admins.item[1]
var/admin_rank = query_load_admins.item[2]
var/admin_ckey = ckey(query_load_admins.item[1])
var/admin_rank = ckeyEx(query_load_admins.item[2])
var/skip
if(rank_names[admin_rank] == null)
message_admins("[admin_ckey] loaded with invalid admin rank [admin_rank].")
@@ -248,7 +248,7 @@ GLOBAL_PROTECT(protected_ranks)
for(var/A in GLOB.admin_datums + GLOB.deadmins)
if(A == "[J]") //this admin was already loaded from txt override
continue
new /datum/admins(rank_names[json["admins"]["[J]"]], "[J]")
new /datum/admins(ckeyEx(rank_names[json["admins"]["[J]"]]), ckey("[J]"))
#ifdef TESTING
var/msg = "Admins Built:\n"
for(var/ckey in GLOB.admin_datums)

View File

@@ -15,7 +15,7 @@
msg = "<span class='admin'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message'>[msg]</span></span>"
to_chat(GLOB.admins, msg)
else
msg = "<span class='adminobserver'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]:</EM> <span class='message'>[msg]</span></span>"
msg = "<span class='adminobserver'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message'>[msg]</span></span>"
to_chat(GLOB.admins, msg)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Asay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -73,7 +73,7 @@
C.prefs.copy_to(M)
M.key = C.key
var/datum/mind/app_mind = M.mind
var/datum/antagonist/wizard/apprentice/app = new()
app.master = user
app.school = kind
@@ -145,6 +145,26 @@
M.mind.add_antag_datum(new_op,creator_op.nuke_team)
M.mind.special_role = "Nuclear Operative"
//////CLOWN OP
/obj/item/antag_spawner/nuke_ops/clown
name = "clown operative teleporter"
desc = "A single-use teleporter designed to quickly reinforce clown operatives in the field."
/obj/item/antag_spawner/nuke_ops/clown/spawn_antag(client/C, turf/T, kind, datum/mind/user)
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
C.prefs.copy_to(M)
M.key = C.key
var/datum/antagonist/nukeop/clownop/new_op = new /datum/antagonist/nukeop/clownop()
new_op.send_to_spawnpoint = FALSE
new_op.nukeop_outfit = /datum/outfit/syndicate/clownop/no_crystals
var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop/clownop,TRUE)
if(creator_op)
M.mind.add_antag_datum(new_op, creator_op.nuke_team)
M.mind.special_role = "Clown Operative"
//////SYNDICATE BORG
/obj/item/antag_spawner/nuke_ops/borg_tele
name = "syndicate cyborg teleporter"
@@ -187,7 +207,7 @@
R.real_name = R.name
R.key = C.key
var/datum/antagonist/nukeop/new_borg = new()
new_borg.send_to_spawnpoint = FALSE
R.mind.add_antag_datum(new_borg,creator_op.nuke_team)

View File

@@ -6,8 +6,8 @@ the new instance inside the host to be updated to the template's stats.
*/
/mob/camera/disease
name = ""
real_name = ""
name = "Sentient Disease"
real_name = "Sentient Disease"
desc = ""
icon = 'icons/mob/blob.dmi'
icon_state = "marker"
@@ -225,7 +225,6 @@ the new instance inside the host to be updated to the template's stats.
disease_instances -= V
hosts -= V.affected_mob
else
points -= 1
to_chat(src, "<span class='notice'>One of your hosts, <b>[V.affected_mob.real_name]</b>, has been purged of your infection.</span>")
var/datum/atom_hud/my_hud = GLOB.huds[DATA_HUD_SENTIENT_DISEASE]

View File

@@ -0,0 +1,25 @@
/datum/antagonist/nukeop/clownop
name = "Clown Operative"
roundend_category = "clown operatives"
antagpanel_category = "ClownOp"
nukeop_outfit = /datum/outfit/syndicate/clownop
/datum/antagonist/nukeop/leader/clownop
name = "Clown Operative Leader"
roundend_category = "clown operatives"
antagpanel_category = "ClownOp"
nukeop_outfit = /datum/outfit/syndicate/clownop/leader
/datum/antagonist/nukeop/leader/clownop/give_alias()
title = pick("Head Honker", "Slipmaster", "Clown King", "Honkbearer")
if(nuke_team && nuke_team.syndicate_name)
owner.current.real_name = "[nuke_team.syndicate_name] [title]"
else
owner.current.real_name = "Syndicate [title]"
/datum/antagonist/nukeop/clownop/admin_add(datum/mind/new_owner,mob/admin)
new_owner.assigned_role = "Clown Operative"
new_owner.add_antag_datum(src)
message_admins("[key_name_admin(admin)] has clown op'ed [new_owner.current].")
log_admin("[key_name(admin)] has clown op'ed [new_owner.current].")

View File

@@ -15,6 +15,7 @@ GLOBAL_LIST_EMPTY(jam_on_wardec)
Such a brazen move will attract the attention of powerful benefactors within the Syndicate, who will supply your team with a massive amount of bonus telecrystals. \
Must be used within five minutes, or your benefactors will lose interest."
var/declaring_war = FALSE
var/uplink_type = /obj/item/device/radio/uplink/nuclear
/obj/item/device/nuclear_challenge/attack_self(mob/living/user)
if(!check_allowed(user))
@@ -59,7 +60,7 @@ GLOBAL_LIST_EMPTY(jam_on_wardec)
for(var/obj/machinery/computer/camera_advanced/shuttle_docker/D in GLOB.jam_on_wardec)
D.jammed = TRUE
new /obj/item/device/radio/uplink/nuclear(get_turf(user), user.key, CHALLENGE_TELECRYSTALS)
new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS)
CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1)
@@ -85,6 +86,9 @@ GLOBAL_LIST_EMPTY(jam_on_wardec)
return FALSE
return TRUE
/obj/item/device/nuclear_challenge/clownops
uplink_type = /obj/item/device/radio/uplink/clownop
#undef CHALLENGE_TELECRYSTALS
#undef CHALLENGE_TIME_LIMIT
#undef CHALLENGE_MIN_PLAYERS

View File

@@ -1,16 +1,3 @@
#define NUKESTATE_INTACT 5
#define NUKESTATE_UNSCREWED 4
#define NUKESTATE_PANEL_REMOVED 3
#define NUKESTATE_WELDED 2
#define NUKESTATE_CORE_EXPOSED 1
#define NUKESTATE_CORE_REMOVED 0
#define NUKE_OFF_LOCKED 0
#define NUKE_OFF_UNLOCKED 1
#define NUKE_ON_TIMING 2
#define NUKE_ON_EXPLODING 3
/obj/machinery/nuclearbomb
name = "nuclear fission explosive"
desc = "You probably shouldn't stick around to see if this is armed."
@@ -59,9 +46,8 @@
set_safety()
GLOB.poi_list -= src
GLOB.nuke_list -= src
if(countdown)
qdel(countdown)
countdown = null
QDEL_NULL(countdown)
QDEL_NULL(core)
. = ..()
/obj/machinery/nuclearbomb/examine(mob/user)
@@ -459,11 +445,13 @@
//Cinematic
SSticker.mode.OnNukeExplosion(off_station)
var/bombz = z
Cinematic(get_cinematic_type(off_station),world,CALLBACK(SSticker,/datum/controller/subsystem/ticker/proc/station_explosion_detonation,src))
INVOKE_ASYNC(GLOBAL_PROC,.proc/KillEveryoneOnZLevel,bombz)
really_actually_explode(off_station)
SSticker.roundend_check_paused = FALSE
/obj/machinery/nuclearbomb/proc/really_actually_explode(off_station)
Cinematic(get_cinematic_type(off_station),world,CALLBACK(SSticker,/datum/controller/subsystem/ticker/proc/station_explosion_detonation,src))
INVOKE_ASYNC(GLOBAL_PROC,.proc/KillEveryoneOnZLevel, z)
/obj/machinery/nuclearbomb/proc/get_cinematic_type(off_station)
if(off_station < 2)
return CINEMATIC_SELFDESTRUCT

View File

@@ -0,0 +1,37 @@
/datum/team/xeno
name = "Aliens"
//Simply lists them.
/datum/team/xeno/roundend_report()
var/list/parts = list()
parts += "<span class='header'>The [name] were:</span>"
parts += printplayerlist(members)
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
/datum/antagonist/xeno
name = "Xenomorph"
job_rank = ROLE_ALIEN
show_in_antagpanel = FALSE
var/datum/team/xeno/xeno_team
/datum/antagonist/xeno/create_team(datum/team/xeno/new_team)
if(!new_team)
for(var/datum/antagonist/xeno/X in GLOB.antagonists)
if(!X.owner || !X.xeno_team)
continue
xeno_team = X.xeno_team
return
xeno_team = new
else
if(!istype(new_team))
CRASH("Wrong xeno team type provided to create_team")
xeno_team = new_team
/datum/antagonist/xeno/get_team()
return xeno_team
//XENO
/mob/living/carbon/alien/mind_initialize()
..()
if(!mind.has_antag_datum(/datum/antagonist/xeno))
mind.add_antag_datum(/datum/antagonist/xeno)

View File

@@ -1274,24 +1274,45 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["taur"] = "None"
if("tail_human")
var/list/snowflake_tails_list = list("Normal" = null)
for(var/path in GLOB.tails_list_human)
var/datum/sprite_accessory/tails/human/instance = GLOB.tails_list_human[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_tails_list[S.name] = path
var/new_tail
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.tails_list_human
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in snowflake_tails_list
if(new_tail)
features["tail_human"] = new_tail
if(new_tail != "None")
features["taur"] = "None"
if("mam_tail")
var/list/snowflake_tails_list = list("Normal" = null)
for(var/path in GLOB.mam_tails_list)
var/datum/sprite_accessory/mam_tails/instance = GLOB.mam_tails_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_tails_list[S.name] = path
var/new_tail
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.mam_tails_list
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in snowflake_tails_list
if(new_tail)
features["mam_tail"] = new_tail
if(new_tail != "None")
features["taur"] = "None"
if("taur")
var/list/snowflake_taur_list = list("Normal" = null)
for(var/path in GLOB.taur_list)
var/datum/sprite_accessory/taur/instance = GLOB.taur_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_taur_list[S.name] = path
var/new_taur
new_taur = input(user, "Choose your character's tauric body:", "Character Preference") as null|anything in GLOB.taur_list
new_taur = input(user, "Choose your character's tauric body:", "Character Preference") as null|anything in snowflake_taur_list
if(new_taur)
features["taur"] = new_taur
if(new_taur != "None")
@@ -1305,8 +1326,15 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["snout"] = new_snout
if("mam_ears")
var/list/snowflake_ears_list = list("Normal" = null)
for(var/path in GLOB.mam_ears_list)
var/datum/sprite_accessory/mam_ears/instance = GLOB.mam_ears_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_ears_list[S.name] = path
var/new_ears
new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in GLOB.mam_ears_list
new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in snowflake_ears_list
if(new_ears)
features["mam_ears"] = new_ears
@@ -1317,8 +1345,15 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["horns"] = new_horns
if("ears")
var/list/snowflake_ears_list = list("Normal" = null)
for(var/path in GLOB.ears_list)
var/datum/sprite_accessory/ears/instance = GLOB.ears_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_ears_list[S.name] = path
var/new_ears
new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in GLOB.ears_list
new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in snowflake_ears_list
if(new_ears)
features["ears"] = new_ears
@@ -1353,8 +1388,15 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["body_markings"] = new_body_markings
if("mam_body_markings")
var/list/snowflake_markings_list = list("Normal" = null)
for(var/path in GLOB.mam_body_markings_list)
var/datum/sprite_accessory/mam_body_markings/instance = GLOB.mam_body_markings_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_markings_list[S.name] = path
var/new_mam_body_markings
new_mam_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in GLOB.mam_body_markings_list
new_mam_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in snowflake_markings_list
if(new_mam_body_markings)
features["mam_body_markings"] = new_mam_body_markings

View File

@@ -4,25 +4,30 @@
name = "mk-honk prototype shoes"
desc = "Lost prototype of advanced clown tech. Powered by bananium, these shoes leave a trail of chaos in their wake."
icon_state = "clown_prototype_off"
var/on = FALSE
actions_types = list(/datum/action/item_action/toggle)
var/on = FALSE
var/always_noslip = FALSE
/obj/item/clothing/shoes/clown_shoes/banana_shoes/Initialize()
. = ..()
AddComponent(/datum/component/material_container, list(MAT_BANANIUM), 200000, TRUE)
AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 75)
if(always_noslip)
flags_1 |= NOSLIP_1
/obj/item/clothing/shoes/clown_shoes/banana_shoes/step_action()
. = ..()
GET_COMPONENT(bananium, /datum/component/material_container)
if(on)
new/obj/item/grown/bananapeel/specialpeel(get_step(src,turn(usr.dir, 180))) //honk
GET_COMPONENT(bananium, /datum/component/material_container)
bananium.use_amount_type(100, MAT_BANANIUM)
if(bananium.amount(MAT_BANANIUM) < 100)
on = !on
flags_1 &= ~NOSLIP_1
if(!always_noslip)
flags_1 &= ~NOSLIP_1
update_icon()
to_chat(loc, "<span class='warning'>You ran out of bananium!</span>")
else
new /obj/item/grown/bananapeel/specialpeel(get_step(src,turn(usr.dir, 180))) //honk
bananium.use_amount_type(100, MAT_BANANIUM)
/obj/item/clothing/shoes/clown_shoes/banana_shoes/attack_self(mob/user)
GET_COMPONENT(bananium, /datum/component/material_container)
@@ -42,10 +47,11 @@
on = !on
update_icon()
to_chat(user, "<span class='notice'>You [on ? "activate" : "deactivate"] the prototype shoes.</span>")
if(on)
flags_1 |= NOSLIP_1
else
flags_1 &= ~NOSLIP_1
if(!always_noslip)
if(on)
flags_1 |= NOSLIP_1
else
flags_1 &= ~NOSLIP_1
else
to_chat(user, "<span class='warning'>You need bananium to turn the prototype shoes on!</span>")

View File

@@ -64,9 +64,7 @@
/obj/item/clothing/shoes/galoshes/dry/step_action()
var/turf/open/t_loc = get_turf(src)
if(istype(t_loc) && t_loc.wet)
t_loc.MakeDry(TURF_WET_WATER)
t_loc.wet_time = 0
t_loc.SendSignal(COMSIG_TURF_MAKE_DRY, TURF_WET_WATER, TRUE, INFINITY)
/obj/item/clothing/shoes/clown_shoes
desc = "The prankster's standard-issue clowning shoes. Damn, they're huge!"

View File

@@ -1,6 +1,5 @@
#define ION_RANDOM 0
#define ION_ANNOUNCE 1
#define ION_FILE "ion_laws.json"
/datum/round_event_control/ion_storm
name = "Ion Storm"
typepath = /datum/round_event/ion_storm

View File

@@ -23,6 +23,21 @@
bonus_reagents = list("sprinkles" = 2, "sugar" = 1)
filling_color = "#FF69B4"
/obj/item/reagent_containers/food/snacks/donut/checkLiked(fraction, mob/M) //Sec officers always love donuts
if(last_check_time + 50 < world.time)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.mind && H.mind.assigned_role == "Security Officer" && !H.has_trait(TRAIT_AGEUSIA))
to_chat(H,"<span class='notice'>I love this taste!</span>")
H.adjust_disgust(-5 + -2.5 * fraction)
GET_COMPONENT_FROM(mood, /datum/component/mood, H)
if(mood)
mood.add_event("fav_food", /datum/mood_event/favorite_food)
last_check_time = world.time
return
..()
/obj/item/reagent_containers/food/snacks/donut/chaos
name = "chaos donut"
desc = "Like life, it never quite tastes the same."

View File

@@ -25,6 +25,7 @@
"sugar" = 5,
"ice" = 5,
"cocoa" = 5,
"vanilla" = 5,
"berryjuice" = 5,
"singulo" = 5)
@@ -40,8 +41,8 @@
return list("flour", "sugar")
if(CONE_CHOC)
return list("flour", "sugar", "cocoa")
else
return list("milk", "ice")
else //ICECREAM_VANILLA
return list("milk", "ice", "vanilla")
/obj/machinery/icecream_vat/proc/get_flavour_name(flavour_type)
@@ -56,7 +57,7 @@
return "waffle"
if(CONE_CHOC)
return "chocolate"
else
else //ICECREAM_VANILLA
return "vanilla"

View File

@@ -146,6 +146,7 @@
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "asclepius_dormant"
var/activated = FALSE
var/usedHand
/obj/item/rod_of_asclepius/attack_self(mob/user)
if(activated)
@@ -154,6 +155,10 @@
to_chat(user, "<span class='warning'>The snake carving seems to come alive, if only for a moment, before returning to it's dormant state, almost as if it finds you incapable of holding it's oath.</span>")
return
var/mob/living/carbon/itemUser = user
usedHand = itemUser.get_held_index_of_item(src)
if(itemUser.has_status_effect(STATUS_EFFECT_HIPPOCRATIC_OATH))
to_chat(user, "<span class='warning'>You can't possibly handle the responsibility of more than one rod!</span>")
return
var/failText = "<span class='warning'>The snake seems unsatisfied with your incomplete oath and returns to it's previous place on the rod, returning to its dormant, wooden state. You must stand still while completing your oath!</span>"
to_chat(itemUser, "<span class='notice'>The wooden snake that was carved into the rod seems to suddenly come alive and begins to slither down your arm! The compulsion to help others grows abnormally strong...</span>")
if(do_after(itemUser, 40, target = itemUser))
@@ -178,7 +183,7 @@
return
to_chat(itemUser, "<span class='notice'>The snake, satisfied with your oath, attaches itself and the rod to your forearm with an inseparable grip. Your thoughts seem to only revolve around the core idea of helping others, and harm is nothing more than a distant, wicked memory...</span>")
var/datum/status_effect/hippocraticOath/effect = itemUser.apply_status_effect(STATUS_EFFECT_HIPPOCRATIC_OATH)
effect.hand = itemUser.get_held_index_of_item(src)
effect.hand = usedHand
activated()
/obj/item/rod_of_asclepius/proc/activated()

View File

@@ -5,7 +5,7 @@
var/extra2 = FALSE
var/extra2_icon = 'icons/mob/mam_bodyparts.dmi'
var/extra2_color_src = MUTCOLORS3
// var/list/ckeys_allowed = null
var/list/ckeys_allowed
/* tbi eventually idk
/datum/sprite_accessory/legs/digitigrade_mam
@@ -97,6 +97,12 @@
extra = TRUE
icon = 'icons/mob/mam_bodyparts.dmi'
//datum/sprite_accessory/ears/elf
// name = "Elf"
// icon_state = "elf"
// icon = 'icons/mob/mam_bodyparts.dmi'
// ckeys_allowed = list("atiefling")
/datum/sprite_accessory/ears/fennec
name = "Fennec"
icon_state = "fennec"
@@ -950,34 +956,44 @@
/datum/sprite_accessory/mam_ears/guilmon
name = "Guilmon"
icon_state = "guilmon"
icon = 'icons/mob/mam_bodyparts.dmi'
/datum/sprite_accessory/snout/guilmon
name = "Guilmon"
icon_state = "guilmon"
/datum/sprite_accessory/mam_tails/shark/datashark
name = "DataShark"
icon_state = "datashark"
color_src = 0
// ckeys_allowed = list("rubyflamewing")
ckeys_allowed = list("rubyflamewing")
/datum/sprite_accessory/mam_tails_animated/shark/datashark
name = "DataShark"
icon_state = "datashark"
color_src = 0
/*
//Till I get my snowflake only ckey lock, these are locked-locked :D
/datum/sprite_accessory/mam_body_markings/shark/datashark
name = "DataShark"
icon_state = "datashark"
color_src = MUTCOLORS2
ckeys_allowed = list("rubyflamewing")
//Sabresune
/datum/sprite_accessory/mam_ears/sabresune
name = "sabresune"
icon_state = "sabresune"
hasinner = 1
extra = TRUE
extra_color_src = MUTCOLORS3
locked = TRUE
ckeys_allowed = list("poojawa")
/datum/sprite_accessory/mam_tails/sabresune
name = "sabresune"
icon_state = "sabresune"
extra = TRUE
locked = TRUE
ckeys_allowed = list("poojawa")
/datum/sprite_accessory/mam_tails_animated/sabresune
name = "sabresune"
@@ -990,5 +1006,5 @@
color_src = MUTCOLORS2
extra = FALSE
extra2 = FALSE
locked = TRUE
*/
ckeys_allowed = list("poojawa")

View File

@@ -170,8 +170,12 @@
return FALSE
return !held_items[hand_index]
/mob/proc/put_in_hand(obj/item/I, hand_index)
if(can_put_in_hand(I, hand_index))
/mob/proc/put_in_hand(obj/item/I, hand_index, forced = FALSE)
if(forced || can_put_in_hand(I, hand_index))
if(hand_index == null)
return FALSE
if(get_item_for_held_index(hand_index) != null)
dropItemToGround(get_item_for_held_index(hand_index), force = TRUE)
I.forceMove(src)
held_items[hand_index] = I
I.layer = ABOVE_HUD_LAYER
@@ -185,7 +189,6 @@
return hand_index || TRUE
return FALSE
//Puts the item into the first available left hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_l_hand(obj/item/I)
return put_in_hand(I, get_empty_held_index_for_side("l"))

View File

@@ -272,7 +272,7 @@
else if(check_zone(M.zone_selected) == "head")
M.visible_message("<span class='notice'>[M] gives [src] a pat on the head to make [p_them()] feel better!</span>", \
"<span class='notice'>You give [src] a pat on the head to make [p_them()] feel better!</span>")
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || (dna.features["tail_human"] != "None") || ("mam_tail" in dna.species.mutant_bodyparts)))
if(dna && dna.species && ((("tail_lizard" || "tail_human" || "mam_tail") in dna.species.mutant_bodyparts && (dna.features["tail_lizard"] || dna.features["tail_human"] || dna.features["mam_tail"])!= "None")))
emote("wag") //lewd
else
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \

View File

@@ -27,7 +27,6 @@
add_logs(src,, "slipped",, "on [O ? O.name : "floor"]")
return loc.handle_slip(src, knockdown_amount, O, lube)
/mob/living/carbon/Process_Spacemove(movement_dir = 0)
if(..())
return 1

View File

@@ -54,7 +54,7 @@
liked_food = MEAT
disliked_food = TOXIC
meat = /obj/item/reagent_containers/food/snacks/carpmeat/aquatic
/datum/species/aquatic/spec_death(gibbed, mob/living/carbon/human/H)
if(H)
H.endTailWag()
@@ -82,7 +82,6 @@
/datum/species/insect/qualifies_for_rank(rank, list/features)
return TRUE
//HERBIVOROUS//
//Alien//
/datum/species/xeno
@@ -159,89 +158,9 @@
description = "A highly corrosive substance, it is capable of burning through most natural or man-made materials in short order."
color = "#66CC00"
toxpwr = 0
acidpwr = 12
acidpwr = 12 */
/datum/species/yautja
name = "Yautja"
id = "pred"
say_mod = "clicks"
eyes = "predeyes"
mutant_organs = list(/obj/item/organ/tongue/yautja)
specflags = list(EYECOLOR)
lang_spoken = YAUTJA
lang_understood = HUMAN|YAUTJA|ALIEN
no_equip = list(slot_head)
punchdamagelow = 4
punchdamagehigh = 14
punchstunthreshold = 13
blacklisted = 1
whitelist = 1
whitelist = list("talkingcactus")
/datum/outfit/yautja_basic
name = "Yautja, Basic"
uniform = /obj/item/clothing/under/mesh
suit = /obj/item/clothing/suit/armor/yautja_fake
shoes = /obj/item/clothing/shoes/yautja_fake
mask = /obj/item/clothing/mask/gas/yautja_fake
/datum/species/yautja/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
var/datum/outfit/yautja_basic/O = new /datum/outfit/yautja_basic//Just basic gear. Doesn't include anything that gives any meaningful advantage.
H.equipOutfit(O, visualsOnly)
return 0
/datum/species/octopus
blacklisted = 1
/datum/species/carp
blacklisted = 1
/datum/species/horse
blacklisted = 1*/
///////////////////
//DONATOR SPECIES//
///////////////////
//ChronoFlux: Slimecoon
/*
/datum/species/jelly/slime/slimecoon
name = "Slime Raccoon"
id = "slimecoon"
limbs_id = "slime"
whitelisted = 1
whitelist = list("chronoflux")
blacklisted = 1
mutant_bodyparts = list("slimecoontail", "slimecoonears", "slimecoonsnout")
default_features = list("slimecoontail" = "Slimecoon Tail", "slimecoonears" = "Slimecoon Ears", "slimecoonsnout" = "Slimecoon Snout")*/
// Fat Shark <3
/*
/datum/species/shark/datashark
name = "DataShark"
id = "datashark"
default_color = "BCAC9B"
species_traits = list(MUTCOLORS_PARTSONLY,EYECOLOR,LIPS,HAIR,SPECIES_ORGANIC)
mutant_bodyparts = list("mam_tail", "mam_body_markings")
default_features = list("mam_tail" = "datashark", "mam_body_markings" = "None")
attack_verb = "bite"
attack_sound = 'sound/weapons/bite.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
whitelisted = 1
whitelist = list("rubyflamewing")
blacklisted = 0
*/
/datum/species/guilmon
name = "Guilmon"
id = "guilmon"
default_color = "4B4B4B"
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,SPECIES_ORGANIC)
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings")
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF", "mcolor3" = "FFF", "mam_tail" = "guilmon", "mam_ears" = "guilmon", "mam_body_markings" = "guilmon")
attack_verb = "claw"
attack_sound = 'sound/weapons/slash.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
//##########SLIMEPEOPLE##########
/datum/species/jelly/roundstartslime

View File

@@ -246,7 +246,7 @@
if(prob(75))
var/turf/open/T = loc
if(istype(T))
T.MakeSlippery(TURF_WET_WATER, min_wet_time = 20, wet_time_to_add = 15)
T.MakeSlippery(TURF_WET_WATER, min_wet_time = 20 SECONDS, wet_time_to_add = 15 SECONDS)
else
visible_message("<span class='danger'>[src] whirs and bubbles violently, before releasing a plume of froth!</span>")
new /obj/effect/particle_effect/foam(loc)

View File

@@ -137,8 +137,8 @@
name = "Syndicate Stormtrooper"
maxHealth = 200
health = 200
casingtype = /obj/item/ammo_casing/shotgun/tengauge
projectilesound = 'sound/weapons/gunshot.ogg'
casingtype = /obj/item/ammo_casing/shotgun/buckshot
loot = list(/obj/effect/gibspawner/human)
///////////////Misc////////////

View File

@@ -425,5 +425,8 @@
if(..())
return 3
/mob/living/simple_animal/slime/can_be_implanted()
return TRUE
/mob/living/simple_animal/slime/random/Initialize(mapload, new_colour, new_is_adult)
. = ..(mapload, pick(slime_colours), prob(50))

View File

@@ -102,3 +102,5 @@
var/list/progressbars = null //for stacking do_after bars
var/list/mousemove_intercept_objects
var/datum/click_intercept

View File

@@ -87,6 +87,7 @@
if(istype(linked_techweb))
linked_techweb.research_points += min(power_produced, 1)
addtimer(CALLBACK(src, .proc/reset_shocked), 10)
tesla_buckle_check(power)
else
..()
@@ -100,6 +101,7 @@
add_load(power)
playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
tesla_zap(src, 10, power/(coeff/2))
tesla_buckle_check(power/(coeff/2))
// Tesla R&D researcher
/obj/machinery/power/tesla_coil/research
@@ -120,6 +122,7 @@
if(istype(linked_techweb))
linked_techweb.research_points += min(power_produced, 3) // 4 coils makes ~720/m bonus for R&D,
addtimer(CALLBACK(src, .proc/reset_shocked), 10)
tesla_buckle_check(power)
else
..()
@@ -136,6 +139,10 @@
return
return ..()
/obj/machinery/power/tesla_coil/research/on_construction()
if(anchored)
connect_to_network()
/obj/machinery/power/grounding_rod
name = "grounding rod"
desc = "Keep an area from being fried from Edison's Bane."
@@ -179,5 +186,6 @@
/obj/machinery/power/grounding_rod/tesla_act(var/power)
if(anchored && !panel_open)
flick("grounding_rodhit", src)
tesla_buckle_check(power)
else
..()
..()

View File

@@ -7,6 +7,11 @@
caliber = "shotgun"
projectile_type = /obj/item/projectile/bullet/shotgun_slug
materials = list(MAT_METAL=4000)
/obj/item/ammo_casing/shotgun/tengauge
name = "10g shotgun slug"
desc = "A 10 gauge lead slug."
projectile_type = /obj/item/projectile/bullet/shotgun_slug/tengauge
/obj/item/ammo_casing/shotgun/beanbag
name = "beanbag slug"

View File

@@ -54,7 +54,7 @@
force = 0
throwforce = 0
mag_type = /obj/item/ammo_box/magazine/internal/shot/toy
clumsy_check = 0
clumsy_check = FALSE
item_flags = NONE
casing_ejector = FALSE
can_suppress = FALSE
@@ -87,6 +87,7 @@
item_flags = NONE
mag_type = /obj/item/ammo_box/magazine/toy/smgm45/riot
casing_ejector = FALSE
clumsy_check = FALSE
/obj/item/gun/ballistic/automatic/c20r/toy/unrestricted //Use this for actual toys
pin = /obj/item/device/firing_pin
@@ -103,6 +104,7 @@
item_flags = NONE
mag_type = /obj/item/ammo_box/magazine/toy/m762/riot
casing_ejector = FALSE
clumsy_check = FALSE
/obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted //Use this for actual toys
pin = /obj/item/device/firing_pin

View File

@@ -1,6 +1,10 @@
/obj/item/projectile/bullet/shotgun_slug
name = "12g shotgun slug"
damage = 60
/obj/item/projectile/bullet/shotgun_slug/tengauge
name = "10g shotgun slug"
damage = 72.5
/obj/item/projectile/bullet/shotgun_beanbag
name = "beanbag slug"

View File

@@ -9,15 +9,17 @@
idle_power_usage = 40
interact_offline = TRUE
resistance_flags = FIRE_PROOF | ACID_PROOF
circuit = /obj/item/circuitboard/machine/chem_dispenser
var/cell_type = /obj/item/stock_parts/cell/high
var/obj/item/stock_parts/cell/cell
var/powerefficiency = 0.01
var/powerefficiency = 0.1
var/amount = 30
var/recharged = 0
var/recharge_delay = 5
var/mutable_appearance/beaker_overlay
var/working_state = "dispenser_working"
var/nopower_state = "dispenser_nopower"
var/macrotier = 1
var/obj/item/reagent_containers/beaker = null
var/list/dispensable_reagents = list(
"hydrogen",
@@ -199,7 +201,7 @@ obj/machinery/chem_dispenser/update_icon()
var/actual = min(amount, (cell.charge * powerefficiency)*10, free)
R.add_reagent(reagent, actual)
cell.use((actual / 10) / powerefficiency)
cell.use(actual / powerefficiency)
work_animation()
. = TRUE
if("remove")
@@ -219,16 +221,17 @@ obj/machinery/chem_dispenser/update_icon()
if("dispense_recipe")
var/recipe_to_use = params["recipe"]
var/list/chemicals_to_dispense = process_recipe_list(recipe_to_use)
var/res = get_macro_resolution()
for(var/key in chemicals_to_dispense) // i suppose you could edit the list locally before passing it
var/list/keysplit = splittext(key," ")
var/r_id = keysplit[1]
if(beaker && dispensable_reagents.Find(r_id)) // but since we verify we have the reagent, it'll be fine
var/datum/reagents/R = beaker.reagents
var/free = R.maximum_volume - R.total_volume
var/actual = min(chemicals_to_dispense[key], (cell.charge * powerefficiency)*10, free)
var/actual = min(round(chemicals_to_dispense[key], res), (cell.charge * powerefficiency)*10, free)
if(actual)
R.add_reagent(r_id, actual)
cell.use((actual / 10) / powerefficiency)
cell.use(actual / powerefficiency)
work_animation()
if("clear_recipes")
var/yesno = alert("Clear all recipes?",, "Yes","No")
@@ -241,21 +244,35 @@ obj/machinery/chem_dispenser/update_icon()
var/list/first_process = splittext(recipe, ";")
if(!LAZYLEN(first_process))
return
var/res = get_macro_resolution()
var/resmismatch = FALSE
for(var/reagents in first_process)
var/list/fuck = splittext(reagents, "=")
if(dispensable_reagents.Find(fuck[1]))
var/list/reagent = splittext(reagents, "=")
if(dispensable_reagents.Find(reagent[1]))
if (!resmismatch && !check_macro_part(reagents, res))
resmismatch = TRUE
continue
else
var/temp = fuck[1]
var/chemid = reagent[1]
visible_message("<span class='warning'>[src] buzzes.</span>", "<span class='italics'>You hear a faint buzz.</span>")
to_chat(usr, "<span class ='danger'>[src] cannot find Chemical ID: <b>[temp]</b>!</span>")
to_chat(usr, "<span class ='danger'>[src] cannot find Chemical ID: <b>[chemid]</b>!</span>")
playsound(src, "sound/machines/buzz-two.ogg", 50, 1)
return
if (resmismatch && alert("[src] is not yet capable of replicating this recipe with the precision it needs, do you want to save it anyway?",, "Yes","No") == "No")
return
saved_recipes += list(list("recipe_name" = name, "contents" = recipe))
/obj/machinery/chem_dispenser/attackby(obj/item/I, mob/user, params)
if(default_unfasten_wrench(user, I))
return
if(default_deconstruction_screwdriver(user, "dispenser-o", "dispenser", I))
return
if(exchange_parts(user, I))
return
if(default_deconstruction_crowbar(I))
return
if(istype(I, /obj/item/reagent_containers) && !(I.flags_1 & ABSTRACT_1) && I.is_open_container())
var/obj/item/reagent_containers/B = I
. = 1 //no afterattack
@@ -294,92 +311,48 @@ obj/machinery/chem_dispenser/update_icon()
visible_message("<span class='danger'>[src] malfunctions, spraying chemicals everywhere!</span>")
..()
/obj/machinery/chem_dispenser/constructable
name = "portable chem dispenser"
icon = 'icons/obj/chemical.dmi'
icon_state = "minidispenser"
powerefficiency = 0.001
amount = 5
recharge_delay = 20
dispensable_reagents = list()
circuit = /obj/item/circuitboard/machine/chem_dispenser
working_state = "minidispenser_working"
nopower_state = "minidispenser_nopower"
var/static/list/dispensable_reagent_tiers = list(
list(
"hydrogen",
"oxygen",
"silicon",
"phosphorus",
"sulfur",
"carbon",
"nitrogen",
"water"
),
list(
"lithium",
"sugar",
"sacid",
"copper",
"mercury",
"sodium",
"iodine",
"bromine"
),
list(
"ethanol",
"chlorine",
"potassium",
"aluminium",
"radium",
"fluorine",
"iron",
"welding_fuel",
"silver",
"stable_plasma"
),
list(
"oil",
"ash",
"acetone",
"saltpetre",
"ammonia",
"diethylamine"
)
)
/obj/machinery/chem_dispenser/constructable/RefreshParts()
/obj/machinery/chem_dispenser/RefreshParts()
var/time = 0
var/i
var/newpowereff = 0.0666666
for(var/obj/item/stock_parts/cell/P in component_parts)
cell = P
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
time += M.rating
newpowereff += 0.0166666666*M.rating
for(var/obj/item/stock_parts/capacitor/C in component_parts)
time += C.rating
recharge_delay = 30/(time/2) //delay between recharges, double the usual time on lowest 50% less than usual on highest
for(var/obj/item/stock_parts/manipulator/M in component_parts)
for(i=1, i<=M.rating, i++)
dispensable_reagents |= dispensable_reagent_tiers[i]
dispensable_reagents = sortList(dispensable_reagents)
if (M.rating > macrotier)
macrotier = M.rating
powerefficiency = round(newpowereff, 0.01)
/obj/machinery/chem_dispenser/constructable/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "minidispenser-o", "minidispenser", I))
return
if(exchange_parts(user, I))
return
if(default_deconstruction_crowbar(I))
return
return ..()
/obj/machinery/chem_dispenser/constructable/on_deconstruction()
/obj/machinery/chem_dispenser/on_deconstruction()
if(beaker)
beaker.forceMove(drop_location())
beaker = null
return ..()
/obj/machinery/chem_dispenser/proc/get_macro_resolution()
. = 5
if (macrotier > 1)
. -= macrotier // 5 for tier1, 3 for 2, 2 for 3, 1 for 4.
/obj/machinery/chem_dispenser/proc/check_macro(var/macro)
var/res = get_macro_resolution()
for (var/reagent in splittext(macro, ";"))
if (!check_macro_part(reagent, res))
return FALSE
return TRUE
/obj/machinery/chem_dispenser/proc/check_macro_part(var/part, var/res = get_macro_resolution())
var/detail = splittext(part, "=")
if (round(text2num(detail[2]), res) != text2num(detail[2]))
return FALSE
return TRUE
/obj/machinery/chem_dispenser/proc/process_recipe_list(var/fucking_hell)
var/list/key_list = list()
var/list/final_list = list()
@@ -389,12 +362,6 @@ obj/machinery/chem_dispenser/update_icon()
final_list += list(avoid_assoc_duplicate_keys(fuck[1],key_list) = text2num(fuck[2]))
return final_list
/obj/machinery/chem_dispenser/constructable/display_beaker()
var/mutable_appearance/b_o = beaker_overlay || mutable_appearance(icon, "disp_beaker")
b_o.pixel_y = -4
b_o.pixel_x = -4
return b_o
/obj/machinery/chem_dispenser/drinks/display_beaker()
var/mutable_appearance/b_o = beaker_overlay || mutable_appearance(icon, "disp_beaker")
switch(dir)

View File

@@ -459,7 +459,7 @@
reac_volume = ..()
var/turf/open/T = get_turf(M)
if(istype(T) && prob(reac_volume))
T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10, wet_time_to_add = 5)
T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
M.adjust_fire_stacks(-(reac_volume / 10))
M.ExtinguishMob()
M.apply_damage(0.4*reac_volume, BRUTE)
@@ -481,7 +481,7 @@
/datum/reagent/blob/pressurized_slime/proc/extinguisharea(obj/structure/blob/B, probchance)
for(var/turf/open/T in range(1, B))
if(prob(probchance))
T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10, wet_time_to_add = 5)
T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
for(var/obj/O in T)
O.extinguish()
for(var/mob/living/L in T)

View File

@@ -124,7 +124,7 @@
if(!istype(T))
return
if(reac_volume >= 5)
T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10, wet_time_to_add = reac_volume * 1.5)
T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume * 1.5 SECONDS)
T.name = "deep-fried [initial(T.name)]"
T.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY)
@@ -249,7 +249,7 @@
if(reac_volume >= 1) // Make Freezy Foam and anti-fire grenades!
if(isopenturf(T))
var/turf/open/OT = T
OT.MakeSlippery(wet_setting=TURF_WET_ICE, min_wet_time=10, wet_time_to_add=reac_volume) // Is less effective in high pressure/high heat capacity environments. More effective in low pressure.
OT.MakeSlippery(wet_setting=TURF_WET_ICE, min_wet_time=100, wet_time_to_add=reac_volume SECONDS) // Is less effective in high pressure/high heat capacity environments. More effective in low pressure.
OT.air.temperature -= MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity() // reduces environment temperature by 5K per unit.
/datum/reagent/consumable/condensedcapsaicin
@@ -433,7 +433,7 @@
/datum/reagent/consumable/cornoil/reaction_turf(turf/open/T, reac_volume)
if (!istype(T))
return
T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10, wet_time_to_add = reac_volume*2)
T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume*2 SECONDS)
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot)
var/datum/gas_mixture/lowertemp = T.remove_air(T.air.total_moles())

View File

@@ -135,7 +135,7 @@
var/CT = cooling_temperature
if(reac_volume >= 5)
T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10, wet_time_to_add = min(reac_volume*1.5, 60))
T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = min(reac_volume*1.5 SECONDS, 60 SECONDS))
for(var/mob/living/simple_animal/slime/M in T)
M.apply_water()
@@ -329,7 +329,7 @@
if (!istype(T))
return
if(reac_volume >= 1)
T.MakeSlippery(TURF_WET_LUBE, 15, min(reac_volume * 2, 120))
T.MakeSlippery(TURF_WET_LUBE, 15 SECONDS, min(reac_volume * 2 SECONDS, 120))
/datum/reagent/spraytan
name = "Spray Tan"
@@ -1613,9 +1613,8 @@
taste_description = "dryness"
/datum/reagent/drying_agent/reaction_turf(turf/open/T, reac_volume)
if(istype(T) && T.wet)
T.wet_time = max(0, T.wet_time-reac_volume*5) // removes 5 seconds of wetness for every unit.
T.HandleWet()
if(istype(T))
T.MakeDry(ALL, TRUE, reac_volume * 5 SECONDS) //50 deciseconds per unit
/datum/reagent/drying_agent/reaction_obj(obj/O, reac_volume)
if(O.type == /obj/item/clothing/shoes/galoshes)

View File

@@ -513,7 +513,7 @@
required_other = 1
/datum/chemical_reaction/slime/slimeradio/on_reaction(datum/reagents/holder, created_volume)
new /obj/item/slimepotion/slimeradio(get_turf(holder.my_atom))
new /obj/item/slimepotion/slime/slimeradio(get_turf(holder.my_atom))
..()
//Cerulean

View File

@@ -49,22 +49,22 @@
/obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user)
..()
if(slime_up_action)
if(slime_up_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
slime_up_action.target = src
slime_up_action.Grant(user)
actions += slime_up_action
if(slime_place_action)
if(slime_place_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
slime_place_action.target = src
slime_place_action.Grant(user)
actions += slime_place_action
if(feed_slime_action)
if(feed_slime_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
feed_slime_action.target = src
feed_slime_action.Grant(user)
actions += feed_slime_action
if(monkey_recycle_action)
if(monkey_recycle_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes remote monkey recycling require XENOBIO_UPGRADE_MONKEYS
monkey_recycle_action.target = src
monkey_recycle_action.Grant(user)
actions += monkey_recycle_action
@@ -74,18 +74,18 @@
scan_action.Grant(user)
actions += scan_action
if(potion_action)
if(potion_action && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV
potion_action.target = src
potion_action.Grant(user)
actions += potion_action
/obj/machinery/computer/camera_advanced/xenobio/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube))
if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube) && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
monkeys++
to_chat(user, "<span class='notice'>You feed [O] to [src]. It now has [monkeys] monkey cubes stored.</span>")
qdel(O)
return
else if(istype(O, /obj/item/storage/bag))
else if(istype(O, /obj/item/storage/bag) && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
var/obj/item/storage/P = O
var/loaded = 0
for(var/obj/G in P.contents)
@@ -96,7 +96,7 @@
if (loaded)
to_chat(user, "<span class='notice'>You fill [src] with the monkey cubes stored in [O]. [src] now has [monkeys] monkey cubes stored.</span>")
return
else if(istype(O, /obj/item/slimepotion/slime))
else if(istype(O, /obj/item/slimepotion/slime) && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV
var/replaced = FALSE
if(user && !user.transferItemToLoc(O, src))
return

View File

@@ -825,9 +825,11 @@
L.regenerate_icons()
qdel(src)
/obj/item/slimepotion/slimeradio
/obj/item/slimepotion/slime/slimeradio
name = "bluespace radio potion"
desc = "A strange chemical that grants those who ingest it the ability to broadcast and recieve subscape radio waves."
icon = 'icons/obj/chemical.dmi'
icon_state = "potgrey"
/obj/item/slimepotion/slime/slimeradio/attack(mob/living/M, mob/user)
if(!ismob(M))

View File

@@ -108,10 +108,14 @@
return FALSE
/obj/docking_port/mobile/arrivals/proc/PersonCheck()
for(var/M in (GLOB.alive_mob_list & GLOB.player_list))
var/mob/living/L = M
if((get_area(M) in areas) && L.stat != DEAD)
return TRUE
for(var/V in GLOB.player_list)
var/mob/M = V
if((get_area(M) in areas) && M.stat != DEAD)
if(!iscameramob(M))
return TRUE
var/mob/camera/C = M
if(C.move_on_shuttle)
return TRUE
return FALSE
/obj/docking_port/mobile/arrivals/proc/NukeDiskCheck()

View File

@@ -67,7 +67,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
else
return
user.ranged_ability = src
user.client.click_intercept = user.ranged_ability
user.click_intercept = src
add_mousepointer(user.client)
ranged_ability_user = user
if(msg)
@@ -87,7 +87,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(!ranged_ability_user || !ranged_ability_user.client || (ranged_ability_user.ranged_ability && ranged_ability_user.ranged_ability != src)) //To avoid removing the wrong ability
return
ranged_ability_user.ranged_ability = null
ranged_ability_user.client.click_intercept = null
ranged_ability_user.click_intercept = null
remove_mousepointer(ranged_ability_user.client)
if(msg)
to_chat(ranged_ability_user, msg)

View File

@@ -12,6 +12,11 @@
GET_COMPONENT(hidden_uplink, /datum/component/uplink)
hidden_uplink.set_gamemode(/datum/game_mode/nuclear)
/obj/item/device/radio/uplink/clownop/Initialize()
. = ..()
GET_COMPONENT(hidden_uplink, /datum/component/uplink)
hidden_uplink.set_gamemode(/datum/game_mode/nuclear/clown_ops)
/obj/item/device/multitool/uplink/Initialize(mapload, _owner, _tc_amount = 20)
. = ..()
AddComponent(/datum/component/uplink, _owner, FALSE, TRUE, null, _tc_amount)

View File

@@ -157,6 +157,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
with suppressors."
item = /obj/item/gun/ballistic/automatic/pistol
cost = 7
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/revolver
name = "Syndicate Revolver"
@@ -164,6 +165,15 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/gun/ballistic/revolver
cost = 13
surplus = 50
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/pie_cannon
name = "Banana Cream Pie Cannon"
desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!"
cost = 10
item = /obj/item/pneumatic_cannon/pie/selfcharge
surplus = 0
include_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/shotgun
name = "Bulldog Shotgun"
@@ -243,6 +253,16 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
pocketed when inactive. Activating it produces a loud, distinctive noise."
item = /obj/item/melee/transforming/energy/sword/saber
cost = 8
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/clownsword
name = "Bananium Energy Sword"
desc = "An energy sword that deals no damage, but will slip anyone it contacts, be it by melee attack, thrown \
impact, or just stepping on it. Beware friendly fire, as even anti-slip shoes will not protect against it."
item = /obj/item/melee/transforming/energy/sword/bananium
cost = 3
surplus = 0
include_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/doublesword
name = "Double-Bladed Energy Sword"
@@ -251,6 +271,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/twohanded/dualsaber
player_minimum = 25
cost = 16
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/doublesword/get_discount()
return pick(4;0.8,2;0.65,1;0.5)
@@ -277,6 +298,25 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
in addition to dealing high amounts of damage to nearby personnel."
item = /obj/item/grenade/syndieminibomb
cost = 6
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/bombanana
name = "Bombanana"
desc = "A banana with an explosive taste! discard the peel quickly, as it will explode with the force of a syndicate minibomb \
a few seconds after the banana is eaten."
item = /obj/item/reagent_containers/food/snacks/grown/banana/bombanana
cost = 4 //it is a bit cheaper than a minibomb because you have to take off your helmet to eat it, which is how you arm it
surplus = 0
include_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/tearstache
name = "Teachstache Grenade"
desc = "A teargas grenade that launches sticky moustaches onto the face of anyone not wearing a clown or mime mask. The moustaches will \
remain attached to the face of all targets for one minute, preventing the use of breath masks and other such devices."
item = /obj/item/grenade/chem_grenade/teargas/moustache
cost = 3
surplus = 0
include_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/foamsmg
name = "Toy Submachine Gun"
@@ -284,7 +324,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/gun/ballistic/automatic/c20r/toy
cost = 5
surplus = 0
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/foammachinegun
name = "Toy Machine Gun"
@@ -293,7 +333,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/gun/ballistic/automatic/l6_saw/toy
cost = 10
surplus = 0
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/viscerators
name = "Viscerator Delivery Grenade"
@@ -302,7 +342,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/grenade/spawnergrenade/manhacks
cost = 5
surplus = 35
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/bioterrorfoam
name = "Chemical Foam Grenade"
@@ -312,7 +352,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/grenade/chem_grenade/bioterrorfoam
cost = 5
surplus = 35
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/bioterror
name = "Biohazardous Chemical Sprayer"
@@ -322,7 +362,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/reagent_containers/spray/chemsprayer/bioterror
cost = 20
surplus = 0
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/stealthy_weapons/virus_grenade
name = "Fungal Tuberculosis Grenade"
@@ -332,7 +372,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/storage/box/syndie_kit/tuberculosisgrenade
cost = 12
surplus = 35
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/dangerous/guardian
name = "Holoparasites"
@@ -341,7 +381,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/storage/box/syndie_kit/guardian
cost = 18
surplus = 0
exclude_modes = list(/datum/game_mode/nuclear)
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
player_minimum = 25
// Ammunition
@@ -355,24 +395,28 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
are dirt cheap but are half as effective as .357 rounds."
item = /obj/item/ammo_box/magazine/m10mm
cost = 1
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/ammo/pistolap
name = "10mm Armour Piercing Magazine"
desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. These rounds are less effective at injuring the target but penetrate protective gear."
item = /obj/item/ammo_box/magazine/m10mm/ap
cost = 2
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/ammo/pistolfire
name = "10mm Incendiary Magazine"
desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with incendiary rounds which ignite the target."
item = /obj/item/ammo_box/magazine/m10mm/fire
cost = 2
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/ammo/pistolhp
name = "10mm Hollow Point Magazine"
desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. These rounds are more damaging but ineffective against armour."
item = /obj/item/ammo_box/magazine/m10mm/hp
cost = 3
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/ammo/pistolaps
name = "9mm Handgun Magazine"
@@ -394,6 +438,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
For when you really need a lot of things dead."
item = /obj/item/ammo_box/a357
cost = 4
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/ammo/shotgun
cost = 2
@@ -517,7 +562,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
and broca systems, making it impossible for them to move or speak for some time."
item = /obj/item/storage/box/syndie_kit/bioterror
cost = 6
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
//Support and Mechs
/datum/uplink_item/support
@@ -532,6 +577,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/antag_spawner/nuke_ops
cost = 25
refundable = TRUE
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/support/reinforcement/assault_borg
name = "Syndicate Assault Cyborg"
@@ -562,6 +608,20 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/mecha/combat/marauder/mauler/loaded
cost = 140
/datum/uplink_item/support/honker
name = "Dark H.O.N.K."
desc = "A clown combat mech equipped with bombanana peel and tearstache grenade launchers, as well as the ubiquitous HoNkER BlAsT 5000."
item = /obj/mecha/combat/honker/dark/loaded
cost = 80
include_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/support/clown_reinforcement
name = "Clown Reinforcements"
desc = "Call in an additional clown to share the fun, equipped with full starting gear, but no telecrystals."
item = /obj/item/antag_spawner/nuke_ops/clown
cost = 20
include_modes = list(/datum/game_mode/nuclear/clown_ops)
// Stealthy Weapons
/datum/uplink_item/stealthy_weapons
category = "Stealthy and Inconspicuous Weapons"
@@ -573,13 +633,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/sleeping_carp_scroll
cost = 17
surplus = 0
exclude_modes = list(/datum/game_mode/nuclear)
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/stealthy_weapons/cqc
name = "CQC Manual"
desc = "A manual that teaches a single user tactical Close-Quarters Combat before self-destructing."
item = /obj/item/cqc_manual
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
cost = 13
surplus = 0
@@ -661,6 +721,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/suppressor
cost = 3
surplus = 10
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/stealthy_weapons/pizza_bomb
name = "Pizza Bomb"
@@ -700,7 +761,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
They do not work on heavily lubricated surfaces."
item = /obj/item/clothing/shoes/chameleon/noslip
cost = 2
exclude_modes = list(/datum/game_mode/nuclear)
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
player_minimum = 20
/datum/uplink_item/stealthy_tools/syndigaloshes/nuke
@@ -709,6 +770,16 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
exclude_modes = list()
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/stealthy_tools/combatbananashoes
name = "Combat Banana Shoes"
desc = "While making the wearer immune to most slipping attacks like regular combat clown shoes, these shoes \
can generate a large number of synthetic banana peels as the wearer walks, slipping up would-be pursuers. They also \
squeek significantly louder."
item = /obj/item/clothing/shoes/clown_shoes/banana_shoes/combat
cost = 6
surplus = 0
include_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/stealthy_tools/frame
name = "F.R.A.M.E. PDA Cartridge"
desc = "When inserted into a personal digital assistant, this cartridge gives you five PDA viruses which \
@@ -767,7 +838,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/reagent_containers/syringe/mulligan
cost = 4
surplus = 30
exclude_modes = list(/datum/game_mode/nuclear)
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/stealthy_tools/emplight
name = "EMP Flashlight"
@@ -823,7 +894,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
provides the user with superior armor and mobility compared to the standard syndicate hardsuit."
item = /obj/item/clothing/suit/space/hardsuit/syndi/elite
cost = 8
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
exclude_modes = list()
/datum/uplink_item/suits/hardsuit/shielded
@@ -832,7 +903,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
The shields can handle up to three impacts within a short duration and will rapidly recharge while not under fire."
item = /obj/item/clothing/suit/space/hardsuit/shielded/syndi
cost = 30
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
exclude_modes = list()
// Devices and Tools
@@ -882,7 +953,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
and other supplies helpful for a field medic."
item = /obj/item/storage/firstaid/tactical
cost = 4
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/device_tools/syndietome
name = "Syndicate Tome"
@@ -952,7 +1023,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
'Advanced Magboots' slow you down in simulated-gravity environments much like the standard issue variety."
item = /obj/item/clothing/shoes/magboots/syndie
cost = 2
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/device_tools/c4
name = "Composition C-4"
@@ -1004,6 +1075,18 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/device/sbeacondrop/bomb
cost = 11
/datum/uplink_item/device_tools/clown_bomb_clownops
name = "Clown Bomb"
desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \
with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \
movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \
transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \
be defused, and some crew may attempt to do so."
item = /obj/item/device/sbeacondrop/clownbomb
cost = 15
surplus = 0
include_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/device_tools/syndicate_detonator
name = "Syndicate Detonator"
desc = "The Syndicate detonator is a companion device to the Syndicate bomb. Simply press the included button \
@@ -1012,7 +1095,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
the blast radius before using the detonator."
item = /obj/item/device/syndicatedetonator
cost = 3
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/device_tools/rad_laser
name = "Radioactive Microlaser"
@@ -1029,7 +1112,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/device/assault_pod
cost = 30
surplus = 0
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/device_tools/shield
name = "Energy Shield"
@@ -1040,20 +1123,30 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
surplus = 20
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/device_tools/shield
name = "Bananium Energy Shield"
desc = "A clown's most powerful defensive weapon, this personal shield provides near immunity to ranged energy attacks \
by bouncing them back at the ones who fired them. It can also be thrown to bounce off of people, slipping them, \
and returning to you even if you miss. WARNING: DO NOT ATTEMPT TO STAND ON SHIELD WHILE DEPLOYED, EVEN IF WEARING ANTI-SLIP SHOES."
item = /obj/item/shield/energy/bananium
cost = 16
surplus = 0
include_modes = list(/datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/device_tools/medgun
name = "Medbeam Gun"
desc = "A wonder of Syndicate engineering, the Medbeam gun, or Medi-Gun enables a medic to keep his fellow \
operatives in the fight, even while under fire."
item = /obj/item/gun/medbeam
cost = 15
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/device_tools/potion
name = "Syndicate Sentience Potion"
item = /obj/item/slimepotion/slime/sentience/nuclear
desc = "A potion recovered at great risk by undercover syndicate operatives and then subsequently modified with syndicate technology. Using it will make any animal sentient, and bound to serve you, as well as implanting an internal radio for communication and an internal ID card for opening doors."
cost = 4
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/device_tools/telecrystal
name = "Raw Telecrystal"
@@ -1189,7 +1282,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
// Role-specific items
/datum/uplink_item/role_restricted
category = "Role-Restricted"
exclude_modes = list(/datum/game_mode/nuclear)
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
surplus = 0
/datum/uplink_item/role_restricted/reverse_revolver
@@ -1346,7 +1439,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/badass/costumes
surplus = 0
include_modes = list(/datum/game_mode/nuclear)
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
cost = 4
cant_discount = TRUE
@@ -1382,7 +1475,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/structure/closet/crate
cost = 20
player_minimum = 25
exclude_modes = list(/datum/game_mode/nuclear)
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
cant_discount = TRUE
var/starting_crate_value = 50