Merge remote-tracking branch 'upstream/master' into wounds-part-2

This commit is contained in:
Timothy Teakettle
2020-08-02 18:11:07 +01:00
84 changed files with 5111 additions and 4076 deletions

View File

@@ -90,11 +90,11 @@
/obj/structure/stone_tile/surrounding_tile{
dir = 8
},
/turf/open/indestructible/necropolis,
/turf/open/indestructible/necropolis/air,
/area/lavaland/surface/outdoors)
"l" = (
/obj/structure/stone_tile/block/cracked,
/turf/open/indestructible/necropolis,
/turf/open/indestructible/necropolis/air,
/area/lavaland/surface/outdoors)
"m" = (
/obj/structure/stone_tile/surrounding_tile/cracked,
@@ -105,7 +105,7 @@
/obj/structure/stone_tile/surrounding_tile{
dir = 8
},
/turf/open/indestructible/necropolis,
/turf/open/indestructible/necropolis/air,
/area/lavaland/surface/outdoors)
"n" = (
/obj/structure/stone_tile/block/cracked{
@@ -136,14 +136,14 @@
},
/obj/structure/table/bronze,
/obj/item/disk/design_disk/adv/knight_gear,
/turf/open/indestructible/necropolis,
/turf/open/indestructible/necropolis/air,
/area/lavaland/surface/outdoors)
"q" = (
/obj/structure/table/bronze,
/obj/item/stack/sheet/mineral/runite{
amount = 5
},
/turf/open/indestructible/necropolis,
/turf/open/indestructible/necropolis/air,
/area/lavaland/surface/outdoors)
"r" = (
/obj/structure/stone_tile/block{
@@ -153,7 +153,7 @@
/obj/item/stack/sheet/mineral/runite{
amount = 5
},
/turf/open/indestructible/necropolis,
/turf/open/indestructible/necropolis/air,
/area/lavaland/surface/outdoors)
"s" = (
/obj/structure/stone_tile/block{
@@ -186,13 +186,13 @@
/obj/structure/stone_tile/surrounding_tile{
dir = 1
},
/turf/open/indestructible/necropolis,
/turf/open/indestructible/necropolis/air,
/area/lavaland/surface/outdoors)
"v" = (
/obj/structure/stone_tile/block{
dir = 1
},
/turf/open/indestructible/necropolis,
/turf/open/indestructible/necropolis/air,
/area/lavaland/surface/outdoors)
"w" = (
/obj/structure/stone_tile/surrounding_tile/cracked{
@@ -205,7 +205,7 @@
/obj/structure/stone_tile/surrounding_tile{
dir = 4
},
/turf/open/indestructible/necropolis,
/turf/open/indestructible/necropolis/air,
/area/lavaland/surface/outdoors)
"x" = (
/obj/structure/stone_tile/block{

View File

@@ -5,9 +5,6 @@
"ab" = (
/turf/closed/mineral/random/low_chance,
/area/ruin/unpowered)
"ac" = (
/turf/open/floor/plating/asteroid,
/area/ruin/unpowered)
"ad" = (
/obj/machinery/hydroponics/soil,
/turf/open/floor/plating/asteroid,
@@ -327,9 +324,6 @@
/obj/item/flashlight/lamp/bananalamp,
/turf/open/floor/plating/asteroid,
/area/ruin/powered)
"bt" = (
/turf/closed/mineral/random/low_chance/earth_like,
/area/ruin/unpowered)
"bC" = (
/obj/item/pickaxe/titanium,
/turf/open/floor/plating/asteroid,
@@ -396,7 +390,7 @@ aa
aa
aa
aa
ac
aA
aO
aA
aA
@@ -2648,7 +2642,7 @@ aa
aa
aa
aa
ac
aA
aa
aa
aa
@@ -2699,9 +2693,9 @@ aa
aa
aa
aa
ac
aA
ab
ac
aA
aa
aa
"}
@@ -2855,9 +2849,9 @@ aa
aa
aa
aa
ac
aA
ab
ac
aA
aa
aa
"}
@@ -2907,7 +2901,7 @@ aa
aa
aa
aa
ac
aA
aa
aa
aa
@@ -2959,7 +2953,7 @@ aa
aa
aa
aa
bt
ab
aa
aa
aa

View File

@@ -288,6 +288,15 @@
dir = 4
},
/obj/item/toy/poolnoodle/red,
/obj/machinery/power/apc{
areastring = "/area/crew_quarters/fitness/pool";
dir = 1;
name = "Pool APC";
pixel_y = 24
},
/obj/structure/cable/white{
icon_state = "0-4"
},
/turf/open/floor/plasteel/dark,
/area/crew_quarters/fitness/pool)
"aaH" = (
@@ -492,8 +501,8 @@
dir = 4
},
/turf/open/floor/plasteel/yellowsiding/corner{
icon_state = "yellowcornersiding";
dir = 8
dir = 8;
icon_state = "yellowcornersiding"
},
/area/crew_quarters/fitness/pool)
"aba" = (
@@ -510,8 +519,8 @@
dir = 8
},
/turf/open/floor/plasteel/yellowsiding{
icon_state = "yellowsiding";
dir = 4
dir = 4;
icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abb" = (
@@ -604,8 +613,8 @@
dir = 4
},
/turf/open/floor/plasteel/yellowsiding{
icon_state = "yellowsiding";
dir = 8
dir = 8;
icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abn" = (
@@ -619,8 +628,8 @@
dir = 8
},
/turf/open/floor/plasteel/yellowsiding{
icon_state = "yellowsiding";
dir = 4
dir = 4;
icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abo" = (
@@ -704,8 +713,8 @@
name = "pool camera"
},
/turf/open/floor/plasteel/yellowsiding{
icon_state = "yellowsiding";
dir = 4
dir = 4;
icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abv" = (
@@ -724,8 +733,8 @@
dir = 4
},
/turf/open/floor/plasteel/yellowsiding{
icon_state = "yellowsiding";
dir = 8
dir = 8;
icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"aby" = (
@@ -765,8 +774,8 @@
dir = 8
},
/turf/open/floor/plasteel/yellowsiding{
icon_state = "yellowsiding";
dir = 4
dir = 4;
icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abC" = (
@@ -904,8 +913,8 @@
pixel_x = -23
},
/turf/open/floor/plasteel/yellowsiding{
icon_state = "yellowsiding";
dir = 4
dir = 4;
icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abP" = (
@@ -972,8 +981,8 @@
pixel_x = -26
},
/turf/open/floor/plasteel/yellowsiding/corner{
icon_state = "yellowcornersiding";
dir = 4
dir = 4;
icon_state = "yellowcornersiding"
},
/area/crew_quarters/fitness/pool)
"abW" = (
@@ -982,8 +991,8 @@
dir = 8
},
/turf/open/floor/plasteel/yellowsiding{
icon_state = "yellowsiding";
dir = 1
dir = 1;
icon_state = "yellowsiding"
},
/area/crew_quarters/fitness/pool)
"abX" = (
@@ -995,8 +1004,8 @@
dir = 4
},
/turf/open/floor/plasteel/yellowsiding/corner{
icon_state = "yellowcornersiding";
dir = 1
dir = 1;
icon_state = "yellowcornersiding"
},
/area/crew_quarters/fitness/pool)
"abY" = (
@@ -31108,6 +31117,11 @@
/obj/effect/turf_decal/tile/green{
dir = 8
},
/obj/machinery/power/apc{
areastring = "/area/hydroponics";
name = "Hydroponics APC";
pixel_y = -24
},
/turf/open/floor/plasteel,
/area/hydroponics)
"beS" = (
@@ -64485,8 +64499,8 @@
/area/library)
"cel" = (
/obj/structure/chair/sofa/right{
icon_state = "sofaend_right";
dir = 8
dir = 8;
icon_state = "sofaend_right"
},
/obj/structure/sign/painting/library{
pixel_x = 32
@@ -92830,6 +92844,9 @@
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/obj/structure/cable/white{
icon_state = "1-2"
},
/turf/open/floor/plasteel,
/area/crew_quarters/fitness/recreation)
"dad" = (
@@ -101794,6 +101811,13 @@
/obj/effect/turf_decal/tile/purple{
dir = 4
},
/obj/structure/cable/white,
/obj/machinery/power/apc{
areastring = "/area/science/misc_lab";
dir = 4;
name = "Science Lounge APC";
pixel_x = 26
},
/turf/open/floor/plasteel/white,
/area/science/misc_lab)
"dqi" = (
@@ -113343,6 +113367,7 @@
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/obj/machinery/light/small,
/turf/open/floor/plasteel/dark/telecomms,
/area/science/server)
"dKg" = (
@@ -125579,6 +125604,20 @@
},
/turf/open/floor/plasteel/dark,
/area/science/mixing)
"ePP" = (
/obj/machinery/door/firedoor,
/obj/effect/turf_decal/stripes/line,
/obj/effect/turf_decal/stripes/line{
dir = 1
},
/obj/machinery/door/airlock/public/glass{
name = "Pool"
},
/obj/structure/cable/white{
icon_state = "1-2"
},
/turf/open/floor/plasteel,
/area/crew_quarters/fitness/pool)
"eTv" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -127072,6 +127111,25 @@
},
/turf/open/floor/plasteel,
/area/science/research/abandoned)
"pQQ" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/structure/cable/white{
icon_state = "1-8"
},
/turf/open/floor/plasteel/dark,
/area/crew_quarters/fitness/pool)
"pWb" = (
/obj/structure/table/wood/fancy,
/obj/structure/window/reinforced{
@@ -127298,6 +127356,24 @@
},
/turf/open/floor/plasteel,
/area/science/circuit)
"tqP" = (
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/structure/cable/white{
icon_state = "1-2"
},
/turf/open/floor/plasteel{
heat_capacity = 1e+006
},
/area/crew_quarters/fitness/recreation)
"twt" = (
/obj/machinery/vr_sleeper,
/obj/effect/turf_decal/tile/neutral{
@@ -127768,8 +127844,8 @@
/area/science/mixing)
"xER" = (
/obj/structure/chair/sofa/left{
icon_state = "sofaend_left";
dir = 8
dir = 8;
icon_state = "sofaend_left"
},
/turf/open/floor/wood,
/area/library)
@@ -127849,6 +127925,22 @@
/obj/structure/fans/tiny/invisible,
/turf/open/space/basic,
/area/space)
"yfK" = (
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/obj/structure/cable/white{
icon_state = "1-2"
},
/turf/open/floor/plasteel,
/area/crew_quarters/fitness/recreation)
"yiv" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/neutral{
@@ -181500,10 +181592,10 @@ cCl
cWD
cAz
dac
cxy
aav
aaz
aaH
yfK
tqP
ePP
pQQ
aaV
aaN
aaN

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@
GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult
GLOBAL_VAR_INIT(clockwork_vitality, 0) //How much Vitality is stored, total
GLOBAL_VAR_INIT(clockwork_power, 0) //How many watts of power are globally available to the clockwork cult
GLOBAL_LIST_EMPTY(active_daemons) //A list of all active tinkerer's daemons
GLOBAL_VAR_INIT(neovgre_exists, 0) //Does neovgre exist?
GLOBAL_LIST_EMPTY(all_clockwork_objects) //All clockwork items, structures, and effects in existence
@@ -19,7 +20,8 @@ GLOBAL_VAR_INIT(ark_of_the_clockwork_justiciar, FALSE) //The Ark on the Reebe z-
GLOBAL_VAR_INIT(clockwork_gateway_activated, FALSE) //if a gateway to the celestial derelict has ever been successfully activated
GLOBAL_VAR_INIT(script_scripture_unlocked, FALSE) //If script scripture is available, through converting at least one crewmember
GLOBAL_VAR_INIT(application_scripture_unlocked, FALSE) //If script scripture is available
GLOBAL_VAR_INIT(application_scripture_unlocked, FALSE) //If application scripture is available
GLOBAL_VAR_INIT(judgement_scripture_unlocked, FALSE) //If judgement scripture is available
GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not used to track existing scripture
//Scripture tiers and requirements; peripherals should never be used
@@ -27,13 +29,13 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
#define SCRIPTURE_DRIVER "Driver"
#define SCRIPTURE_SCRIPT "Script"
#define SCRIPTURE_APPLICATION "Application"
#define SCRIPTURE_JUDGEMENT "Judgement"
//Various costs related to power.
#define MAX_CLOCKWORK_POWER 80000 //The max power in W that the cult can stockpile
#define SCRIPT_UNLOCK_THRESHOLD 35000 //Scripts will unlock if the total power reaches this amount
#define APPLICATION_UNLOCK_THRESHOLD 50000 //Applications will unlock if the total powre reaches this amount
#define ABSCOND_ABDUCTION_COST 95
#define APPLICATION_UNLOCK_THRESHOLD 50000 //Applications will unlock if the total power reaches this amount
#define JUDGEMENT_UNLOCK_THRESHOLD 80000 //might as well have this unlock at a power amount like the other scriptures, Judgement unlocks at this amount.
//clockcult power defines
#define MIN_CLOCKCULT_POWER 25 //the minimum amount of power clockcult machines will handle gracefully
@@ -59,11 +61,11 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
//Ark defines
#define GATEWAY_SUMMON_RATE 1 //the time amount the Gateway to the Celestial Derelict gets each process tick; defaults to 1 per tick
#define GATEWAY_REEBE_FOUND 240 //when progress is at or above this, the gateway finds reebe and begins drawing power
#define GATEWAY_REEBE_FOUND 120 //when progress is at or above this, the gateway finds reebe and begins drawing power
#define GATEWAY_RATVAR_COMING 480 //when progress is at or above this, ratvar has entered and is coming through the gateway
#define GATEWAY_RATVAR_COMING 240 //when progress is at or above this, ratvar has entered and is coming through the gateway
#define GATEWAY_RATVAR_ARRIVAL 600 //when progress is at or above this, game over ratvar's here everybody go home
#define GATEWAY_RATVAR_ARRIVAL 300 //when progress is at or above this, game over ratvar's here everybody go home
//Objective text define
#define CLOCKCULT_OBJECTIVE "Construct the Ark of the Clockwork Justicar and free Ratvar."
@@ -81,7 +83,7 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
#define CLOCKWORK_ARMOR_COOLDOWN 1800 //The cooldown period between summoning suits of clockwork armor
#define RATVARIAN_SPEAR_COOLDOWN 300 //The cooldown period between summoning another Ratvarian spear
#define RATVARIAN_WEAPON_COOLDOWN 300 //The cooldown period between summoning another Ratvarian spear
#define MARAUDER_SCRIPTURE_SCALING_THRESHOLD 600 //The amount of deciseconds that must pass before marauder scripture will not gain a recital penalty
@@ -89,4 +91,8 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
#define MARAUDER_SCRIPTURE_SCALING_MAX 300 //The maximum extra time applied to the marauder scripture
#define ARK_SCREAM_COOLDOWN 600 //This much time has to pass between instances of the Ark taking damage before it will "scream" again
#define GUARDIAN_EMERGE_THRESHOLD 65 //guardian cannot emerge unless host is at this% or less health
#define ARK_SCREAM_COOLDOWN 300 //This much time has to pass between instances of the Ark taking damage before it will "scream" again
#define PRISM_DELAY_DURATION 1200 //how long prolonging prisms delay the shuttle for; defaults to 2 minutes

View File

@@ -154,9 +154,10 @@
#define SHOVE_KNOCKDOWN_HUMAN 30
#define SHOVE_KNOCKDOWN_TABLE 30
#define SHOVE_KNOCKDOWN_COLLATERAL 10
//for the shove slowdown, see __DEFINES/movespeed_modification.dm
#define SHOVE_SLOWDOWN_LENGTH 30
#define SHOVE_SLOWDOWN_STRENGTH 0.85 //multiplier
/// how long they're staggered for
#define SHOVE_STAGGER_DURATION 35
/// how long they're off balance for
#define SHOVE_OFFBALANCE_DURATION 30
//Shove disarming item list
GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
/obj/item/gun)))
@@ -280,7 +281,7 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
/// changeNext_move penalty multiplier of the above.
#define STAM_CRIT_ITEM_ATTACK_DELAY 1.75
/// Damage penalty when fighting prone.
#define LYING_DAMAGE_PENALTY 0.5
#define LYING_DAMAGE_PENALTY 0.7
/// Added delay when firing guns stam-softcritted. Summed with a hardset CLICK_CD_RANGE delay, similar to STAM_CRIT_DAMAGE_DELAY otherwise.
#define STAM_CRIT_GUN_DELAY 2.75

View File

@@ -63,7 +63,6 @@
#define MOVESPEED_ID_TASED_STATUS "TASED"
#define MOVESPEED_ID_ELECTROSTAFF "ELECTROSTAFF"
#define MOVESPEED_ID_SHOVE "SHOVE"
#define MOVESPEED_ID_FAT "FAT"
#define MOVESPEED_ID_COLD "COLD"
#define MOVESPEED_ID_HUNGRY "HUNGRY"

View File

@@ -111,6 +111,9 @@
#define STATUS_EFFECT_LIMP /datum/status_effect/limp //For when you have a busted leg (or two!) and want additional slowdown when walking on that leg
/// shoves inflict this to indicate the next shove while this is in effect should disarm guns
#define STATUS_EFFECT_OFF_BALANCE /datum/status_effect/off_balance
/////////////
// NEUTRAL //
/////////////

View File

@@ -447,8 +447,6 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
var/time_name
if(G.seconds_until_activation)
time_name = "until the Ark activates"
else if(G.grace_period)
time_name = "of grace period remaining"
else if(G.progress_in_seconds)
time_name = "until the Ark finishes summoning"
if(time_info)

View File

@@ -0,0 +1,45 @@
/datum/hud/marauder
var/obj/screen/hosthealth
var/obj/screen/blockchance
var/obj/screen/counterchance
/datum/hud/marauder/New(mob/living/simple_animal/hostile/clockwork/marauder/guardian/owner)
..()
var/obj/screen/using
healths = new /obj/screen/healths/clock()
infodisplay += healths
hosthealth = new /obj/screen/healths/clock()
hosthealth.screen_loc = ui_internal
infodisplay += hosthealth
using = new /obj/screen/marauder/emerge()
using.screen_loc = ui_zonesel
static_inventory += using
/datum/hud/marauder/Destroy()
blockchance = null
counterchance = null
hosthealth = null
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/marauder(src, ui_style2icon(client.prefs.UI_style))
/obj/screen/marauder
icon = 'icons/mob/clockwork_mobs.dmi'
/obj/screen/marauder/emerge
icon_state = "clockguard_emerge"
name = "Emerge/Return"
desc = "Emerge or Return."
/obj/screen/marauder/emerge/Click()
if(istype(usr, /mob/living/simple_animal/hostile/clockwork/marauder/guardian))
var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/G = usr
if(G.is_in_host())
G.try_emerge()
else
G.return_to_host()

View File

@@ -67,9 +67,9 @@
/**
* Called when someone uses us to attack a mob in melee combat.
*
*
* This proc respects CheckAttackCooldown() default clickdelay handling.
*
*
* @params
* * mob/living/M - target
* * mob/living/user - attacker
@@ -201,9 +201,9 @@
if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
bad_trait = SKILL_COMBAT_MODE //blacklist combat skills.
if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE))
. *= 0.5
. *= 0.8
else if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
. *= 1.5
. *= 1.2
if(!user.mind || !I.used_skills)
return
@@ -220,7 +220,7 @@
* Also called when clicking on something with an item without being in melee range
*
* WARNING: This does not automatically check clickdelay if not in a melee attack! Be sure to account for this!
*
*
* @params
* * target - The thing we clicked
* * user - mob of person clicking

View File

@@ -470,3 +470,5 @@
/datum/config_entry/flag/minimaps_enabled
config_entry_value = TRUE
/datum/config_entry/string/centcom_ban_db // URL for the CentCom Galactic Ban DB API

View File

@@ -263,6 +263,14 @@
time = 30
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_reinforcement_kit
name = "Durathread Reinforcement Kit"
result = /obj/item/armorkit
reqs = list(/obj/item/stack/sheet/durathread = 4)
tools = list(/obj/item/stack/sheet/mineral/titanium, TOOL_WIRECUTTER) // tough needle for a tough fabric
time = 40
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_duffelbag
name = "Durathread Dufflebag"
result = /obj/item/storage/backpack/duffelbag/durathread

View File

@@ -102,6 +102,15 @@ GLOBAL_LIST_EMPTY(uplinks)
return //no hitting everyone/everything just to try to slot tcs in!
if(istype(I, /obj/item/stack/telecrystal))
LoadTC(user, I)
if(active)
if(I.GetComponent(/datum/component/uplink))
var/datum/component/uplink/hidden_uplink = I.GetComponent(/datum/component/uplink)
var/amt = hidden_uplink.telecrystals
hidden_uplink.telecrystals -= amt
src.telecrystals += amt
to_chat(user, "<span class='notice'>You connect the [I] to your uplink, siphoning [amt] telecrystals before quickly undoing the connection.")
else
return
for(var/category in uplink_items)
for(var/item in uplink_items[category])
var/datum/uplink_item/UI = uplink_items[category][item]

74
code/datums/http.dm Normal file
View File

@@ -0,0 +1,74 @@
/datum/http_request
var/id
var/in_progress = FALSE
var/method
var/body
var/headers
var/url
var/_raw_response
/datum/http_request/proc/prepare(method, url, body = "", list/headers)
if (!length(headers))
headers = ""
else
headers = json_encode(headers)
src.method = method
src.url = url
src.body = body
src.headers = headers
/datum/http_request/proc/execute_blocking()
_raw_response = rustg_http_request_blocking(method, url, body, headers)
/datum/http_request/proc/begin_async()
if (in_progress)
CRASH("Attempted to re-use a request object.")
id = rustg_http_request_async(method, url, body, headers)
if (isnull(text2num(id)))
stack_trace("Proc error: [id]")
_raw_response = "Proc error: [id]"
else
in_progress = TRUE
/datum/http_request/proc/is_complete()
if (isnull(id))
return TRUE
if (!in_progress)
return TRUE
var/r = rustg_http_check_request(id)
if (r == RUSTG_JOB_NO_RESULTS_YET)
return FALSE
else
_raw_response = r
in_progress = FALSE
return TRUE
/datum/http_request/proc/into_response()
var/datum/http_response/R = new()
try
var/list/L = json_decode(_raw_response)
R.status_code = L["status_code"]
R.headers = L["headers"]
R.body = L["body"]
catch
R.errored = TRUE
R.error = _raw_response
return R
/datum/http_response
var/status_code
var/body
var/list/headers
var/errored = FALSE
var/error

View File

@@ -44,11 +44,11 @@
//Here we roll for our damage to be added into the damage var in the various attack procs. This is changed depending on whether we are in combat mode, lying down, or if our target is in combat mode.
var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh)
if(SEND_SIGNAL(D, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
damage *= 1.5
damage *= 1.2
if(!CHECK_MOBILITY(A, MOBILITY_STAND))
damage *= 0.5
damage *= 0.7
if(SEND_SIGNAL(A, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
damage *= 0.25
damage *= 0.8
return damage
/datum/martial_art/proc/teach(mob/living/carbon/human/H, make_temporary = FALSE)

View File

@@ -97,6 +97,21 @@
duration = set_duration
return ..()
/datum/status_effect/off_balance
id = "offbalance"
alert_type = null
/datum/status_effect/off_balance/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration))
duration = set_duration
return ..()
/datum/status_effect/off_balance/on_remove()
var/active_item = owner.get_active_held_item()
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
owner.visible_message("<span class='warning'>[owner.name] regains their grip on \the [active_item]!</span>", "<span class='warning'>You regain your grip on \the [active_item]</span>", null, COMBAT_MESSAGE_RANGE)
return ..()
/obj/screen/alert/status_effect/asleep
name = "Asleep"
desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."

View File

@@ -38,7 +38,8 @@ Credit where due:
5. Xhuis from /tg/ for coding the first iteration of the mode, and the new, reworked version
6. ChangelingRain from /tg/ for maintaining the gamemode for months after its release prior to its rework
7. Clockwork cult code as of now, at least the one being pulled from Citadel Station's master branch, is being, or already is, fixed by Coolgat3 and Avunia.
8. Modern clockwork cult code mixed with original clockwork code, with various changes to make it less of a fustercluck, done by KeRSe. \
Fixes and assistance done by TimothyTeakettle, Kevinz000, and Deltafire15. -Very glad for the help they gave.
*/
///////////
@@ -133,7 +134,7 @@ Credit where due:
config_tag = "clockwork_cult"
antag_flag = ROLE_SERVANT_OF_RATVAR
false_report_weight = 10
required_players = 35
required_players = 24 //Fixing this directly for now since apparently config machine for forcing modes broke.
required_enemies = 3
recommended_enemies = 5
enemy_minimum_age = 7
@@ -143,13 +144,12 @@ Credit where due:
announce_text = "Servants of Ratvar are trying to summon the Justiciar!\n\
<span class='brass'>Servants</span>: Construct defenses to protect the Ark. Sabotage the station!\n\
<span class='notice'>Crew</span>: Stop the servants before they can summon the Clockwork Justiciar."
var/servants_to_serve = list()
var/list/servants_to_serve = list() //Yes this list is made out of list
var/roundstart_player_count
var/ark_time //In minutes, how long the Ark waits before activation; this is equal to 30 + (number of players / 5) (max 40 mins.)
var/datum/team/clockcult/main_clockcult
/datum/game_mode/clockwork_cult/pre_setup()
/datum/game_mode/clockwork_cult/pre_setup() //Gamemode and job code is pain. Have fun codediving all of that stuff, whoever works on this next - Delta
var/list/errorList = list()
var/list/reebes = SSmapping.LoadGroup(errorList, "Reebe", "map_files/generic", "City_of_Cogs.dmm", default_traits = ZTRAITS_REEBE, silent = TRUE)
if(errorList.len) // reebe failed to load
@@ -162,38 +162,36 @@ Credit where due:
restricted_jobs += protected_jobs
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/starter_servants = 4 //Guaranteed four servants
var/starter_servants = 4 //Try to go for at least four
var/number_players = num_players()
roundstart_player_count = number_players
if(number_players > 30) //plus one servant for every additional 10 players above 30
number_players -= 30
starter_servants += round(number_players / 10)
starter_servants = min(starter_servants, 8) //max 8 servants (that sould only happen with a ton of players)
GLOB.clockwork_vitality += 50 * starter_servants //some starter Vitality to help recover from initial fuck ups
starter_servants = min(starter_servants, 8) //max 8 servants (that sould only happen with a ton of players)
while(starter_servants)
if(!antag_candidates.len)
break //Skip setup, DO NOT RUNTIME
var/datum/mind/servant = antag_pick(antag_candidates)
servants_to_serve += servant
antag_candidates -= servant
servant.assigned_role = ROLE_SERVANT_OF_RATVAR
servant.special_role = ROLE_SERVANT_OF_RATVAR
servant.restricted_roles = restricted_jobs
starter_servants--
ark_time = 30 + round((roundstart_player_count / 5)) //In minutes, how long the Ark will wait before activation
ark_time = min(ark_time, 35) //35 minute maximum for the activation timer
return 1
if(!servants_to_serve.len) //Uh oh, something went wrong
setup_error = "There are no clockcult candidates! (Or something went very wrong)"
return FALSE
GLOB.clockwork_vitality += 50 * servants_to_serve.len //some starter Vitality to help recover from initial fuck ups
return TRUE //Haha yes it works time to not touch it any more than that.
/datum/game_mode/clockwork_cult/post_setup()
for(var/S in servants_to_serve)
var/datum/mind/servant = S
log_game("[key_name(servant)] was made an initial servant of Ratvar")
var/mob/living/L = servant.current
var/turf/T = pick(GLOB.servant_spawns)
L.forceMove(T)
GLOB.servant_spawns -= T
greet_servant(L)
equip_servant(L)
add_servant_of_ratvar(L, TRUE)
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar //that's a mouthful
G.final_countdown(ark_time)
..()
return 1
@@ -201,20 +199,18 @@ Credit where due:
if(!M)
return 0
to_chat(M, "<span class='bold large_brass'>You are a servant of Ratvar, the Clockwork Justiciar!</span>")
to_chat(M, "<span class='brass'>You have approximately <b>[ark_time]</b> minutes until the Ark activates.</span>")
to_chat(M, "<span class='brass'>Unlock <b>Script</b> scripture by converting a new servant.</span>")
to_chat(M, "<span class='brass'><b>Application</b> scripture will be unlocked halfway until the Ark's activation.</span>")
to_chat(M, "<span class='brass'>Unlock <b>Script</b> scripture by converting a new servant or when 35kw of power is reached.</span>")
to_chat(M, "<span class='brass'><b>Application</b> scripture will be unlocked when 50kw of power is reached.</span>")
M.playsound_local(get_turf(M), 'sound/ambience/antag/clockcultalr.ogg', 100, FALSE, pressure_affected = FALSE)
return 1
/datum/game_mode/proc/equip_servant(mob/living/M) //Grants a clockwork slab to the mob, with one of each component
/datum/game_mode/proc/equip_servant(mob/living/M) //Grants a clockwork slab to the mob
if(!M || !ishuman(M))
return FALSE
var/mob/living/carbon/human/L = M
L.equipOutfit(/datum/outfit/servant_of_ratvar)
var/obj/item/clockwork/slab/S = new
var/slot = "At your feet"
var/list/slots = list("In your left pocket" = SLOT_L_STORE, "In your right pocket" = SLOT_R_STORE, "In your backpack" = SLOT_IN_BACKPACK, "On your belt" = SLOT_BELT)
var/list/slots = list("In your left pocket" = SLOT_L_STORE, "In your right pocket" = SLOT_R_STORE, "In your backpack" = SLOT_IN_BACKPACK)
if(ishuman(L))
var/mob/living/carbon/human/H = L
slot = H.equip_in_one_of_slots(S, slots)
@@ -224,7 +220,6 @@ Credit where due:
if(!S.forceMove(get_turf(L)))
qdel(S)
if(S && !QDELETED(S))
to_chat(L, "<span class='bold large_brass'>There is a paper in your backpack! It'll tell you if anything's changed, as well as what to expect.</span>")
to_chat(L, "<span class='alloy'>[slot] is a <b>clockwork slab</b>, a multipurpose tool used to construct machines and invoke ancient words of power. If this is your first time \
as a servant, you can find a concise tutorial in the Recollection category of its interface.</span>")
to_chat(L, "<span class='alloy italics'>If you want more information, you can read <a href=\"https://tgstation13.org/wiki/Clockwork_Cult\">the wiki page</a> to learn more.</span>")
@@ -278,7 +273,7 @@ Credit where due:
gloves = /obj/item/clothing/gloves/color/yellow
belt = /obj/item/storage/belt/utility/servant
backpack_contents = list(/obj/item/storage/box/engineer = 1, \
/obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1, /obj/item/reagent_containers/food/drinks/bottle/holyoil = 1)
/obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/reagent_containers/food/drinks/bottle/holyoil = 1)
id = /obj/item/pda
var/plasmaman //We use this to determine if we should activate internals in post_equip()
@@ -305,54 +300,3 @@ Credit where due:
PDA.update_label()
PDA.id_check(H, W)
H.sec_hud_set_ID()
//This paper serves as a quick run-down to the cult as well as a changelog to refer to.
//Check strings/clockwork_cult_changelog.txt for the changelog, and update it when you can!
/obj/item/paper/servant_primer
name = "The Ark And You: A Primer On Servitude"
color = "#DAAA18"
info = "<b>DON'T PANIC.</b><br><br>\
Here's a quick primer on what you should know here.\
<ol>\
<li>You're in a place called Reebe right now. The crew can't get here normally.</li>\
<li>In the north is your base camp, with supplies, consoles, and the Ark. In the south is an inaccessible area that the crew can walk between \
once they arrive (more on that later.) Everything between that space is an open area.</li>\
<li>Your job as a servant is to build fortifications and defenses to protect the Ark and your base once the Ark activates. You can do this \
however you like, but work with your allies and coordinate your efforts.</li>\
<li>Once the Ark activates, the station will be alerted. Portals to Reebe will open up in nearly every room. When they take these portals, \
the crewmembers will arrive in the area that you can't access, but can get through it freely - whereas you can't. Treat this as the \"spawn\" of the \
crew and defend it accordingly.</li>\
</ol>\
<hr>\
Here is the layout of Reebe, from left to right:\
<ul>\
<li><b>Dressing Room:</b> Contains clothing, a dresser, and a mirror. There are spare slabs and absconders here.</li>\
<li><b>Listening Station:</b> Contains intercoms, a telecomms relay, and a list of frequencies.</li>\
<li><b>Ark Chamber:</b> Houses the Ark.</li>\
<li><b>Observation Room:</b> Contains five camera observers. These can be used to watch the station through its cameras, as well as to teleport down \
to most areas. To do this, use the Warp action while hovering over the tile you want to warp to.</li>\
<li><b>Infirmary:</b> Contains sleepers and basic medical supplies for superficial wounds. The sleepers can consume Vitality to heal any occupants. \
This room is generally more useful during the preparation phase; when defending the Ark, scripture is more useful.</li>\
</ul>\
<hr>\
<h2>Things that have changed:</h2>\
<ul>\
CLOCKCULTCHANGELOG\
</ul>\
<hr>\
<b>Good luck!</b>"
/obj/item/paper/servant_primer/Initialize()
. = ..()
var/changelog = world.file2list("strings/clockwork_cult_changelog.txt")
var/changelog_contents = ""
for(var/entry in changelog)
changelog_contents += "<li>[entry]</li>"
info = replacetext(info, "CLOCKCULTCHANGELOG", changelog_contents)
/*
/obj/item/paper/servant_primer/oui_getcontent(mob/target)
if(!is_servant_of_ratvar(target) && !isobserver(target))
return "<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)]<HR>[stamps]</BODY></HTML>"
return ..()
*/

View File

@@ -273,112 +273,4 @@
C.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
C.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console!
else
playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, 0)
//Used by servants of Ratvar! They let you beam to the station.
/obj/machinery/computer/camera_advanced/ratvar
name = "ratvarian camera observer"
desc = "A console used to snoop on the station's goings-on. A jet of steam occasionally whooshes out from slats on its sides."
use_power = FALSE
networks = list("ss13", "minisat") //:eye:
var/datum/action/innate/servant_warp/warp_action = new
/obj/machinery/computer/camera_advanced/ratvar/Initialize()
. = ..()
ratvar_act()
/obj/machinery/computer/camera_advanced/ratvar/process()
if(prob(1))
playsound(src, 'sound/machines/clockcult/steam_whoosh.ogg', 25, TRUE)
new/obj/effect/temp_visual/steam_release(get_turf(src))
/obj/machinery/computer/camera_advanced/ratvar/CreateEye()
..()
eyeobj.visible_icon = TRUE
eyeobj.icon = 'icons/mob/cameramob.dmi' //in case you still had any doubts
eyeobj.icon_state = "generic_camera"
/obj/machinery/computer/camera_advanced/ratvar/GrantActions(mob/living/carbon/user)
..()
if(warp_action)
warp_action.Grant(user)
warp_action.target = src
actions += warp_action
/obj/machinery/computer/camera_advanced/ratvar/can_use(mob/living/user)
if(!is_servant_of_ratvar(user))
to_chat(user, "<span class='warning'>[src]'s keys are in a language foreign to you, and you don't understand anything on its screen.</span>")
return
if(clockwork_ark_active())
to_chat(user, "<span class='warning'>The Ark is active, and [src] has shut down.</span>")
return
. = ..()
/datum/action/innate/servant_warp
name = "Warp"
desc = "Warps to the tile you're viewing. You can use the Abscond scripture to return. Clicking this button again cancels the warp."
icon_icon = 'icons/mob/actions/actions_clockcult.dmi'
button_icon_state = "warp_down"
background_icon_state = "bg_clock"
buttontooltipstyle = "clockcult"
var/cancel = FALSE //if TRUE, an active warp will be canceled
var/obj/effect/temp_visual/ratvar/warp_marker/warping
/datum/action/innate/servant_warp/Activate()
if(QDELETED(target) || !(ishuman(owner) || iscyborg(owner)) || !owner.canUseTopic(target))
return
if(!GLOB.servants_active) //No leaving unless there's servants from the get-go
return
if(warping)
cancel = TRUE
return
var/mob/living/carbon/human/user = owner
var/mob/camera/aiEye/remote/remote_eye = user.remote_control
var/obj/machinery/computer/camera_advanced/ratvar/R = target
var/turf/T = get_turf(remote_eye)
if(!is_reebe(user.z) || !is_station_level(T.z))
return
if(isclosedturf(T))
to_chat(user, "<span class='sevtug_small'>You can't teleport into a wall.</span>")
return
else if(isspaceturf(T))
to_chat(user, "<span class='sevtug_small'>[prob(1) ? "Servant cannot into space." : "You can't teleport into space."]</span>")
return
else if(T.flags_1 & NOJAUNT_1)
to_chat(user, "<span class='sevtug_small'>This tile is blessed by holy water and deflects the warp.</span>")
return
var/area/AR = get_area(T)
if(!AR.clockwork_warp_allowed)
to_chat(user, "<span class='sevtug_small'>[AR.clockwork_warp_fail]</span>")
return
if(alert(user, "Are you sure you want to warp to [AR]?", target.name, "Warp", "Cancel") == "Cancel" || QDELETED(R) || !user.canUseTopic(R))
return
do_sparks(5, TRUE, user)
do_sparks(5, TRUE, T)
warping = new(T)
user.visible_message("<span class='warning'>[user]'s [target.name] flares!</span>", "<span class='bold sevtug_small'>You begin warping to [AR]...</span>")
button_icon_state = "warp_cancel"
owner.update_action_buttons()
if(!do_after(user, 50, target = warping, extra_checks = CALLBACK(src, .proc/is_canceled)))
to_chat(user, "<span class='bold sevtug_small'>Warp interrupted.</span>")
QDEL_NULL(warping)
button_icon_state = "warp_down"
owner.update_action_buttons()
cancel = FALSE
return
button_icon_state = "warp_down"
owner.update_action_buttons()
QDEL_NULL(warping)
if(!do_teleport(user, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE))
to_chat(user, "<span class='bold sevtug_small'>Warp Failed. Something deflected our attempt to warp to [AR].</span>")
return
T.visible_message("<span class='warning'>[user] warps in!</span>")
playsound(user, 'sound/magic/magic_missile.ogg', 50, TRUE)
playsound(T, 'sound/magic/magic_missile.ogg', 50, TRUE)
user.setDir(SOUTH)
flash_color(user, flash_color = "#AF0AAF", flash_time = 5)
R.remove_eye_control(user)
/datum/action/innate/servant_warp/proc/is_canceled()
return !cancel
playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, 0)

View File

@@ -15,6 +15,8 @@
internals_req_access = list()
add_req_access = 0
wreckage = /obj/structure/mecha_wreckage/durand/neovgre
stepsound = 'sound/mecha/neostep2.ogg'
turnsound = 'sound/mecha/powerloader_step.ogg'
/obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar!
internals_action.Grant(user, src)
@@ -32,7 +34,7 @@
/obj/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user)
if(!is_servant_of_ratvar(user))
to_chat(user, "<span class='brass'>BEGONE HERETIC!</span>")
to_chat(user, "<span class='neovgre'>BEGONE HEATHEN!</span>")
return
else
..()
@@ -91,7 +93,7 @@
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre
equip_cooldown = 8 //Rapid fire heavy laser cannon, simple yet elegant
energy_drain = 30
name = "Aribter Laser Cannon"
name = "Arbiter Laser Cannon"
desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Nanotrasen issue Solaris laser cannon - Nezbere"
fire_sound = 'sound/weapons/neovgre_laser.ogg'

View File

@@ -0,0 +1,44 @@
// Armor kits! Reinforcing uniforms to maintain fashion and also armor capabilities.
/obj/item/armorkit
name = "durathread armor kit"
desc = "A glorified sewing kit with durathread sheets, thread, and a titanium needle, for reinforcing jumpsuits and uniforms."
icon = 'icons/obj/clothing/reinf_kits.dmi'
w_class = WEIGHT_CLASS_SMALL
icon_state = "durathread_kit" // shoutout to my guy Toriate for being good at sprites tho
/obj/item/armorkit/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
// yeah have fun making subtypes and modifying the afterattack if you want to make variants
// idiot
// - hatter
var/used = FALSE
if(isobj(target) && istype(target, /obj/item/clothing/under))
var/obj/item/clothing/under/C = target
if(C.armor.melee < 10)
C.armor.melee = 10
used = TRUE
if(C.armor.laser < 10)
C.armor.laser = 10
used = TRUE
if(C.armor.fire < 40)
C.armor.fire = 40
used = TRUE
if(C.armor.acid < 10)
C.armor.acid = 10
used = TRUE
if(C.armor.bomb < 5)
C.armor.bomb = 5
used = TRUE
if(used)
user.visible_message("<span class = 'notice'>[user] uses [src] on [C], reinforcing it and tossing the empty case away afterwards.</span>", \
"<span class = 'notice'>You reinforce [C] with [src], making it a little more protective! You toss the empty casing away afterwards.</span>")
C.name = "durathread [C.name]" // this disappears if it gets repaired, which is annoying
qdel(src)
return
else
to_chat(user, "<span class = 'notice'>You stare at [src] and [C], coming to the conclusion that you probably don't need to reinforce it any further.")
return
else
return

View File

@@ -263,3 +263,11 @@
icon = 'icons/obj/advancedtools.dmi'
icon_state = "multitool"
toolspeed = 0.2
/obj/item/multitool/advanced/brass
name = "clockwork multitool"
desc = "A brass...multitool? With three prongs arcing electricity between them. It vibrates subtly in your hand."
icon = 'icons/obj/tools.dmi'
icon_state = "clockitool"
toolspeed = 0.2

View File

@@ -477,6 +477,23 @@
name = "empty scroll"
icon_state = "blankscroll"
/obj/item/book/granter/martial/krav_maga
martial = /datum/martial_art/krav_maga
name = "parchment scroll"
martialname = "krav maga"
desc = "A worn parchment scrap written in an ancient language. Somehow you can still understand the lessons!"
greet = "<span class='sciradio'>You have learned the ancient martial art of Krav Maga. You have special attacks with which to take down your foes.</span>"
icon = 'icons/obj/wizard.dmi'
icon_state ="scroll2"
remarks = list("Sweep the legs...", "Chop the throat...", "Punch the lungs...", "Get the gold...", "Where are my sick gloves..?")
/obj/item/book/granter/martial/krav_maga/onlearned(mob/living/carbon/user)
. = ..()
if(oneuse == TRUE)
desc = "It's completely blank."
name = "empty scroll"
icon_state = "blankscroll"
// I did not include mushpunch's grant, it is not a book and the item does it just fine.

View File

@@ -120,7 +120,7 @@
new /obj/item/wrench/brass(src)
new /obj/item/crowbar/brass(src)
new /obj/item/weldingtool/experimental/brass(src)
new /obj/item/multitool(src)
new /obj/item/multitool/advanced/brass(src)
new /obj/item/stack/cable_coil(src, 30, "yellow")
/obj/item/storage/belt/medical

View File

@@ -1230,7 +1230,7 @@
name = "steampunk watch"
desc = "A stylish steampunk watch made out of thousands of tiny cogwheels."
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "dread_ipad"
icon_state = "clockwork_slab"
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0

View File

@@ -40,6 +40,11 @@
if(M.client)
body += "<br>\[<b>First Seen:</b> [M.client.player_join_date]\]\[<b>Byond account registered on:</b> [M.client.account_join_date]\]"
body += "<br><br><b>CentCom Galactic Ban DB: </b> "
if(CONFIG_GET(string/centcom_ban_db))
body += "<a href='?_src_=holder;[HrefToken()];centcomlookup=[M.client.ckey]'>Search</a>"
else
body += "<i>Disabled</i>"
body += "<br><br><b>Show related accounts by:</b> "
body += "\[ <a href='?_src_=holder;[HrefToken()];showrelatedacc=cid;client=[REF(M.client)]'>CID</a> | "
body += "<a href='?_src_=holder;[HrefToken()];showrelatedacc=ip;client=[REF(M.client)]'>IP</a> \]"

View File

@@ -2834,6 +2834,60 @@
usr << browse(dat.Join("<br>"), "window=related_[C];size=420x300")
else if(href_list["centcomlookup"])
if(!check_rights(R_ADMIN))
return
if(!CONFIG_GET(string/centcom_ban_db))
to_chat(usr, "<span class='warning'>Centcom Galactic Ban DB is disabled!</span>")
return
var/ckey = href_list["centcomlookup"]
// Make the request
var/datum/http_request/request = new()
request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/centcom_ban_db)]/[ckey]", "", "")
request.begin_async()
UNTIL(request.is_complete() || !usr)
if (!usr)
return
var/datum/http_response/response = request.into_response()
var/list/bans
var/list/dat = list("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><body>")
if(response.errored)
dat += "<br>Failed to connect to CentCom."
else if(response.status_code != 200)
dat += "<br>Failed to connect to CentCom. Status code: [response.status_code]"
else
if(response.body == "[]")
dat += "<center><b>0 bans detected for [ckey]</b></center>"
else
bans = json_decode(response["body"])
dat += "<center><b>[bans.len] ban\s detected for [ckey]</b></center>"
for(var/list/ban in bans)
dat += "<b>Server: </b> [sanitize(ban["sourceName"])]<br>"
dat += "<b>RP Level: </b> [sanitize(ban["sourceRoleplayLevel"])]<br>"
dat += "<b>Type: </b> [sanitize(ban["type"])]<br>"
dat += "<b>Banned By: </b> [sanitize(ban["bannedBy"])]<br>"
dat += "<b>Reason: </b> [sanitize(ban["reason"])]<br>"
dat += "<b>Datetime: </b> [sanitize(ban["bannedOn"])]<br>"
var/expiration = ban["expires"]
dat += "<b>Expires: </b> [expiration ? "[sanitize(expiration)]" : "Permanent"]<br>"
if(ban["type"] == "job")
dat += "<b>Jobs: </b> "
var/list/jobs = ban["jobs"]
dat += sanitize(jobs.Join(", "))
dat += "<br>"
dat += "<hr>"
dat += "<br></body>"
var/datum/browser/popup = new(usr, "centcomlookup-[ckey]", "<div align='center'>Central Command Galactic Ban Database</div>", 700, 600)
popup.set_content(dat.Join())
popup.open(0)
else if(href_list["modantagrep"])
if(!check_rights(R_ADMIN))
return

View File

@@ -60,8 +60,10 @@
/datum/antagonist/abductor/greet()
to_chat(owner.current, "<span class='notice'>You are the [owner.special_role]!</span>")
to_chat(owner.current, "<span class='notice'>With the help of your teammate, kidnap and experiment on station crew members!</span>")
to_chat(owner.current, "<span class='notice'>Try not to disturb the habitat, it could lead to dead specimens.</span>")
to_chat(owner.current, "<span class='notice'>You are an operative for your home planet's government. Your mission is to detain, experiment, and observe.</span>")
to_chat(owner.current, "<span class='notice'>Work together with your teammate to bring live subjects from the space station nearby onto your ship for experimentation.</span>")
to_chat(owner.current, "<span class='notice'>For the sake of the mission, do not damage the integrity of the station, do not kill anyone unless in self defense, always capture specimens first if you can, and do not steal equipment or belongings from abducted specimens.</span>")
to_chat(owner.current, "<span class='notice'>Your task is to observe and take notes of the effects of your experiments.</span>")
to_chat(owner.current, "<span class='notice'>[greet_text]</span>")
owner.announce_objectives()

View File

@@ -216,6 +216,20 @@
else if(get_clockwork_power())
to_chat(L, "<span class='brass'>You feel a slight, static shock.</span>")
/obj/effect/clockwork/sigil/transmission/process()
var/power_drained = 0
var/power_mod = 0.005
for(var/t in spiral_range_turfs(SIGIL_ACCESS_RANGE, src))
var/turf/T = t
for(var/M in T)
var/atom/movable/A = M
power_drained += A.power_drain(TRUE)
CHECK_TICK
adjust_clockwork_power(power_drained * power_mod * 15)
new /obj/effect/temp_visual/ratvar/sigil/transmission(loc, 1 + (power_drained * 0.0035))
/obj/effect/clockwork/sigil/transmission/proc/charge_cyborg(mob/living/silicon/robot/cyborg)
if(!cyborg_checks(cyborg))
return

View File

@@ -14,6 +14,8 @@
var/uses = 1 //How many objects or mobs can go through the portal
var/obj/effect/clockwork/spatial_gateway/linked_gateway //The gateway linked to this one
var/timerid
var/is_stable = FALSE
var/busy = FALSE //If someone is already working on closing the gateway, only needed for stable gateways but in the parent to not need typecasting
/obj/effect/clockwork/spatial_gateway/Initialize()
. = ..()
@@ -31,11 +33,16 @@
clockwork_desc = "A gateway in reality. It can both send and receive objects."
else
clockwork_desc = "A gateway in reality. It can only [sender ? "send" : "receive"] objects."
timerid = QDEL_IN(src, lifetime)
if(is_stable)
return
timerid = QDEL_IN(src, lifetime) //We only need this if the gateway is not stable
//set up a gateway with another gateway
/obj/effect/clockwork/spatial_gateway/proc/setup_gateway(obj/effect/clockwork/spatial_gateway/gatewayB, set_duration, set_uses, two_way)
if(!gatewayB || !set_duration || !uses)
if(!gatewayB)
return FALSE
if((!set_duration || !uses) && !is_stable)
return FALSE
linked_gateway = gatewayB
gatewayB.linked_gateway = src
@@ -55,7 +62,7 @@
/obj/effect/clockwork/spatial_gateway/examine(mob/user)
. = ..()
if(is_servant_of_ratvar(user) || isobserver(user))
. += "<span class='brass'>It has [uses] use\s remaining.</span>"
. += "<span class='brass'> [is_stable ? "It is stabilised and can be used as much as is neccessary." : "It has [uses] use\s remaining."]</span>"
//ATTACK GHOST IGNORING PARENT RETURN VALUE
/obj/effect/clockwork/spatial_gateway/attack_ghost(mob/user)
@@ -121,9 +128,9 @@
/obj/effect/clockwork/spatial_gateway/Bumped(atom/movable/AM)
..()
if(!QDELETED(AM))
pass_through_gateway(AM, FALSE)
pass_through_gateway(AM)
/obj/effect/clockwork/spatial_gateway/proc/pass_through_gateway(atom/movable/A, no_cost)
/obj/effect/clockwork/spatial_gateway/proc/pass_through_gateway(atom/movable/A, no_cost = FALSE)
if(!linked_gateway)
qdel(src)
return FALSE
@@ -197,6 +204,10 @@
return procure_gateway(invoker, time_duration, gateway_uses, two_way)
var/istargetobelisk = istype(target, /obj/structure/destructible/clockwork/powered/clockwork_obelisk)
var/issrcobelisk = istype(src, /obj/structure/destructible/clockwork/powered/clockwork_obelisk)
if(!issrcobelisk && target.z != invoker.z && (is_reebe(invoker.z) || is_reebe(target.z)) && !GLOB.ratvar_awakens) //You need obilisks to get from and to reebe. Costs alot of power, unless you use stable gateways.
to_chat(invoker, "<span class='heavy brass'>The distance between reebe and the mortal realm is far too vast to bridge with a gateway your slab can create, my child. \
Use an obilisk instead!</span>")
return procure_gateway(invoker, time_duration, gateway_uses, two_way)
if(issrcobelisk)
if(!anchored)
to_chat(invoker, "<span class='warning'>[src] is no longer secured!</span>")
@@ -217,12 +228,63 @@
gateway_uses = round(gateway_uses * (2 * efficiency), 1)
time_duration = round(time_duration * (2 * efficiency), 1)
CO.active = TRUE //you'd be active in a second but you should update immediately
invoker.visible_message("<span class='warning'>The air in front of [invoker] ripples before suddenly tearing open!</span>", \
"<span class='brass'>With a word, you rip open a [two_way ? "two-way":"one-way"] rift to [input_target_key]. It will last for [DisplayTimeText(time_duration)] and has [gateway_uses] use[gateway_uses > 1 ? "s" : ""].</span>")
var/obj/effect/clockwork/spatial_gateway/S1 = new(issrcobelisk ? get_turf(src) : get_step(get_turf(invoker), invoker.dir))
var/obj/effect/clockwork/spatial_gateway/S2 = new(istargetobelisk ? get_turf(target) : get_step(get_turf(target), target.dir))
if(issrcobelisk && istargetobelisk && src.z != target.z && (is_reebe(src.z) || is_reebe(target.z)))
invoker.visible_message("<span class='warning'>The air in front of [invoker] ripples before suddenly tearing open!</span>", \
"<span class='brass'>With a word, you rip open a stable two-way rift between reebe and the mortal realm.</span>")
var/obj/effect/clockwork/spatial_gateway/stable/stable_S1 = new(get_turf(src))
var/obj/effect/clockwork/spatial_gateway/stable/stable_S2 = new(get_turf(target))
stable_S1.setup_gateway(stable_S2)
stable_S2.visible_message("<span class='warning'>The air in front of [target] ripples before suddenly tearing open!</span>")
else
invoker.visible_message("<span class='warning'>The air in front of [invoker] ripples before suddenly tearing open!</span>", \
"<span class='brass'>With a word, you rip open a [two_way ? "two-way":"one-way"] rift to [input_target_key]. It will last for [DisplayTimeText(time_duration)] and has [gateway_uses] use[gateway_uses > 1 ? "s" : ""].</span>")
var/obj/effect/clockwork/spatial_gateway/S1 = new(issrcobelisk ? get_turf(src) : get_step(get_turf(invoker), invoker.dir))
var/obj/effect/clockwork/spatial_gateway/S2 = new(istargetobelisk ? get_turf(target) : get_step(get_turf(target), target.dir))
//Set up the portals now that they've spawned
S1.setup_gateway(S2, time_duration, gateway_uses, two_way)
S2.visible_message("<span class='warning'>The air in front of [target] ripples before suddenly tearing open!</span>")
//Set up the portals now that they've spawned
S1.setup_gateway(S2, time_duration, gateway_uses, two_way)
S2.visible_message("<span class='warning'>The air in front of [target] ripples before suddenly tearing open!</span>")
return TRUE
//Stable Gateway: Used to travel to and from reebe without any further powercost. Needs a clockwork obilisk to keep active, but stays active as long as it is not deactivated via an null rod or a slab, or the obilisk is destroyed
/obj/effect/clockwork/spatial_gateway/stable
name = "stable gateway"
is_stable = TRUE
/obj/effect/clockwork/spatial_gateway/stable/ex_act(severity)
if(severity == 1)
start_shutdown() //Yes, you can chain devastation-level explosions to delay a gateway shutdown, if you somehow manage to do it without breaking the obelisk. Is it worth it? Probably not.
return TRUE
return FALSE
/obj/effect/clockwork/spatial_gateway/stable/setup_gateway(obj/effect/clockwork/spatial_gateway/stable/gatewayB) //Reduced setup call due to some things being irrelevant for stable gateways
return ..(gatewayB, 1, 1, TRUE) //Uses and time irrelevant due to is_stable
/obj/effect/clockwork/spatial_gateway/stable/attackby(obj/item/I, mob/living/user, params)
if(!istype(I, /obj/item/clockwork/slab) || !is_servant_of_ratvar(user) || busy)
return ..()
busy = TRUE
linked_gateway.busy = TRUE
user.visible_message("<span class='warning'>The rift begins to ripple as [user] points [user.p_their()] slab at it!</span>", "<span class='brass'> You begin to shutdown the stabilised gateway with your slab.</span>")
linked_gateway.visible_message("<span class='warning'[linked_gateway] begins to ripple, but nothing comes through...</span>")
var/datum/beam/B = user.Beam(src, icon_state = "nzcrentrs_power", maxdistance = 50, time = 80) //Not too fancy, but this'll do.. for now.
if(do_after(user, 80, target = src)) //Eight seconds to initiate the closing, then another two before is closes.
to_chat(user, "<span class='brass'>You successfully set the gateway to shutdown in another two seconds.</span>")
start_shutdown()
qdel(B)
busy = FALSE
linked_gateway.busy = FALSE
return TRUE
/obj/effect/clockwork/spatial_gateway/stable/proc/start_shutdown()
deltimer(timerid)
deltimer(linked_gateway.timerid)
timerid = QDEL_IN(src, 20)
linked_gateway.timerid = QDEL_IN(linked_gateway, 20)
animate(src, alpha = 0, transform = matrix()*2, time = 20, flags = ANIMATION_END_NOW)
animate(linked_gateway, alpha = 0, transform = matrix()*2, time = 20, flags = ANIMATION_END_NOW)
src.visible_message("<span class='warning'>[src] begins to destabilise!</span>")
linked_gateway.visible_message("<span class='warning'>[linked_gateway] begins to destabilise!</span>")
/obj/effect/clockwork/spatial_gateway/stable/pass_through_gateway(atom/movable/A, no_cost = TRUE)
return ..()

View File

@@ -29,7 +29,7 @@
owner.visible_message("<span class='danger'>[owner]'s [weapon.name] flickers and disappears!</span>")
to_chat(owner, "<span class='brass'>You dismiss [weapon].</span>")
QDEL_NULL(weapon)
weapon_reset(RATVARIAN_SPEAR_COOLDOWN * 0.5)
weapon_reset(RATVARIAN_WEAPON_COOLDOWN * 0.5)
return
else
weapon.visible_message("<span class='warning'>[weapon] suddenly flickers and disappears!</span>")

View File

@@ -78,5 +78,5 @@
if(T) //make sure we're not in null or something
T.visible_message("<span class='warning'>[src] [pick("cracks in two and fades away", "snaps in two and dematerializes")]!</span>")
new /obj/effect/temp_visual/ratvar/spearbreak(T)
action.weapon_reset(RATVARIAN_SPEAR_COOLDOWN)
action.weapon_reset(RATVARIAN_WEAPON_COOLDOWN)

View File

@@ -8,7 +8,7 @@
resistance_flags = FIRE_PROOF | ACID_PROOF
flags_inv = HIDEEARS|HIDEHAIR|HIDEFACE|HIDESNOUT
mutantrace_variation = STYLE_MUZZLE
armor = list("melee" = 50, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
armor = list("melee" = 50, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 60, "wound" = 65)
/obj/item/clothing/head/helmet/clockwork/Initialize()
. = ..()
@@ -21,17 +21,17 @@
/obj/item/clothing/head/helmet/clockwork/ratvar_act()
if(GLOB.ratvar_awakens)
armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100)
armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100, magic = 100, wound = 100)
clothing_flags |= STOPSPRESSUREDAMAGE
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else if(GLOB.ratvar_approaches)
armor = getArmor(melee = 70, bullet = 80, laser = -15, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100)
armor = getArmor(melee = 70, bullet = 80, laser = 10, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100,, magic = 70, wound = 75)
clothing_flags |= STOPSPRESSUREDAMAGE
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
armor = getArmor(melee = 60, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
armor = getArmor(melee = 60, bullet = 70, laser = 0, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 60, wound = 65)
clothing_flags &= ~STOPSPRESSUREDAMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -68,7 +68,7 @@
cold_protection = CHEST|GROIN|LEGS
heat_protection = CHEST|GROIN|LEGS
resistance_flags = FIRE_PROOF | ACID_PROOF
armor = list("melee" = 60, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
armor = list("melee" = 60, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 60, "wound" = 65)
allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel, /obj/item/reagent_containers/food/drinks/bottle/holyoil)
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC
@@ -83,17 +83,17 @@
/obj/item/clothing/suit/armor/clockwork/ratvar_act()
if(GLOB.ratvar_awakens)
armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100)
armor = getArmor(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100, magic = 100, wound = 100)
clothing_flags |= STOPSPRESSUREDAMAGE
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else if(GLOB.ratvar_approaches)
armor = getArmor(melee = 70, bullet = 80, laser = -15, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100)
armor = getArmor(melee = 70, bullet = 80, laser = 10, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100, magic = 70, wound = 75)
clothing_flags |= STOPSPRESSUREDAMAGE
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
armor = getArmor(melee = 60, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
armor = getArmor(melee = 60, bullet = 70, laser = 0, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 60, wound = 65)
clothing_flags &= ~STOPSPRESSUREDAMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -135,7 +135,7 @@
siemens_coefficient = 0
permeability_coefficient = 0.05
resistance_flags = FIRE_PROOF | ACID_PROOF
armor = list("melee" = 80, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
armor = list("melee" = 80, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 70, "wound" = 85)
/obj/item/clothing/gloves/clockwork/Initialize()
. = ..()
@@ -153,7 +153,7 @@
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
armor = getArmor(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
armor = getArmor(melee = 80, bullet = 70, laser = 0, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 70, wound = 85)
clothing_flags &= ~STOPSPRESSUREDAMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)

View File

@@ -4,7 +4,7 @@
clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant.\
It can be used to link traps and triggers by attacking them with the slab. Keep in mind that traps linked with one another will activate in tandem!"
icon_state = "dread_ipad"
icon_state = "clockwork_slab"
lefthand_file = 'icons/mob/inhands/antag/clockwork_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/clockwork_righthand.dmi'
var/inhand_overlay //If applicable, this overlay will be applied to the slab's inhand
@@ -21,7 +21,7 @@
var/recollecting = TRUE //if we're looking at fancy recollection. tutorial enabled by default
var/recollection_category = "Default"
var/list/quickbound = list(/datum/clockwork_scripture/abscond, \
var/list/quickbound = list(/datum/clockwork_scripture/spatial_gateway, \
/datum/clockwork_scripture/ranged_ability/kindle, /datum/clockwork_scripture/ranged_ability/hateful_manacles) //quickbound scripture, accessed by index
var/maximum_quickbound = 5 //how many quickbound scriptures we can have
@@ -69,29 +69,32 @@
maximum_quickbound = 6 //we usually have one or two unique scriptures, so if ratvar is up let us bind one more
actions_types = list()
/obj/item/clockwork/slab/cyborg/engineer //three scriptures, plus a fabricator
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transmission, /datum/clockwork_scripture/create_object/stargazer)
/obj/item/clockwork/slab/cyborg/engineer //six scriptures, plus a fabricator. Might revert this if its too OP, I just thought that engineering borgs should get the all the structures
quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transmission, /datum/clockwork_scripture/create_object/stargazer, \
/datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/clockwork_obelisk, /datum/clockwork_scripture/create_object/mania_motor)
/obj/item/clockwork/slab/cyborg/medical //five scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \
/datum/clockwork_scripture/create_object/vitality_matrix)
/obj/item/clockwork/slab/cyborg/medical //six scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \
/datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/channeled/mending_mantra)
/obj/item/clockwork/slab/cyborg/security //twoscriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/hateful_manacles, /datum/clockwork_scripture/ranged_ability/judicial_marker)
/obj/item/clockwork/slab/cyborg/peacekeeper //two scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/hateful_manacles, /datum/clockwork_scripture/ranged_ability/judicial_marker)
/obj/item/clockwork/slab/cyborg/security //four scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/channeled/volt_blaster, /datum/clockwork_scripture/ranged_ability/hateful_manacles, \
/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/channeled/belligerent)
/obj/item/clockwork/slab/cyborg/peacekeeper //four scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/channeled/volt_blaster, /datum/clockwork_scripture/ranged_ability/hateful_manacles, \
/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/channeled/belligerent)
/*//this module was commented out so why wasn't this?
/obj/item/clockwork/slab/cyborg/janitor //six scriptures, plus a fabricator
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transgression, \
quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transgression, \
/datum/clockwork_scripture/create_object/stargazer, /datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/mania_motor)
*/
/obj/item/clockwork/slab/cyborg/service //six scriptures, plus xray vision
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant,/datum/clockwork_scripture/create_object/stargazer, \
quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/replicant,/datum/clockwork_scripture/create_object/stargazer, \
/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/clockwork_obelisk)
/obj/item/clockwork/slab/cyborg/miner //two scriptures, plus a spear and xray vision
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/spatial_gateway)
/obj/item/clockwork/slab/cyborg/miner //three scriptures, plus a spear and xray vision
quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/channeled/volt_blaster)
/obj/item/clockwork/slab/cyborg/access_display(mob/living/user)
if(!GLOB.ratvar_awakens)
@@ -242,7 +245,7 @@
var/datum/clockwork_scripture/S = GLOB.all_scripture[s]
if(S.tier == SCRIPTURE_PERIPHERAL) //yes, tiers are the tabs.
continue
var/list/data = list()
data["name"] = S.name
data["descname"] = S.descname
@@ -253,13 +256,13 @@
data["quickbind"] = S.quickbind //this is if it cant quickbind
data["fontcolor"] = get_component_color_bright(S.primary_component)
data["important"] = S.important //italic!
var/found = quickbound.Find(S.type)
if(found)
data["bound"] = found //number (pos) on where is it on the list
if(S.invokers_required > 1)
data["invokers"] = "Invokers: [S.invokers_required]"
.["rec_binds"] = list()
for(var/i in 1 to maximum_quickbound)
if(GLOB.ratvar_awakens)
@@ -269,10 +272,10 @@
else
var/datum/clockwork_scripture/quickbind_slot = quickbound[i]
.["rec_binds"] += list(list(
"name" = initial(quickbind_slot.name),
"name" = initial(quickbind_slot.name),
"color" = get_component_color_bright(initial(quickbind_slot.primary_component))
))
.["scripture"][S.tier] += list(data)
/obj/item/clockwork/slab/ui_static_data(mob/user)
@@ -290,6 +293,10 @@
"requirement" = "Unlock these optional scriptures by converting another servant or if [DisplayPower(APPLICATION_UNLOCK_THRESHOLD)] of power is reached..",
"ready" = SSticker.scripture_states[SCRIPTURE_APPLICATION]
)
.["tier_infos"][SCRIPTURE_JUDGEMENT] = list(
"requirement" = "Unlock powerful equipment and structures by converting five servants or if [DisplayPower(JUDGEMENT_UNLOCK_THRESHOLD)] of power is reached..",
"ready" = SSticker.scripture_states[SCRIPTURE_JUDGEMENT]
)
// .["selected"] = selected_scripture
generate_all_scripture()
@@ -362,4 +369,4 @@
Q.button_icon_state = quickbind_slot.name
Q.UpdateButtonIcon()
if(isliving(loc))
Q.Grant(loc)
Q.Grant(loc)

View File

@@ -30,6 +30,7 @@
var/obj/item/stock_parts/cell/cell = apc.cell
if(cell && (cell.charge / cell.maxcharge > COG_MAX_SIPHON_THRESHOLD))
cell.use(1)
apc.cog_drained++
adjust_clockwork_power(2) //Power is shared, so only do it once; this runs very quickly so it's about 10 W/second
else
adjust_clockwork_power(1) //Continue generating power when the cell has run dry; 5 W/second

View File

@@ -124,3 +124,437 @@
#undef MARAUDER_SLOWDOWN_PERCENTAGE
#undef MARAUDER_SHIELD_REGEN_TIME
//Clockwork guardian: Slow but with high damage, resides inside of a servant. Created via the Memory Allocation scripture.
/mob/living/simple_animal/hostile/clockwork/marauder/guardian
name = "clockwork guardian"
desc = "A stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield and stands ready by its master."
icon_state = "clockwork_marauder"
health = 300
maxHealth = 300
speed = 1
obj_damage = 40
melee_damage_lower = 12
melee_damage_upper = 12
attack_verb_continuous = "slashes"
attack_verb_simple = "slash"
attack_sound = 'sound/weapons/bladeslice.ogg'
weather_immunities = list("lava")
movement_type = FLYING
AIStatus = AI_OFF //this has to be manually set so that the guardian doesn't start bashing the host, how annoying -_-
loot = list(/obj/item/clockwork/component/geis_capacitor/fallen_armor)
max_shield_health = 0
shield_health = 0
var/true_name = "Meme Master 69" //Required to call forth the guardian
var/global/list/possible_true_names = list("Servant", "Warden", "Serf", "Page", "Usher", "Knave", "Vassal", "Escort")
var/mob/living/host //The mob that the guardian is living inside of
var/recovering = FALSE //If the guardian is recovering from recalling
var/blockchance = 17 //chance to block attacks entirely
var/counterchance = 30 //chance to counterattack after blocking
var/static/list/damage_heal_order = list(OXY, BURN, BRUTE, TOX) //we heal our host's damage in this order
light_range = 2
light_power = 1.1
playstyle_string = "<span class='sevtug'>You are a clockwork guardian</span><b>, a living extension of Sevtug's will. As a guardian, you are somewhat slow, but may block attacks, \
and have a chance to also counter blocked melee attacks for extra damage, in addition to being immune to extreme temperatures and pressures. \
Your primary goal is to serve the creature that you are now a part of, as well as The Clockwork Justiciar, Ratvar. You can use <span class='sevtug_small'><i>The Hierophant Network</i></span> to communicate silently with your master and their allies, \
but can only exit if your master calls your true name or if they are exceptionally damaged. \
\n\n\
Stay near your host to protect and heal them; being too far from your host will rapidly cause you massive damage. Recall to your host if you are too weak and believe you cannot continue \
fighting safely. As a final note, you should probably avoid harming any fellow servants of Ratvar.</span>"
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Initialize()
. = ..()
true_name = pick(possible_true_names)
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/BiologicalLife(seconds, times_fired)
..()
if(is_in_host())
if(!is_servant_of_ratvar(host))
emerge_from_host(FALSE, TRUE)
unbind_from_host()
return
if(!GLOB.ratvar_awakens && host.stat == DEAD)
death()
return
if(GLOB.ratvar_awakens)
adjustHealth(-50)
else
adjustHealth(-10)
if(!recovering)
heal_host() //also heal our host if inside of them and we aren't recovering
else if(health == maxHealth)
to_chat(src, "<span class='userdanger'>Your strength has returned. You can once again come forward!</span>")
to_chat(host, "<span class='userdanger'>Your guardian is now strong enough to come forward again!</span>")
recovering = FALSE
else
if(GLOB.ratvar_awakens) //If Ratvar is alive, guardians don't need a host and are downright impossible to kill
adjustHealth(-5)
heal_host()
else if(host)
if(!is_servant_of_ratvar(host))
unbind_from_host()
return
if(host.stat == DEAD)
adjustHealth(50)
to_chat(src, "<span class='userdanger'>Your host is dead!</span>")
return
if(z && host.z && z == host.z)
switch(get_dist(get_turf(src), get_turf(host)))
if(2)
adjustHealth(-1)
if(3)
//EQUILIBRIUM
if(4)
adjustHealth(1)
if(5)
adjustHealth(3)
if(6)
adjustHealth(6)
if(7)
adjustHealth(9)
if(8 to INFINITY)
adjustHealth(15)
to_chat(src, "<span class='userdanger'>You're too far from your host and rapidly taking damage!</span>")
else //right next to or on top of host
adjustHealth(-2)
heal_host() //gradually heal host if nearby and host is very weak
else //well then, you're not even in the same zlevel
adjustHealth(15)
to_chat(src, "<span class='userdanger'>You're too far from your host and rapidly taking damage!</span>")
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/death(gibbed)
emerge_from_host(FALSE, TRUE)
unbind_from_host()
visible_message("<span class='warning'>[src]'s equipment clatters lifelessly to the ground as the red flames within dissipate.</span>", \
"<span class='userdanger'>Your equipment falls away. You feel a moment of confusion before your fragile form is annihilated.</span>")
. = ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Stat()
..()
if(statpanel("Status"))
stat(null, "Current True Name: [true_name]")
stat(null, "Host: [host ? host : "NONE"]")
if(host)
var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
if(iscarbon(host))
resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
stat(null, "Host Health: [resulthealth]%")
if(GLOB.ratvar_awakens)
stat(null, "You are [recovering ? "un" : ""]able to deploy!")
else
if(resulthealth > GUARDIAN_EMERGE_THRESHOLD)
stat(null, "You are [recovering ? "unable to deploy" : "able to deploy on hearing your True Name"]!")
else
stat(null, "You are [recovering ? "unable to deploy" : "able to deploy to protect your host"]!")
stat(null, "You do [melee_damage_upper] damage on melee attacks.")
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Process_Spacemove(movement_dir = 0)
return 1
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/bind_to_host(mob/living/new_host)
if(!new_host)
return FALSE
host = new_host
var/datum/action/innate/summon_guardian/SG = new()
SG.linked_guardian = src
SG.Grant(host)
var/datum/action/innate/linked_minds/LM = new()
LM.linked_guardian = src
LM.Grant(host)
return TRUE
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/unbind_from_host()
if(host)
for(var/datum/action/innate/summon_guardian/SG in host.actions)
qdel(SG)
for(var/datum/action/innate/linked_minds/LM in host.actions)
qdel(LM)
host = null
return TRUE
return FALSE
//DAMAGE and FATIGUE
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/heal_host()
if(!host)
return
var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
if(iscarbon(host))
resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
if(GLOB.ratvar_awakens || resulthealth <= GUARDIAN_EMERGE_THRESHOLD)
new /obj/effect/temp_visual/heal(host.loc, "#AF0AAF")
host.heal_ordered_damage(4, damage_heal_order)
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
if(amount > 0)
for(var/mob/living/L in view(2, src))
if(L.is_holding_item_of_type(/obj/item/nullrod))
to_chat(src, "<span class='userdanger'>The presence of a brandished holy artifact weakens your armor!</span>")
amount *= 4 //if a wielded null rod is nearby, it takes four times the health damage
break
. = ..()
if(src && updating_health)
update_health_hud()
update_stats()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/update_health_hud()
if(hud_used && hud_used.healths)
if(istype(hud_used, /datum/hud/marauder))
var/datum/hud/marauder/G = hud_used
var/resulthealth
if(host)
if(iscarbon(host))
resulthealth = "[round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)]%"
else
resulthealth = "[round((host.health / host.maxHealth) * 100, 0.5)]%"
else
resulthealth = "NONE"
G.hosthealth.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#AF0AAF'>HOST<br>[resulthealth]</font></div>"
hud_used.healths.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#AF0AAF'>[round((health / maxHealth) * 100, 0.5)]%</font>"
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/update_stats()
if(GLOB.ratvar_awakens)
speed = 0
melee_damage_lower = 20
melee_damage_upper = 20
attack_verb_continuous = "devastates"
else
var/healthpercent = (health/maxHealth) * 100
switch(healthpercent)
if(100 to 70) //Bonuses to speed and damage at high health
speed = 0
melee_damage_lower = 16
melee_damage_upper = 16
attack_verb_continuous = "viciously slashes"
if(70 to 40)
speed = initial(speed)
melee_damage_lower = initial(melee_damage_lower)
melee_damage_upper = initial(melee_damage_upper)
attack_verb_continuous = initial(attack_verb_continuous)
if(40 to 30) //Damage decrease, but not speed
speed = initial(speed)
melee_damage_lower = 10
melee_damage_upper = 10
attack_verb_continuous = "lightly slashes"
if(30 to 20) //Speed decrease
speed = 2
melee_damage_lower = 8
melee_damage_upper = 8
attack_verb_continuous = "lightly slashes"
if(20 to 10) //Massive speed decrease and weak melee attacks
speed = 3
melee_damage_lower = 6
melee_damage_upper = 6
attack_verb_continuous = "weakly slashes"
if(10 to 0) //We are super weak and going to die
speed = 4
melee_damage_lower = 4
melee_damage_upper = 4
attack_verb_continuous = "taps"
//ATTACKING, BLOCKING, and COUNTERING
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/AttackingTarget()
if(is_in_host())
return FALSE
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/bullet_act(obj/item/projectile/Proj)
if(blockOrCounter(null, Proj))
return
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/hitby(atom/movable/AM, skipcatch, hitpush, blocked, atom/movable/AM, datum/thrownthing/throwingdatum)
if(blockOrCounter(null, AM))
return
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_animal(mob/living/simple_animal/M)
if(istype(M, /mob/living/simple_animal/hostile/clockwork/marauder/guardian) || !blockOrCounter(M, M)) //we don't want infinite blockcounter loops if fighting another guardian
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_paw(mob/living/carbon/monkey/M)
if(!blockOrCounter(M, M))
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_alien(mob/living/carbon/alien/humanoid/M)
if(!blockOrCounter(M, M))
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_slime(mob/living/simple_animal/slime/M)
if(!blockOrCounter(M, M))
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_hand(mob/living/carbon/human/M)
if(!blockOrCounter(M, M))
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/nullrod) || !blockOrCounter(user, I))
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/blockOrCounter(mob/target, atom/textobject)
if(GLOB.ratvar_awakens) //if ratvar has woken, we block nearly everything at a very high chance
blockchance = 90
counterchance = 90
if(prob(blockchance))
. = TRUE
if(target)
target.do_attack_animation(src)
target.DelayNextAction(CLICK_CD_MELEE)
blockchance = initial(blockchance)
playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 30, 1, 0, 1) //clang
visible_message("<span class='boldannounce'>[src] blocks [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!</span>", \
"<span class='userdanger'>You block [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!</span>")
if(target && Adjacent(target))
if(prob(counterchance))
counterchance = initial(counterchance)
var/previousattack_verb_continuous = attack_verb_continuous
attack_verb_continuous = "counters"
UnarmedAttack(target)
attack_verb_continuous = previousattack_verb_continuous
else
counterchance = min(counterchance + initial(counterchance), 100)
else
blockchance = min(blockchance + initial(blockchance), 100)
if(GLOB.ratvar_awakens)
blockchance = 90
counterchance = 90
//COMMUNICATION and EMERGENCE
/*
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/handle_inherent_channels(message, message_mode)
if(host && (is_in_host() || message_mode == MODE_BINARY))
guardian_comms(message)
return TRUE
return ..()
*/
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/guardian_comms(message)
var/name_part = "<span class='sevtug'>[src] ([true_name])</span>"
message = "<span class='sevtug_small'>\"[message]\"</span>" //Processed output
to_chat(src, "[name_part]<span class='sevtug_small'>:</span> [message]")
to_chat(host, "[name_part]<span class='sevtug_small'>:</span> [message]")
for(var/M in GLOB.mob_list)
if(isobserver(M))
var/link = FOLLOW_LINK(M, src)
to_chat(M, "[link] [name_part] <span class='sevtug_small'>(to</span> <span class='sevtug'>[findtextEx(host.name, host.real_name) ? "[host.name]" : "[host.real_name] (as [host.name])"]</span><span class='sevtug_small'>):</span> [message] ")
return TRUE
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/return_to_host()
if(is_in_host())
return FALSE
if(!host)
to_chat(src, "<span class='warning'>You don't have a host!</span>")
return FALSE
var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
if(iscarbon(host))
resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
host.visible_message("<span class='warning'>[host]'s skin flashes crimson!</span>", "<span class='sevtug'>You feel [true_name]'s consciousness settle in your mind.</span>")
visible_message("<span class='warning'>[src] suddenly disappears!</span>", "<span class='sevtug'>You return to [host].</span>")
forceMove(host)
if(resulthealth > GUARDIAN_EMERGE_THRESHOLD && health != maxHealth)
recovering = TRUE
to_chat(src, "<span class='userdanger'>You have weakened and will need to recover before manifesting again!</span>")
to_chat(host, "<span class='sevtug'>[true_name] has weakened and will need to recover before manifesting again!</span>")
return TRUE
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/try_emerge()
if(!host)
to_chat(src, "<span class='warning'>You don't have a host!</span>")
return FALSE
if(!GLOB.ratvar_awakens)
var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
if(iscarbon(host))
resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
if(host.stat != DEAD && resulthealth > GUARDIAN_EMERGE_THRESHOLD) //if above 20 health, fails
to_chat(src, "<span class='warning'>Your host must be at [GUARDIAN_EMERGE_THRESHOLD]% or less health to emerge like this!</span>")
return FALSE
return emerge_from_host(FALSE)
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/emerge_from_host(hostchosen, force) //Notice that this is a proc rather than a verb - guardians can NOT exit at will, but they CAN return
if(!is_in_host())
return FALSE
if(!force && recovering)
if(hostchosen)
to_chat(host, "<span class='sevtug'>[true_name] is too weak to come forth!</span>")
else
to_chat(host, "<span class='sevtug'>[true_name] tries to emerge to protect you, but it's too weak!</span>")
to_chat(src, "<span class='userdanger'>You try to come forth, but you're too weak!</span>")
return FALSE
if(!force)
if(hostchosen) //guardian approved
to_chat(host, "<span class='sevtug'>Your words echo with power as [true_name] emerges from your body!</span>")
else
to_chat(host, "<span class='sevtug'>[true_name] emerges from your body to protect you!</span>")
forceMove(host.loc)
visible_message("<span class='warning'>[host]'s skin glows red as [name] emerges from their body!</span>", "<span class='sevtug_small'>You exit the safety of [host]'s body!</span>")
return TRUE
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/get_alt_name()
return " ([text2ratvar(true_name)])"
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/is_in_host() //Checks if the guardian is inside of their host
return host && loc == host
//HOST ACTIONS
//Summon guardian action: Calls forth or recalls your guardian
/datum/action/innate/summon_guardian
name = "Force Guardian to Emerge/Recall"
desc = "Allows you to force your clockwork guardian to emerge or recall as required."
button_icon_state = "clockwork_marauder"
background_icon_state = "bg_clock"
check_flags = AB_CHECK_CONSCIOUS
buttontooltipstyle = "clockcult"
var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/linked_guardian
var/list/defend_phrases = list("Defend me", "Come forth", "Assist me", "Protect me", "Give aid", "Help me")
var/list/return_phrases = list("Return", "Return to me", "Your job is done", "You have served", "Come back", "Retreat")
/datum/action/innate/summon_guardian/IsAvailable()
if(!linked_guardian)
return FALSE
if(isliving(owner))
var/mob/living/L = owner
if(!L.can_speak_vocal() || L.stat)
return FALSE
return ..()
/datum/action/innate/summon_guardian/Activate()
if(linked_guardian.is_in_host())
clockwork_say(owner, text2ratvar("[pick(defend_phrases)], [linked_guardian.true_name]!"))
linked_guardian.emerge_from_host(TRUE)
else
clockwork_say(owner, text2ratvar("[pick(return_phrases)], [linked_guardian.true_name]!"))
linked_guardian.return_to_host()
return TRUE
//Linked Minds action: talks to your guardian
/datum/action/innate/linked_minds
name = "Linked Minds"
desc = "Allows you to silently communicate with your guardian."
button_icon_state = "linked_minds"
background_icon_state = "bg_clock"
check_flags = AB_CHECK_CONSCIOUS
buttontooltipstyle = "clockcult"
var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/linked_guardian
/datum/action/innate/linked_minds/IsAvailable()
if(!linked_guardian)
return FALSE
return ..()
/datum/action/innate/linked_minds/Activate()
var/message = stripped_input(owner, "Enter a message to tell your guardian.", "Telepathy")
if(!owner || !message)
return FALSE
if(!linked_guardian)
to_chat(owner, "<span class='warning'>Your guardian seems to have been destroyed!</span>")
return FALSE
var/name_part = "<span class='sevtug'>Servant [findtextEx(owner.name, owner.real_name) ? "[owner.name]" : "[owner.real_name] (as [owner.name])"]</span>"
message = "<span class='sevtug_small'>\"[message]\"</span>" //Processed output
to_chat(owner, "[name_part]<span class='sevtug_small'>:</span> [message]")
to_chat(linked_guardian, "[name_part]<span class='sevtug_small'>:</span> [message]")
for(var/M in GLOB.mob_list)
if(isobserver(M))
var/link = FOLLOW_LINK(M, src)
to_chat(M, "[link] [name_part] <span class='sevtug_small'>(to</span> <span class='sevtug'>[linked_guardian] ([linked_guardian.true_name])</span><span class='sevtug_small'>):</span> [message]")
return TRUE

View File

@@ -3,8 +3,9 @@ Tiers and Requirements
Pieces of scripture require certain follower counts, contruction value, and active caches in order to recite.
Drivers: Unlocked by default
Scripts: 5 servants and a cache
Applications: 8 servants, 3 caches, and 100 CV
Scripts: 35k power or one convert
Applications: 50k or three converts
Judgement 5 converts
*/
/datum/clockwork_scripture
@@ -129,11 +130,11 @@ Applications: 8 servants, 3 caches, and 100 CV
SEND_SOUND(invoker, sound('sound/magic/clockwork/invoke_general.ogg'))
return TRUE
/datum/clockwork_scripture/proc/check_offstation_penalty()
/datum/clockwork_scripture/proc/check_offstation_penalty()//don't cast spells away from the station
var/turf/T = get_turf(invoker)
if(!T || (!is_centcom_level(T.z) && !is_station_level(T.z) && !is_mining_level(T.z) && !is_reebe(T.z)))
channel_time *= 2
power_cost *= 2
channel_time *= 3
power_cost *= 3
return TRUE
/datum/clockwork_scripture/proc/check_special_requirements() //Special requirements for scriptures, checked multiple times during invocation

View File

@@ -1,5 +1,5 @@
//////////////////
// APPLICATIONS //
// APPLICATIONS // For various structures and base building, as well as advanced power generation.
//////////////////
@@ -23,6 +23,37 @@
quickbind = TRUE
quickbind_desc = "Creates a Sigil of Transmission, which can drain and will store power for clockwork structures."
//Prolonging Prism: Creates a prism that will delay the shuttle at a power cost
/datum/clockwork_scripture/create_object/prolonging_prism
descname = "Powered Structure, Delay Emergency Shuttles"
name = "Prolonging Prism"
desc = "Creates a mechanized prism which will delay the arrival of an emergency shuttle by 2 minutes at a massive power cost."
invocations = list("May this prism...", "...grant us time to enact his will!")
channel_time = 80
power_cost = 300
object_path = /obj/structure/destructible/clockwork/powered/prolonging_prism
creator_message = "<span class='brass'>You form a prolonging prism, which will delay the arrival of an emergency shuttle at a massive power cost.</span>"
observer_message = "<span class='warning'>An onyx prism forms in midair and sprouts tendrils to support itself!</span>"
invokers_required = 2
multiple_invokers_used = TRUE
usage_tip = "The power cost to delay a shuttle increases based on the number of times activated."
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
primary_component = VANGUARD_COGWHEEL
sort_priority = 4
important = TRUE
quickbind = TRUE
quickbind_desc = "Creates a Prolonging Prism, which will delay the arrival of an emergency shuttle by 2 minutes at a massive power cost."
/datum/clockwork_scripture/create_object/prolonging_prism/check_special_requirements()
if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
to_chat(invoker, "<span class='inathneq'>\"It is too late to construct one of these, champion.\"</span>")
return FALSE
var/turf/T = get_turf(invoker)
if(!T || !is_station_level(T.z))
to_chat(invoker, "<span class='inathneq'>\"You must be on the station to construct one of these, champion.\"</span>")
return FALSE
return ..()
//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
/datum/clockwork_scripture/create_object/mania_motor
@@ -44,6 +75,7 @@
sort_priority = 2
quickbind = TRUE
quickbind_desc = "Creates a Mania Motor, which causes minor damage and negative mental effects in non-Servants."
requires_full_power = TRUE
//Clockwork Obelisk: Creates a powerful obelisk that can be used to broadcast messages or open a gateway to any servant or clockwork obelisk at a power cost.
@@ -67,6 +99,64 @@
quickbind = TRUE
quickbind_desc = "Creates a Clockwork Obelisk, which can send messages or open Spatial Gateways with power."
//Memory Allocation: Finds a willing ghost and makes them into a clockwork guardian for the invoker.
/datum/clockwork_scripture/memory_allocation
descname = "Personal Guardian, A Peice Of Your Mind."
name = "Memory Allocation"
desc = "Allocates part of your consciousness to a Clockwork Guardian, a variant of Marauder that lives within you, able to be \
called forth by Speaking its True Name or if you become exceptionally low on health.<br>\
If it remains close to you, you will gradually regain health up to a low amount, but it will die if it goes too far from you."
invocations = list("Fright's will...", "...call forth...")
channel_time = 100
power_cost = 8000
usage_tip = "guardians are useful as personal bodyguards and frontline warriors."
tier = SCRIPTURE_APPLICATION
primary_component = GEIS_CAPACITOR
sort_priority = 5
/datum/clockwork_scripture/memory_allocation/check_special_requirements()
for(var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/M in GLOB.all_clockwork_mobs)
if(M.host == invoker)
to_chat(invoker, "<span class='warning'>You can only house one guardian at a time!</span>")
return FALSE
return TRUE
/datum/clockwork_scripture/memory_allocation/scripture_effects()
return create_guardian()
/datum/clockwork_scripture/memory_allocation/proc/create_guardian()
invoker.visible_message("<span class='warning'>A purple tendril appears from [invoker]'s [slab.name] and impales itself in [invoker.p_their()] forehead!</span>", \
"<span class='sevtug'>A tendril flies from [slab] into your forehead. You begin waiting while it painfully rearranges your thought pattern...</span>")
//invoker.notransform = TRUE //Vulnerable during the process
slab.busy = "Thought Modification in progress"
if(!do_after(invoker, 50, target = invoker))
invoker.visible_message("<span class='warning'>The tendril, covered in blood, retracts from [invoker]'s head and back into the [slab.name]!</span>", \
"<span class='userdanger'>Total agony overcomes you as the tendril is forced out early!</span>")
invoker.Knockdown(100)
invoker.apply_damage(50, BRUTE, "head")//Sevtug leaves a gaping hole in your face if interrupted.
slab.busy = null
return FALSE
clockwork_say(invoker, text2ratvar("...the mind made..."))
//invoker.notransform = FALSE
slab.busy = "Guardian Selection in progress"
if(!check_special_requirements())
return FALSE
to_chat(invoker, "<span class='warning'>The tendril shivers slightly as it selects a guardian...</span>")
var/list/marauder_candidates = pollGhostCandidates("Do you want to play as the clockwork guardian of [invoker.real_name]?", ROLE_SERVANT_OF_RATVAR, null, FALSE, 50, POLL_IGNORE_HOLOPARASITE)
if(!check_special_requirements())
return FALSE
if(!marauder_candidates.len)
invoker.visible_message("<span class='warning'>The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!</span>", \
"<span class='warning'>The tendril was unsuccessful! Perhaps you should try again another time.</span>")
return FALSE
clockwork_say(invoker, text2ratvar("...sword and shield!"))
var/mob/dead/observer/theghost = pick(marauder_candidates)
var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/M = new(invoker)
M.key = theghost.key
M.bind_to_host(invoker)
invoker.visible_message("<span class='warning'>The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!</span>", \
"<span class='sevtug'>[M.true_name], a clockwork guardian, has taken up residence in your mind. Communicate with it via the \"Linked Minds\" action button.</span>")
return TRUE
//Clockwork Marauder: Creates a construct shell for a clockwork marauder, a well-rounded frontline fighter.
/datum/clockwork_scripture/create_object/construct/clockwork_marauder
@@ -81,7 +171,7 @@
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
primary_component = BELLIGERENT_EYE
sort_priority = 4
sort_priority = 6
quickbind = TRUE
quickbind_desc = "Creates a clockwork marauder, used for frontline combat."
object_path = /obj/item/clockwork/construct_chassis/clockwork_marauder
@@ -117,14 +207,13 @@
/datum/clockwork_scripture/create_object/summon_arbiter
descname = "Powerful Assault Mech"
name = "Summon Neovgre, the Anima Bulwark"
desc = "Calls forth the mighty Anima Bulwark, a weapon of unmatched power,\
mech with superior defensive and offensive capabilities. It will \
desc = "Calls forth the mighty Anima Bulwark, a mech with superior defensive and offensive capabilities. It will \
steadily regenerate HP and triple its regeneration speed while standing \
on a clockwork tile. It will automatically draw power from nearby sigils of \
transmission should the need arise. Its Arbiter laser cannon can decimate foes \
from a range and is capable of smashing through any barrier presented to it. \
Be warned, choosing to pilot Neovgre is a lifetime commitment, once you are \
in you cannot leave and when it is destroyed it will explode catastrophically with you inside."
Be warned however, choosing to pilot Neovgre is a lifetime commitment, once you are \
in you cannot leave and when it is destroyed it will explode catastrophically, with you inside."
invocations = list("By the strength of the alloy...!!", "...call forth the Arbiter!!")
channel_time = 200 // This is a strong fucking weapon, 20 seconds channel time is getting off light I tell ya.
power_cost = 75000 //75 KW
@@ -134,7 +223,7 @@
object_path = /obj/mecha/combat/neovgre
tier = SCRIPTURE_APPLICATION
primary_component = BELLIGERENT_EYE
sort_priority = 2
sort_priority = 7
creator_message = "<span class='brass'>Neovgre, the Anima Bulwark towers over you... your enemies reckoning has come.</span>"
/datum/clockwork_scripture/create_object/summon_arbiter/check_special_requirements()

View File

@@ -1,5 +1,5 @@
/////////////////
// CYBORG ONLY //
// CYBORG ONLY // Cyborgs only, fleshed ones.
/////////////////
//Linked Vanguard: grants Vanguard to the invoker and a target

View File

@@ -1,5 +1,5 @@
/////////////
// DRIVERS //
// DRIVERS // Starter spells
/////////////
//Stargazer: Creates a stargazer, a cheap power generator that utilizes starlight.
@@ -97,7 +97,7 @@
desc = "Charges your slab with divine energy, allowing you to overwhelm a target with Ratvar's light."
invocations = list("Divinity, show them your light!")
whispered = TRUE
channel_time = 20 // I think making kindle channel a third of the time less is a good make up for the fact that it silences people for such a little amount of time.
channel_time = 10 // I think making kindle channel a third of the time less is a good make up for the fact that it silences people for such a little amount of time.
power_cost = 125
usage_tip = "The light can be used from up to two tiles away. Damage taken will GREATLY REDUCE the stun's duration."
tier = SCRIPTURE_DRIVER
@@ -113,7 +113,6 @@
quickbind = TRUE
quickbind_desc = "Stuns and mutes a target from a short range."
//Hateful Manacles: Applies restraints from melee over several seconds. The restraints function like handcuffs and break on removal.
/datum/clockwork_scripture/ranged_ability/hateful_manacles
descname = "Handcuffs"
@@ -192,43 +191,39 @@
Click your slab to cancel.</b></span>"
/*//commenting this out until its reworked to actually do random teleports
//Abscond: Used to return to Reebe.
/datum/clockwork_scripture/abscond
descname = "Return to Reebe"
descname = "Safety warp, teleports you somewhere random. moderately high power cost to use."
name = "Abscond"
desc = "Yanks you through space, returning you to home base."
desc = "Yanks you through space, putting you in hopefully a safe location."
invocations = list("As we bid farewell, and return to the stars...", "...we shall find our way home.")
whispered = TRUE
channel_time = 50
power_cost = 5
special_power_text = "POWERCOST to bring pulled creature"
special_power_cost = ABSCOND_ABDUCTION_COST
channel_time = 3.5
power_cost = 10000
usage_tip = "This can't be used while on Reebe, for obvious reasons."
tier = SCRIPTURE_DRIVER
primary_component = GEIS_CAPACITOR
sort_priority = 9
important = TRUE
quickbind = TRUE
quickbind_desc = "Returns you to Reebe."
quickbind_desc = "Teleports you somewhere random, or to an active Ark if one exists. Use in emergencies."
var/client_color
requires_full_power = TRUE
/datum/clockwork_scripture/abscond/check_special_requirements()
if(is_reebe(invoker.z))
to_chat(invoker, "<span class='danger'>You're already at Reebe.</span>")
to_chat(invoker, "<span class='danger'>You're at Reebe, attempting to warp in the void could cause you to share your masters fate of banishment!.</span>")
return
if(!isturf(invoker.loc))
to_chat(invoker, "<span class='danger'>You must be visible to return!</span>")
to_chat(invoker, "<span class='danger'>You must be visible to warp!</span>")
return
return TRUE
/datum/clockwork_scripture/abscond/recital()
client_color = invoker.client.color
animate(invoker.client, color = "#AF0AAF", time = 50)
. = ..()
/datum/clockwork_scripture/abscond/scripture_effects()
var/mob/living/pulled_mob = (invoker.pulling && isliving(invoker.pulling) && get_clockwork_power(ABSCOND_ABDUCTION_COST)) ? invoker.pulling : null
var/turf/T
if(GLOB.ark_of_the_clockwork_justiciar)
T = get_step(GLOB.ark_of_the_clockwork_justiciar, SOUTH)
@@ -237,21 +232,12 @@
if(!do_teleport(invoker, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE))
return
invoker.visible_message("<span class='warning'>[invoker] flickers and phases out of existence!</span>", \
"<span class='bold sevtug_small'>You feel a dizzying sense of vertigo as you're yanked back to Reebe!</span>")
"<span class='bold sevtug_small'>You feel a dizzying sense of vertigo as you're yanked through the fabric of reality!</span>")
T.visible_message("<span class='warning'>[invoker] flickers and phases into existence!</span>")
playsound(invoker, 'sound/magic/magic_missile.ogg', 50, TRUE)
playsound(T, 'sound/magic/magic_missile.ogg', 50, TRUE)
do_sparks(5, TRUE, invoker)
do_sparks(5, TRUE, T)
if(pulled_mob && do_teleport(pulled_mob, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE))
adjust_clockwork_power(-special_power_cost)
invoker.start_pulling(pulled_mob) //forcemove resets pulls, so we need to re-pull
if(invoker.client)
animate(invoker.client, color = client_color, time = 25)
/datum/clockwork_scripture/abscond/scripture_fail()
if(invoker && invoker.client)
animate(invoker.client, color = client_color, time = 10)
do_sparks(5, TRUE, T)*/
//Replicant: Creates a new clockwork slab.
@@ -265,7 +251,7 @@
whispered = TRUE
object_path = /obj/item/clockwork/slab
creator_message = "<span class='brass'>You copy a piece of replicant alloy and command it into a new slab.</span>"
usage_tip = "This is inefficient as a way to produce components, as the slab produced must be held by someone with no other slabs to produce components."
usage_tip = "This is inefficient as a way to produce power, as the slab produced must be held by someone with no other slabs to produce any."
tier = SCRIPTURE_DRIVER
space_allowed = TRUE
primary_component = GEIS_CAPACITOR
@@ -293,3 +279,50 @@
sort_priority = 11
quickbind = TRUE
quickbind_desc = "Creates a pair of Wraith Spectacles, which grant true sight but cause gradual vision loss."
//Spatial Gateway: Allows the invoker to teleport themselves and any nearby allies to a conscious servant or clockwork obelisk.
/datum/clockwork_scripture/spatial_gateway
descname = "Teleport Gate"
name = "Spatial Gateway"
desc = "Tears open a miniaturized gateway in spacetime to any conscious servant that can transport objects or creatures to its destination. \
Each servant assisting in the invocation adds one additional use and four additional seconds to the gateway's uses and duration."
invocations = list("Spatial Gateway...", "...activate!")
channel_time = 30
power_cost = 400
whispered = TRUE
multiple_invokers_used = TRUE
multiple_invokers_optional = TRUE
usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal."
tier = SCRIPTURE_DRIVER
primary_component = GEIS_CAPACITOR
sort_priority = 9
quickbind = TRUE
quickbind_desc = "Allows you to create a one-way Spatial Gateway to a living Servant or Clockwork Obelisk."
/datum/clockwork_scripture/spatial_gateway/check_special_requirements()
if(!isturf(invoker.loc))
to_chat(invoker, "<span class='warning'>You must not be inside an object to use this scripture!</span>")
return FALSE
var/other_servants = 0
for(var/mob/living/L in GLOB.alive_mob_list)
if(is_servant_of_ratvar(L) && !L.stat && L != invoker)
other_servants++
for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in GLOB.all_clockwork_objects)
if(O.anchored)
other_servants++
if(!other_servants)
to_chat(invoker, "<span class='warning'>There are no other conscious servants or anchored clockwork obelisks!</span>")
return FALSE
return TRUE
/datum/clockwork_scripture/spatial_gateway/scripture_effects()
var/portal_uses = 0
var/duration = 0
for(var/mob/living/L in range(1, invoker))
if(!L.stat && is_servant_of_ratvar(L))
portal_uses++
duration += 40 //4 seconds
if(GLOB.ratvar_awakens)
portal_uses = max(portal_uses, 100) //Very powerful if Ratvar has been summoned
duration = max(duration, 100)
return slab.procure_gateway(invoker, duration, portal_uses)

View File

@@ -0,0 +1,44 @@
///////////////
// JUDGEMENT // For the big game changing things. TODO: Summonable generals, just need mob sprites for them.
///////////////
//Ark of the Clockwork Justiciar: Creates a Gateway to the Celestial Derelict, summoning ratvar.
/datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar
descname = "Structure, Win Condition"
name = "Ark of the Clockwork Justiciar"
desc = "Tears apart a rift in spacetime to Reebe, the Celestial Derelict, using a massive amount of power.\n\
This gateway will, after some time, call forth Ratvar from his exile and massively empower all scriptures and tools."
invocations = list("ARMORER! FRIGHT! AMPERAGE! VANGUARD! WE CALL UPON YOU!!", \
"THE TIME HAS COME FOR OUR MASTER TO BREAK THE CHAINS OF EXILE!!", \
"LEND US YOUR AID! ENGINE COMES!!")
channel_time = 150
power_cost = 70000 //70 KW. It's literally the thing wrenching the god out of another dimension why wouldn't it be costly.
invokers_required = 6
multiple_invokers_used = TRUE
object_path = /obj/structure/destructible/clockwork/massive/celestial_gateway
creator_message = "<span class='heavy_brass'>The Ark swirls into existance before you with the help of the Generals. After all this time, he shall, finally, be free</span>"
usage_tip = "The gateway is completely vulnerable to attack during its five-minute duration. It will periodically give indication of its general position to everyone on the station \
as well as being loud enough to be heard throughout the entire sector. Defend it with your life!"
tier = SCRIPTURE_APPLICATION
sort_priority = 8
requires_full_power = TRUE
/datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar/check_special_requirements()
if(!slab.no_cost)
if(GLOB.ratvar_awakens)
to_chat(invoker, "<span class='big_brass'>\"I am already here, there is no point in that.\"</span>")
return FALSE
for(var/obj/structure/destructible/clockwork/massive/celestial_gateway/G in GLOB.all_clockwork_objects)
var/area/gate_area = get_area(G)
to_chat(invoker, "<span class='userdanger'>There is already an Ark at [gate_area.map_name]!</span>")
return FALSE
var/area/A = get_area(invoker)
var/turf/T = get_turf(invoker)
if(!T || !is_station_level(T.z) || istype(A, /area/shuttle) || !A.blob_allowed)
to_chat(invoker, "<span class='warning'>You must be on the station to activate the Ark!</span>")
return FALSE
if(GLOB.clockwork_gateway_activated)
to_chat(invoker, "<span class='warning'>Ratvar's recent banishment renders him too weak to be wrung forth from Reebe!</span>")
return FALSE
return ..()

View File

@@ -1,5 +1,5 @@
/////////////
// SCRIPTS //
// SCRIPTS // Various miscellanious spells for offense/defense/construction.
/////////////
@@ -217,53 +217,6 @@
weapon_type = /obj/item/clockwork/weapon/ratvarian_spear
//Spatial Gateway: Allows the invoker to teleport themselves and any nearby allies to a conscious servant or clockwork obelisk.
/datum/clockwork_scripture/spatial_gateway
descname = "Teleport Gate"
name = "Spatial Gateway"
desc = "Tears open a miniaturized gateway in spacetime to any conscious servant that can transport objects or creatures to its destination. \
Each servant assisting in the invocation adds one additional use and four additional seconds to the gateway's uses and duration."
invocations = list("Spatial Gateway...", "...activate!")
channel_time = 80
power_cost = 400
multiple_invokers_used = TRUE
multiple_invokers_optional = TRUE
usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal."
tier = SCRIPTURE_SCRIPT
primary_component = GEIS_CAPACITOR
sort_priority = 9
quickbind = TRUE
quickbind_desc = "Allows you to create a one-way Spatial Gateway to a living Servant or Clockwork Obelisk."
/datum/clockwork_scripture/spatial_gateway/check_special_requirements()
if(!isturf(invoker.loc))
to_chat(invoker, "<span class='warning'>You must not be inside an object to use this scripture!</span>")
return FALSE
var/other_servants = 0
for(var/mob/living/L in GLOB.alive_mob_list)
if(is_servant_of_ratvar(L) && !L.stat && L != invoker)
other_servants++
for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in GLOB.all_clockwork_objects)
if(O.anchored)
other_servants++
if(!other_servants)
to_chat(invoker, "<span class='warning'>There are no other conscious servants or anchored clockwork obelisks!</span>")
return FALSE
return TRUE
/datum/clockwork_scripture/spatial_gateway/scripture_effects()
var/portal_uses = 0
var/duration = 0
for(var/mob/living/L in range(1, invoker))
if(!L.stat && is_servant_of_ratvar(L))
portal_uses++
duration += 40 //4 seconds
if(GLOB.ratvar_awakens)
portal_uses = max(portal_uses, 100) //Very powerful if Ratvar has been summoned
duration = max(duration, 100)
return slab.procure_gateway(invoker, duration, portal_uses)
//Mending Mantra: Channeled for up to ten times over twenty seconds to repair structures and heal allies
/datum/clockwork_scripture/channeled/mending_mantra
descname = "Channeled, Area Healing and Repair"
@@ -487,3 +440,26 @@
invoker.light_range = 0
invoker.update_light()
return ..()
//Belligerent: Channeled for up to fifteen times over thirty seconds. Forces non-servants that can hear the chant to walk, doing minor damage. Nar-Sian cultists are burned.
/datum/clockwork_scripture/channeled/belligerent
descname = "Channeled, Area Slowdown"
name = "Belligerent"
desc = "Forces all nearby non-servants to walk rather than run, doing minor damage. Chanted every two seconds for up to thirty seconds."
chant_invocations = list("Punish their blindness!", "Take time, make slow!", "Kneel before The Justiciar!", "Halt their charges!", "Cease the tides!")
chant_amount = 15
chant_interval = 20
channel_time = 20
power_cost = 300
usage_tip = "Useful for crowd control in a populated area and disrupting mass movement."
tier = SCRIPTURE_DRIVER
primary_component = BELLIGERENT_EYE
sort_priority = 1
quickbind = TRUE
quickbind_desc = "Forces nearby non-Servants to walk, doing minor damage with each chant.<br><b>Maximum 15 chants.</b>"
/datum/clockwork_scripture/channeled/belligerent/chant_effects(chant_number)
for(var/mob/living/carbon/C in hearers(7, invoker))
C.apply_status_effect(STATUS_EFFECT_BELLIGERENT)
new /obj/effect/temp_visual/ratvar/belligerent(get_turf(invoker))
return TRUE

View File

@@ -1,5 +1,3 @@
#define ARK_GRACE_PERIOD 300 //In seconds, how long the crew has before the Ark truly "begins"
/proc/clockwork_ark_active() //A helper proc so the Ark doesn't have to be typecast every time it's checked; returns null if there is no Ark and its active var otherwise
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
if(!G)
@@ -11,7 +9,7 @@
name = "\improper Ark of the Clockwork Justicar"
desc = "A massive, hulking amalgamation of parts. It seems to be maintaining a very unstable bluespace anomaly."
clockwork_desc = "Nezbere's magnum opus: a hulking clockwork machine capable of combining bluespace and steam power to summon Ratvar. Once activated, \
its instability will cause one-way bluespace rifts to open across the station to the City of Cogs, so be prepared to defend it at all costs."
its instability will alert the entire area, so be prepared to defend it at all costs."
max_integrity = 500
mouse_opacity = MOUSE_OPACITY_OPAQUE
icon = 'icons/effects/clockwork_effects.dmi'
@@ -22,9 +20,8 @@
immune_to_servant_attacks = TRUE
var/active = FALSE
var/progress_in_seconds = 0 //Once this reaches GATEWAY_RATVAR_ARRIVAL, it's game over
var/grace_period = ARK_GRACE_PERIOD //This exists to allow the crew to gear up and prepare for the invasion
var/initial_activation_delay = -1 //How many seconds the Ark will have initially taken to activate
var/seconds_until_activation = -1 //How many seconds until the Ark activates; if it should never activate, set this to -1
var/initial_activation_delay = 5 //How many seconds the Ark will have initially taken to activate
var/seconds_until_activation = 5 //How many seconds until the Ark activates; if it should never activate, set this to -1
var/purpose_fulfilled = FALSE
var/first_sound_played = FALSE
var/second_sound_played = FALSE
@@ -38,10 +35,21 @@
/obj/structure/destructible/clockwork/massive/celestial_gateway/Initialize()
. = ..()
INVOKE_ASYNC(src, .proc/spawn_animation)
glow = new(get_turf(src))
if(!GLOB.ark_of_the_clockwork_justiciar)
GLOB.ark_of_the_clockwork_justiciar = src
START_PROCESSING(SSprocessing, src)
/obj/structure/destructible/clockwork/massive/celestial_gateway/on_attack_hand(mob/user, act_intent, unarmed_attack_flags)
if(!active && is_servant_of_ratvar(user) && user.canUseTopic(src, !issilicon(user), NO_DEXTERY))
if(alert(user, "Are you sure you want to activate the ark? Once enabled, there will be no turning back.", "Enabling the ark", "Activate!", "Cancel") == "Activate!")
if(active)
return
log_game("[key_name(user)] has activated an Ark of the Clockwork Justicar at [COORD(src)].")
START_PROCESSING(SSprocessing, src)
SSshuttle.registerHostileEnvironment(src)
else
to_chat(user, "<span class='brass'>You decide against activating the ark.. for now.</span>")
/obj/structure/destructible/clockwork/massive/celestial_gateway/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
@@ -49,7 +57,7 @@
flick("clockwork_gateway_damaged", glow)
playsound(src, 'sound/machines/clockcult/ark_damage.ogg', 75, FALSE)
if(last_scream < world.time)
audible_message("<span class='boldwarning'>An unearthly screaming sound resonates throughout Reebe!</span>")
audible_message("<span class='boldwarning'>An unearthly screaming sound resonates throughout the area!</span>")
for(var/V in GLOB.player_list)
var/mob/M = V
var/turf/T = get_turf(M)
@@ -60,31 +68,19 @@
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/final_countdown(ark_time) //WE'RE LEAVING TOGETHEEEEEEEEER
if(!ark_time)
ark_time = 30 //minutes
initial_activation_delay = ark_time * 60
seconds_until_activation = ark_time * 60 //60 seconds in a minute * number of minutes
ark_time = 5 //5 minutes
for(var/obj/item/clockwork/construct_chassis/cogscarab/C in GLOB.all_clockwork_objects)
C.infinite_resources = FALSE
GLOB.servants_active = TRUE
SSshuttle.registerHostileEnvironment(src)
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/cry_havoc()
visible_message("<span class='boldwarning'>[src] shudders and roars to life, its parts beginning to whirr and screech!</span>")
hierophant_message("<span class='bold large_brass'>The Ark is activating! You will be transported there soon!</span>")
for(var/mob/M in GLOB.player_list)
var/turf/T = get_turf(M)
if(is_servant_of_ratvar(M) || isobserver(M) || (T && T.z == z))
M.playsound_local(M, 'sound/magic/clockwork/ark_activation_sequence.ogg', 30, FALSE, pressure_affected = FALSE)
addtimer(CALLBACK(src, .proc/let_slip_the_dogs), 300)
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/let_slip_the_dogs()
spawn_animation()
first_sound_played = TRUE
active = TRUE
visible_message("<span class='boldwarning'>[src] shudders and roars to life, its parts beginning to whirr and screech!</span>")
priority_announce("Massive [Gibberish("bluespace", 100)] anomaly detected on all frequencies. All crew are directed to \
@!$, [text2ratvar("PURGE ALL UNTRUTHS")] <&. the anomalies and destroy their source to prevent further damage to corporate property. This is \
not a drill.[grace_period ? " Estimated time of appearance: [grace_period] seconds. Use this time to prepare for an attack on [station_name()]." : ""]", \
"Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ark_activation.ogg')
not a drill.", "Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ark_activation_sequence.ogg')
set_security_level("delta")
for(var/V in SSticker.mode.servants_of_ratvar)
var/datum/mind/M = V
@@ -92,15 +88,6 @@
continue
if(ishuman(M.current))
M.current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER))
for(var/V in GLOB.brass_recipes)
var/datum/stack_recipe/R = V
if(!R)
continue
if(R.title == "wall gear")
R.time *= 2 //Building walls becomes slower when the Ark activates
mass_recall()
recalls_remaining++ //So it doesn't use up a charge
var/turf/T = get_turf(src)
var/list/open_turfs = list()
for(var/turf/open/OT in orange(1, T))
@@ -110,14 +97,35 @@
for(var/mob/living/L in T)
L.forceMove(pick(open_turfs))
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/open_portal(turf/T)
new/obj/effect/clockwork/city_of_cogs_rift(T)
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/spawn_animation()
hierophant_message("<span class='bold large_brass'>The Ark has activated! [grace_period ? "You have [round(grace_period / 60)] minutes until the crew invades! " : ""]Defend it at all costs!</span>", FALSE, src)
sound_to_playing_players(volume = 10, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_charging.ogg', TRUE))
seconds_until_activation = 0
SSshuttle.registerHostileEnvironment(src)
var/turf/T = get_turf(src)
new/obj/effect/clockwork/general_marker/inathneq(T)
hierophant_message("<span class='inathneq'>\"[text2ratvar("Engine, come forth and show your servants your mercy")]!\"</span>")
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 30, 0)
sleep(10)
new/obj/effect/clockwork/general_marker/sevtug(T)
hierophant_message("<span class='sevtug'>\"[text2ratvar("Engine, come forth and show this station your decorating skills")]!\"</span>")
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 45, 0)
sleep(10)
new/obj/effect/clockwork/general_marker/nezbere(T)
hierophant_message("<span class='nezbere'>\"[text2ratvar("Engine, come forth and shine your light across this realm")]!!\"</span>")
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 60, 0)
sleep(10)
new/obj/effect/clockwork/general_marker/nzcrentr(T)
hierophant_message("<span class='nzcrentr'>\"[text2ratvar("Engine, come forth")].\"</span>")
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 75, 0)
sleep(10)
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 100, 0)
var/list/open_turfs = list()
for(var/turf/open/OT in orange(1, T))
if(!is_blocked_turf(OT, TRUE))
open_turfs |= OT
if(open_turfs.len)
for(var/mob/living/L in T)
L.forceMove(pick(open_turfs))
glow = new(get_turf(src))
var/area/gate_area = get_area(src)
hierophant_message("<span class='large_brass'><b>An Ark of the Clockwork Justicar has been created in [gate_area.map_name]!</b></span>", FALSE, src)
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/initiate_mass_recall()
recalling = TRUE
@@ -141,35 +149,22 @@
transform = matrix() * 2
animate(src, transform = matrix() * 0.5, time = 30, flags = ANIMATION_END_NOW)
/obj/structure/destructible/clockwork/massive/celestial_gateway/Destroy()
obj/structure/destructible/clockwork/massive/celestial_gateway/Destroy()
STOP_PROCESSING(SSprocessing, src)
if(!purpose_fulfilled)
var/area/gate_area = get_area(src)
hierophant_message("<span class='large_brass'><b>An Ark of the Clockwork Justicar has fallen at [gate_area.map_name]!</b></span>")
send_to_playing_players(sound(null, 0, channel = CHANNEL_JUSTICAR_ARK))
var/was_stranded = SSshuttle.emergency.mode == SHUTTLE_STRANDED
SSshuttle.clearHostileEnvironment(src)
if(!purpose_fulfilled && istype(SSticker.mode, /datum/game_mode/clockwork_cult))
hierophant_message("<span class='bold large_brass'>The Ark has fallen!</span>")
sound_to_playing_players(null, channel = CHANNEL_JUSTICAR_ARK)
SSticker.force_ending = TRUE //rip
if(!was_stranded && !purpose_fulfilled)
priority_announce("Massive energy anomaly no longer on short-range scanners, bluespace distortions still detected.","Central Command Higher Dimensional Affairs")
if(glow)
qdel(glow)
glow = null
if(countdown)
qdel(countdown)
countdown = null
for(var/mob/L in GLOB.player_list)
var/turf/T = get_turf(L)
if(T && T.z == z)
var/atom/movable/target = L
if(isobj(L.loc))
target = L.loc
target.forceMove(get_turf(pick(GLOB.generic_event_spawns)))
L.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
L.clear_fullscreen("flash", 30)
if(isliving(L))
var/mob/living/LI = L
LI.Stun(50)
for(var/obj/effect/clockwork/city_of_cogs_rift/R in GLOB.all_clockwork_objects)
qdel(R)
if(GLOB.ark_of_the_clockwork_justiciar == src)
GLOB.ark_of_the_clockwork_justiciar = null
. = ..()
/obj/structure/destructible/clockwork/massive/celestial_gateway/deconstruct(disassembled = TRUE)
@@ -203,8 +198,6 @@
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_time(var/deciseconds = TRUE)
if(seconds_until_activation)
. = seconds_until_activation
else if(grace_period)
. = grace_period
else if(GATEWAY_RATVAR_ARRIVAL - progress_in_seconds > 0)
. = round(max((GATEWAY_RATVAR_ARRIVAL - progress_in_seconds) / (GATEWAY_SUMMON_RATE), 0), 1)
if(deciseconds)
@@ -213,8 +206,6 @@
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_text(s_on_time)
if(seconds_until_activation)
return "[get_arrival_time()][s_on_time ? "S" : ""]"
if(grace_period)
return "[get_arrival_time()][s_on_time ? "S" : ""]"
. = "IMMINENT"
if(!obj_integrity)
. = "DETONATING"
@@ -229,17 +220,14 @@
if(!active)
. += "<span class='big'><b>Time until the Ark's activation:</b> [DisplayTimeText(get_arrival_time())]</span>"
else
if(grace_period)
. += "<span class='big'><b>Crew grace period time remaining:</b> [DisplayTimeText(get_arrival_time())]</span>"
else
. += "<span class='big'><b>Time until Ratvar's arrival:</b> [DisplayTimeText(get_arrival_time())]</span>"
switch(progress_in_seconds)
if(-INFINITY to GATEWAY_REEBE_FOUND)
. += "<span class='heavy_brass'>The Ark is feeding power into the bluespace field.</span>"
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
. += "<span class='heavy_brass'>The field is ripping open a copy of itself in Ratvar's prison.</span>"
if(GATEWAY_RATVAR_COMING to INFINITY)
. += "<span class='heavy_brass'>With the bluespace field established, Ratvar is preparing to come through!</span>"
. += "<span class='big'><b>Time until Ratvar's arrival:</b> [DisplayTimeText(get_arrival_time())]</span>"
switch(progress_in_seconds)
if(-INFINITY to GATEWAY_REEBE_FOUND)
. += "<span class='heavy_brass'>The Ark is feeding power into the bluespace field.</span>"
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
. += "<span class='heavy_brass'>The field is ripping open a copy of itself in Ratvar's prison.</span>"
if(GATEWAY_RATVAR_COMING to INFINITY)
. += "<span class='heavy_brass'>With the bluespace field established, Ratvar is preparing to come through!</span>"
else
if(!active)
. += "<span class='warning'>Whatever it is, it doesn't seem to be active.</span>"
@@ -253,20 +241,14 @@
. += "<span class='boldwarning'>The anomaly is stable! Something is coming through!</span>"
/obj/structure/destructible/clockwork/massive/celestial_gateway/process()
if(seconds_until_activation == -1) //we never do anything
return
adjust_clockwork_power(2.5) //Provides weak power generation on its own
if(seconds_until_activation)
if(!countdown)
countdown = new(src)
countdown.start()
seconds_until_activation--
if(!GLOB.script_scripture_unlocked && initial_activation_delay * 0.5 > seconds_until_activation)
GLOB.script_scripture_unlocked = TRUE
hierophant_message("<span class='large_brass bold'>The Ark is halfway prepared. Script scripture is now available!</span>")
if(!seconds_until_activation)
cry_havoc()
seconds_until_activation = -1 //we'll set this after cry_havoc()
let_slip_the_dogs()
return
if(!first_sound_played || prob(7))
for(var/mob/M in GLOB.player_list)
@@ -285,6 +267,9 @@
if(!step_away(O, src, 2) || get_dist(O, src) < 2)
O.take_damage(50, BURN, "bomb")
O.update_icon()
conversion_pulse() //Converts the nearby area into clockcult-style
for(var/V in GLOB.player_list)
var/mob/M = V
var/turf/T = get_turf(M)
@@ -292,29 +277,24 @@
M.forceMove(get_step(src, SOUTH))
M.overlay_fullscreen("flash", /obj/screen/fullscreen/flash)
M.clear_fullscreen("flash", 5)
if(grace_period)
grace_period--
return
progress_in_seconds += GATEWAY_SUMMON_RATE
switch(progress_in_seconds)
if(-INFINITY to GATEWAY_REEBE_FOUND)
if(!second_sound_played)
for(var/V in GLOB.generic_event_spawns)
addtimer(CALLBACK(src, .proc/open_portal, get_turf(V)), rand(100, 600))
sound_to_playing_players('sound/magic/clockwork/invoke_general.ogg', 30, FALSE)
sound_to_playing_players(volume = 20, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_charging.ogg', TRUE))
sound_to_playing_players(volume = 10, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_charging.ogg', TRUE))
second_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_charging"
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
if(!third_sound_played)
sound_to_playing_players(volume = 25, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_active.ogg', TRUE))
sound_to_playing_players(volume = 30, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_active.ogg', TRUE))
third_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_active"
if(GATEWAY_RATVAR_COMING to GATEWAY_RATVAR_ARRIVAL)
if(!fourth_sound_played)
sound_to_playing_players(volume = 30, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_closing.ogg', TRUE))
sound_to_playing_players(volume = 70, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_closing.ogg', TRUE))
fourth_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_closing"
@@ -334,7 +314,6 @@
GLOB.clockwork_gateway_activated = TRUE
var/turf/T = SSmapping.get_station_center()
new /obj/structure/destructible/clockwork/massive/ratvar(T)
SSticker.force_ending = TRUE
var/x0 = T.x
var/y0 = T.y
for(var/I in spiral_range_turfs(255, T, tick_checked = TRUE))
@@ -349,6 +328,17 @@
T.ratvar_act(dist)
CHECK_TICK
//Converts nearby turfs into their clockwork equivalent, with ever-increasing range the closer the ark is to summoning Ratvar
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/conversion_pulse()
var/convert_dist = 1 + (round(FLOOR(progress_in_seconds, 15) * 0.067))
for(var/t in RANGE_TURFS(convert_dist, loc))
var/turf/T = t
if(!T)
continue
var/dist = cheap_hypotenuse(T.x, T.y, x, y)
if(dist < convert_dist)
T.ratvar_act(FALSE, TRUE, 3)
//ATTACK GHOST IGNORING PARENT RETURN VALUE
/obj/structure/destructible/clockwork/massive/celestial_gateway/attack_ghost(mob/user)
if(!IsAdminGhost(user))
@@ -361,9 +351,9 @@
if(alert(user, "You're REALLY SURE? This cannot be undone.", name, "Yes - Activate the Ark", "No") == "Yes - Activate the Ark")
message_admins("<span class='danger'>Admin [key_name_admin(user)] started the Ark's countdown!</span>")
log_admin("Admin [key_name(user)] started the Ark's countdown on a non-clockcult mode!")
to_chat(user, "<span class='userdanger'>The gamemode is now being treated as clockwork cult, and the Ark is counting down from 30 \
to_chat(user, "<span class='userdanger'>The gamemode is now being treated as clockwork cult, and the Ark is counting down from 5 \
minutes. You will need to create servant players yourself.</span>")
final_countdown(35)
final_countdown(5)

View File

@@ -41,6 +41,11 @@
affected += try_use_power(MIN_CLOCKCULT_POWER*4)
return affected
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/Destroy()
for(var/obj/effect/clockwork/spatial_gateway/SG in loc)
SG.ex_act(EXPLODE_DEVASTATE)
return ..()
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
@@ -48,7 +53,7 @@
if(!is_servant_of_ratvar(user) || !can_access_clockwork_power(src, hierophant_cost) || !anchored)
to_chat(user, "<span class='warning'>You place your hand on [src], but it doesn't react.</span>")
return
var/choice = alert(user,"You place your hand on [src]...",,"Hierophant Broadcast","Spatial Gateway","Cancel")
var/choice = alert(user,"You place your hand on [src]...",,"Hierophant Broadcast","Spatial Gateway","Cancel") //Will create a stable gateway instead if between two obelisks one of which is onstation and the other on reebe
switch(choice)
if("Hierophant Broadcast")
if(active)
@@ -96,7 +101,7 @@
if(!anchored)
return
var/obj/effect/clockwork/spatial_gateway/SG = locate(/obj/effect/clockwork/spatial_gateway) in loc
if(SG && SG.timerid) //it's a valid gateway, we're active
if(SG && (SG.timerid || SG.is_stable)) //it's a valid gateway, we're active
icon_state = active_icon
density = FALSE
active = TRUE

View File

@@ -27,9 +27,6 @@
if(C.clock_team.eminence)
to_chat(user, "<span class='warning'>There's already an Eminence!</span>")
return
if(!GLOB.servants_active)
to_chat(user, "<span class='warning'>The Ark isn't active!</span>")
return
if(eminence_nominee) //This could be one large proc, but is split into three for ease of reading
if(eminence_nominee == user)
cancelation(user)

View File

@@ -1,3 +1,5 @@
//Used to "declare war" against the station. The servants' equipment will be permanently supercharged, and the Ark given extra time to prepare.
//This will send an announcement to the station, meaning that they will be warned very early in advance about the impending attack.
/obj/structure/destructible/clockwork/heralds_beacon
@@ -108,5 +110,4 @@
to_chat(H, "<span class='bold alloy'>The beacon's power warps your body into a clockwork form! You are now immune to many hazards, and your body is more robust against damage!</span>")
H.set_species(/datum/species/golem/clockwork/no_scrap)
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
G.grace_period = FALSE //no grace period if we've declared war
G.recalls_remaining++

View File

@@ -0,0 +1,134 @@
//Prolonging Prism: A prism that consumes power to delay the shuttle
/obj/structure/destructible/clockwork/powered/prolonging_prism
name = "prolonging prism"
desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
clockwork_desc = "A powerful prism that will delay the arrival of an emergency shuttle."
icon_state = "prolonging_prism_inactive"
active_icon = "prolonging_prism"
inactive_icon = "prolonging_prism_inactive"
unanchored_icon = "prolonging_prism_unwrenched"
construction_value = 20
max_integrity = 125
break_message = "<span class='warning'>The prism falls to the ground with a heavy thud!</span>"
debris = list(/obj/item/clockwork/alloy_shards/small = 3, \
/obj/item/clockwork/alloy_shards/medium = 1, \
/obj/item/clockwork/alloy_shards/large = 1, \
/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism = 1)
var/static/power_refund = 250
var/static/delay_cost = 2000 //Updated power values for new-newclock. Easier to activate and sustain, you are quite literally pointing the entire station towards you as opposed to blood-delay after all.
var/static/delay_cost_increase = 1000
var/static/delay_remaining = 0
/obj/structure/destructible/clockwork/powered/prolonging_prism/examine(mob/user)
. = ..()
if(is_servant_of_ratvar(user) || isobserver(user))
if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
. += "<span class='inathneq'>An emergency shuttle has arrived and this prism is no longer useful; attempt to activate it to gain a partial refund of components used.</span>"
else
var/efficiency = get_efficiency_mod(TRUE)
. += "<span class='inathneq_small'>It requires at least <b>[DisplayPower(get_delay_cost())]</b> of power to attempt to delay the arrival of an emergency shuttle by <b>[2 * efficiency]</b> minutes.</span>"
. += "<span class='inathneq_small'>This cost increases by <b>[DisplayPower(delay_cost_increase)]</b> for every previous activation.</span>"
/obj/structure/destructible/clockwork/powered/prolonging_prism/forced_disable(bad_effects)
if(active)
if(bad_effects)
try_use_power(MIN_CLOCKCULT_POWER*4)
visible_message("<span class='warning'>[src] emits an airy chuckling sound and falls dark!</span>")
toggle()
return TRUE
/obj/structure/destructible/clockwork/powered/prolonging_prism/on_attack_hand(mob/living/user)
if(user.canUseTopic(src, !issilicon(user), NO_DEXTERY) && is_servant_of_ratvar(user))
if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
to_chat(user, "<span class='brass'>You break [src] apart, refunding some of the power used.</span>")
adjust_clockwork_power(power_refund)
take_damage(max_integrity)
return 0
if(active)
return 0
var/turf/T = get_turf(src)
if(!T || !is_station_level(T.z))
to_chat(user, "<span class='warning'>[src] must be on the station to function!</span>")
return 0
if(SSshuttle.emergency.mode != SHUTTLE_CALL)
to_chat(user, "<span class='warning'>No emergency shuttles are attempting to arrive at the station!</span>")
return 0
if(!try_use_power(get_delay_cost()))
to_chat(user, "<span class='warning'>[src] needs more power to function!</span>")
return 0
delay_cost += delay_cost_increase
delay_remaining += PRISM_DELAY_DURATION
toggle(0, user)
/obj/structure/destructible/clockwork/powered/prolonging_prism/process()
var/turf/own_turf = get_turf(src)
if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || !is_station_level(own_turf.z))
forced_disable(FALSE)
return
. = ..()
var/delay_amount = 40
delay_remaining -= delay_amount
var/efficiency = get_efficiency_mod()
SSshuttle.emergency.setTimer(SSshuttle.emergency.timeLeft(1) + (delay_amount * efficiency))
var/highest_y
var/highest_x
var/lowest_y
var/lowest_x
var/list/prism_turfs = list()
for(var/t in SSshuttle.emergency.ripple_area(SSshuttle.getDock("emergency_home")))
prism_turfs[t] = TRUE
var/turf/T = t
if(!highest_y || T.y > highest_y)
highest_y = T.y
if(!highest_x || T.x > highest_x)
highest_x = T.x
if(!lowest_y || T.y < lowest_y)
lowest_y = T.y
if(!lowest_x || T.x < lowest_x)
lowest_x = T.x
var/mean_y = LERP(lowest_y, highest_y, 0.5)
var/mean_x = LERP(lowest_x, highest_x, 0.5)
if(prob(50))
mean_y = CEILING(mean_y, 1)
else
mean_y = FLOOR(mean_y, 1) //Yes, I know round(mean_y) does the same, just left as FLOOR for consistancy sake
if(prob(50))
mean_x = CEILING(mean_x, 1)
else
mean_x = FLOOR(mean_x, 1)
var/turf/semi_random_center_turf = locate(mean_x, mean_y, z)
for(var/t in getline(src, semi_random_center_turf))
prism_turfs[t] = TRUE
var/placement_style = prob(50)
for(var/t in prism_turfs)
var/turf/T = t
if(placement_style)
if(ISODD(T.x + T.y))
seven_random_hexes(T, efficiency)
else if(prob(50 * efficiency))
new /obj/effect/temp_visual/ratvar/prolonging_prism(T)
else
if(ISEVEN(T.x + T.y))
seven_random_hexes(T, efficiency)
else if(prob(50 * efficiency))
new /obj/effect/temp_visual/ratvar/prolonging_prism(T)
CHECK_TICK //we may be going over a hell of a lot of turfs
/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/get_delay_cost()
return FLOOR(delay_cost, MIN_CLOCKCULT_POWER)
/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/seven_random_hexes(turf/T, efficiency)
var/static/list/hex_states = list("prismhex1", "prismhex2", "prismhex3", "prismhex4", "prismhex5", "prismhex6", "prismhex7")
var/mutable_appearance/hex_combo
for(var/n in hex_states) //BUILD ME A HEXAGON
if(prob(50 * efficiency))
if(!hex_combo)
hex_combo = mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)
else
hex_combo.add_overlay(mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER))
if(hex_combo) //YOU BUILT A HEXAGON
hex_combo.pixel_x = -16
hex_combo.pixel_y = -16
hex_combo.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
hex_combo.plane = GAME_PLANE
new /obj/effect/temp_visual/ratvar/prolonging_prism(T, hex_combo)

View File

@@ -101,8 +101,8 @@
return
clashing = TRUE
GLOB.cult_narsie.clashing = TRUE
to_chat(world, "<span class='bold brass'><font size=5>\"YOU.\"</font></span>")
to_chat(world, "<span class='bold cult'><font size=5>\"Ratvar?!\"</font></span>")
to_chat(world, "<span class='bold brass'><font size=5>\"[pick("YOU.", "BLOOD GOD!!", "FACE ME, COWARD!")]\"</font></span>")
to_chat(world, "<span class='bold cult'><font size=5>\"[pick("Ratvar?! How?!", "YOU. BANISHED ONCE. KILLED NOW.", "SCRAP HEAP!!")]\"</font></span>")
clash_of_the_titans(GLOB.cult_narsie) // >:(
return TRUE
@@ -137,15 +137,16 @@
base_victory_chance *= 2 //The clash has a higher chance of resolving each time both gods attack one another
switch(winner)
if("Ratvar")
send_to_playing_players("<span class='heavy_brass'><font size=5>\"[pick("DIE.", "ROT.")]\"</font></span>\n\
send_to_playing_players("<span class='heavy_brass'><font size=5>\"[pick("DIE.", "ROT FOR CENTURIES, AS I HAVE!.","PERISH, HEATHEN.", "DIE, MONSTER, YOU DON'T BELONG IN THIS WORLD.")]\"</font></span>\n\
<span class='cult'><font size=5>\"<b>[pick("Nooooo...", "Not die. To y-", "Die. Ratv-", "Sas tyen re-")]\"</b></font></span>") //Nar'Sie get out
sound_to_playing_players('sound/magic/clockwork/anima_fragment_attack.ogg')
sound_to_playing_players('sound/magic/demon_dies.ogg', 50)
sound_to_playing_players('sound/magic/abomscream.ogg', 50)
clashing = FALSE
qdel(narsie)
if("Nar'Sie")
send_to_playing_players("<span class='cult'><font size=5>\"<b>[pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")]</b>\"</font></span>") //Broken English
sound_to_playing_players('sound/magic/demon_attack1.ogg')
sound_to_playing_players('sound/magic/clockwork/anima_fragment_death.ogg', 62)
send_to_playing_players("<span class='cult'><font size=5>\"<b>[pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")]</b>\"</font></span>\n\
<span class='heavy_brass'><font size=5>\"[pick("NO, YOUR SHADOWS SHALL NO-", "ZNL GUR FGERNZF BS GVZR PNEEL ZL RKVFG-", "MY LIGHT CANNO-")]\"</font></span>")
sound_to_playing_players('sound/magic/demon_attack1.ogg', 50)
sound_to_playing_players('sound/machines/clockcult/ratvar_scream.ogg', 80)
narsie.clashing = FALSE
qdel(src)

View File

@@ -167,10 +167,10 @@
return
if(last_man_standing)
if(syndicate)
to_chat(owner.current,"<span class='userdanger'> All the loyalist agents are dead, and no more is required of you. Die a glorious death, agent. </span>")
to_chat(owner.current,"<span class='userdanger'>All the suspected agents are dead, and no more is required of you. Die a glorious death, agent.</span>")
replace_escape_objective(owner)
else
to_chat(owner.current,"<span class='userdanger'> All the other agents are dead, and you're the last loose end. Stage a Syndicate terrorist attack to cover up for today's events. You no longer have any limits on collateral damage.</span>")
replace_escape_objective(owner)
to_chat(owner.current,"<span class='userdanger'>All the other agents are dead. You have done us all a great service and shall be honorably exiled upon returning to base.</span>")
/datum/antagonist/traitor/internal_affairs/proc/iaa_process()
if(owner&&owner.current&&owner.current.stat!=DEAD)
@@ -193,7 +193,7 @@
if(syndicate)
fail_msg += "<span class='userdanger'> You no longer have permission to die. </span>"
else
fail_msg += "<span class='userdanger'> The truth could still slip out!</font><B><font size=5 color=red> Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated.</span>"
fail_msg += "<span class='userdanger'> The truth could still slip out!</font><B><font size=5 color=red> Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to great shame.</span>"
reinstate_escape_objective(owner)
last_man_standing = FALSE
to_chat(owner.current, fail_msg)
@@ -226,18 +226,20 @@
add_objective(escape_objective)
/datum/antagonist/traitor/internal_affairs/proc/greet_iaa()
var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "receiving bribes", "malpractice", "worship of prohibited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence")
var/crime = pick("distribution of contraband" , "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "receiving bribes", "malpractice", "worship of prohibited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence")
to_chat(owner.current, "<span class='userdanger'>You are the [special_role].</span>")
if(syndicate)
to_chat(owner.current, "<span class='userdanger'>Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.</span>")
to_chat(owner.current, "<B><font size=5 color=red>Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.</font></B>")
to_chat(owner.current, "<span class='userdanger'> You have been provided with a standard uplink to accomplish your task. </span>")
to_chat(owner.current, "<span class='userdanger'>By no means reveal that you, or any other NT employees, are undercover agents.</span>")
to_chat(owner.current, "<span class='userdanger'>GREAT LEADER IS DEAD. NANOTRASEN MUST FALL.</span>")
to_chat(owner.current, "<span class='userdanger'>Your have infiltrated this vessel to cause chaos and assassinate targets known to have conspired against the Syndicate.</span>")
to_chat(owner.current, "<span class='userdanger'>Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.</span>")
to_chat(owner.current, "<span class='userdanger'>You have been provided with a standard uplink to accomplish your task. </span>")
to_chat(owner.current, "<span class='userdanger'>By no means reveal that you are a Syndicate agent. By no means reveal that your targets are being hunted.</span>")
else
to_chat(owner.current, "<span class='userdanger'>Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.</span>")
to_chat(owner.current, "<B><font size=5 color=red>While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.</font></B>")
to_chat(owner.current, "<span class='userdanger'>For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.</span>")
to_chat(owner.current, "<span class='userdanger'>CAUTION: Your legal status as a citizen of NanoTrasen will be permanently revoked upon completion of your first contract.</span>")
to_chat(owner.current, "<span class='userdanger'>Your target has been suspected of [crime], and must be removed from this plane.</span>")
to_chat(owner.current, "<span class='userdanger'>While you have a license to kill, you are to eliminate your targets with no collateral or unrelated deaths.</span>")
to_chat(owner.current, "<span class='userdanger'>For the sake of plausable deniability, you have been equipped with captured Syndicate equipment via uplink.</span>")
to_chat(owner.current, "<span class='userdanger'>By no means reveal that you, or any other NT employees, are undercover agents.</span>")
to_chat(owner.current, "<span class='userdanger'>Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.</span>")

View File

@@ -257,10 +257,8 @@
if(14 to 25) // 1.3ish% chance to stumble and be a bit off balance (like being disarmed)
to_chat(our_guy, "<span class='danger'>You stumble a bit on your untied shoelaces!</span>")
if(!our_guy.has_movespeed_modifier(/datum/movespeed_modifier/shove))
our_guy.add_movespeed_modifier(/datum/movespeed_modifier/shove)
addtimer(CALLBACK(our_guy, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
our_guy.ShoveOffBalance(SHOVE_OFFBALANCE_DURATION)
our_guy.Stagger(SHOVE_OFFBALANCE_DURATION) //yes, same.
if(26 to 1000)
wiser = FALSE
if(wiser)

View File

@@ -29,6 +29,28 @@
create_reagents(volume, INJECTABLE | DRAWABLE)
/obj/item/seeds/replicapod/pre_attack(obj/machinery/hydroponics/I)
if(istype(I, /obj/machinery/hydroponics))
if(!I.myseed)
START_PROCESSING(SSobj, src)
return ..()
/obj/item/seeds/replicapod/proc/check_mind_orbiting(atom/A)
for(var/mob/M in A.orbiters?.orbiters)
if(mind && M.mind && ckey(M.mind.key) == ckey(mind.key) && M.ckey && M.client && M.stat == DEAD && !M.suiciding && isobserver(M))
return TRUE
return FALSE
/obj/item/seeds/replicapod/process()
var/obj/machinery/hydroponics/parent = loc
if(parent.harvest != 1)
return
if (check_mind_orbiting(parent))
icon_harvest = "replicapod-orbit"
else
icon_harvest = "replicapod-harvest"
parent.update_icon_plant()
/obj/item/seeds/replicapod/on_reagent_change(changetype)
if(changetype == ADD_REAGENT)
var/datum/reagent/blood/B = reagents.has_reagent(/datum/reagent/blood)
@@ -59,8 +81,11 @@
/obj/item/seeds/replicapod/get_analyzer_text()
var/text = ..()
var/obj/machinery/hydroponics/parent = loc
if(contains_sample)
text += "\n It contains a blood sample!"
if (parent && istype(parent) && check_mind_orbiting(parent))
text += "\n The soul is ready to enter the body."
return text
@@ -115,7 +140,7 @@
features["mcolor"] = "#59CE00"
for(var/V in quirks)
new V(podman)
podman.hardset_dna(null,null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
podman.hardset_dna(null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
podman.set_cloned_appearance()
else //else, one packet of seeds. maybe two

View File

@@ -1040,12 +1040,6 @@
return TRUE
return FALSE
/mob/living/carbon/human/proc/clear_shove_slowdown()
remove_movespeed_modifier(/datum/movespeed_modifier/shove)
var/active_item = get_active_held_item()
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
visible_message("<span class='warning'>[src.name] regains their grip on \the [active_item]!</span>", "<span class='warning'>You regain your grip on \the [active_item]</span>", null, COMBAT_MESSAGE_RANGE)
/mob/living/carbon/human/updatehealth()
. = ..()

View File

@@ -1492,11 +1492,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//CITADEL CHANGES - makes resting and disabled combat mode reduce punch damage, makes being out of combat mode result in you taking more damage
if(!SEND_SIGNAL(target, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
damage *= 1.5
damage *= 1.2
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
damage *= 0.5
damage *= 0.8
if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
damage *= 0.25
damage *= 0.8
//END OF CITADEL CHANGES
var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected))
@@ -1935,11 +1935,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
target.visible_message("<span class='danger'>[user.name] shoves [target.name]!</span>",
"<span class='danger'>[user.name] shoves you!</span>", null, COMBAT_MESSAGE_RANGE, null,
user, "<span class='danger'>You shove [target.name]!</span>")
target.Stagger(SHOVE_STAGGER_DURATION)
var/obj/item/target_held_item = target.get_active_held_item()
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove))
target.add_movespeed_modifier(/datum/movespeed_modifier/shove)
if(!target.has_status_effect(STATUS_EFFECT_OFF_BALANCE))
if(target_held_item)
if(!HAS_TRAIT(target_held_item, TRAIT_NODROP))
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
@@ -1947,12 +1947,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
append_message += ", loosening their grip on [target_held_item]"
else
append_message += ", but couldn't loose their grip on [target_held_item]"
addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
else if(target_held_item)
if(target.dropItemToGround(target_held_item))
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!!</span>",
"<span class='danger'>You drop \the [target_held_item]!!</span>", null, COMBAT_MESSAGE_RANGE)
append_message += ", causing them to drop [target_held_item]"
target.ShoveOffBalance(SHOVE_OFFBALANCE_DURATION)
log_combat(user, target, "shoved", append_message)
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)

View File

@@ -139,7 +139,7 @@
ExtinguishMob()
return
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(G.get_moles(/datum/gas/oxygen, 1))
if(!G.get_moles(/datum/gas/oxygen, 1))
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return
var/turf/location = get_turf(src)

View File

@@ -500,6 +500,15 @@
S = apply_status_effect(STATUS_EFFECT_SLEEPING, amount, updating)
return S
///////////////////////////////// OFF BALANCE/SHOVIES ////////////////////////
/mob/living/proc/ShoveOffBalance(amount)
var/datum/status_effect/off_balance/B = has_status_effect(STATUS_EFFECT_OFF_BALANCE)
if(B)
B.duration = max(world.time + amount, B.duration)
else if(amount > 0)
B = apply_status_effect(STATUS_EFFECT_OFF_BALANCE, amount)
return B
///////////////////////////////// FROZEN /////////////////////////////////////
/mob/living/proc/IsFrozen()

View File

@@ -78,9 +78,6 @@
blacklisted_movetypes = FLOATING
variable = TRUE
/datum/movespeed_modifier/shove
multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH
/datum/movespeed_modifier/human_carry
variable = TRUE

View File

@@ -38,6 +38,8 @@
#define APC_CHARGING 1
#define APC_FULLY_CHARGED 2
#define MAXIMUM_COG_REGAIN 100 //How much charge drained by an integration cog can be priority-recharged in one processing-tick
// the Area Power Controller (APC), formerly Power Distribution Unit (PDU)
// one per area, needs wire connection to power network through a terminal
@@ -94,6 +96,7 @@
var/mob/living/silicon/ai/occupier = null
var/transfer_in_progress = FALSE //Is there an AI being transferred out of us?
var/obj/item/clockwork/integration_cog/integration_cog //Is there a cog siphoning power?
var/cog_drained = 0 //How much of the cell's charge was drained by an integration cog, recovering this amount takes priority over the normal APC cell recharge calculations, but comes after powering Essentials.
var/longtermpower = 10
var/auto_name = 0
var/failure_timer = 0
@@ -499,6 +502,7 @@
cell.forceMove(T)
cell.update_icon()
cell = null
cog_drained = 0 //No more cell means no more averting celldrain
charging = APC_NOT_CHARGING
update_icon()
return
@@ -701,7 +705,7 @@
START_PROCESSING(SSfastprocess, W)
playsound(src, 'sound/machines/clockcult/steam_whoosh.ogg', 50, FALSE)
opened = APC_COVER_CLOSED
locked = FALSE
locked = TRUE //Clockies get full APC access on cogged APCs, but they can't lock or unlock em unless they steal some ID to give all of them APC access, soo this is pretty much just QoL for them and makes cogs a tiny bit more stealthy
update_icon()
return
else if(panel_open && !opened && is_wire_tool(W))
@@ -1311,6 +1315,11 @@
cur_used -= lastused_light
lighting_satisfied = TRUE
//If drained by an integration cog: Forcefully avert as much of the powerdrain as possible, though a maximum of MAXIMUM_COG_REGAIN
if(cur_excess && cog_drained && cell)
var/cog_regain = cell.give(min(min(cog_drained, cur_excess), MAXIMUM_COG_REGAIN))
cur_excess -= cog_regain
cog_drained = max(0, cog_drained - cog_regain)
// next: take from or charge to the cell, depending on how much is left
if(cell && !shorted)
@@ -1573,6 +1582,8 @@
#undef APC_UPOVERLAY_LOCKED
#undef APC_UPOVERLAY_OPERATING
#undef MAXIMUM_COG_REGAIN
/*Power module, used for APC construction*/
/obj/item/electronics/apc
name = "power control module"

View File

@@ -375,7 +375,6 @@
log_combat(user, target, "shoved", "into [src] (disposal bin)")
return TRUE
/obj/machinery/disposal/bin/flush()
..()
full_pressure = FALSE

View File

@@ -1,4 +1,4 @@
#define SYNDICATE_CHALLENGE_TIMER 12000 //20 minutes
#define SYNDICATE_CHALLENGE_TIMER 9000 // 15 minutes
/obj/machinery/computer/shuttle/syndicate
name = "syndicate shuttle terminal"
@@ -21,8 +21,8 @@
/obj/machinery/computer/shuttle/syndicate/Topic(href, href_list)
if(href_list["move"])
var/obj/item/circuitboard/computer/syndicate_shuttle/board = circuit
if(board.challenge && world.time < SYNDICATE_CHALLENGE_TIMER)
to_chat(usr, "<span class='warning'>You've issued a combat challenge to the station! You've got to give them at least [DisplayTimeText(SYNDICATE_CHALLENGE_TIMER - world.time)] more to allow them to prepare.</span>")
if(board.challenge && ((world.time - SSticker.round_start_time) < SYNDICATE_CHALLENGE_TIMER))
to_chat(usr, "<span class='warning'>You've issued a combat challenge to the station! You've got to give them at least [DisplayTimeText(SYNDICATE_CHALLENGE_TIMER - (world.time - SSticker.round_start_time))] more to allow them to prepare.</span>")
return 0
board.moved = TRUE
..()

View File

@@ -50,7 +50,7 @@
Combines with all martial arts, but the user will be unable to bring themselves to use guns, nor remove the armbands."
item = /obj/item/storage/box/syndie_kit/northstar
cost = 20
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/suits/infiltrator_bundle
name = "Insidious Infiltration Gear Case"
@@ -117,7 +117,7 @@
you will receive. May contain discontinued and/or exotic items."
item = /obj/item/storage/box/syndicate
cost = 20
exclude_modes = list(/datum/game_mode/nuclear)
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/traitor/internal_affairs)
cant_discount = TRUE
/datum/uplink_item/bundles_TC/surplus
@@ -127,7 +127,7 @@
item = /obj/structure/closet/crate
cost = 20
player_minimum = 25
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
cant_discount = TRUE
var/starting_crate_value = 50
@@ -163,7 +163,7 @@
/datum/uplink_item/bundles_TC/reroll
name = "Renegotiate Contract"
desc = "Selecting this will inform the syndicate that you wish to change employers. Can only be done once; no take-backs."
desc = "Selecting this will inform your employers that you wish for new objectives. Can only be done once; no take-backs."
item = /obj/effect/gibspawner/generic
cost = 0
cant_discount = TRUE
@@ -184,6 +184,7 @@
item = /obj/effect/gibspawner/generic // non-tangible item because techwebs use this path to determine illegal tech
cost = 0
cant_discount = TRUE
exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/bundles_TC/random/purchase(mob/user, datum/component/uplink/U)
var/list/uplink_items = U.uplink_items

View File

@@ -21,7 +21,7 @@
item = /obj/item/storage/box/syndie_kit/revolver
cost = 13
surplus = 50
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/dangerous/rawketlawnchair
name = "84mm Rocket Propelled Grenade Launcher"
@@ -112,7 +112,7 @@
item = /obj/item/dualsaber
player_minimum = 25
cost = 16
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/dangerous/doublesword/get_discount()
return pick(4;0.8,2;0.65,1;0.5)
@@ -123,7 +123,7 @@
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)
exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/dangerous/shield
name = "Energy Shield"
@@ -141,7 +141,7 @@
However, due to the size of the blade and obvious nature of the sheath, the weapon stands out as being obviously nefarious."
item = /obj/item/storage/belt/sabre/rapier
cost = 8
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/dangerous/flamethrower
name = "Flamethrower"
@@ -180,7 +180,7 @@
refundable = TRUE
cant_discount = TRUE
surplus = 0
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
player_minimum = 25
restricted = TRUE
refund_path = /obj/item/guardiancreator/tech/choose/traitor
@@ -211,6 +211,7 @@
deal extra damage and hit targets further. Use a screwdriver to take out any attached tanks."
item = /obj/item/melee/powerfist
cost = 8
exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/dangerous/sniper
name = "Sniper Rifle"
@@ -250,4 +251,4 @@
darts effective at incapacitating a target."
item = /obj/item/gun/ballistic/automatic/toy/pistol/riot
cost = 3
surplus = 10
surplus = 10

View File

@@ -58,6 +58,7 @@
item = /obj/item/storage/backpack/duffelbag/syndie/x4
cost = 4 //
cant_discount = TRUE
exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/explosives/clown_bomb_clownops
name = "Clown Bomb"
@@ -123,6 +124,7 @@
be defused, and some crew may attempt to do so."
item = /obj/item/sbeacondrop/bomb
cost = 11
exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/explosives/syndicate_detonator
name = "Syndicate Detonator"
@@ -140,7 +142,7 @@
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)
exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/explosives/tearstache
name = "Teachstache Grenade"

View File

@@ -30,6 +30,7 @@
item = /obj/item/gun/blastcannon
cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist.
restricted_roles = list("Research Director", "Scientist")
exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/role_restricted/alientech
name = "Alien Research Disk"
@@ -100,6 +101,7 @@
player_minimum = 20
refundable = TRUE
restricted_roles = list("Chaplain")
exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/role_restricted/arcane_tome
name = "Arcane Tome"
@@ -109,6 +111,7 @@
player_minimum = 20
refundable = TRUE
restricted_roles = list("Chaplain")
exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/role_restricted/explosive_hot_potato
name = "Exploding Hot Potato"

View File

@@ -65,6 +65,16 @@
surplus = 0
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
/datum/uplink_item/stealthy_weapons/martialartsthree
name = "Krav Maga Scroll"
desc = "This scroll contains the secrets of an ancient martial arts technique. You will gain special unarmed attacks for \
stealthy takedowns."
item = /obj/item/book/granter/martial/krav_maga
cost = 16
player_minimum = 25
surplus = 0
include_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/stealthy_weapons/crossbow
name = "Miniature Energy Crossbow"
desc = "A short bow mounted across a tiller in miniature. Small enough to \

View File

@@ -10,6 +10,7 @@
/obj/item/cartridge/security = 10,
/obj/item/cartridge/janitor = 10,
/obj/item/cartridge/signal/toxins = 10,
/obj/item/cartridge/roboticist = 10,
/obj/item/pda/heads = 10)
premium = list(/obj/item/cartridge/captain = 2,
/obj/item/cartridge/quartermaster = 2)

View File

@@ -525,3 +525,7 @@ FAIL2TOPIC_RULE_NAME _dd_fail2topic
## Enable automatic profiling - Byond 513.1506 and newer only.
#AUTO_PROFILE
## Uncomment to enable global ban DB using the provided URL. The API should expect to receive a ckey at the end of the URL.
## More API details can be found here: https://centcom.melonmesa.com
CENTCOM_BAN_DB https://centcom.melonmesa.com/ban/search

View File

@@ -50,6 +50,49 @@
-->
<div class="commit sansserif">
<h2 class="date">02 August 2020</h2>
<h3 class="author">Auris456852 updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Added B.O.O.P. Remote Control cartridges to the PTech.</li>
</ul>
<h3 class="author">Hatterhat updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Durathread reinforcement kits! Sprites by Toriate, sets jumpsuit armor to durathread levels, craft in the crafting menu.</li>
</ul>
<h3 class="author">KeRSedChaplain updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">The belligerent scripture and a brass multitool, and a new marauder variant which act similar to holoparasites/guardian spirits.</li>
<li class="rscdel">Removed the abductor teleport consoles they get, removes abscond for the time being as I've not seen much use for it other than just spamming it and hoping you end up in the armory.</li>
<li class="tweak">moved around scriptures to make the cult work better as being based around the station, makes the Ark scream more often and work as a summonable object, clockwork armor now has a flat 0 defense up to 10 instead of negatives against laser damage. Makes the Ark work better in a station based setting, as well as the Heralds beacon in case It works for the mode.</li>
<li class="soundadd">added powerloaderstep.ogg for Neovgre</li>
<li class="tweak">changes 'Dread_Ipad.dmi' to 'clockwork_slab.dmi'</li>
</ul>
<h3 class="author">MrJWhit updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">Adjusts abductor spawntext</li>
</ul>
<h3 class="author">Seris02 updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">fixed replica pods</li>
</ul>
<h3 class="author">dapnee updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">fixed active turfs on wizard ruin and space hermit, fixed missing APC's and added a light on Delta</li>
</ul>
<h3 class="author">ike709 and bobbahbrown updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Admins can now see your bans on (some) other servers.</li>
</ul>
<h3 class="author">kappa-sama updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">chaplain cultists being able to convert people to full clockwork cult status</li>
</ul>
<h3 class="author">timothyteakettle updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">combat mode now has weaker buffs in terms of damage dealt and took for being or not being in the mode</li>
<li class="tweak">damage debuff for laying down has been decreased from 0.5x to 0.7x</li>
</ul>
<h2 class="date">01 August 2020</h2>
<h3 class="author">dapnee updated:</h3>
<ul class="changes bgimages16">
@@ -60,6 +103,7 @@
<h3 class="author">silicons updated:</h3>
<ul class="changes bgimages16">
<li class="tweak">toy shotguns no longer need 2 hands to fire</li>
<li class="bugfix">being on fire works again.</li>
</ul>
<h3 class="author">timothyteakettle updated:</h3>
<ul class="changes bgimages16">

View File

@@ -26658,5 +26658,41 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
AIR alarm, arrivals no longer has active atmos tiles.
silicons:
- tweak: toy shotguns no longer need 2 hands to fire
- bugfix: being on fire works again.
timothyteakettle:
- bugfix: monkeys no longer continuously bleed everywhere
2020-08-02:
Auris456852:
- rscadd: Added B.O.O.P. Remote Control cartridges to the PTech.
Hatterhat:
- rscadd: Durathread reinforcement kits! Sprites by Toriate, sets jumpsuit armor
to durathread levels, craft in the crafting menu.
KeRSedChaplain:
- rscadd: The belligerent scripture and a brass multitool, and a new marauder variant
which act similar to holoparasites/guardian spirits.
- rscdel: Removed the abductor teleport consoles they get, removes abscond for the
time being as I've not seen much use for it other than just spamming it and
hoping you end up in the armory.
- tweak: moved around scriptures to make the cult work better as being based around
the station, makes the Ark scream more often and work as a summonable object,
clockwork armor now has a flat 0 defense up to 10 instead of negatives against
laser damage. Makes the Ark work better in a station based setting, as well
as the Heralds beacon in case It works for the mode.
- soundadd: added powerloaderstep.ogg for Neovgre
- tweak: changes 'Dread_Ipad.dmi' to 'clockwork_slab.dmi'
MrJWhit:
- tweak: Adjusts abductor spawntext
Seris02:
- bugfix: fixed replica pods
dapnee:
- bugfix: fixed active turfs on wizard ruin and space hermit, fixed missing APC's
and added a light on Delta
ike709 and bobbahbrown:
- rscadd: Admins can now see your bans on (some) other servers.
kappa-sama:
- bugfix: chaplain cultists being able to convert people to full clockwork cult
status
timothyteakettle:
- tweak: combat mode now has weaker buffs in terms of damage dealt and took for
being or not being in the mode
- tweak: damage debuff for laying down has been decreased from 0.5x to 0.7x

View File

@@ -0,0 +1,4 @@
author: "Linzolle"
delete-after: True
changes:
- bugfix: "uv penlight no longer invisible"

View File

@@ -0,0 +1,5 @@
author: "silicons"
delete-after: True
changes:
- rscadd: "shoves have been buffed to apply a status effect rather than a 0.85 movespeed modifier, meaning repeatedly shoving someone now renews the debuff"
- balance: "shoves now stagger for 3.5 seconds."

View File

@@ -0,0 +1,4 @@
author: "silicons"
delete-after: True
changes:
- tweak: "war operatives now actually time 20 minutes since roundstart to depart instead of 15."

View File

@@ -0,0 +1,4 @@
author: "KeRSedChaplain"
delete-after: True
changes:
- bugfix: "fixed clockwork guardians being able to reflect ranged weapons"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

BIN
sound/magic/abomscream.ogg Normal file

Binary file not shown.

BIN
sound/mecha/neostep1.ogg Normal file

Binary file not shown.

BIN
sound/mecha/neostep2.ogg Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -232,6 +232,7 @@
#include "code\_onclick\hud\alien_larva.dm"
#include "code\_onclick\hud\blob_overmind.dm"
#include "code\_onclick\hud\blobbernauthud.dm"
#include "code\_onclick\hud\clockwork_marauder.dm"
#include "code\_onclick\hud\constructs.dm"
#include "code\_onclick\hud\credits.dm"
#include "code\_onclick\hud\devil.dm"
@@ -377,6 +378,7 @@
#include "code\datums\explosion.dm"
#include "code\datums\forced_movement.dm"
#include "code\datums\holocall.dm"
#include "code\datums\http.dm"
#include "code\datums\hud.dm"
#include "code\datums\mind.dm"
#include "code\datums\mutable_appearance.dm"
@@ -972,6 +974,7 @@
#include "code\game\objects\items\AI_modules.dm"
#include "code\game\objects\items\airlock_painter.dm"
#include "code\game\objects\items\apc_frame.dm"
#include "code\game\objects\items\armor_kits.dm"
#include "code\game\objects\items\balls.dm"
#include "code\game\objects\items\binoculars.dm"
#include "code\game\objects\items\blueprints.dm"
@@ -1543,6 +1546,7 @@
#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_applications.dm"
#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_cyborg.dm"
#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_drivers.dm"
#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_judgement.dm"
#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_scripts.dm"
#include "code\modules\antagonists\clockcult\clock_structures\_trap_object.dm"
#include "code\modules\antagonists\clockcult\clock_structures\ark_of_the_clockwork_justicar.dm"
@@ -1551,6 +1555,7 @@
#include "code\modules\antagonists\clockcult\clock_structures\heralds_beacon.dm"
#include "code\modules\antagonists\clockcult\clock_structures\mania_motor.dm"
#include "code\modules\antagonists\clockcult\clock_structures\ocular_warden.dm"
#include "code\modules\antagonists\clockcult\clock_structures\prolonging_prism.dm"
#include "code\modules\antagonists\clockcult\clock_structures\ratvar_the_clockwork_justicar.dm"
#include "code\modules\antagonists\clockcult\clock_structures\reflector.dm"
#include "code\modules\antagonists\clockcult\clock_structures\stargazer.dm"