Merge branch 'master' into digileg-runtime
This commit is contained in:
@@ -8,4 +8,5 @@
|
||||
#define CINEMATIC_CULT 8
|
||||
#define CINEMATIC_NUKE_FAKE 9
|
||||
#define CINEMATIC_NUKE_NO_CORE 10
|
||||
#define CINEMATIC_NUKE_FAR 11
|
||||
#define CINEMATIC_NUKE_FAR 11
|
||||
#define CINEMATIC_NUKE_CLOWNOP 12
|
||||
@@ -110,6 +110,11 @@
|
||||
|
||||
#define CITADEL_MENTOR_OOC_COLOUR "#224724"
|
||||
|
||||
//xenobio console upgrade stuff
|
||||
#define XENOBIO_UPGRADE_MONKEYS 1
|
||||
#define XENOBIO_UPGRADE_SLIMEBASIC 2
|
||||
#define XENOBIO_UPGRADE_SLIMEADV 4
|
||||
|
||||
//stamina stuff
|
||||
#define STAMINA_SOFTCRIT 100 //softcrit for stamina damage. prevents standing up, prevents performing actions that cost stamina, etc, but doesn't force a rest or stop movement
|
||||
#define STAMINA_CRIT 140 //crit for stamina damage. forces a rest, and stops movement until stamina goes back to stamina softcrit
|
||||
|
||||
@@ -142,3 +142,7 @@
|
||||
|
||||
#define EMP_HEAVY 1
|
||||
#define EMP_LIGHT 2
|
||||
|
||||
#define GRENADE_CLUMSY_FUMBLE 1
|
||||
#define GRENADE_NONCLUMSY_FUMBLE 2
|
||||
#define GRENADE_NO_FUMBLE 3
|
||||
|
||||
@@ -86,3 +86,8 @@
|
||||
|
||||
#define CALTROP_BYPASS_SHOES 1
|
||||
#define CALTROP_IGNORE_WALKERS 2
|
||||
|
||||
//Component Specific Signals
|
||||
//Wet floors
|
||||
#define COMSIG_TURF_IS_WET "check_turf_wet" //(): Returns bitflags of wet values.
|
||||
#define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool.
|
||||
|
||||
@@ -85,3 +85,16 @@
|
||||
#define SUPERMATTER_DANGER 4 // Integrity < 50%
|
||||
#define SUPERMATTER_EMERGENCY 5 // Integrity < 25%
|
||||
#define SUPERMATTER_DELAMINATING 6 // Pretty obvious.
|
||||
|
||||
//Nuclear bomb stuff
|
||||
#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
|
||||
|
||||
@@ -185,15 +185,17 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache)
|
||||
#define HAS_SENSORS 1
|
||||
#define LOCKED_SENSORS 2
|
||||
|
||||
//Turf wet states
|
||||
//Wet floor type flags. Stronger ones should be higher in number.
|
||||
#define TURF_DRY 0
|
||||
#define TURF_WET_WATER 1
|
||||
#define TURF_WET_LUBE 2
|
||||
#define TURF_WET_ICE 3
|
||||
#define TURF_WET_PERMAFROST 4
|
||||
#define TURF_WET_ICE 4
|
||||
#define TURF_WET_PERMAFROST 8
|
||||
|
||||
//Maximum amount of time, (in approx. seconds.) a tile can be wet for.
|
||||
#define MAXIMUM_WET_TIME 300
|
||||
#define IS_WET_OPEN_TURF(O) O.GetComponent(/datum/component/wet_floor)
|
||||
|
||||
//Maximum amount of time, (in deciseconds) a tile can be wet for.
|
||||
#define MAXIMUM_WET_TIME 3000
|
||||
|
||||
//unmagic-strings for types of polls
|
||||
#define POLLTYPE_OPTION "OPTION"
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
#define FIRE_PRIORITY_SERVER_MAINT 10
|
||||
#define FIRE_PRIORITY_RESEARCH 10
|
||||
#define FIRE_PRIORITY_GARBAGE 15
|
||||
#define FIRE_PRIORITY_WET_FLOORS 20
|
||||
#define FIRE_PRIORITY_AIR 20
|
||||
#define FIRE_PRIORITY_NPC 20
|
||||
#define FIRE_PRIORITY_PROCESS 25
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define ION_FILE "ion_laws.json"
|
||||
|
||||
/proc/lizard_name(gender)
|
||||
if(gender == MALE)
|
||||
return "[pick(GLOB.lizard_names_male)]-[pick(GLOB.lizard_names_male)]"
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
Note that AI have no need for the adjacency proc, and so this proc is a lot cleaner.
|
||||
*/
|
||||
/mob/living/silicon/ai/DblClickOn(var/atom/A, params)
|
||||
if(client.click_intercept)
|
||||
if(call(client.click_intercept, "InterceptClickOn")(src, params, A))
|
||||
return
|
||||
if(check_click_intercept(params,A))
|
||||
return
|
||||
|
||||
if(control_disabled || incapacitated())
|
||||
return
|
||||
@@ -27,9 +26,8 @@
|
||||
return
|
||||
next_click = world.time + 1
|
||||
|
||||
if(client.click_intercept)
|
||||
if(call(client.click_intercept, "InterceptClickOn")(src, params, A))
|
||||
return
|
||||
if(check_click_intercept(params,A))
|
||||
return
|
||||
|
||||
if(control_disabled || incapacitated())
|
||||
return
|
||||
|
||||
@@ -61,9 +61,8 @@
|
||||
return
|
||||
next_click = world.time + 1
|
||||
|
||||
if(client && client.click_intercept)
|
||||
if(call(client.click_intercept, "InterceptClickOn")(src, params, A))
|
||||
return
|
||||
if(check_click_intercept(params,A))
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["shift"] && modifiers["middle"])
|
||||
@@ -476,7 +475,7 @@
|
||||
var/mob/living/carbon/C = usr
|
||||
C.swap_hand()
|
||||
else
|
||||
var/turf/T = params2turf(modifiers["screen-loc"], get_turf(usr))
|
||||
var/turf/T = params2turf(modifiers["screen-loc"], get_turf(usr.client ? usr.client.eye : usr))
|
||||
params += "&catcher=1"
|
||||
if(T)
|
||||
T.Click(location, control, params)
|
||||
@@ -496,3 +495,16 @@
|
||||
else
|
||||
view = 1
|
||||
add_view_range(view)
|
||||
|
||||
/mob/proc/check_click_intercept(params,A)
|
||||
//Client level intercept
|
||||
if(client && client.click_intercept)
|
||||
if(call(client.click_intercept, "InterceptClickOn")(src, params, A))
|
||||
return TRUE
|
||||
|
||||
//Mob level intercept
|
||||
if(click_intercept)
|
||||
if(call(click_intercept, "InterceptClickOn")(src, params, A))
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
@@ -11,9 +11,8 @@
|
||||
return
|
||||
next_click = world.time + 1
|
||||
|
||||
if(client.click_intercept)
|
||||
if(call(client.click_intercept,"InterceptClickOn")(src,params,A))
|
||||
return
|
||||
if(check_click_intercept(params,A))
|
||||
return
|
||||
|
||||
if(stat || lockcharge || IsKnockdown() || IsStun() || IsUnconscious())
|
||||
return
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
C.parallax_layers_cached = list()
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_1(null, C.view)
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_2(null, C.view)
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/planet(null, C.view)
|
||||
C.parallax_layers_cached += new /obj/screen/parallax_layer/layer_3(null, C.view)
|
||||
|
||||
C.parallax_layers = C.parallax_layers_cached.Copy()
|
||||
@@ -86,6 +87,7 @@
|
||||
/datum/hud/proc/update_parallax_pref(mob/viewmob)
|
||||
remove_parallax(viewmob)
|
||||
create_parallax(viewmob)
|
||||
update_parallax()
|
||||
|
||||
// This sets which way the current shuttle is moving (returns true if the shuttle has stopped moving so the caller can append their animation)
|
||||
/datum/hud/proc/set_parallax_movedir(new_parallax_movedir, skip_windups)
|
||||
@@ -194,18 +196,27 @@
|
||||
var/obj/screen/parallax_layer/L = thing
|
||||
if (L.view_sized != C.view)
|
||||
L.update_o(C.view)
|
||||
var/change_x = offset_x * L.speed
|
||||
L.offset_x -= change_x
|
||||
var/change_y = offset_y * L.speed
|
||||
L.offset_y -= change_y
|
||||
if(L.offset_x > 240)
|
||||
L.offset_x -= 480
|
||||
if(L.offset_x < -240)
|
||||
L.offset_x += 480
|
||||
if(L.offset_y > 240)
|
||||
L.offset_y -= 480
|
||||
if(L.offset_y < -240)
|
||||
L.offset_y += 480
|
||||
|
||||
var/change_x
|
||||
var/change_y
|
||||
|
||||
if(L.absolute)
|
||||
L.offset_x = -(posobj.x - SSparallax.planet_x_offset) * L.speed
|
||||
L.offset_y = -(posobj.y - SSparallax.planet_y_offset) * L.speed
|
||||
else
|
||||
change_x = offset_x * L.speed
|
||||
L.offset_x -= change_x
|
||||
change_y = offset_y * L.speed
|
||||
L.offset_y -= change_y
|
||||
|
||||
if(L.offset_x > 240)
|
||||
L.offset_x -= 480
|
||||
if(L.offset_x < -240)
|
||||
L.offset_x += 480
|
||||
if(L.offset_y > 240)
|
||||
L.offset_y -= 480
|
||||
if(L.offset_y < -240)
|
||||
L.offset_y += 480
|
||||
|
||||
|
||||
if(!areaobj.parallax_movedir && C.dont_animate_parallax <= world.time && (offset_x || offset_y) && abs(offset_x) <= max(C.parallax_throttle/world.tick_lag+1,1) && abs(offset_y) <= max(C.parallax_throttle/world.tick_lag+1,1) && (round(abs(change_x)) > 1 || round(abs(change_y)) > 1))
|
||||
@@ -232,6 +243,7 @@
|
||||
var/offset_x = 0
|
||||
var/offset_y = 0
|
||||
var/view_sized
|
||||
var/absolute = FALSE
|
||||
blend_mode = BLEND_ADD
|
||||
plane = PLANE_SPACE_PARALLAX
|
||||
screen_loc = "CENTER-7,CENTER-7"
|
||||
@@ -247,7 +259,7 @@
|
||||
/obj/screen/parallax_layer/proc/update_o(view)
|
||||
if (!view)
|
||||
view = world.view
|
||||
|
||||
|
||||
var/list/viewscales = getviewsize(view)
|
||||
var/countx = CEILING((viewscales[1]/2)/(480/world.icon_size), 1)+1
|
||||
var/county = CEILING((viewscales[2]/2)/(480/world.icon_size), 1)+1
|
||||
@@ -278,6 +290,16 @@
|
||||
speed = 1.4
|
||||
layer = 3
|
||||
|
||||
/obj/screen/parallax_layer/planet
|
||||
icon_state = "planet"
|
||||
blend_mode = BLEND_OVERLAY
|
||||
absolute = TRUE //Status of seperation
|
||||
speed = 3
|
||||
layer = 30
|
||||
|
||||
/obj/screen/parallax_layer/planet/update_o()
|
||||
return //Shit wont move
|
||||
|
||||
#undef LOOP_NONE
|
||||
#undef LOOP_NORMAL
|
||||
#undef LOOP_REVERSE
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/mob/dead/observer/DblClickOn(var/atom/A, var/params)
|
||||
if(client.click_intercept)
|
||||
if(call(client.click_intercept,"InterceptClickOn")(src,params,A))
|
||||
return
|
||||
if(check_click_intercept(params,A))
|
||||
return
|
||||
|
||||
if(can_reenter_corpse && mind && mind.current)
|
||||
if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it
|
||||
@@ -18,9 +17,8 @@
|
||||
update_parallax_contents()
|
||||
|
||||
/mob/dead/observer/ClickOn(var/atom/A, var/params)
|
||||
if(client.click_intercept)
|
||||
if(call(client.click_intercept,"InterceptClickOn")(src,params,A))
|
||||
return
|
||||
if(check_click_intercept(params,A))
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["shift"] && modifiers["middle"])
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
SUBSYSTEM_DEF(parallax)
|
||||
name = "Parallax"
|
||||
wait = 2
|
||||
flags = SS_POST_FIRE_TIMING | SS_BACKGROUND | SS_NO_INIT
|
||||
flags = SS_POST_FIRE_TIMING | SS_BACKGROUND
|
||||
priority = FIRE_PRIORITY_PARALLAX
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
var/list/currentrun
|
||||
var/planet_x_offset = 128
|
||||
var/planet_y_offset = 128
|
||||
|
||||
/datum/controller/subsystem/parallax/Initialize(timeofday)
|
||||
. = ..()
|
||||
planet_y_offset = rand(100, 160)
|
||||
planet_x_offset = rand(100, 160)
|
||||
|
||||
/datum/controller/subsystem/parallax/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
|
||||
5
code/controllers/subsystem/processing/wet_floors.dm
Normal file
5
code/controllers/subsystem/processing/wet_floors.dm
Normal file
@@ -0,0 +1,5 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(wet_floors)
|
||||
name = "Wet floors"
|
||||
priority = FIRE_PRIORITY_WET_FLOORS
|
||||
wait = 15
|
||||
stat_tag = "WFP" //Used for logging
|
||||
@@ -51,7 +51,7 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
for(var/A in GLOB.cinematics)
|
||||
var/datum/cinematic/C = A
|
||||
if(C == src)
|
||||
continue
|
||||
continue
|
||||
if(C.is_global || !is_global)
|
||||
return //Can't play two global or local cinematics at the same time
|
||||
|
||||
@@ -73,7 +73,7 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
if(is_global)
|
||||
M.notransform = TRUE
|
||||
locked += M
|
||||
|
||||
|
||||
//Actually play it
|
||||
content()
|
||||
//Cleanup
|
||||
@@ -209,6 +209,17 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
cinematic_sound(sound('sound/effects/explosion_distant.ogg'))
|
||||
special()
|
||||
|
||||
/datum/cinematic/clownop
|
||||
id = CINEMATIC_NUKE_CLOWNOP
|
||||
cleanup_time = 100
|
||||
|
||||
/datum/cinematic/clownop/content()
|
||||
flick("intro_nuke",screen)
|
||||
sleep(35)
|
||||
cinematic_sound(sound('sound/items/airhorn.ogg'))
|
||||
flick("summary_selfdes",screen) //???
|
||||
special()
|
||||
|
||||
/* Intended usage.
|
||||
Nuke.Explosion()
|
||||
-> Cinematic(NUKE_BOOM,world)
|
||||
|
||||
171
code/datums/components/wet_floor.dm
Normal file
171
code/datums/components/wet_floor.dm
Normal file
@@ -0,0 +1,171 @@
|
||||
/datum/component/wet_floor
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
||||
var/highest_strength = TURF_DRY
|
||||
var/lube_flags = NONE //why do we have this?
|
||||
var/list/time_left_list //In deciseconds.
|
||||
var/static/mutable_appearance/permafrost_overlay = mutable_appearance('icons/effects/water.dmi', "ice_floor")
|
||||
var/static/mutable_appearance/ice_overlay = mutable_appearance('icons/turf/overlays.dmi', "snowfloor")
|
||||
var/static/mutable_appearance/water_overlay = mutable_appearance('icons/effects/water.dmi', "wet_floor_static")
|
||||
var/static/mutable_appearance/generic_turf_overlay = mutable_appearance('icons/effects/water.dmi', "wet_static")
|
||||
var/current_overlay
|
||||
var/permanent = FALSE
|
||||
|
||||
/datum/component/wet_floor/InheritComponent(datum/newcomp, orig, argslist)
|
||||
if(!newcomp) //We are getting passed the arguments of a would-be new component, but not a new component
|
||||
add_wet(arglist(argslist))
|
||||
else //We are being passed in a full blown component
|
||||
var/datum/component/wet_floor/WF = newcomp //Lets make an assumption
|
||||
if(WF.gc()) //See if it's even valid, still. Also does LAZYLEN and stuff for us.
|
||||
CRASH("Wet floor component tried to inherit another, but the other was able to garbage collect while being inherited! What a waste of time!")
|
||||
return
|
||||
for(var/i in WF.time_left_list)
|
||||
add_wet(text2num(i), WF.time_left_list[i])
|
||||
|
||||
/datum/component/wet_floor/Initialize(strength, duration_minimum, duration_add, duration_maximum, permanent = FALSE)
|
||||
if(!isopenturf(parent))
|
||||
. = COMPONENT_INCOMPATIBLE
|
||||
CRASH("Wet floor component attempted to be applied to a non open turf!")
|
||||
add_wet(strength, duration_minimum, duration_add, duration_maximum)
|
||||
RegisterSignal(COMSIG_TURF_IS_WET, .proc/is_wet)
|
||||
RegisterSignal(COMSIG_TURF_MAKE_DRY, .proc/dry)
|
||||
if(!permanent)
|
||||
START_PROCESSING(SSwet_floors, src)
|
||||
if(gc())
|
||||
stack_trace("Warning: Wet floor component added and immediately deleted! What a waste of time!")
|
||||
|
||||
/datum/component/wet_floor/Destroy()
|
||||
STOP_PROCESSING(SSwet_floors, src)
|
||||
var/turf/T = parent
|
||||
qdel(T.GetComponent(/datum/component/slippery))
|
||||
if(istype(T)) //If this is false there is so many things wrong with it.
|
||||
T.cut_overlay(current_overlay)
|
||||
else
|
||||
stack_trace("Warning: Wet floor component wasn't on a turf when being destroyed! This is really bad!")
|
||||
return ..()
|
||||
|
||||
/datum/component/wet_floor/proc/update_overlay()
|
||||
var/intended
|
||||
if(!istype(parent, /turf/open/floor))
|
||||
intended = generic_turf_overlay
|
||||
else
|
||||
switch(highest_strength)
|
||||
if(TURF_WET_PERMAFROST)
|
||||
intended = permafrost_overlay
|
||||
if(TURF_WET_ICE)
|
||||
intended = ice_overlay
|
||||
else
|
||||
intended = water_overlay
|
||||
if(current_overlay != intended)
|
||||
var/turf/T = parent
|
||||
T.cut_overlay(current_overlay)
|
||||
T.add_overlay(intended)
|
||||
current_overlay = intended
|
||||
|
||||
/datum/component/wet_floor/proc/AfterSlip(mob/living/L)
|
||||
if(highest_strength == TURF_WET_LUBE)
|
||||
L.confused = max(L.confused, 8)
|
||||
|
||||
/datum/component/wet_floor/proc/update_flags()
|
||||
var/intensity
|
||||
lube_flags = NONE
|
||||
switch(highest_strength)
|
||||
if(TURF_WET_WATER)
|
||||
intensity = 60
|
||||
lube_flags = NO_SLIP_WHEN_WALKING
|
||||
if(TURF_WET_LUBE)
|
||||
intensity = 80
|
||||
lube_flags = SLIDE | GALOSHES_DONT_HELP
|
||||
if(TURF_WET_ICE)
|
||||
intensity = 120
|
||||
lube_flags = SLIDE | GALOSHES_DONT_HELP
|
||||
if(TURF_WET_PERMAFROST)
|
||||
intensity = 120
|
||||
lube_flags = SLIDE_ICE | GALOSHES_DONT_HELP
|
||||
else
|
||||
qdel(parent.GetComponent(/datum/component/slippery))
|
||||
return
|
||||
|
||||
var/datum/component/slippery/S = parent.LoadComponent(/datum/component/slippery, NONE, CALLBACK(src, .proc/AfterSlip))
|
||||
S.intensity = intensity
|
||||
S.lube_flags = lube_flags
|
||||
|
||||
/datum/component/wet_floor/proc/dry(strength = TURF_WET_WATER, immediate = FALSE, duration_decrease = INFINITY)
|
||||
for(var/i in time_left_list)
|
||||
if(text2num(i) <= strength)
|
||||
time_left_list[i] = max(0, time_left_list[i] - duration_decrease)
|
||||
if(immediate)
|
||||
check()
|
||||
|
||||
/datum/component/wet_floor/proc/max_time_left()
|
||||
. = 0
|
||||
for(var/i in time_left_list)
|
||||
. = max(., time_left_list[i])
|
||||
|
||||
/datum/component/wet_floor/process()
|
||||
var/turf/open/T = parent
|
||||
var/decrease = 0
|
||||
var/t = T.GetTemperature()
|
||||
switch(t)
|
||||
if(-INFINITY to T0C)
|
||||
add_wet(TURF_WET_ICE, max_time_left()) //Water freezes into ice!
|
||||
if(T0C to T0C + 100)
|
||||
decrease = (T.air.temperature - T0C) //one ds per degree.
|
||||
if(T0C + 100 to INFINITY)
|
||||
decrease = INFINITY
|
||||
if((is_wet() & TURF_WET_ICE) && t > T0C) //Ice melts into water!
|
||||
for(var/obj/O in T.contents)
|
||||
if(O.flags_2 & FROZEN_2)
|
||||
O.make_unfrozen()
|
||||
add_wet(TURF_WET_WATER, max_time_left())
|
||||
dry(TURF_WET_ICE)
|
||||
dry(ALL, FALSE, decrease)
|
||||
check()
|
||||
|
||||
/datum/component/wet_floor/proc/update_strength()
|
||||
highest_strength = 0 //Not bitflag.
|
||||
for(var/i in time_left_list)
|
||||
highest_strength = max(highest_strength, text2num(i))
|
||||
|
||||
/datum/component/wet_floor/proc/is_wet()
|
||||
. = 0
|
||||
for(var/i in time_left_list)
|
||||
. |= text2num(i)
|
||||
|
||||
/datum/component/wet_floor/OnTransfer(datum/to_datum)
|
||||
if(!isopenturf(to_datum))
|
||||
. = COMPONENT_INCOMPATIBLE
|
||||
CRASH("Wet floor component attempted to be transferred to a non open turf!")
|
||||
var/turf/O = parent
|
||||
O.cut_overlay(current_overlay)
|
||||
var/turf/T = to_datum
|
||||
T.add_overlay(current_overlay)
|
||||
|
||||
/datum/component/wet_floor/proc/add_wet(type, duration_minimum = 0, duration_add = 0, duration_maximum = MAXIMUM_WET_TIME)
|
||||
var/static/list/allowed_types = list(TURF_WET_WATER, TURF_WET_LUBE, TURF_WET_ICE, TURF_WET_PERMAFROST)
|
||||
if(!duration_minimum || duration_minimum < 0 || !type || !(type in allowed_types))
|
||||
return FALSE
|
||||
var/time = 0
|
||||
if(LAZYACCESS(time_left_list, "[type]"))
|
||||
time = CLAMP(LAZYACCESS(time_left_list, "[type]") + duration_add, duration_minimum, duration_maximum)
|
||||
else
|
||||
time = min(duration_minimum, duration_maximum)
|
||||
LAZYSET(time_left_list, "[type]", time)
|
||||
check(TRUE)
|
||||
return TRUE
|
||||
|
||||
/datum/component/wet_floor/proc/gc()
|
||||
if(!LAZYLEN(time_left_list))
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/datum/component/wet_floor/proc/check(force_update = FALSE)
|
||||
var/changed = FALSE
|
||||
for(var/i in time_left_list)
|
||||
if(time_left_list[i] <= 0)
|
||||
time_left_list -= i
|
||||
changed = TRUE
|
||||
if(changed || force_update)
|
||||
update_strength()
|
||||
update_overlay()
|
||||
update_flags()
|
||||
gc()
|
||||
@@ -813,11 +813,6 @@
|
||||
if(!mind.assigned_role)
|
||||
mind.assigned_role = "Unassigned" //default
|
||||
|
||||
//XENO
|
||||
/mob/living/carbon/alien/mind_initialize()
|
||||
..()
|
||||
mind.special_role = ROLE_ALIEN
|
||||
|
||||
//AI
|
||||
/mob/living/silicon/ai/mind_initialize()
|
||||
..()
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
mood_change = -3
|
||||
|
||||
/datum/mood_event/brain_damage/add_effects()
|
||||
var/damage_message = pick_list_replacements("BRAIN_DAMAGE_FILE", "brain_damage")
|
||||
var/damage_message = pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage")
|
||||
description = "<span class='warning'>Hurr durr... [damage_message]</span>\n"
|
||||
|
||||
/datum/mood_event/hulk //Entire duration of having the hulk mutation
|
||||
|
||||
@@ -501,19 +501,15 @@
|
||||
if(((hand % 2) == 0))
|
||||
var/obj/item/bodypart/L = itemUser.newBodyPart("r_arm", FALSE, FALSE)
|
||||
L.attach_limb(itemUser)
|
||||
itemUser.put_in_r_hand(newRod)
|
||||
itemUser.put_in_hand(newRod, hand, forced = TRUE)
|
||||
else
|
||||
var/obj/item/bodypart/L = itemUser.newBodyPart("l_arm", FALSE, FALSE)
|
||||
L.attach_limb(itemUser)
|
||||
itemUser.put_in_l_hand(newRod)
|
||||
itemUser.put_in_hand(newRod, hand, forced = TRUE)
|
||||
to_chat(itemUser, "<span class='notice'>Your arm suddenly grows back with the Rod of Asclepius still attached!</span>")
|
||||
else
|
||||
//Otherwise get rid of whatever else is in their hand and return the rod to said hand
|
||||
itemUser.dropItemToGround(itemUser.get_item_for_held_index(hand))
|
||||
if(((hand % 2) == 0))
|
||||
itemUser.put_in_r_hand(newRod)
|
||||
else
|
||||
itemUser.put_in_l_hand(newRod)
|
||||
itemUser.put_in_hand(newRod, hand, forced = TRUE)
|
||||
to_chat(itemUser, "<span class='notice'>The Rod of Asclepius suddenly grows back out of your arm!</span>")
|
||||
//Because a servant of medicines stops at nothing to help others, lets keep them on their toes and give them an additional boost.
|
||||
if(itemUser.health < itemUser.maxHealth)
|
||||
|
||||
@@ -304,6 +304,9 @@
|
||||
if(AM && isturf(AM.loc))
|
||||
step(AM, turn(AM.dir, 180))
|
||||
|
||||
/atom/proc/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube)
|
||||
return
|
||||
|
||||
//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list
|
||||
/mob/living/proc/get_blood_dna_list()
|
||||
if(get_blood_id() != "blood")
|
||||
@@ -354,9 +357,6 @@
|
||||
/atom/proc/handle_fall()
|
||||
return
|
||||
|
||||
/atom/proc/handle_slip()
|
||||
return
|
||||
|
||||
/atom/proc/singularity_act()
|
||||
return
|
||||
|
||||
|
||||
59
code/game/gamemodes/clown_ops/bananium_bomb.dm
Normal file
59
code/game/gamemodes/clown_ops/bananium_bomb.dm
Normal file
@@ -0,0 +1,59 @@
|
||||
/obj/machinery/nuclearbomb/syndicate/bananium
|
||||
name = "bananium fission explosive"
|
||||
desc = "You probably shouldn't stick around to see if this is armed."
|
||||
icon = 'icons/obj/machines/nuke.dmi'
|
||||
icon_state = "bananiumbomb_base"
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate/bananium/update_icon()
|
||||
if(deconstruction_state == NUKESTATE_INTACT)
|
||||
switch(get_nuke_state())
|
||||
if(NUKE_OFF_LOCKED, NUKE_OFF_UNLOCKED)
|
||||
icon_state = "bananiumbomb_base"
|
||||
update_icon_interior()
|
||||
update_icon_lights()
|
||||
if(NUKE_ON_TIMING)
|
||||
cut_overlays()
|
||||
icon_state = "bananiumbomb_timing"
|
||||
if(NUKE_ON_EXPLODING)
|
||||
cut_overlays()
|
||||
icon_state = "bananiumbomb_exploding"
|
||||
else
|
||||
icon_state = "bananiumbomb_base"
|
||||
update_icon_interior()
|
||||
update_icon_lights()
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate/bananium/get_cinematic_type(off_station)
|
||||
switch(off_station)
|
||||
if(0)
|
||||
return CINEMATIC_NUKE_CLOWNOP
|
||||
if(1)
|
||||
return CINEMATIC_NUKE_MISS
|
||||
if(2)
|
||||
return CINEMATIC_NUKE_FAKE //it is farther away, so just a bikehorn instead of an airhorn
|
||||
return CINEMATIC_NUKE_FAKE
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate/bananium/really_actually_explode(off_station)
|
||||
Cinematic(get_cinematic_type(off_station), world)
|
||||
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
|
||||
var/turf/T = get_turf(H)
|
||||
if(!T || T.z != z)
|
||||
continue
|
||||
H.Stun(10)
|
||||
var/obj/item/clothing/C
|
||||
if(!H.w_uniform || H.dropItemToGround(H.w_uniform))
|
||||
C = new /obj/item/clothing/under/rank/clown(H)
|
||||
C.flags_1 |= NODROP_1 //mwahaha
|
||||
H.equip_to_slot_or_del(C, slot_w_uniform)
|
||||
|
||||
if(!H.shoes || H.dropItemToGround(H.shoes))
|
||||
C = new /obj/item/clothing/shoes/clown_shoes(H)
|
||||
C.flags_1 |= NODROP_1
|
||||
H.equip_to_slot_or_del(C, slot_shoes)
|
||||
|
||||
if(!H.wear_mask || H.dropItemToGround(H.wear_mask))
|
||||
C = new /obj/item/clothing/mask/gas/clown_hat(H)
|
||||
C.flags_1 |= NODROP_1
|
||||
H.equip_to_slot_or_del(C, slot_wear_mask)
|
||||
|
||||
H.dna.add_mutation(CLOWNMUT)
|
||||
H.gain_trauma(/datum/brain_trauma/mild/phobia, TRAUMA_RESILIENCE_LOBOTOMY, "clowns") //MWA HA HA
|
||||
66
code/game/gamemodes/clown_ops/clown_ops.dm
Normal file
66
code/game/gamemodes/clown_ops/clown_ops.dm
Normal file
@@ -0,0 +1,66 @@
|
||||
/datum/game_mode/nuclear/clown_ops
|
||||
name = "clown ops"
|
||||
config_tag = "clownops"
|
||||
|
||||
announce_span = "danger"
|
||||
announce_text = "Clown empire forces are approaching the station in an attempt to HONK it!\n\
|
||||
<span class='danger'>Operatives</span>: Secure the nuclear authentication disk and use your bananium fission explosive to HONK the station.\n\
|
||||
<span class='notice'>Crew</span>: Defend the nuclear authentication disk and ensure that it leaves with you on the emergency shuttle."
|
||||
|
||||
operative_antag_datum_type = /datum/antagonist/nukeop/clownop
|
||||
leader_antag_datum_type = /datum/antagonist/nukeop/leader/clownop
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/game_mode/nuclear/clown_ops/pre_setup()
|
||||
. = ..()
|
||||
if(.)
|
||||
for(var/obj/machinery/nuclearbomb/syndicate/S in GLOB.nuke_list)
|
||||
var/turf/T = get_turf(S)
|
||||
if(T)
|
||||
qdel(S)
|
||||
new /obj/machinery/nuclearbomb/syndicate/bananium(T)
|
||||
for(var/V in pre_nukeops)
|
||||
var/datum/mind/the_op = V
|
||||
the_op.assigned_role = "Clown Operative"
|
||||
the_op.special_role = "Clown Operative"
|
||||
|
||||
/datum/game_mode/nuclear/clown_ops/generate_report()
|
||||
return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \
|
||||
transport containing a bananium fission explosive, although it is useless without the proper code and authorization disk. While the code was likely found in minutes, the only disk that \
|
||||
can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders."
|
||||
|
||||
|
||||
/datum/outfit/syndicate/clownop
|
||||
name = "Clown Operative - Basic"
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
shoes = /obj/item/clothing/shoes/clown_shoes/combat
|
||||
mask = /obj/item/clothing/mask/gas/clown_hat
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
back = /obj/item/storage/backpack/clown
|
||||
ears = /obj/item/device/radio/headset/syndicate/alt
|
||||
l_pocket = /obj/item/pinpointer/nuke/syndicate
|
||||
r_pocket = /obj/item/bikehorn
|
||||
id = /obj/item/card/id/syndicate
|
||||
backpack_contents = list(/obj/item/storage/box/syndie=1,\
|
||||
/obj/item/kitchen/knife/combat/survival,
|
||||
/obj/item/reagent_containers/spray/waterflower/lube)
|
||||
implants = list(/obj/item/implant/sad_trombone)
|
||||
|
||||
uplink_type = /obj/item/device/radio/uplink/clownop
|
||||
|
||||
/datum/outfit/syndicate/clownop/no_crystals
|
||||
tc = 0
|
||||
|
||||
/datum/outfit/syndicate/clownop/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
..()
|
||||
if(visualsOnly)
|
||||
return
|
||||
H.dna.add_mutation(CLOWNMUT)
|
||||
|
||||
/datum/outfit/syndicate/clownop/leader
|
||||
name = "Clown Operative Leader - Basic"
|
||||
id = /obj/item/card/id/syndicate/nuke_leader
|
||||
r_hand = /obj/item/device/nuclear_challenge/clownops
|
||||
command_radio = TRUE
|
||||
298
code/game/gamemodes/clown_ops/clown_weapons.dm
Normal file
298
code/game/gamemodes/clown_ops/clown_weapons.dm
Normal file
@@ -0,0 +1,298 @@
|
||||
/obj/item/reagent_containers/spray/waterflower/lube
|
||||
name = "water flower"
|
||||
desc = "A seemingly innocent sunflower...with a twist. A <i>slippery</i> twist."
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "sunflower"
|
||||
item_state = "sunflower"
|
||||
amount_per_transfer_from_this = 3
|
||||
spray_range = 1
|
||||
stream_range = 1
|
||||
volume = 30
|
||||
list_reagents = list("lube" = 30)
|
||||
|
||||
//COMBAT CLOWN SHOES
|
||||
//Clown shoes with combat stats and noslip. Of course they still squeek.
|
||||
/obj/item/clothing/shoes/clown_shoes/combat
|
||||
name = "combat clown shoes"
|
||||
desc = "advanced clown shoes that protect the wearer and render them nearly immune to slipping on their own peels. They also squeek at 100% capacity."
|
||||
flags_1 = NOSLIP_1
|
||||
slowdown = SHOES_SLOWDOWN
|
||||
armor = list("melee" = 25, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 10, "rad" = 0, "fire" = 70, "acid" = 50)
|
||||
strip_delay = 70
|
||||
resistance_flags = NONE
|
||||
permeability_coefficient = 0.05
|
||||
pockets = /obj/item/storage/internal/pocket/shoes
|
||||
|
||||
//The super annoying version
|
||||
/obj/item/clothing/shoes/clown_shoes/banana_shoes/combat
|
||||
name = "mk-honk combat shoes"
|
||||
desc = "The culmination of years of clown combat research, these shoes leave a trail of chaos in their wake. They will slowly recharge themselves over time, or can be manually charged with bananium."
|
||||
slowdown = SHOES_SLOWDOWN
|
||||
armor = list("melee" = 25, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 10, "rad" = 0, "fire" = 70, "acid" = 50)
|
||||
strip_delay = 70
|
||||
resistance_flags = NONE
|
||||
permeability_coefficient = 0.05
|
||||
pockets = /obj/item/storage/internal/pocket/shoes
|
||||
always_noslip = TRUE
|
||||
var/max_recharge = 3000 //30 peels worth
|
||||
var/recharge_rate = 34 //about 1/3 of a peel per tick
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/banana_shoes/combat/Initialize()
|
||||
. = ..()
|
||||
GET_COMPONENT(bananium, /datum/component/material_container)
|
||||
bananium.insert_amount(max_recharge, MAT_BANANIUM)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/banana_shoes/combat/process()
|
||||
GET_COMPONENT(bananium, /datum/component/material_container)
|
||||
var/bananium_amount = bananium.amount(MAT_BANANIUM)
|
||||
if(bananium_amount < max_recharge)
|
||||
bananium.insert_amount(min(recharge_rate, max_recharge - bananium_amount), MAT_BANANIUM)
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/banana_shoes/combat/attack_self(mob/user)
|
||||
ui_action_click(user)
|
||||
|
||||
//BANANIUM SWORD
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/bananium
|
||||
name = "bananium sword"
|
||||
desc = "An elegant weapon, for a more civilized age."
|
||||
force = 0
|
||||
throwforce = 0
|
||||
force_on = 0
|
||||
throwforce_on = 0
|
||||
hitsound = null
|
||||
attack_verb_on = list("slipped")
|
||||
clumsy_check = FALSE
|
||||
sharpness = IS_BLUNT
|
||||
item_color = "yellow"
|
||||
heat = 0
|
||||
light_color = "#ffff00"
|
||||
var/next_trombone_allowed = 0
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/bananium/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/slippery, 60, GALOSHES_DONT_HELP)
|
||||
GET_COMPONENT(slipper, /datum/component/slippery)
|
||||
slipper.enabled = active
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/bananium/attack(mob/living/M, mob/living/user)
|
||||
..()
|
||||
if(active)
|
||||
GET_COMPONENT(slipper, /datum/component/slippery)
|
||||
slipper.Slip(M)
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/bananium/throw_impact(atom/hit_atom, throwingdatum)
|
||||
. = ..()
|
||||
if(active)
|
||||
GET_COMPONENT(slipper, /datum/component/slippery)
|
||||
slipper.Slip(hit_atom)
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/bananium/attackby(obj/item/I, mob/living/user, params)
|
||||
if((world.time > next_trombone_allowed) && istype(I, /obj/item/melee/transforming/energy/sword/bananium))
|
||||
next_trombone_allowed = world.time + 50
|
||||
to_chat(user, "You slap the two swords together. Sadly, they do not seem to fit.")
|
||||
playsound(src, 'sound/misc/sadtrombone.ogg', 50)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/bananium/transform_weapon(mob/living/user, supress_message_text)
|
||||
..()
|
||||
GET_COMPONENT(slipper, /datum/component/slippery)
|
||||
slipper.enabled = active
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/bananium/ignition_effect(atom/A, mob/user)
|
||||
return ""
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/bananium/suicide_act(mob/user)
|
||||
if(!active)
|
||||
transform_weapon(user, TRUE)
|
||||
user.visible_message("<span class='suicide'>[user] is [pick("slitting [user.p_their()] stomach open with", "falling on")] [src]! It looks like [user.p_theyre()] trying to commit seppuku, but the blade slips off of them harmlessly!</span>")
|
||||
GET_COMPONENT(slipper, /datum/component/slippery)
|
||||
slipper.Slip(user)
|
||||
return SHAME
|
||||
|
||||
//BANANIUM SHIELD
|
||||
|
||||
/obj/item/shield/energy/bananium
|
||||
name = "bananium energy shield"
|
||||
desc = "A shield that stops most melee attacks, protects user from almost all energy projectiles, and can be thrown to slip opponents."
|
||||
throw_speed = 1
|
||||
clumsy_check = 0
|
||||
base_icon_state = "bananaeshield"
|
||||
force = 0
|
||||
throwforce = 0
|
||||
throw_range = 5
|
||||
on_force = 0
|
||||
on_throwforce = 0
|
||||
on_throw_speed = 1
|
||||
|
||||
/obj/item/shield/energy/bananium/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/slippery, 60, GALOSHES_DONT_HELP)
|
||||
GET_COMPONENT(slipper, /datum/component/slippery)
|
||||
slipper.enabled = active
|
||||
|
||||
/obj/item/shield/energy/bananium/attack_self(mob/living/carbon/human/user)
|
||||
..()
|
||||
GET_COMPONENT(slipper, /datum/component/slippery)
|
||||
slipper.enabled = active
|
||||
|
||||
/obj/item/shield/energy/bananium/throw_at(atom/target, range, speed, mob/thrower, spin=1)
|
||||
if(active)
|
||||
if(iscarbon(thrower))
|
||||
var/mob/living/carbon/C = thrower
|
||||
C.throw_mode_on() //so they can catch it on the return.
|
||||
return ..()
|
||||
|
||||
/obj/item/shield/energy/bananium/throw_impact(atom/hit_atom)
|
||||
if(active)
|
||||
var/caught = hit_atom.hitby(src, 0, 0)
|
||||
if(iscarbon(hit_atom) && !caught)//if they are a carbon and they didn't catch it
|
||||
GET_COMPONENT(slipper, /datum/component/slippery)
|
||||
slipper.Slip(hit_atom)
|
||||
if(thrownby && !caught)
|
||||
throw_at(thrownby, throw_range+2, throw_speed, null, 1)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
//BOMBANANA
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana/bombanana
|
||||
trash = /obj/item/grown/bananapeel/bombanana
|
||||
bitesize = 1
|
||||
customfoodfilling = FALSE
|
||||
seed = null
|
||||
tastes = list("explosives" = 10)
|
||||
list_reagents = list("vitamin" = 1)
|
||||
|
||||
/obj/item/grown/bananapeel/bombanana
|
||||
desc = "A peel from a banana. Why is it beeping?"
|
||||
seed = null
|
||||
var/det_time = 50
|
||||
var/obj/item/grenade/syndieminibomb/bomb
|
||||
|
||||
/obj/item/grown/bananapeel/bombanana/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/slippery, det_time)
|
||||
bomb = new /obj/item/grenade/syndieminibomb(src)
|
||||
bomb.det_time = det_time
|
||||
if(iscarbon(loc))
|
||||
to_chat(loc, "[src] begins to beep.")
|
||||
var/mob/living/carbon/C = loc
|
||||
C.throw_mode_on()
|
||||
bomb.preprime(loc, null, FALSE)
|
||||
|
||||
/obj/item/grown/bananapeel/bombanana/Destroy()
|
||||
. = ..()
|
||||
QDEL_NULL(bomb)
|
||||
|
||||
/obj/item/grown/bananapeel/bombanana/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is deliberately slipping on the [src.name]! It looks like \he's trying to commit suicide.</span>")
|
||||
playsound(loc, 'sound/misc/slip.ogg', 50, 1, -1)
|
||||
bomb.preprime(user, 0, FALSE)
|
||||
return (BRUTELOSS)
|
||||
|
||||
//TEARSTACHE GRENADE
|
||||
|
||||
/obj/item/grenade/chem_grenade/teargas/moustache
|
||||
name = "tear-stache grenade"
|
||||
desc = "A handsomely-attired teargas grenade."
|
||||
icon_state = "moustacheg"
|
||||
clumsy_check = GRENADE_NONCLUMSY_FUMBLE
|
||||
|
||||
/obj/item/grenade/chem_grenade/teargas/moustache/prime()
|
||||
var/myloc = get_turf(src)
|
||||
. = ..()
|
||||
for(var/mob/living/carbon/M in view(6, myloc))
|
||||
if(!istype(M.wear_mask, /obj/item/clothing/mask/gas/clown_hat) && !istype(M.wear_mask, /obj/item/clothing/mask/gas/mime) )
|
||||
if(!M.wear_mask || M.dropItemToGround(M.wear_mask))
|
||||
var/obj/item/clothing/mask/fakemoustache/sticky/the_stash = new /obj/item/clothing/mask/fakemoustache/sticky()
|
||||
M.equip_to_slot_or_del(the_stash, slot_wear_mask, TRUE, TRUE, TRUE, TRUE)
|
||||
|
||||
/obj/item/clothing/mask/fakemoustache/sticky
|
||||
var/unstick_time = 600
|
||||
|
||||
/obj/item/clothing/mask/fakemoustache/sticky/Initialize()
|
||||
. = ..()
|
||||
flags_1 |= NODROP_1
|
||||
addtimer(CALLBACK(src, .proc/unstick), unstick_time)
|
||||
|
||||
/obj/item/clothing/mask/fakemoustache/sticky/proc/unstick()
|
||||
flags_1 &= ~NODROP_1
|
||||
|
||||
//DARK H.O.N.K. AND CLOWN MECH WEAPONS
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/bombanana
|
||||
name = "bombanana mortar"
|
||||
desc = "Equipment for clown exosuits. Launches exploding banana peels."
|
||||
icon_state = "mecha_bananamrtr"
|
||||
projectile = /obj/item/grown/bananapeel/bombanana
|
||||
projectiles = 8
|
||||
projectile_energy_cost = 1000
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/bombanana/can_attach(obj/mecha/combat/honker/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/tearstache
|
||||
name = "\improper HONKeR-6 grenade launcher"
|
||||
desc = "A weapon for combat exosuits. Launches primed tear-stache grenades."
|
||||
icon_state = "mecha_grenadelnchr"
|
||||
projectile = /obj/item/grenade/chem_grenade/teargas/moustache
|
||||
fire_sound = 'sound/weapons/grenadelaunch.ogg'
|
||||
projectiles = 6
|
||||
missile_speed = 1.5
|
||||
projectile_energy_cost = 800
|
||||
equip_cooldown = 60
|
||||
det_time = 20
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/tearstache/can_attach(obj/mecha/combat/honker/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/mecha/combat/honker/dark
|
||||
desc = "Produced by \"Tyranny of Honk, INC\", this exosuit is designed as heavy clown-support. This one has been painted black for maximum fun. HONK!"
|
||||
name = "\improper Dark H.O.N.K"
|
||||
icon_state = "darkhonker"
|
||||
max_integrity = 300
|
||||
deflect_chance = 15
|
||||
armor = list("melee" = 40, "bullet" = 40, "laser" = 50, "energy" = 35, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
max_temperature = 35000
|
||||
operation_req_access = list(ACCESS_SYNDICATE)
|
||||
wreckage = /obj/structure/mecha_wreckage/honker/dark
|
||||
max_equip = 3
|
||||
|
||||
/obj/mecha/combat/honker/dark/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
thrusters_action.Grant(user, src)
|
||||
|
||||
|
||||
/obj/mecha/combat/honker/dark/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
thrusters_action.Remove(user)
|
||||
|
||||
/obj/mecha/combat/honker/dark/add_cell(obj/item/stock_parts/cell/C)
|
||||
if(C)
|
||||
C.forceMove(src)
|
||||
cell = C
|
||||
return
|
||||
cell = new /obj/item/stock_parts/cell/hyper(src)
|
||||
|
||||
/obj/mecha/combat/honker/dark/loaded/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/honker()
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/bombanana()//Needed more offensive weapons.
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/tearstache()//The mousetrap mortar was not up-to-snuff.
|
||||
ME.attach(src)
|
||||
|
||||
/obj/structure/mecha_wreckage/honker/dark
|
||||
name = "\improper Dark H.O.N.K wreckage"
|
||||
icon_state = "darkhonker-broken"
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
var/datum/team/nuclear/nuke_team
|
||||
|
||||
var/operative_antag_datum_type = /datum/antagonist/nukeop
|
||||
var/leader_antag_datum_type = /datum/antagonist/nukeop/leader
|
||||
|
||||
/datum/game_mode/nuclear/pre_setup()
|
||||
var/n_agents = min(round(num_players() / 10), antag_candidates.len, agents_possible)
|
||||
if(n_agents >= required_enemies)
|
||||
@@ -37,12 +40,12 @@
|
||||
/datum/game_mode/nuclear/post_setup()
|
||||
//Assign leader
|
||||
var/datum/mind/leader_mind = pre_nukeops[1]
|
||||
var/datum/antagonist/nukeop/L = leader_mind.add_antag_datum(/datum/antagonist/nukeop/leader)
|
||||
var/datum/antagonist/nukeop/L = leader_mind.add_antag_datum(leader_antag_datum_type)
|
||||
nuke_team = L.nuke_team
|
||||
//Assign the remaining operatives
|
||||
for(var/i = 2 to pre_nukeops.len)
|
||||
var/datum/mind/nuke_mind = pre_nukeops[i]
|
||||
nuke_mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team)
|
||||
nuke_mind.add_antag_datum(operative_antag_datum_type)
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/nuclear/OnNukeExplosion(off_station)
|
||||
@@ -131,6 +134,7 @@
|
||||
|
||||
var/tc = 25
|
||||
var/command_radio = FALSE
|
||||
var/uplink_type = /obj/item/device/radio/uplink/nuclear
|
||||
|
||||
|
||||
/datum/outfit/syndicate/leader
|
||||
@@ -150,7 +154,7 @@
|
||||
R.command = TRUE
|
||||
|
||||
if(tc)
|
||||
var/obj/item/device/radio/uplink/nuclear/U = new(H, H.key, tc)
|
||||
var/obj/item/device/radio/uplink/U = new uplink_type(H, H.key, tc)
|
||||
H.equip_to_slot_or_del(U, slot_in_backpack)
|
||||
|
||||
var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(H)
|
||||
|
||||
@@ -76,6 +76,11 @@
|
||||
|
||||
var/wall_turret_direction //The turret will try to shoot from a turf in that direction when in a wall
|
||||
|
||||
var/manual_control = FALSE //
|
||||
var/datum/action/turret_quit/quit_action
|
||||
var/datum/action/turret_toggle/toggle_action
|
||||
var/mob/remote_controller
|
||||
|
||||
/obj/machinery/porta_turret/Initialize()
|
||||
. = ..()
|
||||
if(!base)
|
||||
@@ -154,6 +159,7 @@
|
||||
cp = null
|
||||
QDEL_NULL(stored_gun)
|
||||
QDEL_NULL(spark_system)
|
||||
remove_control()
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -179,6 +185,14 @@
|
||||
dat += "Neutralize All Non-Security and Non-Command Personnel: <A href='?src=[REF(src)];operation=shootall'>[stun_all ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Neutralize All Unidentified Life Signs: <A href='?src=[REF(src)];operation=checkxenos'>[check_anomalies ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Neutralize All Non-Loyalty Implanted Personnel: <A href='?src=[REF(src)];operation=checkloyal'>[shoot_unloyal ? "Yes" : "No"]</A><BR>"
|
||||
if(issilicon(user))
|
||||
if(!manual_control)
|
||||
var/mob/living/silicon/S = user
|
||||
if(S.hack_software)
|
||||
dat += "Assume direct control : <a href='?src=[REF(src)];operation=manual'>Manual Control</a><br>"
|
||||
else
|
||||
dat += "Warning! Remote control protocol enabled.<br>"
|
||||
|
||||
|
||||
var/datum/browser/popup = new(user, "autosec", "Automatic Portable Turret Installation", 300, 300)
|
||||
popup.set_content(dat)
|
||||
@@ -212,6 +226,9 @@
|
||||
check_anomalies = !check_anomalies
|
||||
if("checkloyal")
|
||||
shoot_unloyal = !shoot_unloyal
|
||||
if("manual")
|
||||
if(issilicon(usr) && !manual_control)
|
||||
give_control(usr)
|
||||
interact(usr)
|
||||
|
||||
/obj/machinery/porta_turret/power_change()
|
||||
@@ -359,6 +376,8 @@
|
||||
popDown()
|
||||
return
|
||||
|
||||
if(manual_control)
|
||||
return
|
||||
var/list/targets = list()
|
||||
var/static/things_to_scan = typecacheof(list(/mob/living, /obj/mecha))
|
||||
|
||||
@@ -566,6 +585,66 @@
|
||||
src.mode = mode
|
||||
power_change()
|
||||
|
||||
|
||||
/datum/action/turret_toggle
|
||||
name = "Toggle Mode"
|
||||
icon_icon = 'icons/mob/actions/actions_mecha.dmi'
|
||||
button_icon_state = "mech_cycle_equip_off"
|
||||
|
||||
/datum/action/turret_toggle/Trigger()
|
||||
var/obj/machinery/porta_turret/P = target
|
||||
if(!istype(P))
|
||||
return
|
||||
P.setState(P.on,!P.mode)
|
||||
|
||||
/datum/action/turret_quit
|
||||
name = "Release Control"
|
||||
icon_icon = 'icons/mob/actions/actions_mecha.dmi'
|
||||
button_icon_state = "mech_eject"
|
||||
|
||||
/datum/action/turret_quit/Trigger()
|
||||
var/obj/machinery/porta_turret/P = target
|
||||
if(!istype(P))
|
||||
return
|
||||
P.remove_control(owner)
|
||||
|
||||
/obj/machinery/porta_turret/proc/give_control(mob/A)
|
||||
if(manual_control)
|
||||
return FALSE
|
||||
remote_controller = A
|
||||
if(!quit_action)
|
||||
quit_action = new(src)
|
||||
quit_action.Grant(remote_controller)
|
||||
if(!toggle_action)
|
||||
toggle_action = new(src)
|
||||
toggle_action.Grant(remote_controller)
|
||||
remote_controller.reset_perspective(src)
|
||||
remote_controller.click_intercept = src
|
||||
manual_control = TRUE
|
||||
always_up = TRUE
|
||||
popUp()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/porta_turret/proc/remove_control()
|
||||
if(!manual_control)
|
||||
return FALSE
|
||||
if(remote_controller)
|
||||
quit_action.Remove(remote_controller)
|
||||
toggle_action.Remove(remote_controller)
|
||||
remote_controller.click_intercept = null
|
||||
remote_controller.reset_perspective()
|
||||
always_up = initial(always_up)
|
||||
manual_control = FALSE
|
||||
remote_controller = null
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/porta_turret/proc/InterceptClickOn(mob/living/caller, params, atom/A)
|
||||
if(!manual_control)
|
||||
return FALSE
|
||||
add_logs(caller,A,"fired with manual turret control at")
|
||||
target(A)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/porta_turret/syndicate
|
||||
installation = null
|
||||
always_up = 1
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
var/equip_ready = 1 //whether the equipment is ready for use. (or deactivated/activated for static stuff)
|
||||
var/energy_drain = 0
|
||||
var/obj/mecha/chassis = null
|
||||
var/range = MELEE //bitflags
|
||||
var/range = MELEE //bitFflags
|
||||
var/salvageable = 1
|
||||
var/selectable = 1 // Set to 0 for passive equipment such as mining scanner or armor plates
|
||||
var/pacifist_safe = TRUE //Controls if equipment can be used to attack by a pacifist.
|
||||
@@ -94,9 +94,16 @@
|
||||
chassis.use_power(energy_drain)
|
||||
. = do_after(chassis.occupant, equip_cooldown, target=target)
|
||||
set_ready_state(1)
|
||||
if(!chassis || chassis.loc != C || src != chassis.selected)
|
||||
if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir))
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/do_after_mecha(atom/target, delay)
|
||||
if(!chassis)
|
||||
return
|
||||
var/C = chassis.loc
|
||||
. = do_after(chassis.occupant, delay, target=target)
|
||||
if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir))
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/mecha/M)
|
||||
if(M.equipment.len<M.max_equip)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
// Drill, Diamond drill, Mining scanner
|
||||
|
||||
#define DRILL_BASIC 1
|
||||
#define DRILL_HARDENED 2
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill
|
||||
name = "exosuit drill"
|
||||
@@ -10,6 +13,8 @@
|
||||
energy_drain = 10
|
||||
force = 15
|
||||
pacifist_safe = FALSE
|
||||
var/drill_delay = 7
|
||||
var/drill_level = DRILL_BASIC
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/Initialize()
|
||||
. = ..()
|
||||
@@ -29,27 +34,39 @@
|
||||
"<span class='italics'>You hear drilling.</span>")
|
||||
|
||||
if(do_after_cooldown(target))
|
||||
set_ready_state(FALSE)
|
||||
log_message("Started drilling [target]")
|
||||
if(isturf(target))
|
||||
var/turf/T = target
|
||||
T.drill_act(src)
|
||||
else
|
||||
log_message("Drilled through [target]")
|
||||
set_ready_state(TRUE)
|
||||
return
|
||||
while(do_after_mecha(target, drill_delay))
|
||||
if(isliving(target))
|
||||
if(istype(src , /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill))
|
||||
drill_mob(target, chassis.occupant, 120)
|
||||
else
|
||||
drill_mob(target, chassis.occupant)
|
||||
drill_mob(target, chassis.occupant)
|
||||
playsound(src,'sound/weapons/drill.ogg',40,1)
|
||||
else if(isobj(target))
|
||||
var/obj/O = target
|
||||
O.take_damage(15, BRUTE, 0, FALSE, get_dir(chassis, target))
|
||||
playsound(src,'sound/weapons/drill.ogg',40,1)
|
||||
else
|
||||
target.ex_act(EXPLODE_HEAVY)
|
||||
set_ready_state(TRUE)
|
||||
return
|
||||
set_ready_state(TRUE)
|
||||
|
||||
/turf/proc/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
return
|
||||
|
||||
/turf/closed/wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
if(drill.do_after_mecha(src, 60 / drill.drill_level))
|
||||
drill.log_message("Drilled through [src]")
|
||||
dismantle_wall(TRUE, FALSE)
|
||||
|
||||
/turf/closed/wall/r_wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
if(istype(drill, /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill))
|
||||
if(drill.do_after_cooldown(src))//To slow down how fast mechs can drill through the station
|
||||
if(drill.drill_level >= DRILL_HARDENED)
|
||||
if(drill.do_after_mecha(src, 120 / drill.drill_level))
|
||||
drill.log_message("Drilled through [src]")
|
||||
ex_act(EXPLODE_LIGHT)
|
||||
dismantle_wall(TRUE, FALSE)
|
||||
else
|
||||
drill.occupant_message("<span class='danger'>[src] is too durable to drill through.</span>")
|
||||
|
||||
@@ -91,30 +108,40 @@
|
||||
GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
|
||||
butchering.butchering_enabled = FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/proc/drill_mob(mob/living/target, mob/user, var/drill_damage=80)
|
||||
target.visible_message("<span class='danger'>[chassis] drills [target] with [src].</span>", \
|
||||
"<span class='userdanger'>[chassis] drills [target] with [src].</span>")
|
||||
add_logs(user, target, "attacked", "[name]", "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])")
|
||||
if(target.stat == DEAD)
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/proc/drill_mob(mob/living/target, mob/user)
|
||||
target.visible_message("<span class='danger'>[chassis] is drilling [target] with [src]!</span>", \
|
||||
"<span class='userdanger'>[chassis] is drilling you with [src]!</span>")
|
||||
add_logs(user, target, "drilled", "[name]", "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])")
|
||||
if(target.stat == DEAD && target.getBruteLoss() >= 200)
|
||||
add_logs(user, target, "gibbed", name)
|
||||
if(target.butcher_results.len || target.guaranteed_butcher_results.len)
|
||||
if(LAZYLEN(target.butcher_results) || LAZYLEN(target.guaranteed_butcher_results))
|
||||
GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
|
||||
butchering.Butcher(chassis, target)
|
||||
else
|
||||
target.gib()
|
||||
else
|
||||
target.take_bodypart_damage(drill_damage)
|
||||
//drill makes a hole
|
||||
var/obj/item/bodypart/target_part = target.get_bodypart(ran_zone("chest"))
|
||||
target.apply_damage(10, BRUTE, "chest", target.run_armor_check(target_part, "melee"))
|
||||
|
||||
if(target)
|
||||
target.Unconscious(200)
|
||||
target.updatehealth()
|
||||
//blood splatters
|
||||
var/splatter_dir = get_dir(chassis, target)
|
||||
if(isalien(target))
|
||||
new /obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter(target.drop_location(), splatter_dir)
|
||||
else
|
||||
new /obj/effect/temp_visual/dir_setting/bloodsplatter(target.drop_location(), splatter_dir)
|
||||
|
||||
//organs go everywhere
|
||||
if(target_part && prob(10 * drill_level))
|
||||
target_part.dismember(BRUTE)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill
|
||||
name = "diamond-tipped exosuit drill"
|
||||
desc = "Equipment for engineering and combat exosuits. This is an upgraded version of the drill that'll pierce the heavens!"
|
||||
icon_state = "mecha_diamond_drill"
|
||||
equip_cooldown = 10
|
||||
drill_delay = 4
|
||||
drill_level = DRILL_HARDENED
|
||||
force = 15
|
||||
|
||||
|
||||
@@ -140,3 +167,6 @@
|
||||
return
|
||||
scanning_time = world.time + equip_cooldown
|
||||
mineral_scan_pulse(get_turf(src))
|
||||
|
||||
#undef DRILL_BASIC
|
||||
#undef DRILL_HARDENED
|
||||
@@ -138,16 +138,16 @@
|
||||
return ..()
|
||||
|
||||
/obj/effect/portal/attack_ghost(mob/dead/observer/O)
|
||||
if(!teleport(O))
|
||||
if(!teleport(O, TRUE))
|
||||
return ..()
|
||||
|
||||
/obj/effect/portal/proc/teleport(atom/movable/M)
|
||||
if(!istype(M) || istype(M, /obj/effect) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
|
||||
/obj/effect/portal/proc/teleport(atom/movable/M, force = FALSE)
|
||||
if(!force && (!istype(M) || istype(M, /obj/effect) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M)))) //Things that shouldn't teleport.
|
||||
return
|
||||
var/turf/real_target = get_link_target_turf()
|
||||
if(!istype(real_target))
|
||||
return FALSE
|
||||
if(!ismecha(M) && !istype(M, /obj/item/projectile) && M.anchored && !allow_anchored)
|
||||
if(!force && (!ismecha(M) && !istype(M, /obj/item/projectile) && M.anchored && !allow_anchored))
|
||||
return
|
||||
if(ismegafauna(M))
|
||||
message_admins("[M] has used a portal at [ADMIN_COORDJMP(src)] made by [usr].")
|
||||
|
||||
@@ -599,8 +599,8 @@
|
||||
/obj/item/stock_parts/capacitor = 6)
|
||||
|
||||
/obj/item/circuitboard/machine/chem_dispenser
|
||||
name = "Portable Chem Dispenser (Machine Board)"
|
||||
build_path = /obj/machinery/chem_dispenser/constructable
|
||||
name = "Chem Dispenser (Machine Board)"
|
||||
build_path = /obj/machinery/chem_dispenser
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/matter_bin = 2,
|
||||
/obj/item/stock_parts/capacitor = 1,
|
||||
|
||||
@@ -202,6 +202,6 @@
|
||||
var/turf/T = get_turf(loc)
|
||||
if(isopenturf(T))
|
||||
var/turf/open/theturf = T
|
||||
theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10, wet_time_to_add = 5)
|
||||
theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
|
||||
|
||||
user.visible_message("[user] empties out \the [src] onto the floor using the release valve.", "<span class='info'>You quietly empty out \the [src] using its release valve.</span>")
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
var/active = 0
|
||||
var/det_time = 50
|
||||
var/display_timer = 1
|
||||
var/clumsy_check = GRENADE_CLUMSY_FUMBLE
|
||||
|
||||
/obj/item/grenade/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] primes [src], then eats it! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
@@ -32,8 +33,14 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
|
||||
if(user.has_trait(TRAIT_CLUMSY) && prob(50))
|
||||
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
|
||||
var/clumsy = user.has_trait(TRAIT_CLUMSY)
|
||||
if(clumsy && (clumsy_check == GRENADE_CLUMSY_FUMBLE))
|
||||
if(prob(50))
|
||||
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
|
||||
preprime(user, 5, FALSE)
|
||||
return FALSE
|
||||
else if(!clumsy && (clumsy_check == GRENADE_NONCLUMSY_FUMBLE))
|
||||
to_chat(user, "<span class='warning'>You pull the pin on [src]. Attached to it is a pink ribbon that says, \"<span class='clown'>HONK</span>\"</span>")
|
||||
preprime(user, 5, FALSE)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -43,8 +43,7 @@
|
||||
for(var/turf/T in view(freeze_range,loc))
|
||||
if(isfloorturf(T))
|
||||
var/turf/open/floor/F = T
|
||||
F.wet = TURF_WET_PERMAFROST
|
||||
addtimer(CALLBACK(F, /turf/open/floor.proc/MakeDry, TURF_WET_PERMAFROST), rand(3000, 3100))
|
||||
F.MakeSlippery(TURF_WET_PERMAFROST, 6 MINUTES)
|
||||
for(var/mob/living/carbon/L in T)
|
||||
L.adjustStaminaLoss(stamina_damage)
|
||||
L.adjust_bodytemperature(-230)
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/transforming/energy/suicide_act(mob/user)
|
||||
if(!active)
|
||||
transform_weapon(user, TRUE)
|
||||
user.visible_message("<span class='suicide'>[user] is [pick("slitting [user.p_their()] stomach open with", "falling on")] [src]! It looks like [user.p_theyre()] trying to commit seppuku!</span>")
|
||||
return (BRUTELOSS|FIRELOSS)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/obj/item/melee/transforming
|
||||
sharpness = IS_SHARP
|
||||
var/active = FALSE
|
||||
var/force_on = 30 //force when active
|
||||
var/faction_bonus_force = 0 //Bonus force dealt against certain factions
|
||||
@@ -8,10 +9,10 @@
|
||||
var/list/attack_verb_on = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
var/list/attack_verb_off = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
sharpness = IS_SHARP
|
||||
var/bonus_active = FALSE //If the faction damage bonus is active
|
||||
var/list/nemesis_factions //Any mob with a faction that exists in this list will take bonus damage/effects
|
||||
var/w_class_on = WEIGHT_CLASS_BULKY
|
||||
var/clumsy_check = TRUE
|
||||
|
||||
/obj/item/melee/transforming/Initialize()
|
||||
. = ..()
|
||||
@@ -81,6 +82,6 @@
|
||||
to_chat(user, "<span class='notice'>[src] [active ? "is now active":"can now be concealed"].</span>")
|
||||
|
||||
/obj/item/melee/transforming/proc/clumsy_transform_effect(mob/living/user)
|
||||
if(user.has_trait(TRAIT_CLUMSY) && prob(50))
|
||||
if(clumsy_check && user.has_trait(TRAIT_CLUMSY) && prob(50))
|
||||
to_chat(user, "<span class='warning'>You accidentally cut yourself with [src], like a doofus!</span>")
|
||||
user.take_bodypart_damage(5,5)
|
||||
|
||||
@@ -60,16 +60,24 @@
|
||||
name = "energy combat shield"
|
||||
desc = "A shield that reflects almost all energy projectiles, but is useless against physical attacks. It can be retracted, expanded, and stored anywhere."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "eshield0" // eshield1 for expanded
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
attack_verb = list("shoved", "bashed")
|
||||
throw_range = 5
|
||||
force = 3
|
||||
throwforce = 3
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
attack_verb = list("shoved", "bashed")
|
||||
var/base_icon_state = "eshield" // [base_icon_state]1 for expanded, [base_icon_state]0 for contracted
|
||||
var/on_force = 10
|
||||
var/on_throwforce = 8
|
||||
var/on_throw_speed = 2
|
||||
var/active = 0
|
||||
var/clumsy_check = TRUE
|
||||
|
||||
/obj/item/shield/energy/Initialize()
|
||||
. = ..()
|
||||
icon_state = "[base_icon_state]0"
|
||||
|
||||
/obj/item/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
return 0
|
||||
@@ -78,23 +86,23 @@
|
||||
return (active)
|
||||
|
||||
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
|
||||
if(user.has_trait(TRAIT_CLUMSY) && prob(50))
|
||||
if(clumsy_check && user.has_trait(TRAIT_CLUMSY) && prob(50))
|
||||
to_chat(user, "<span class='warning'>You beat yourself in the head with [src].</span>")
|
||||
user.take_bodypart_damage(5)
|
||||
active = !active
|
||||
icon_state = "eshield[active]"
|
||||
icon_state = "[base_icon_state][active]"
|
||||
|
||||
if(active)
|
||||
force = 10
|
||||
throwforce = 8
|
||||
throw_speed = 2
|
||||
force = on_force
|
||||
throwforce = on_throwforce
|
||||
throw_speed = on_throw_speed
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
playsound(user, 'sound/weapons/saberon.ogg', 35, 1)
|
||||
to_chat(user, "<span class='notice'>[src] is now active.</span>")
|
||||
else
|
||||
force = 3
|
||||
throwforce = 3
|
||||
throw_speed = 3
|
||||
force = initial(force)
|
||||
throwforce = initial(throwforce)
|
||||
throw_speed = initial(throw_speed)
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
playsound(user, 'sound/weapons/saberoff.ogg', 35, 1)
|
||||
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
|
||||
|
||||
@@ -227,6 +227,14 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
tesla_zap(src, 3, power_bounced)
|
||||
addtimer(CALLBACK(src, .proc/reset_shocked), 10)
|
||||
|
||||
//The surgeon general warns that being buckled to certain objects recieving powerful shocks is greatly hazardous to your health
|
||||
//Only tesla coils and grounding rods currently call this because mobs are already targeted over all other objects, but this might be useful for more things later.
|
||||
/obj/proc/tesla_buckle_check(var/strength)
|
||||
if(has_buckled_mobs())
|
||||
for(var/m in buckled_mobs)
|
||||
var/mob/living/buckled_mob = m
|
||||
buckled_mob.electrocute_act((CLAMP(round(strength/400), 10, 90) + rand(-5, 5)), src, tesla_shock = 1)
|
||||
|
||||
/obj/proc/reset_shocked()
|
||||
obj_flags &= ~BEING_SHOCKED
|
||||
|
||||
|
||||
@@ -7,11 +7,7 @@
|
||||
anchored = TRUE
|
||||
icon = 'icons/turf/walls/wall.dmi'
|
||||
icon_state = "wall"
|
||||
var/mineral = /obj/item/stack/sheet/metal
|
||||
var/mineral_amount = 2
|
||||
var/walltype = /turf/closed/wall
|
||||
var/girder_type = /obj/structure/girder/displaced
|
||||
var/opening = FALSE
|
||||
layer = CLOSED_TURF_LAYER
|
||||
density = TRUE
|
||||
opacity = 1
|
||||
max_integrity = 100
|
||||
@@ -28,6 +24,11 @@
|
||||
smooth = SMOOTH_TRUE
|
||||
can_be_unanchored = FALSE
|
||||
CanAtmosPass = ATMOS_PASS_DENSITY
|
||||
var/mineral = /obj/item/stack/sheet/metal
|
||||
var/mineral_amount = 2
|
||||
var/walltype = /turf/closed/wall
|
||||
var/girder_type = /obj/structure/girder/displaced
|
||||
var/opening = FALSE
|
||||
|
||||
/obj/structure/falsewall/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -534,9 +534,6 @@
|
||||
new/obj/structure/showcase/machinery/oldpod/used(drop_location())
|
||||
return ..()
|
||||
|
||||
|
||||
#define PIRATE_NAMES_FILE "pirates.json"
|
||||
|
||||
/obj/effect/mob_spawn/human/pirate
|
||||
name = "space pirate sleeper"
|
||||
desc = "A cryo sleeper smelling faintly of rum."
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
attack_hand(user)
|
||||
|
||||
/obj/structure/table/attack_hand(mob/living/user)
|
||||
if(user.pulling && isliving(user.pulling))
|
||||
if(Adjacent(user) && user.pulling && isliving(user.pulling))
|
||||
var/mob/living/pushed_mob = user.pulling
|
||||
if(pushed_mob.buckled)
|
||||
to_chat(user, "<span class='warning'>[pushed_mob] is buckled to [pushed_mob.buckled]!</span>")
|
||||
@@ -81,6 +81,9 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/structure/table/attack_tk()
|
||||
return FALSE
|
||||
|
||||
/obj/structure/table/CanPass(atom/movable/mover, turf/target)
|
||||
if(istype(mover) && (mover.pass_flags & PASSTABLE))
|
||||
return 1
|
||||
|
||||
@@ -247,7 +247,7 @@
|
||||
soundloop.stop()
|
||||
if(isopenturf(loc))
|
||||
var/turf/open/tile = loc
|
||||
tile.MakeSlippery(TURF_WET_WATER, min_wet_time = 5, wet_time_to_add = 1)
|
||||
tile.MakeSlippery(TURF_WET_WATER, min_wet_time = 5 SECONDS, wet_time_to_add = 1 SECONDS)
|
||||
|
||||
|
||||
/obj/machinery/shower/attackby(obj/item/I, mob/user, params)
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
/turf/open
|
||||
var/slowdown = 0 //negative for faster, positive for slower
|
||||
|
||||
var/wet = 0
|
||||
var/wet_time = 0 // Time in seconds that this floor will be wet for.
|
||||
var/mutable_appearance/wet_overlay
|
||||
var/postdig_icon_change = FALSE
|
||||
var/postdig_icon
|
||||
var/list/archdrops
|
||||
var/wet
|
||||
|
||||
/turf/open/Initialize()
|
||||
. = ..()
|
||||
if(wet)
|
||||
AddComponent(/datum/component/wet_floor, wet, INFINITY, 0, INFINITY, TRUE)
|
||||
|
||||
/turf/open/indestructible
|
||||
name = "floor"
|
||||
@@ -164,11 +168,11 @@
|
||||
for(var/mob/living/L in contents)
|
||||
if(L.bodytemperature <= 50)
|
||||
L.apply_status_effect(/datum/status_effect/freon)
|
||||
MakeSlippery(TURF_WET_PERMAFROST, 5)
|
||||
MakeSlippery(TURF_WET_PERMAFROST, 50)
|
||||
return 1
|
||||
|
||||
/turf/open/proc/water_vapor_gas_act()
|
||||
MakeSlippery(TURF_WET_WATER, min_wet_time = 10, wet_time_to_add = 5)
|
||||
MakeSlippery(TURF_WET_WATER, min_wet_time = 100, wet_time_to_add = 50)
|
||||
|
||||
for(var/mob/living/simple_animal/slime/M in src)
|
||||
M.apply_water()
|
||||
@@ -177,7 +181,7 @@
|
||||
for(var/obj/effect/O in src)
|
||||
if(is_cleanable(O))
|
||||
qdel(O)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/turf/open/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube)
|
||||
if(C.movement_type & FLYING)
|
||||
@@ -224,132 +228,23 @@
|
||||
|
||||
/turf/open/copyTurf(turf/T)
|
||||
. = ..()
|
||||
if(. && isopenturf(T) && wet_time)
|
||||
var/turf/open/O = T
|
||||
O.MakeSlippery(wet_setting = wet, wet_time_to_add = wet_time) //we're copied, copy how wet we are also
|
||||
if(. && isopenturf(T))
|
||||
GET_COMPONENT(slip, /datum/component/wet_floor)
|
||||
if(slip)
|
||||
var/datum/component/wet_floor/WF = T.AddComponent(/datum/component/wet_floor)
|
||||
WF.InheritComponent(slip)
|
||||
|
||||
/turf/open/proc/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0) // 1 = Water, 2 = Lube, 3 = Ice, 4 = Permafrost, 5 = Slide
|
||||
wet_time = max(wet_time+wet_time_to_add, min_wet_time)
|
||||
if(wet >= wet_setting)
|
||||
return
|
||||
wet = wet_setting
|
||||
UpdateSlip()
|
||||
if(wet_setting != TURF_DRY)
|
||||
if(wet_overlay)
|
||||
cut_overlay(wet_overlay)
|
||||
else
|
||||
wet_overlay = mutable_appearance()
|
||||
var/turf/open/floor/F = src
|
||||
if(istype(F))
|
||||
if(wet_setting == TURF_WET_PERMAFROST)
|
||||
wet_overlay.icon = 'icons/effects/water.dmi'
|
||||
wet_overlay.icon_state = "ice_floor"
|
||||
else if(wet_setting == TURF_WET_ICE)
|
||||
wet_overlay.icon = 'icons/turf/overlays.dmi'
|
||||
wet_overlay.icon_state = "snowfloor"
|
||||
else
|
||||
wet_overlay.icon = 'icons/effects/water.dmi'
|
||||
wet_overlay.icon_state = "wet_floor_static"
|
||||
else
|
||||
wet_overlay.icon = 'icons/effects/water.dmi'
|
||||
wet_overlay.icon_state = "wet_static"
|
||||
add_overlay(wet_overlay)
|
||||
HandleWet()
|
||||
/turf/open/proc/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0, max_wet_time = MAXIMUM_WET_TIME, permanent)
|
||||
AddComponent(/datum/component/wet_floor, wet_setting, min_wet_time, wet_time_to_add, max_wet_time, permanent)
|
||||
|
||||
/turf/open/proc/UpdateSlip()
|
||||
var/intensity
|
||||
var/lube_flags
|
||||
switch(wet)
|
||||
if(TURF_WET_WATER)
|
||||
intensity = 60
|
||||
lube_flags = NO_SLIP_WHEN_WALKING
|
||||
if(TURF_WET_LUBE)
|
||||
intensity = 80
|
||||
lube_flags = SLIDE | GALOSHES_DONT_HELP
|
||||
if(TURF_WET_ICE)
|
||||
intensity = 120
|
||||
lube_flags = SLIDE | GALOSHES_DONT_HELP
|
||||
if(TURF_WET_PERMAFROST)
|
||||
intensity = 120
|
||||
lube_flags = SLIDE_ICE | GALOSHES_DONT_HELP
|
||||
else
|
||||
qdel(GetComponent(/datum/component/slippery))
|
||||
return
|
||||
var/datum/component/slippery/S = LoadComponent(/datum/component/slippery, NONE, CALLBACK(src, .proc/AfterSlip))
|
||||
S.intensity = intensity
|
||||
S.lube_flags = lube_flags
|
||||
|
||||
/turf/open/proc/AfterSlip(mob/living/L)
|
||||
if(wet == TURF_WET_LUBE)
|
||||
L.confused = max(L.confused, 8)
|
||||
|
||||
/turf/open/proc/MakeDry(wet_setting = TURF_WET_WATER)
|
||||
if(wet > wet_setting || !wet)
|
||||
return
|
||||
spawn(rand(0,20))
|
||||
if(wet == TURF_WET_PERMAFROST)
|
||||
wet = TURF_WET_ICE
|
||||
else if(wet == TURF_WET_ICE)
|
||||
wet = TURF_WET_WATER
|
||||
else
|
||||
wet = TURF_DRY
|
||||
if(wet_overlay)
|
||||
cut_overlay(wet_overlay)
|
||||
UpdateSlip()
|
||||
|
||||
/turf/open/proc/HandleWet()
|
||||
if(!wet)
|
||||
//It's possible for this handler to get called after all the wetness is
|
||||
//cleared, so bail out if that is the case
|
||||
return
|
||||
if(!wet_time && wet < TURF_WET_ICE)
|
||||
MakeDry(TURF_WET_ICE)
|
||||
if(wet_time > MAXIMUM_WET_TIME)
|
||||
wet_time = MAXIMUM_WET_TIME
|
||||
if(wet == TURF_WET_ICE && air.temperature > T0C)
|
||||
for(var/obj/O in contents)
|
||||
if(O.flags_2 & FROZEN_2)
|
||||
O.make_unfrozen()
|
||||
MakeDry(TURF_WET_ICE)
|
||||
MakeSlippery(TURF_WET_WATER)
|
||||
if(wet != TURF_WET_PERMAFROST)
|
||||
switch(air.temperature)
|
||||
if(-INFINITY to T0C)
|
||||
if(wet != TURF_WET_ICE && wet)
|
||||
MakeDry(TURF_WET_ICE)
|
||||
MakeSlippery(TURF_WET_ICE)
|
||||
if(T0C to T20C)
|
||||
wet_time = max(0, wet_time-1)
|
||||
if(T20C to T0C + 40)
|
||||
wet_time = max(0, wet_time-2)
|
||||
if(T0C + 40 to T0C + 60)
|
||||
wet_time = max(0, wet_time-3)
|
||||
if(T0C + 60 to T0C + 80)
|
||||
wet_time = max(0, wet_time-5)
|
||||
if(T0C + 80 to T0C + 100)
|
||||
wet_time = max(0, wet_time-10)
|
||||
if(T0C + 100 to INFINITY)
|
||||
wet_time = 0
|
||||
else if (GetTemperature() > BODYTEMP_COLD_DAMAGE_LIMIT) //seems like a good place
|
||||
MakeDry(TURF_WET_PERMAFROST)
|
||||
else
|
||||
wet_time = max(0, wet_time-5)
|
||||
if(wet && wet < TURF_WET_ICE && !wet_time)
|
||||
MakeDry(TURF_WET_ICE)
|
||||
if(!wet && wet_time)
|
||||
wet_time = 0
|
||||
if(wet)
|
||||
addtimer(CALLBACK(src, .proc/HandleWet), 15, TIMER_UNIQUE)
|
||||
/turf/open/proc/MakeDry(wet_setting = TURF_WET_WATER, immediate = FALSE, amount = INFINITY)
|
||||
SendSignal(COMSIG_TURF_MAKE_DRY, wet_setting, immediate, amount)
|
||||
|
||||
/turf/open/get_dumping_location()
|
||||
return src
|
||||
|
||||
/turf/open/proc/ClearWet()//Nuclear option of immediately removing slipperyness from the tile instead of the natural drying over time
|
||||
wet = TURF_DRY
|
||||
UpdateSlip()
|
||||
if(wet_overlay)
|
||||
cut_overlay(wet_overlay)
|
||||
|
||||
qdel(GetComponent(/datum/component/wet_floor))
|
||||
|
||||
/turf/open/rad_act(pulse_strength)
|
||||
. = ..()
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
GET_COMPONENT(chasm_component, /datum/component/chasm)
|
||||
chasm_component.drop(AM)
|
||||
|
||||
/turf/open/chasm/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0)
|
||||
/turf/open/chasm/MakeSlippery()
|
||||
return
|
||||
|
||||
/turf/open/chasm/MakeDry(wet_setting = TURF_WET_WATER)
|
||||
/turf/open/chasm/MakeDry()
|
||||
return
|
||||
|
||||
/turf/open/chasm/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
|
||||
@@ -33,10 +33,10 @@
|
||||
/turf/open/floor/plating/asteroid/burn_tile()
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/asteroid/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0)
|
||||
/turf/open/floor/plating/asteroid/MakeSlippery()
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/asteroid/MakeDry(wet_setting = TURF_WET_WATER)
|
||||
/turf/open/floor/plating/asteroid/MakeDry()
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/asteroid/attackby(obj/item/W, mob/user, params)
|
||||
|
||||
@@ -143,22 +143,15 @@
|
||||
planetary_atmos = TRUE
|
||||
baseturfs = /turf/open/floor/plating/ice
|
||||
slowdown = 1
|
||||
wet = TURF_WET_PERMAFROST
|
||||
attachment_holes = FALSE
|
||||
|
||||
/turf/open/floor/plating/ice/Initialize()
|
||||
. = ..()
|
||||
UpdateSlip()
|
||||
MakeSlippery(TURF_WET_PERMAFROST, INFINITY, 0, INFINITY, TRUE)
|
||||
|
||||
/turf/open/floor/plating/ice/try_replace_tile(obj/item/stack/tile/T, mob/user, params)
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/ice/HandleWet()
|
||||
if(wet == TURF_WET_ICE)
|
||||
return
|
||||
..()
|
||||
MakeSlippery(TURF_WET_ICE) //rewet after ..() clears out lube/ice etc.
|
||||
|
||||
/turf/open/floor/plating/ice/smooth
|
||||
icon_state = "smooth"
|
||||
smooth = SMOOTH_MORE | SMOOTH_BORDER
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
/turf/open/lava/ex_act(severity, target)
|
||||
contents_explosion(severity, target)
|
||||
|
||||
/turf/open/lava/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0)
|
||||
/turf/open/lava/MakeSlippery()
|
||||
return
|
||||
|
||||
/turf/open/lava/MakeDry(wet_setting = TURF_WET_WATER)
|
||||
|
||||
@@ -7,10 +7,7 @@
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
slowdown = 1
|
||||
wet = TURF_WET_WATER
|
||||
|
||||
/turf/open/water/HandleWet()
|
||||
if(wet == TURF_WET_WATER)
|
||||
return
|
||||
..()
|
||||
MakeSlippery(TURF_WET_WATER) //rewet after ..() clears out lube/ice etc.
|
||||
/turf/open/water/Initialize()
|
||||
. = ..()
|
||||
MakeSlippery(TURF_WET_WATER, INFINITY, 0, INFINITY, TRUE)
|
||||
|
||||
@@ -84,6 +84,9 @@
|
||||
/turf/open/space/proc/CanBuildHere()
|
||||
return TRUE
|
||||
|
||||
/turf/open/space/handle_slip()
|
||||
return
|
||||
|
||||
/turf/open/space/attackby(obj/item/C, mob/user, params)
|
||||
..()
|
||||
if(!CanBuildHere())
|
||||
@@ -162,10 +165,7 @@
|
||||
A.newtonian_move(A.inertia_dir)
|
||||
|
||||
|
||||
/turf/open/space/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0)
|
||||
return
|
||||
|
||||
/turf/open/space/handle_slip()
|
||||
/turf/open/space/MakeSlippery()
|
||||
return
|
||||
|
||||
/turf/open/space/singularity_act()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
25
code/modules/antagonists/nukeop/clownop.dm
Normal file
25
code/modules/antagonists/nukeop/clownop.dm
Normal 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].")
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
37
code/modules/antagonists/xeno/xeno.dm
Normal file
37
code/modules/antagonists/xeno/xeno.dm
Normal 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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>")
|
||||
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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>", \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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////////////
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -102,3 +102,5 @@
|
||||
var/list/progressbars = null //for stacking do_after bars
|
||||
|
||||
var/list/mousemove_intercept_objects
|
||||
|
||||
var/datum/click_intercept
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
..()
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user