Merge branch 'master' into slime-puddle

This commit is contained in:
Timothy Teakettle
2020-10-07 23:37:30 +01:00
committed by GitHub
165 changed files with 3034 additions and 2094 deletions
+15
View File
@@ -9,32 +9,47 @@ jobs:
name: "Compile changelogs"
runs-on: ubuntu-latest
steps:
- name: "Check for CHANGELOG_ENABLER secret and pass true to output if it exists to be checked by later steps"
id: value_holder
env:
CHANGELOG_ENABLER: ${{ secrets.CHANGELOG_ENABLER }}
run: |
unset SECRET_EXISTS
if [-n $CHANGELOG_ENABLER]; then SECRET_EXISTS='true' ; fi
echo ::set-output name=CL_ENABLED::${SECRET_EXISTS}
- name: "Setup python"
if: steps.value_holder.outputs.CL_ENABLED
uses: actions/setup-python@v1
with:
python-version: '3.x'
- name: "Install deps"
if: steps.value_holder.outputs.CL_ENABLED
run: |
python -m pip install --upgrade pip
python -m pip install pyyaml
sudo apt-get install dos2unix
- name: "Checkout"
if: steps.value_holder.outputs.CL_ENABLED
uses: actions/checkout@v1
with:
fetch-depth: 25
- name: "Compile"
if: steps.value_holder.outputs.CL_ENABLED
run: |
python tools/ss13_genchangelog.py html/changelog.html html/changelogs
- name: "Convert Lineendings"
if: steps.value_holder.outputs.CL_ENABLED
run: |
unix2dos html/changelogs/.all_changelog.yml
- name: Commit
if: steps.value_holder.outputs.CL_ENABLED
run: |
git config --local user.email "action@github.com"
git config --local user.name "Changelogs"
git pull origin master
git commit -m "Automatic changelog compile [ci skip]" -a || true
- name: "Push"
if: steps.value_holder.outputs.CL_ENABLED
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
+61 -50
View File
@@ -1529,6 +1529,7 @@
icon_state = "warningline";
dir = 1
},
/obj/item/paper/fluff/ruins/skelter/cloner,
/turf/open/floor/plasteel,
/area/ruin/space/has_grav/skelter/med)
"dJ" = (
@@ -2485,10 +2486,13 @@
/turf/open/floor/plating,
/area/ruin/space/has_grav/skelter/engine/powerstorage)
"fR" = (
/obj/structure/cable{
icon_state = "2-8"
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/obj/item/ammo_casing/c45,
/obj/structure/cable/yellow{
icon_state = "4-8"
},
/obj/item/kitchen/knife/combat,
/turf/open/floor/plating,
/area/ruin/space/has_grav/skelter/engine/powerstorage)
"fS" = (
@@ -2826,10 +2830,12 @@
/turf/open/floor/plasteel/dark,
/area/ruin/space/has_grav/skelter/sec)
"gI" = (
/obj/structure/rack,
/obj/item/gun/ballistic/automatic/pistol/m1911,
/turf/open/floor/plasteel/dark,
/area/ruin/space/has_grav/skelter/sec)
/obj/structure/cable{
icon_state = "2-8"
},
/obj/item/ammo_casing/c10mm,
/turf/open/floor/plating,
/area/ruin/space/has_grav/skelter/engine/powerstorage)
"gJ" = (
/obj/machinery/power/terminal{
dir = 1
@@ -3285,17 +3291,10 @@
/turf/open/floor/plasteel/showroomfloor,
/area/ruin/space/has_grav/skelter/comms)
"hJ" = (
/obj/effect/turf_decal/trimline/blue/line,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/obj/structure/cable/yellow{
icon_state = "1-2"
},
/obj/item/ammo_casing/c45,
/turf/open/floor/plasteel/showroomfloor,
/area/ruin/space/has_grav/skelter/comms)
/obj/structure/rack,
/obj/item/ammo_box/magazine/m10mm,
/turf/open/floor/plasteel/dark,
/area/ruin/space/has_grav/skelter/sec)
"hK" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
icon_state = "trimline_fill";
@@ -3843,19 +3842,10 @@
/turf/open/floor/plasteel/showroomfloor,
/area/ruin/space/has_grav/skelter/comms)
"iP" = (
/obj/effect/turf_decal/tile/blue,
/obj/effect/turf_decal/tile/blue{
dir = 4
},
/obj/effect/turf_decal/tile/blue{
dir = 8
},
/obj/effect/turf_decal/tile/blue{
dir = 1
},
/obj/item/gun/ballistic/automatic/pistol/m1911/no_mag,
/turf/open/floor/plasteel/showroomfloor,
/area/ruin/space/has_grav/skelter/comms)
/obj/structure/rack,
/obj/item/gun/ballistic/automatic/pistol,
/turf/open/floor/plasteel/dark,
/area/ruin/space/has_grav/skelter/sec)
"iQ" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/closed/wall/mineral/titanium,
@@ -3934,17 +3924,15 @@
/turf/open/floor/plasteel/showroomfloor,
/area/ruin/space/has_grav/skelter/comms)
"iX" = (
/obj/effect/turf_decal/tile/blue,
/obj/effect/turf_decal/tile/blue{
/obj/effect/turf_decal/trimline/blue/line,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/obj/effect/turf_decal/tile/blue{
dir = 8
/obj/structure/cable/yellow{
icon_state = "1-2"
},
/obj/effect/turf_decal/tile/blue{
dir = 1
},
/obj/item/ammo_casing/c45,
/obj/item/ammo_casing/c10mm,
/turf/open/floor/plasteel/showroomfloor,
/area/ruin/space/has_grav/skelter/comms)
"iY" = (
@@ -4149,16 +4137,39 @@
/turf/open/floor/carpet,
/area/ruin/space/has_grav/skelter/admin)
"jv" = (
/obj/structure/rack,
/obj/item/ammo_box/magazine/m45,
/turf/open/floor/plasteel/dark,
/area/ruin/space/has_grav/skelter/sec)
/obj/effect/turf_decal/tile/blue,
/obj/effect/turf_decal/tile/blue{
dir = 4
},
/obj/effect/turf_decal/tile/blue{
dir = 8
},
/obj/effect/turf_decal/tile/blue{
dir = 1
},
/obj/item/gun/ballistic/automatic/pistol/no_mag,
/turf/open/floor/plasteel/showroomfloor,
/area/ruin/space/has_grav/skelter/comms)
"jw" = (
/turf/open/space/basic,
/area/space/nearstation)
"jx" = (
/turf/open/space/basic,
/area/template_noop)
"jy" = (
/obj/effect/turf_decal/tile/blue,
/obj/effect/turf_decal/tile/blue{
dir = 4
},
/obj/effect/turf_decal/tile/blue{
dir = 8
},
/obj/effect/turf_decal/tile/blue{
dir = 1
},
/obj/item/ammo_casing/c10mm,
/turf/open/floor/plasteel/showroomfloor,
/area/ruin/space/has_grav/skelter/comms)
(1,1,1) = {"
ah
@@ -4479,7 +4490,7 @@ eW
cF
fN
gj
jv
hJ
gl
hw
hU
@@ -4539,7 +4550,7 @@ eX
fx
fN
gj
gI
iP
gl
hx
hx
@@ -4657,7 +4668,7 @@ dI
bI
fc
fA
fR
gI
go
gL
iC
@@ -4715,7 +4726,7 @@ bI
bI
bI
eA
fd
fR
fA
fA
fA
@@ -4991,10 +5002,10 @@ ju
gw
dO
hk
hJ
iX
ij
iF
iP
jv
iW
jh
jl
@@ -5025,7 +5036,7 @@ hK
ii
jm
jn
iX
jy
ii
jl
ah
+24 -18
View File
@@ -428,7 +428,7 @@
/area/awaymission/cabin)
"bm" = (
/obj/machinery/door/airlock/wood{
id_tag = "snowdinbutworse5";
id_tag = "snowdorm5";
name = "Cabin 5"
},
/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto,
@@ -3318,7 +3318,7 @@
/area/awaymission/cabin)
"iV" = (
/obj/machinery/door/airlock/wood{
id_tag = "snowdinbutworse1";
id_tag = "snowdorm1";
name = "Cabin 1"
},
/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto,
@@ -3326,7 +3326,7 @@
/area/awaymission/cabin)
"iW" = (
/obj/machinery/door/airlock/wood{
id_tag = "snowdinbutworse2";
id_tag = "snowdorm2";
name = "Cabin 2"
},
/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto,
@@ -3334,7 +3334,7 @@
/area/awaymission/cabin)
"iX" = (
/obj/machinery/door/airlock/wood{
id_tag = "snowdinbutworse3";
id_tag = "snowdorm3";
name = "Cabin 3"
},
/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto,
@@ -3342,7 +3342,7 @@
/area/awaymission/cabin)
"iY" = (
/obj/machinery/door/airlock/wood{
id_tag = "snowdinbutworse4";
id_tag = "snowdorm4";
name = "Cabin 4"
},
/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto,
@@ -3419,31 +3419,37 @@
/area/awaymission/cabin)
"jg" = (
/obj/machinery/button/door{
id = "snowdinbutworse2";
name = "airlock button";
pixel_y = -27
id = "snowdorm2";
name = "Dorm Bolt Control";
normaldoorcontrol = 1;
pixel_y = -25;
specialfunctions = 4
},
/turf/open/floor/wood,
/area/awaymission/cabin)
"jh" = (
/obj/machinery/button/door{
id = "snowdinbutworse1";
name = "airlock button";
pixel_y = -27
id = "snowdorm1";
name = "Dorm Bolt Control";
normaldoorcontrol = 1;
pixel_y = -25;
specialfunctions = 4
},
/turf/open/floor/wood,
/area/awaymission/cabin)
"ji" = (
/obj/machinery/button/door{
id = "snowdinbutworse3";
name = "airlock button";
pixel_y = -27
id = "snowdorm3";
name = "Dorm Bolt Control";
normaldoorcontrol = 1;
pixel_y = -25;
specialfunctions = 4
},
/turf/open/floor/wood,
/area/awaymission/cabin)
"jj" = (
/obj/machinery/button/door{
id = "snowdinbutworse4";
id = "snowdorm4";
name = "airlock button";
pixel_y = -27
},
@@ -3451,7 +3457,7 @@
/area/awaymission/cabin)
"jk" = (
/obj/machinery/button/door{
id = "snowdinbutworse5";
id = "snowdorm5";
name = "airlock button";
pixel_y = -27
},
@@ -4024,8 +4030,8 @@
pixel_y = -2
},
/obj/item/clothing/head/christmashatg{
pixel_y = 12;
pixel_x = 3
pixel_x = 3;
pixel_y = 12
},
/turf/open/floor/plating/asteroid/snow,
/area/awaymission/cabin/caves)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4
View File
@@ -63,6 +63,10 @@
#define CONTRACT_UPLINK_PAGE_CONTRACTS "CONTRACTS"
#define CONTRACT_UPLINK_PAGE_HUB "HUB"
//Lingblood stuff
#define LINGBLOOD_DETECTION_THRESHOLD 1
#define LINGBLOOD_EXPLOSION_MULT 2
#define LINGBLOOD_EXPLOSION_THRESHOLD (LINGBLOOD_DETECTION_THRESHOLD * LINGBLOOD_EXPLOSION_MULT) //Hey, important to note here: the explosion threshold is explicitly more than, rather than more than or equal to. This stops a single loud ability from triggering the explosion threshold.
///Heretics --
#define IS_HERETIC(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic))
+9
View File
@@ -105,3 +105,12 @@
//belly sound pref things
#define NORMIE_HEARCHECK 4
//icon states for the default eyes and for a state for no eye
#define DEFAULT_EYES_TYPE "normal"
#define DEFAULT_LEFT_EYE_STATE "normal_left_eye"
#define DEFAULT_RIGHT_EYE_STATE "normal_right_eye"
#define DEFAULT_NO_EYE_STATE "no_eye"
//special species definitions
#define MINIMUM_MUTANT_COLOR "#202020" //this is how dark players mutant parts and skin can be
+15 -3
View File
@@ -5,9 +5,21 @@
// global signals
// These are signals which can be listened to by any component on any parent
// start global signals with "!", this used to be necessary but now it's just a formatting choice
#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args)
#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message)
/// from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
#define COMSIG_GLOB_NEW_Z "!new_z"
/// called after a successful var edit somewhere in the world: (list/args)
#define COMSIG_GLOB_VAR_EDIT "!var_edit"
/// called after an explosion happened : (epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
#define COMSIG_GLOB_EXPLOSION "!explosion"
/// mob was created somewhere : (mob)
#define COMSIG_GLOB_MOB_CREATED "!mob_created"
/// mob died somewhere : (mob , gibbed)
#define COMSIG_GLOB_MOB_DEATH "!mob_death"
/// global living say plug - use sparingly: (mob/speaker , message)
#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special"
/// called by datum/cinematic/play() : (datum/cinematic/new_cinematic)
#define COMSIG_GLOB_PLAY_CINEMATIC "!play_cinematic"
#define COMPONENT_GLOB_BLOCK_CINEMATIC 1
// signals from globally accessible objects
/// from SSsun when the sun changes position : (azimuth)
+2
View File
@@ -1186,6 +1186,8 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico
SSassets.transport.register_asset(key, I)
for (var/thing2 in targets)
SSassets.transport.send_assets(thing2, key)
if(sourceonly)
return SSassets.transport.get_asset_url(key)
return "<img class='icon icon-[icon_state]' src='[SSassets.transport.get_asset_url(key)]'>"
+5 -3
View File
@@ -12,15 +12,17 @@
))
var/list/processing_list = list(location)
. = list()
while(processing_list.len)
var/atom/thing = processing_list[1]
processing_list -= thing
var/i = 0
var/lim = 1
while(i < lim)
var/atom/thing = processing_list[++i]
if(ignored_things[thing.type])
continue
. += thing
if((thing.rad_flags & RAD_PROTECT_CONTENTS) || (SEND_SIGNAL(thing, COMSIG_ATOM_RAD_PROBE) & COMPONENT_BLOCK_RADIATION))
continue
processing_list += thing.contents
lim = processing_list.len
/proc/radiation_pulse(atom/source, intensity, range_modifier, log=FALSE, can_contaminate=TRUE)
if(!SSradiation.can_fire)
+9 -5
View File
@@ -457,21 +457,23 @@ Turf and target are separate in case you want to teleport some distance from a t
/atom/proc/GetAllContents(var/T)
var/list/processing_list = list(src)
var/i = 0
var/lim = 1
if(T)
. = list()
var/i = 0
while(i < length(processing_list))
while(i < lim)
var/atom/A = processing_list[++i]
//Byond does not allow things to be in multiple contents, or double parent-child hierarchies, so only += is needed
//This is also why we don't need to check against assembled as we go along
processing_list += A.contents
lim = processing_list.len
if(istype(A,T))
. += A
else
var/i = 0
while(i < length(processing_list))
while(i < lim)
var/atom/A = processing_list[++i]
processing_list += A.contents
lim = processing_list.len
return processing_list
/atom/proc/GetAllContentsIgnoring(list/ignore_typecache)
@@ -480,10 +482,12 @@ Turf and target are separate in case you want to teleport some distance from a t
var/list/processing = list(src)
. = list()
var/i = 0
while(i < length(processing))
var/lim = 1
while(i < lim)
var/atom/A = processing[++i]
if(!ignore_typecache[A.type])
processing += A.contents
lim = processing.len
. += A
+6
View File
@@ -284,3 +284,9 @@ GLOBAL_LIST_INIT(greyscale_limb_types, list("human","moth","lizard","pod","plant
//body ids that have prosthetic sprites
GLOBAL_LIST_INIT(prosthetic_limb_types, list("xion","bishop","cybersolutions","grayson","hephaestus","nanotrasen","talon"))
//body ids that have non-gendered bodyparts
GLOBAL_LIST_INIT(nongendered_limb_types, list("fly", "zombie" ,"synth", "shadow", "cultgolem", "agent", "plasmaman", "clockgolem", "clothgolem"))
//list of eye types, corresponding to a respective left and right icon state for the set of eyes
GLOBAL_LIST_INIT(eye_types, list("normal", "insect", "moth", "double", "double2", "double3", "cyclops"))
+3 -1
View File
@@ -3,7 +3,9 @@
name = "Initializing..."
var/target
/obj/effect/statclick/New(loc, text, target) //Don't port this to Initialize it's too critical
INITIALIZE_IMMEDIATE(/obj/effect/statclick) //it's new, but rebranded.
/obj/effect/statclick/Initialize(mapload, text, target) //Don't port this to Initialize it's too critical
. = ..()
name = text
src.target = target
+3 -3
View File
@@ -1,4 +1,4 @@
/**
/**
* Failsafe
*
* Pretty much pokes the MC to make sure it's still alive.
@@ -31,7 +31,7 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
Initialize()
/datum/controller/failsafe/Initialize()
set waitfor = 0
set waitfor = FALSE
Failsafe.Loop()
if(!QDELETED(src))
qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us
@@ -97,4 +97,4 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
/datum/controller/failsafe/stat_entry(msg)
msg = "Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"
return msg
return msg
+3 -2
View File
@@ -20,8 +20,9 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
Initialize()
/datum/controller/global_vars/Destroy()
//fuck off kevinz
/datum/controller/global_vars/Destroy(force)
// This is done to prevent an exploit where admins can get around protected vars
SHOULD_CALL_PARENT(FALSE)
return QDEL_HINT_IWILLGC
/datum/controller/global_vars/stat_entry(msg)
+2 -2
View File
@@ -97,9 +97,9 @@
return
//This is used so the mc knows when the subsystem sleeps. do not override.
/datum/controller/subsystem/proc/ignite(resumed = 0)
/datum/controller/subsystem/proc/ignite(resumed = FALSE)
SHOULD_NOT_OVERRIDE(TRUE)
set waitfor = 0
set waitfor = FALSE
. = SS_SLEEPING
fire(resumed)
. = state
+1
View File
@@ -1,6 +1,7 @@
PROCESSING_SUBSYSTEM_DEF(dcs)
name = "Datum Component System"
flags = SS_NO_INIT
wait = 1 SECONDS
var/list/elements_by_type = list()
+3 -3
View File
@@ -60,9 +60,9 @@ SUBSYSTEM_DEF(economy)
secmedsrv_payout() // Payout based on crew safety, health, and mood.
civ_payout() // Payout based on ??? Profit
car_payout() // Cargo's natural gain in the cash moneys.
for(var/A in bank_accounts)
var/datum/bank_account/B = A
B.payday(1)
for(var/account in bank_accounts)
var/datum/bank_account/bank_account = account
bank_account.payday(1)
/datum/controller/subsystem/economy/proc/get_dep_account(dep_id)
+1 -1
View File
@@ -100,7 +100,7 @@ SUBSYSTEM_DEF(events)
// REEEEEEEEE
/client/proc/forceEvent()
set name = "Trigger Event"
set category = "Fun"
set category = "Admin.Events"
if(!holder ||!check_rights(R_FUN))
return
+9 -3
View File
@@ -665,7 +665,7 @@ SUBSYSTEM_DEF(job)
message_admins(msg)
CRASH(msg)
/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, equipbackpackstuff, bypass_prereqs = FALSE)
/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, equipbackpackstuff, bypass_prereqs = FALSE, can_drop = TRUE)
var/mob/the_mob = N
if(!the_mob)
the_mob = M // cause this doesn't get assigned if player is a latejoiner
@@ -694,9 +694,15 @@ SUBSYSTEM_DEF(job)
var/mob/living/carbon/C = M
var/obj/item/storage/backpack/B = C.back
if(!B || !SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, I, null, TRUE, TRUE)) // Otherwise, try to put it in the backpack, for carbons.
I.forceMove(get_turf(C))
if(can_drop)
I.forceMove(get_turf(C))
else
qdel(I)
else if(!M.equip_to_slot_if_possible(I, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // Otherwise, try to put it in the backpack
I.forceMove(get_turf(M)) // If everything fails, just put it on the floor under the mob.
if(can_drop)
I.forceMove(get_turf(M)) // If everything fails, just put it on the floor under the mob.
else
qdel(I)
/datum/controller/subsystem/job/proc/FreeRole(rank)
if(!rank)
+1 -1
View File
@@ -447,7 +447,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
//Manual loading of away missions.
/client/proc/admin_away()
set name = "Load Away Mission / Virtual Reality"
set category = "Fun"
set category = "Admin.Events"
if(!holder ||!check_rights(R_FUN))
return
+25 -22
View File
@@ -27,28 +27,6 @@ SUBSYSTEM_DEF(statpanels)
var/ETA = SSshuttle.emergency.getModeStr()
if(ETA)
global_data += "[ETA] [SSshuttle.emergency.getTimerStr()]"
/* Please fix
if(SSvote.mode)
var/static/list/supported = list(PLURALITY_VOTING, APPROVAL_VOTING)
global_data += "Vote active!, There is currently a vote running. Question: [SSvote.question]"
if(!(SSvote.vote_system in supported))
global_data += "<STATPANEL VOTING DISABLED>, The current vote system is not supported by statpanel rendering. Please vote manually by opening the vote popup using the action button or chat link."
return
global_data += "Time Left:, [round(SSvote.end_time - world.time)] seconds"
global_data += "Choices:"
for(var/i in 1 to SSvote.choice_statclicks.len)
var/choice = SSvote.choice_statclicks[i]
var/ivotedforthis = FALSE
if(usr.ckey)
switch(SSvote.vote_system)
if(APPROVAL_VOTING)
ivotedforthis = SSvote.voted[usr.ckey] && (i in SSvote.voted[usr.ckey])
if(PLURALITY_VOTING)
ivotedforthis = SSvote.voted[usr.ckey] == i
global_data += (ivotedforthis? "\[X\]" : "\[ \]", SSvote.choice_statclicks[choice])
*/
encoded_global_data = url_encode(json_encode(global_data))
src.currentrun = GLOB.clients.Copy()
@@ -63,6 +41,31 @@ SUBSYSTEM_DEF(statpanels)
var/ping_str = url_encode("Ping: [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)")
var/other_str = url_encode(json_encode(target.mob.get_status_tab_items()))
target << output("[encoded_global_data];[ping_str];[other_str]", "statbrowser:update")
if(SSvote.mode)
var/list/vote_arry = list(
list("Vote active!", "There is currently a vote running. Question: [SSvote.question]")
) //see the MC on how this works.
if(!(SSvote.vote_system in list(PLURALITY_VOTING, APPROVAL_VOTING)))
vote_arry[++vote_arry.len] += list("STATPANEL VOTING DISABLED!", "The current vote system is not supported by statpanel rendering. Please vote manually by opening the vote popup using the action button or chat link.", "disabled")
//does not return.
else
vote_arry[++vote_arry.len] += list("Time Left:", " [round(SSvote.end_time - world.time)] seconds")
vote_arry[++vote_arry.len] += list("Choices:", "")
for(var/choice in SSvote.choice_statclicks)
var/choice_id = SSvote.choice_statclicks[choice]
var/ivotedforthis = FALSE
if(target.ckey)
switch(SSvote.vote_system)
if(APPROVAL_VOTING)
ivotedforthis = SSvote.voted[target.ckey] && (text2num(choice_id) in SSvote.voted[usr.ckey])
if(PLURALITY_VOTING)
ivotedforthis = (SSvote.voted[target.ckey] == text2num(choice_id))
vote_arry[++vote_arry.len] += list(ivotedforthis ? "\[X\]" : "\[ \]", choice, "[REF(SSvote)];vote=[choice_id];statpannel=1")
var/vote_str = url_encode(json_encode(vote_arry))
target << output("[vote_str]", "statbrowser:update_voting")
else
var/null_bullet = url_encode(json_encode(list(list(null))))
target << output("[null_bullet]", "statbrowser:update_voting")
if(!target.holder)
target << output("", "statbrowser:remove_admin_tabs")
else
+6 -48
View File
@@ -16,6 +16,7 @@ SUBSYSTEM_DEF(vote)
var/question = null
var/list/choices = list()
/// List of choice = object for statclick objects for statpanel voting
/// statclick rework? 2: list("name"="id")
var/list/choice_statclicks = list()
var/list/scores = list()
var/list/choice_descs = list() // optional descriptions
@@ -49,34 +50,6 @@ SUBSYSTEM_DEF(vote)
client_popup.open(0)
next_pop = world.time+VOTE_COOLDOWN
/**
* Renders a statpanel. Directly uses statpanel/stat calls since this is called from base of mob/Stat().
*/
/datum/controller/subsystem/vote/proc/render_statpanel(mob/M)
if(!mode) // check if vote is running
return
if(!statpanel("Status")) // don't bother if they're not focused on this panel
return
var/static/list/supported = list(PLURALITY_VOTING, APPROVAL_VOTING)
stat("Vote active!", "There is currently a vote running. Question: [question]")
if(!(vote_system in supported))
stat("<STATPANEL VOTING DISABLED>", "The current vote system is not supported by statpanel rendering. Please vote manually by opening the vote popup using the action button or chat link.")
return
stat("Time Left:", "[round(end_time - world.time)] seconds")
stat(null, null)
stat("Choices:", null)
stat(null, null)
for(var/i in 1 to choice_statclicks.len)
var/choice = choice_statclicks[i]
var/ivotedforthis = FALSE
switch(vote_system)
if(APPROVAL_VOTING)
ivotedforthis = voted[usr.ckey] && (i in voted[usr.ckey])
if(PLURALITY_VOTING)
ivotedforthis = voted[usr.ckey] == i
stat(ivotedforthis? "\[X\]" : "\[ \]", choice_statclicks[choice])
stat(null, null)
/datum/controller/subsystem/vote/proc/reset()
initiator = null
end_time = 0
@@ -87,26 +60,10 @@ SUBSYSTEM_DEF(vote)
voted.Cut()
voting.Cut()
scores.Cut()
cleanup_statclicks()
choice_statclicks = list()
display_votes = initial(display_votes) //CIT CHANGE - obfuscated votes
remove_action_buttons()
/datum/controller/subsystem/vote/proc/cleanup_statclicks()
for(var/choice in choice_statclicks)
qdel(choice_statclicks[choice])
choice_statclicks = list()
/obj/effect/statclick/vote
name = "ERROR"
var/choice
/obj/effect/statclick/vote/Click()
SSvote.submit_vote(choice)
/obj/effect/statclick/vote/New(loc, choice, name)
src.choice = choice
src.name = name
/datum/controller/subsystem/vote/proc/get_result()
//get the highest number of votes
var/greatest_votes = 0
@@ -582,10 +539,10 @@ SUBSYSTEM_DEF(vote)
to_chat(world, "\n<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=[REF(src)]'>here</a> to place your votes.\nYou have [DisplayTimeText(vp)] to vote.</font>")
end_time = started_time+vp
// generate statclick list
cleanup_statclicks()
choice_statclicks = list()
for(var/i in 1 to choices.len)
var/choice = choices[i]
choice_statclicks[choice] = new /obj/effect/statclick/vote(null, i, choice)
choice_statclicks[choice] = "[i]"
//
for(var/c in GLOB.clients)
SEND_SOUND(c, sound('sound/misc/server-ready.ogg'))
@@ -785,7 +742,8 @@ SUBSYSTEM_DEF(vote)
submit_vote(round(text2num(href_list["vote"])),round(text2num(href_list["score"])))
else
submit_vote(round(text2num(href_list["vote"])))
usr.vote()
if(!href_list["statpannel"])
usr.vote()
/datum/controller/subsystem/vote/proc/remove_action_buttons()
for(var/v in generated_actions)
+1 -1
View File
@@ -451,7 +451,7 @@
// otherwise, just reset the client mob's machine var.
//
/client/verb/windowclose(atomref as text)
set hidden = 1 // hide this verb from the user's panel
set hidden = TRUE // hide this verb from the user's panel
set name = ".windowclose" // no autocomplete on cmd line
if(atomref!="null") // if passed a real atomref
+51 -34
View File
@@ -1,5 +1,3 @@
GLOBAL_LIST_EMPTY(cinematics)
// Use to play cinematics.
// Watcher can be world,mob, or a list of mobs
// Blocks until sequence is done.
@@ -18,6 +16,7 @@ GLOBAL_LIST_EMPTY(cinematics)
playing.is_global = TRUE
watcher = GLOB.mob_list
playing.play(watcher)
qdel(playing)
/obj/screen/cinematic
icon = 'icons/effects/station_explosion.dmi'
@@ -25,12 +24,13 @@ GLOBAL_LIST_EMPTY(cinematics)
plane = SPLASHSCREEN_PLANE
layer = SPLASHSCREEN_LAYER
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
screen_loc = "1,1"
screen_loc = "BOTTOM,LEFT+50%"
appearance_flags = APPEARANCE_UI | TILE_BOUND
/datum/cinematic
var/id = CINEMATIC_DEFAULT
var/list/watching = list() //List of clients watching this
var/list/locked = list() //Who had mob_transforming set during the cinematic
var/list/locked = list() //Who had mob_transforming set during the cinematic
var/is_global = FALSE //Global cinematics will override mob-specific ones
var/obj/screen/cinematic/screen
var/datum/callback/special_callback //For special effects synced with animation (explosions after the countdown etc)
@@ -38,28 +38,35 @@ GLOBAL_LIST_EMPTY(cinematics)
var/stop_ooc = TRUE //Turns off ooc when played globally.
/datum/cinematic/New()
GLOB.cinematics += src
screen = new(src)
/datum/cinematic/Destroy()
GLOB.cinematics -= src
for(var/CC in watching)
if(!CC)
continue
var/client/C = CC
//C.mob.clear_fullscreen("cinematic")
C.screen -= screen
watching = null
QDEL_NULL(screen)
for(var/mob/M in locked)
M.mob_transforming = FALSE
QDEL_NULL(special_callback)
for(var/MM in locked)
if(!MM)
continue
var/mob/M = MM
M.mob_transforming = FALSE
locked = null
return ..()
/datum/cinematic/proc/play(watchers)
//Check if you can actually play it (stop mob cinematics for global ones) and create screen objects
for(var/A in GLOB.cinematics)
var/datum/cinematic/C = A
if(C == src)
continue
if(C.is_global || !is_global)
return //Can't play two global or local cinematics at the same time
//Check if cinematic can actually play (stop mob cinematics for global ones)
if(SEND_GLOBAL_SIGNAL(COMSIG_GLOB_PLAY_CINEMATIC, src) & COMPONENT_GLOB_BLOCK_CINEMATIC)
return
//Close all open windows if global
if(is_global)
SStgui.close_all_uis()
//We are now playing this cinematic
//Handle what happens when a different cinematic tries to play over us
RegisterSignal(SSdcs, COMSIG_GLOB_PLAY_CINEMATIC, .proc/replacement_cinematic)
//Pause OOC
var/ooc_toggled = FALSE
@@ -67,24 +74,17 @@ GLOBAL_LIST_EMPTY(cinematics)
ooc_toggled = TRUE
toggle_ooc(FALSE)
for(var/mob/M in GLOB.mob_list)
if(M in watchers)
M.mob_transforming = TRUE //Should this be done for non-global cinematics or even at all ?
locked += M
//Close watcher ui's
SStgui.close_user_uis(M)
if(M.client)
watching += M.client
M.client.screen += screen
else
if(is_global)
M.mob_transforming = TRUE
locked += M
//Place /obj/screen/cinematic into everyone's screens, prevent them from moving
for(var/MM in watchers)
var/mob/M = MM
show_to(M, M.client)
RegisterSignal(M, COMSIG_MOB_CLIENT_LOGIN, .proc/show_to)
//Close watcher ui's
SStgui.close_user_uis(M)
//Actually play it
content()
//Cleanup
sleep(cleanup_time)
@@ -92,7 +92,17 @@ GLOBAL_LIST_EMPTY(cinematics)
if(ooc_toggled)
toggle_ooc(TRUE)
qdel(src)
/datum/cinematic/proc/show_to(mob/M, client/C)
//SIGNAL_HANDLER //must not wait.
if(!M.mob_transforming)
locked += M
M.mob_transforming = TRUE //Should this be done for non-global cinematics or even at all ?
if(!C)
return
watching += C
//M.overlay_fullscreen("cinematic",/obj/screen/fullscreen/cinematic_backdrop)
C.screen += screen
//Sound helper
/datum/cinematic/proc/cinematic_sound(s)
@@ -111,6 +121,13 @@ GLOBAL_LIST_EMPTY(cinematics)
/datum/cinematic/proc/content()
sleep(50)
/datum/cinematic/proc/replacement_cinematic(datum/source, datum/cinematic/other)
//SIGNAL_HANDLER
if(!is_global && other.is_global) //Allow it to play if we're local and it's global
return NONE
return COMPONENT_GLOB_BLOCK_CINEMATIC
/datum/cinematic/nuke_win
id = CINEMATIC_NUKE_WIN
+45 -17
View File
@@ -15,22 +15,32 @@
* If this is non zero then the object has been garbage collected and is awaiting either
* a hard del by the GC subsystme, or to be autocollected (if it has no references)
*/
var/gc_destroyed //Time when this object was destroyed.
var/gc_destroyed
/// Active timers with this datum as the target
var/list/active_timers
/// Status traits attached to this datum
var/list/status_traits
/// Components attached to this datum
/// Lazy associated list in the structure of `type:component/list of components`
/**
* Components attached to this datum
*
* Lazy associated list in the structure of `type:component/list of components`
*/
var/list/datum_components
/// Any datum registered to receive signals from this datum is in this list
/// Lazy associated list in the structure of `signal:registree/list of registrees`
var/list/comp_lookup //it used to be for looking up components which had registered a signal but now anything can register
/**
* Any datum registered to receive signals from this datum is in this list
*
* Lazy associated list in the structure of `signal:registree/list of registrees`
*/
var/list/comp_lookup
/// Lazy associated list in the structure of `signals:proctype` that are run when the datum receives that signal
var/list/list/datum/callback/signal_procs
/// Is this datum capable of sending signals?
/// Set to true when a signal has been registered
/**
* Is this datum capable of sending signals?
*
* Set to true when a signal has been registered
*/
var/signal_enabled = FALSE
/// Datum level flags
@@ -39,7 +49,12 @@
/// A weak reference to another datum
var/datum/weakref/weak_reference
///Lazy associative list of currently active cooldowns.
/*
* Lazy associative list of currently active cooldowns.
*
* cooldowns [ COOLDOWN_INDEX ] = add_timer()
* add_timer() returns the truthy value of -1 when not stoppable, and else a truthy numeric index
*/
var/list/cooldowns
#ifdef TESTING
@@ -51,23 +66,34 @@
var/list/cached_vars
#endif
/**
* Called when a href for this datum is clicked
*
* Sends a [COMSIG_TOPIC] signal
*/
/datum/Topic(href, href_list[])
..()
SEND_SIGNAL(src, COMSIG_TOPIC, usr, href_list)
/**
* Default implementation of clean-up code.
*
* This should be overridden to remove all references pointing to the object being destroyed, if
* you do override it, make sure to call the parent and return it's return value by default
*
* Return an appropriate QDEL_HINT to modify handling of your deletion;
* in most cases this is QDEL_HINT_QUEUE.
* Return an appropriate [QDEL_HINT][QDEL_HINT_QUEUE] to modify handling of your deletion;
* in most cases this is [QDEL_HINT_QUEUE].
*
* The base case is responsible for doing the following
* * Erasing timers pointing to this datum
* * Erasing compenents on this datum
* * Notifying datums listening to signals from this datum that we are going away
*
* Returns QDEL_HINT_QUEUE
* Returns [QDEL_HINT_QUEUE]
*/
/datum/proc/Destroy(force=FALSE, ...)
SHOULD_CALL_PARENT(TRUE)
tag = null
datum_flags &= ~DF_USE_TAG //In case something tries to REF us
weak_reference = null //ensure prompt GCing of weakref.
@@ -112,7 +138,7 @@
UnregisterSignal(target, signal_procs[target])
//END: ECS SHIT
SSsounds.free_datum_channels(src)
SSsounds.free_datum_channels(src) //?? (not on tg)
return QDEL_HINT_QUEUE
@@ -143,15 +169,15 @@
to_chat(target, txt_changed_vars())
#endif
//Return a LIST for serialize_datum to encode! Not the actual json!
///Return a LIST for serialize_datum to encode! Not the actual json!
/datum/proc/serialize_list(list/options)
CRASH("Attempted to serialize datum [src] of type [type] without serialize_list being implemented!")
//Accepts a LIST from deserialize_datum. Should return src or another datum.
///Accepts a LIST from deserialize_datum. Should return src or another datum.
/datum/proc/deserialize_list(json, list/options)
CRASH("Attempted to deserialize datum [src] of type [type] without deserialize_list being implemented!")
//Serializes into JSON. Does not encode type.
///Serializes into JSON. Does not encode type.
/datum/proc/serialize_json(list/options)
. = serialize_list(options)
if(!islist(.))
@@ -159,13 +185,14 @@
else
. = json_encode(.)
//Deserializes from JSON. Does not parse type.
///Deserializes from JSON. Does not parse type.
/datum/proc/deserialize_json(list/input, list/options)
var/list/jsonlist = json_decode(input)
. = deserialize_list(jsonlist)
if(!istype(., /datum))
. = null
///Convert a datum into a json blob
/proc/json_serialize_datum(datum/D, list/options)
if(!istype(D))
return
@@ -174,6 +201,7 @@
jsonlist["DATUM_TYPE"] = D.type
return json_encode(jsonlist)
/// Convert a list of json to datum
/proc/json_deserialize_datum(list/jsonlist, list/options, target_type, strict_target_type = FALSE)
if(!islist(jsonlist))
if(!istext(jsonlist))
+2
View File
@@ -89,6 +89,8 @@ GLOBAL_LIST_EMPTY(explosions)
if(adminlog)
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in [ADMIN_VERBOSEJMP(epicenter)]")
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in [loc_name(epicenter)]")
deadchat_broadcast("<span class='deadsay bold'>An explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) has occured at ([get_area(epicenter)])</span>", turf_target = get_turf(epicenter))
var/x0 = epicenter.x
var/y0 = epicenter.y
+1
View File
@@ -214,6 +214,7 @@
/datum/point/vector/processed/Destroy()
STOP_PROCESSING(SSprojectiles, src)
return ..()
/datum/point/vector/processed/proc/start()
last_process = world.time
+1
View File
@@ -171,6 +171,7 @@ GLOBAL_LIST_INIT_TYPED(skill_datums, /datum/skill, init_skill_datums())
continue
max_assoc = levels[lvl-1]
levels["[max_assoc] +[max_assoc_start++]"] = value
continue
levels[key] = value
/datum/skill/level/sanitize_value(new_value)
+2 -1
View File
@@ -1,6 +1,7 @@
/datum/skill/level/dorfy/blacksmithing
/datum/skill/level/dwarfy/blacksmithing
name = "Blacksmithing"
desc = "Making metal into fancy shapes using heat and force. Higher levels increase both your working speed at an anvil as well as the quality of your works."
name_color = COLOR_FLOORTILE_GRAY
skill_traits = list(SKILL_SANITY, SKILL_INTELLIGENCE, SKILL_USE_TOOL, SKILL_TRAINING_TOOL)
ui_category = SKILL_UI_CAT_MISC
standard_xp_lvl_up = 100 //Effectively 200xp for level 1 because of how this code works. 300 more for 2, Etc,
+1 -1
View File
@@ -1046,7 +1046,7 @@ datum/status_effect/pacify
id = "fake_virus"
duration = 1800//3 minutes
status_type = STATUS_EFFECT_REPLACE
tick_interval = 1
tick_interval = 20
alert_type = null
var/msg_stage = 0//so you dont get the most intense messages immediately
+6 -2
View File
@@ -16,8 +16,12 @@
/datum/weakref/New(datum/thing)
reference = REF(thing)
/datum/weakref/Destroy()
return QDEL_HINT_LETMELIVE //Let BYOND autoGC thiswhen nothing is using it anymore.
/datum/weakref/Destroy(force)
if(!force)
return QDEL_HINT_LETMELIVE //Let BYOND autoGC thiswhen nothing is using it anymore.
var/datum/target = resolve()
target?.weak_reference = null
return ..()
/datum/weakref/proc/resolve()
var/datum/D = locate(reference)
+1 -1
View File
@@ -79,7 +79,7 @@
/// Used to "load" a persistent scar
/datum/scar/proc/load(obj/item/bodypart/BP, version, description, specific_location, severity=WOUND_SEVERITY_SEVERE)
if(!(BP.body_zone in applicable_zones) || !BP.is_organic_limb())
if(!(BP.body_zone in applicable_zones) || !(BP.is_organic_limb() || BP.render_like_organic))
qdel(src)
return
+1 -1
View File
@@ -110,7 +110,7 @@
* * smited- If this is a smite, we don't care about this wound for stat tracking purposes (not yet implemented)
*/
/datum/wound/proc/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE)
if(!istype(L) || !L.owner || !(L.body_zone in viable_zones) || isalien(L.owner) || !L.is_organic_limb())
if(!istype(L) || !L.owner || !(L.body_zone in viable_zones) || isalien(L.owner) || !(L.is_organic_limb() || L.render_like_organic))
qdel(src)
return
+5 -2
View File
@@ -18,9 +18,10 @@ GLOBAL_LIST_EMPTY(announcement_systems)
var/obj/item/radio/headset/radio
var/arrival = "%PERSON has signed up as %RANK"
var/arrivalToggle = 1
var/arrivalToggle = TRUE
var/newhead = "%PERSON, %RANK, is the department head."
var/newheadToggle = 1
var/newheadToggle = TRUE
var/cryostorage = "%PERSON, %RANK, has been moved into cryogenic storage." // this shouldnt be changed
var/greenlight = "Light_Green"
var/pinklight = "Light_Pink"
@@ -84,6 +85,8 @@ GLOBAL_LIST_EMPTY(announcement_systems)
message = CompileText(arrival, user, rank)
else if(message_type == "NEWHEAD" && newheadToggle)
message = CompileText(newhead, user, rank)
else if(message_type == "CRYOSTORAGE")
message = CompileText(cryostorage, user, rank)
else if(message_type == "ARRIVALS_BROKEN")
message = "The arrivals shuttle has been damaged. Docking for repairs..."
+2
View File
@@ -64,6 +64,8 @@
/obj/mecha/combat/neovgre/process()
..()
if(!obj_integrity) //Integrity is zero but we would heal out of that state if we went into this before it recognises it being zero
return
if(GLOB.ratvar_awakens) // At this point only timley intervention by lord singulo could hope to stop the superweapon
cell.charge = INFINITY
max_integrity = INFINITY
+1
View File
@@ -10,6 +10,7 @@
if(log)
message_admins("EMP with power [power], max distance [max_distance] in area [epicenter.loc.name] ")
log_game("EMP with power [power], max distance [max_distance] in area [epicenter.loc.name] ")
deadchat_broadcast("<span class='deadsay bold'>EMP with power ([power]), max distance ([max_distance]) in [epicenter.loc.name]</span>", turf_target = epicenter)
if(power > 100)
new /obj/effect/temp_visual/emp/pulse(epicenter)
+26 -2
View File
@@ -165,6 +165,30 @@
throwforce = 15
bayonet = TRUE
/obj/item/kitchen/knife/combat/survival/knuckledagger
name = "survival dagger"
icon_state = "glaive-dagger"
desc = "An enhanced hunting grade survival dagger, with a bright light and a handguard that makes it better for efficient butchery."
actions_types = list(/datum/action/item_action/toggle_light)
var/light_on = FALSE
var/brightness_on = 7
/obj/item/kitchen/knife/combat/survival/knuckledagger/Initialize()
. = ..()
AddComponent(/datum/component/butchering, 50, 120, 5) // it's good for butchering stuff
/obj/item/kitchen/knife/combat/survival/knuckledagger/ui_action_click(mob/user, actiontype)
light_on = !light_on
playsound(user, 'sound/weapons/empty.ogg', 100, TRUE)
update_brightness(user)
update_icon()
/obj/item/kitchen/knife/combat/survival/knuckledagger/proc/update_brightness(mob/user = null)
if(light_on)
set_light(brightness_on)
else
set_light(0)
/obj/item/kitchen/knife/combat/bone
name = "bone dagger"
item_state = "bone_dagger"
@@ -222,10 +246,10 @@
/* Trays moved to /obj/item/storage/bag */
/obj/item/kitchen/knife/scimitar
name = "Scimitar knife"
name = "scimitar knife"
desc = "A knife used to cleanly butcher. Its razor-sharp edge has been honed for butchering, but has been poorly maintained over the years."
attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
/obj/item/kitchen/knife/scimiar/Initialize()
/obj/item/kitchen/knife/scimitar/Initialize()
. = ..()
AddComponent(/datum/component/butchering, 90 - force, 100, force - 60) //bonus chance increases depending on force
+11 -6
View File
@@ -150,6 +150,7 @@
if(squeak_override)
var/datum/component/squeak/S = GetComponent(/datum/component/squeak)
S?.override_squeak_sounds = squeak_override
snowflake_id = id
/obj/item/toy/plush/handle_atom_del(atom/A)
if(A == grenade)
@@ -827,12 +828,16 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
if(!victim)
return
visible_message("<span class='warning'>[src] gruesomely mutilliates [victim], leaving nothing more than dust!</span>")
name = victim.name
desc = victim.desc + " Wait, did it just move..?"
icon_state = victim.icon_state
item_state = victim.item_state
squeak_override = victim.squeak_override
attack_verb = victim.attack_verb
if(victim.snowflake_id) //Snowflake code for snowflake plushies.
set_snowflake_from_config(victim.snowflake_id)
desc += " Wait, did it just move..?"
else
name = victim.name
desc = victim.desc + " Wait, did it just move..?"
icon_state = victim.icon_state
item_state = victim.item_state
squeak_override = victim.squeak_override
attack_verb = victim.attack_verb
new /obj/effect/decal/cleanable/ash(get_turf(victim))
qdel(victim)
@@ -27,6 +27,13 @@
return FALSE
return TRUE
/*
This proc gets called by upgrades after installing them. Use this for things that for example need to be moved into a specific borg item,
as performing this in action() will cause the upgrade to end up in the borg instead of its intended location due to forceMove() being called afterwards..
*/
/obj/item/borg/upgrade/proc/afterInstall(mob/living/silicon/robot/R, user = usr)
return
/obj/item/borg/upgrade/proc/deactivate(mob/living/silicon/robot/R, user = usr)
if (!(src in R.upgrades))
return FALSE
@@ -211,6 +211,12 @@
turf_type = /turf/open/floor/carpet/black
tableVariant = /obj/structure/table/wood/fancy/black
/obj/item/stack/tile/carpet/arcade
name = "arcade carpet"
icon_state = "tile-carpet-arcade"
turf_type = /turf/open/floor/carpet/arcade
tableVariant = null
/obj/item/stack/tile/carpet/blackred
name = "red carpet"
icon_state = "tile-carpet-blackred"
@@ -297,6 +303,15 @@
/obj/item/stack/tile/carpet/black/fifty
amount = 50
/obj/item/stack/tile/carpet/arcade/ten
amount = 10
/obj/item/stack/tile/carpet/arcade/twenty
amount = 20
/obj/item/stack/tile/carpet/arcade/fifty
amount = 50
/obj/item/stack/tile/carpet/blackred/ten
amount = 10
+4
View File
@@ -98,6 +98,10 @@
/obj/structure/holosign/barrier/firelock/BlockSuperconductivity()
return TRUE
/obj/structure/holosign/barrier/firelock/Initialize()
. = ..()
air_update_turf(TRUE)
/obj/structure/holosign/barrier/combifan
name = "holo combifan"
desc = "A holographic barrier resembling a blue-accented tiny fan. Though it does not prevent solid objects from passing through, gas and temperature changes are kept out."
+2 -2
View File
@@ -163,7 +163,7 @@
var/custom_tone = input(user, "Choose your custom skin tone:", "Race change", default) as color|null
if(custom_tone)
var/temp_hsv = RGBtoHSV(new_s_tone)
if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3])
to_chat(H,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
else
H.skin_tone = custom_tone
@@ -177,7 +177,7 @@
if(new_mutantcolor)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright
if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright
H.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
else
+2 -5
View File
@@ -131,15 +131,12 @@
return ..()
/obj/structure/toilet/secret
var/obj/item/secret
var/secret_type = null
/obj/structure/toilet/secret/Initialize(mapload)
/obj/structure/toilet/secret/Initialize()
. = ..()
if (secret_type)
secret = new secret_type(src)
secret.desc += "" //In case you want to add something to the item that spawns
contents += secret
new secret_type(src)
/obj/structure/toilet/secret/LateInitialize()
. = ..()
+1 -1
View File
@@ -46,7 +46,7 @@
"basalt0","basalt1","basalt2","basalt3","basalt4",
"basalt5","basalt6","basalt7","basalt8","basalt9","basalt10","basalt11","basalt12",
"oldburning","light-on-r","light-on-y","light-on-g","light-on-b", "wood", "carpetsymbol", "carpetstar",
"carpetcorner", "carpetside", "carpet", "ironsand1", "ironsand2", "ironsand3", "ironsand4", "ironsand5",
"carpetcorner", "carpetside", "carpet", "arcade", "ironsand1", "ironsand2", "ironsand3", "ironsand4", "ironsand5",
"ironsand6", "ironsand7", "ironsand8", "ironsand9", "ironsand10", "ironsand11",
"ironsand12", "ironsand13", "ironsand14", "ironsand15",
"snow", "snow0", "snow1", "snow2", "snow3", "snow4", "snow5", "snow6", "snow7", "snow8", "snow9", "snow10", "snow11", "snow12", "snow-ice", "snow_dug",
@@ -273,6 +273,13 @@
smooth = SMOOTH_MORE
canSmoothWith = list(/turf/open/floor/carpet/black, /turf/open/floor/carpet/blackred, /turf/open/floor/carpet/monochrome)
/turf/open/floor/carpet/arcade
icon = 'icons/turf/floors.dmi'
icon_state = "arcade"
floor_tile = /obj/item/stack/tile/carpet/arcade
smooth = SMOOTH_FALSE
canSmoothWith = list()
/turf/open/floor/carpet/blackred
icon = 'icons/turf/floors/carpet_blackred.dmi'
floor_tile = /obj/item/stack/tile/carpet/blackred
+2 -2
View File
@@ -12,7 +12,7 @@
///////////////////////////////////////////////////////////////////////////////////////////////Panels
/datum/admins/proc/show_player_panel(mob/M in GLOB.mob_list)
set category = "Admin"
set category = "Admin.Game"
set name = "Show Player Panel"
set desc="Edit player (respawn, ban, heal, etc)"
@@ -211,7 +211,7 @@
/datum/admins/proc/access_news_network() //MARKER
set category = "Fun"
set category = "Admin.Events"
set name = "Access Newscaster Network"
set desc = "Allows you to view, add and edit news feeds."
+1 -1
View File
@@ -6,7 +6,7 @@
/client/proc/investigate_show()
set name = "Investigate"
set category = "Admin"
set category = "Admin.Game"
if(!holder)
return
+14 -14
View File
@@ -348,7 +348,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/admin_ghost()
set category = "Admin"
set category = "Admin.Game"
set name = "Aghost"
if(!holder)
return FALSE
@@ -379,7 +379,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/invisimin()
set name = "Invisimin"
set category = "Admin"
set category = "Admin.Game"
set desc = "Toggles ghost-like invisibility (Don't abuse this)"
if(holder && mob)
if(mob.invisibility == INVISIBILITY_OBSERVER)
@@ -391,7 +391,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/check_antagonists()
set name = "Check Antagonists"
set category = "Admin"
set category = "Admin.Game"
if(holder)
holder.check_antagonists()
log_admin("[key_name(usr)] checked antagonists.") //for tsar~
@@ -411,14 +411,14 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/game_panel()
set name = "Game Panel"
set category = "Admin"
set category = "Admin.Game"
if(holder)
holder.Game()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Game Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/secrets()
set name = "Secrets"
set category = "Admin"
set category = "Admin.Game"
if (holder)
holder.Secrets()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Secrets Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -472,7 +472,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Stealth Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/drop_bomb()
set category = "Special Verbs"
set category = "Admin.Fun"
set name = "Drop Bomb"
set desc = "Cause an explosion of varying strength at your location."
@@ -514,7 +514,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Bomb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/drop_dynex_bomb()
set category = "Special Verbs"
set category = "Admin.Fun"
set name = "Drop DynEx Bomb"
set desc = "Cause an explosion of varying strength at your location."
@@ -561,7 +561,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
message_admins("[key_name_admin(usr)] has modified Dynamic Explosion Scale: [ex_scale]")
/client/proc/give_spell(mob/T in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Give Spell"
set desc = "Gives a spell to a mob."
@@ -585,7 +585,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
message_admins("<span class='danger'>Spells given to mindless mobs will not be transferred in mindswap or cloning!</span>")
/client/proc/remove_spell(mob/T in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Remove Spell"
set desc = "Remove a spell from the selected mob."
@@ -598,7 +598,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Spell") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/give_disease(mob/living/T in GLOB.mob_living_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Give Disease"
set desc = "Gives a Disease to a mob."
if(!istype(T))
@@ -613,7 +613,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] gave [key_name(T)] the disease [D].</span>")
/client/proc/object_say(obj/O in world)
set category = "Special Verbs"
set category = "Admin.Events"
set name = "OSay"
set desc = "Makes an object say something."
var/message = input(usr, "What do you want the message to be?", "Make Sound") as text | null
@@ -625,7 +625,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Object Say") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/togglebuildmodeself()
set name = "Toggle Build Mode Self"
set category = "Special Verbs"
set category = "Admin.Events"
if (!(holder.rank.rights & R_BUILDMODE))
return
if(src.mob)
@@ -634,7 +634,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/check_ai_laws()
set name = "Check AI Laws"
set category = "Admin"
set category = "Admin.Game"
if(holder)
src.holder.output_ai_laws()
@@ -717,7 +717,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/toggle_AI_interact()
set name = "Toggle Admin AI Interact"
set category = "Admin"
set category = "Admin.Game"
set desc = "Allows you to interact with most machines as an AI would as a ghost"
AI_Interact = !AI_Interact
+1 -1
View File
@@ -5,7 +5,7 @@
/datum/verbs/menu/Admin/verb/playerpanel()
set name = "Player Panel"
set desc = "Player Panel"
set category = "Admin"
set category = "Admin.Game"
if(usr.client.holder)
usr.client.holder.player_panel_new()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Player Panel New") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+8 -8
View File
@@ -1,7 +1,7 @@
/client/proc/jumptoarea(area/A in GLOB.sortedAreas)
set name = "Jump to Area"
set desc = "Area to jump to"
set category = "Admin"
set category = "Admin.Game"
if(!src.holder)
to_chat(src, "Only administrators may use this command.", confidential = TRUE)
return
@@ -28,7 +28,7 @@
/client/proc/jumptoturf(turf/T in world)
set name = "Jump to Turf"
set category = "Admin"
set category = "Admin.Game"
if(!src.holder)
to_chat(src, "Only administrators may use this command.", confidential = TRUE)
return
@@ -40,7 +40,7 @@
return
/client/proc/jumptomob(mob/M in GLOB.mob_list)
set category = "Admin"
set category = "Admin.Game"
set name = "Jump to Mob"
if(!src.holder)
@@ -59,7 +59,7 @@
to_chat(A, "This mob is not located in the game world.", confidential = TRUE)
/client/proc/jumptocoord(tx as num, ty as num, tz as num)
set category = "Admin"
set category = "Admin.Game"
set name = "Jump to Coordinate"
if (!holder)
@@ -74,7 +74,7 @@
message_admins("[key_name_admin(usr)] jumped to coordinates [tx], [ty], [tz]")
/client/proc/jumptokey()
set category = "Admin"
set category = "Admin.Game"
set name = "Jump to Key"
if(!src.holder)
@@ -97,7 +97,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/Getmob(mob/M in GLOB.mob_list - GLOB.dummy_mob_list)
set category = "Admin"
set category = "Admin.Game"
set name = "Get Mob"
set desc = "Mob to teleport"
if(!src.holder)
@@ -113,7 +113,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Get Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/Getkey()
set category = "Admin"
set category = "Admin.Game"
set name = "Get Key"
set desc = "Key to teleport"
@@ -141,7 +141,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Get Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/sendmob(mob/M in sortmobs())
set category = "Admin"
set category = "Admin.Game"
set name = "Send Mob"
if(!src.holder)
to_chat(src, "Only administrators may use this command.", confidential = TRUE)
+1 -1
View File
@@ -1,5 +1,5 @@
/datum/admins/proc/open_borgopanel(borgo in GLOB.silicon_mobs)
set category = "Admin"
set category = "Admin.Game"
set name = "Show Borg Panel"
set desc = "Show borg panel"
+1 -1
View File
@@ -1,6 +1,6 @@
/client/proc/cinematic()
set name = "cinematic"
set category = "Fun"
set category = "Admin.Fun"
set desc = "Shows a cinematic." // Intended for testing but I thought it might be nice for events on the rare occasion Feel free to comment it out if it's not wanted.
set hidden = 1
if(!SSticker)
+1 -1
View File
@@ -1,5 +1,5 @@
/client/proc/dsay(msg as text)
set category = "Special Verbs"
set category = "Admin.Game"
set name = "Dsay"
set hidden = 1
if(!holder)
+35 -8
View File
@@ -27,7 +27,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Air Status In Location") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_robotize(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make Robot"
if(!SSticker.HasRoundStarted())
@@ -43,7 +43,7 @@
alert("Invalid mob")
/client/proc/cmd_admin_blobize(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make Blob"
if(!SSticker.HasRoundStarted())
@@ -58,7 +58,7 @@
/client/proc/cmd_admin_animalize(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make Simple Animal"
if(!SSticker.HasRoundStarted())
@@ -79,7 +79,7 @@
/client/proc/makepAI(turf/T in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make pAI"
set desc = "Specify a location to spawn a pAI device, then specify a key to play that pAI"
@@ -106,7 +106,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make pAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_alienize(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make Alien"
if(!SSticker.HasRoundStarted())
@@ -121,7 +121,7 @@
alert("Invalid mob")
/client/proc/cmd_admin_slimeize(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make slime"
if(!SSticker.HasRoundStarted())
@@ -211,7 +211,7 @@
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has granted [M.key] full access.</span>")
/client/proc/cmd_assume_direct_control(mob/M in GLOB.mob_list)
set category = "Admin"
set category = "Admin.Game"
set name = "Assume direct control"
set desc = "Direct intervention"
@@ -229,6 +229,33 @@
qdel(adminmob)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Assume Direct Control") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_give_direct_control(mob/M in GLOB.mob_list)
set category = "Admin.Game"
set name = "Give direct control"
if(!M)
return
if(M.ckey)
if(alert("This mob is being controlled by [M.key]. Are you sure you wish to give someone else control of it? [M.key] will be made a ghost.",,"Yes","No") != "Yes")
return
var/client/newkey = input(src, "Pick the player to put in control.", "New player") as null|anything in sortList(GLOB.clients)
var/mob/oldmob = newkey.mob
var/delmob = FALSE
if((isobserver(oldmob) || alert("Do you want to delete [newkey]'s old mob?","Delete?","Yes","No") != "No"))
delmob = TRUE
if(!M || QDELETED(M))
to_chat(usr, "<span class='warning'>The target mob no longer exists, aborting.</span>")
return
if(M.ckey)
M.ghostize(FALSE)
M.ckey = newkey.key
M.client?.init_verbs()
if(delmob)
qdel(oldmob)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] gave away direct control of [M] to [newkey].</span>")
log_admin("[key_name(usr)] gave away direct control of [M] to [newkey].")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Direct Control") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_test_atmos_controllers()
set category = "Mapping"
set name = "Test Atmos Monitoring Consoles"
@@ -455,7 +482,7 @@
cmd_admin_areatest(FALSE)
/client/proc/cmd_admin_dress(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Events"
set name = "Select equipment"
if(!(ishuman(M) || isobserver(M)))
alert("Invalid mob")
+1 -1
View File
@@ -1,5 +1,5 @@
/client/proc/roll_dices()
set category = "Fun"
set category = "Admin.Fun"
set name = "Roll Dice"
if(!check_rights(R_FUN))
return
+1 -1
View File
@@ -1,7 +1,7 @@
/client/proc/one_click_antag()
set name = "Create Antagonist"
set desc = "Auto-create an antagonist of your choice"
set category = "Admin"
set category = "Admin.Events"
if(holder)
holder.one_click_antag()
+5 -5
View File
@@ -1,5 +1,5 @@
/client/proc/play_sound(S as sound)
set category = "Fun"
set category = "Admin.Fun"
set name = "Play Global Sound"
if(!check_rights(R_SOUNDS))
return
@@ -42,7 +42,7 @@
/client/proc/play_local_sound(S as sound)
set category = "Fun"
set category = "Admin.Fun"
set name = "Play Local Sound"
if(!check_rights(R_SOUNDS))
return
@@ -53,7 +53,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Local Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/play_web_sound()
set category = "Fun"
set category = "Admin.Fun"
set name = "Play Internet Sound"
if(!check_rights(R_SOUNDS))
return
@@ -136,7 +136,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Internet Sound")
/client/proc/manual_play_web_sound()
set category = "Fun"
set category = "Admin.Fun"
set name = "Manual Play Internet Sound"
if(!check_rights(R_SOUNDS))
return
@@ -182,7 +182,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Manual Play Internet Sound")
/client/proc/set_round_end_sound(S as sound)
set category = "Fun"
set category = "Admin.Fun"
set name = "Set Round End Sound"
if(!check_rights(R_SOUNDS))
return
+70 -29
View File
@@ -20,7 +20,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list)
set category = "Special Verbs"
set category = "Admin.Events"
set name = "Subtle Message"
if(!ismob(M))
@@ -46,7 +46,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_headset_message(mob/M in GLOB.mob_list)
set category = "Special Verbs"
set category = "Admin.Events"
set name = "Headset Message"
admin_headset_message(M)
@@ -128,7 +128,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Modify Antagonist Reputation") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_world_narrate()
set category = "Special Verbs"
set category = "Admin.Events"
set name = "Global Narrate"
if(!check_rights(R_ADMIN))
@@ -144,7 +144,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Global Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_direct_narrate(mob/M)
set category = "Special Verbs"
set category = "Admin.Events"
set name = "Direct Narrate"
if(!check_rights(R_ADMIN))
@@ -169,7 +169,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Direct Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_local_narrate(atom/A)
set category = "Special Verbs"
set category = "Admin.Events"
set name = "Local Narrate"
if(!check_rights(R_ADMIN))
@@ -190,7 +190,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Local Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_godmode(mob/M in GLOB.mob_list)
set category = "Special Verbs"
set category = "Admin.Game"
set name = "Godmode"
if(!check_rights(R_ADMIN))
return
@@ -335,7 +335,7 @@ Works kind of like entering the game with a new character. Character receives a
Traitors and the like can also be revived with the previous role mostly intact.
/N */
/client/proc/respawn_character()
set category = "Special Verbs"
set category = "Admin.Game"
set name = "Respawn Character"
set desc = "Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into."
if(!check_rights(R_ADMIN))
@@ -503,7 +503,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
return new_character
/client/proc/cmd_admin_add_freeform_ai_law()
set category = "Fun"
set category = "Admin.Events"
set name = "Add Custom AI law"
if(!check_rights(R_ADMIN))
@@ -546,7 +546,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
SSblackbox.record_feedback("tally", "admin_verb", 1, "Rejuvinate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_create_centcom_report()
set category = "Special Verbs"
set category = "Admin.Events"
set name = "Create Command Report"
if(!check_rights(R_ADMIN))
@@ -572,7 +572,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
SSblackbox.record_feedback("tally", "admin_verb", 1, "Create Command Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_change_command_name()
set category = "Special Verbs"
set category = "Admin.Events"
set name = "Change Command Name"
if(!check_rights(R_ADMIN))
@@ -595,7 +595,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
admin_delete(A)
/client/proc/cmd_admin_list_open_jobs()
set category = "Admin"
set category = "Admin.Game"
set name = "Manage Job Slots"
if(!check_rights(R_ADMIN))
@@ -604,7 +604,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
SSblackbox.record_feedback("tally", "admin_verb", 1, "Manage Job Slots") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world)
set category = "Special Verbs"
set category = "Admin.Fun"
set name = "Explosion"
if(!check_rights(R_ADMIN))
@@ -640,7 +640,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
return
/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world)
set category = "Special Verbs"
set category = "Admin.Fun"
set name = "EM Pulse"
if(!check_rights(R_ADMIN))
@@ -656,7 +656,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
SSblackbox.record_feedback("tally", "admin_verb", 1, "EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_gib(mob/M in GLOB.mob_list)
set category = "Special Verbs"
set category = "Admin.Fun"
set name = "Gib"
if(!check_rights(R_ADMIN))
@@ -683,7 +683,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/cmd_admin_gib_self()
set name = "Gibself"
set category = "Fun"
set category = "Admin.Fun"
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm == "Yes")
@@ -702,7 +702,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
SSblackbox.record_feedback("tally", "admin_verb", 1, "Check Contents") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/toggle_view_range()
set category = "Special Verbs"
set category = "Admin.Game"
set name = "Change View Range"
set desc = "switches between 1x and custom views"
@@ -717,8 +717,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Change View Range", "[view]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/admin_call_shuttle()
set category = "Admin"
set category = "Admin.Events"
set name = "Call Shuttle"
if(EMERGENCY_AT_LEAST_DOCKED)
@@ -738,7 +737,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
return
/client/proc/admin_cancel_shuttle()
set category = "Admin"
set category = "Admin.Events"
set name = "Cancel Shuttle"
if(!check_rights(0))
return
@@ -754,9 +753,51 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("<span class='adminnotice'>[key_name_admin(usr)] admin-recalled the emergency shuttle.</span>")
return
/*
/client/proc/admin_disable_shuttle()
set category = "Admin.Events"
set name = "Disable Shuttle"
if(!check_rights(R_ADMIN))
return
if(SSshuttle.emergency.mode == SHUTTLE_DISABLED)
to_chat(usr, "<span class='warning'>Error, shuttle is already disabled.</span>")
return
if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes")
return
message_admins("<span class='adminnotice'>[key_name_admin(usr)] disabled the shuttle.</span>")
SSshuttle.lastMode = SSshuttle.emergency.mode
SSshuttle.lastCallTime = SSshuttle.emergency.timeLeft(1)
SSshuttle.adminEmergencyNoRecall = TRUE
SSshuttle.emergency.setTimer(0)
SSshuttle.emergency.mode = SHUTTLE_DISABLED
priority_announce("Warning: Emergency Shuttle uplink failure, shuttle disabled until further notice.", "Emergency Shuttle Uplink Alert", 'sound/misc/announce_dig.ogg')
/client/proc/admin_enable_shuttle()
set category = "Admin - Events"
set category = "Admin.Events"
set name = "Enable Shuttle"
if(!check_rights(R_ADMIN))
return
if(SSshuttle.emergency.mode != SHUTTLE_DISABLED)
to_chat(usr, "<span class='warning'>Error, shuttle not disabled.</span>")
return
if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes")
return
message_admins("<span class='adminnotice'>[key_name_admin(usr)] enabled the emergency shuttle.</span>")
SSshuttle.adminEmergencyNoRecall = FALSE
SSshuttle.emergencyNoRecall = FALSE
if(SSshuttle.lastMode == SHUTTLE_DISABLED) //If everything goes to shit, fix it.
SSshuttle.lastMode = SHUTTLE_IDLE
SSshuttle.emergency.mode = SSshuttle.lastMode
if(SSshuttle.lastCallTime < 10 SECONDS && SSshuttle.lastMode != SHUTTLE_IDLE)
SSshuttle.lastCallTime = 10 SECONDS //Make sure no insta departures.
SSshuttle.emergency.setTimer(SSshuttle.lastCallTime)
priority_announce("Warning: Emergency Shuttle uplink reestablished, shuttle enabled.", "Emergency Shuttle Uplink Alert", 'sound/misc/announce_dig.ogg')
*/
/client/proc/everyone_random()
set category = "Fun"
set category = "Admin.Fun"
set name = "Make Everyone Random"
set desc = "Make everyone have a random appearance. You can only use this before rounds!"
@@ -804,7 +845,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/admin_change_sec_level()
set category = "Special Verbs"
set category = "Admin.Events"
set name = "Set Security Level"
set desc = "Changes the security level. Announcement only, i.e. setting to Delta won't activate nuke"
@@ -821,7 +862,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in GLOB.nuke_list)
set name = "Toggle Nuke"
set category = "Fun"
set category = "Admin.Events"
set popup_menu = 0
if(!check_rights(R_DEBUG))
return
@@ -1016,7 +1057,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
usr << browse(dat, "window=dressup;size=550x600")
/client/proc/toggle_combo_hud()
set category = "Admin"
set category = "Admin.Game"
set name = "Toggle Combo HUD"
set desc = "Toggles the Admin Combo HUD (antag, sci, med, eng)"
@@ -1051,7 +1092,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
/client/proc/run_weather()
set category = "Fun"
set category = "Admin.Events"
set name = "Run Weather"
set desc = "Triggers a weather on the z-level you choose."
@@ -1075,7 +1116,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
SSblackbox.record_feedback("tally", "admin_verb", 1, "Run Weather")
/client/proc/mass_zombie_infection()
set category = "Fun"
set category = "Admin.Fun"
set name = "Mass Zombie Infection"
set desc = "Infects all humans with a latent organ that will zombify \
them on death."
@@ -1095,7 +1136,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
SSblackbox.record_feedback("tally", "admin_verb", 1, "Mass Zombie Infection")
/client/proc/mass_zombie_cure()
set category = "Fun"
set category = "Admin.Fun"
set name = "Mass Zombie Cure"
set desc = "Removes the zombie infection from all humans, returning them to normal."
if(!check_rights(R_ADMIN))
@@ -1113,7 +1154,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
SSblackbox.record_feedback("tally", "admin_verb", 1, "Mass Zombie Cure")
/client/proc/polymorph_all()
set category = "Fun"
set category = "Admin.Fun"
set name = "Polymorph All"
set desc = "Applies the effects of the bolt of change to every single mob."
@@ -1203,7 +1244,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggled Hub Visibility", "[GLOB.hub_visibility ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_toggle_fov()
set category = "Fun"
set category = "Admin.Fun"
set name = "Enable/Disable Field of Vision"
var/static/busy_toggling_fov = FALSE
@@ -1256,7 +1297,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
/client/proc/smite(mob/living/carbon/human/target as mob)
set name = "Smite"
set category = "Fun"
set category = "Admin.Fun"
if(!check_rights(R_ADMIN) || !check_rights(R_FUN))
return
+1 -1
View File
@@ -1,5 +1,5 @@
/datum/admins/proc/open_shuttlepanel()
set category = "Admin"
set category = "Admin.Events"
set name = "Shuttle Manipulator"
set desc = "Opens the shuttle manipulator UI."
+1 -1
View File
@@ -1,5 +1,5 @@
/client/proc/triple_ai()
set category = "Fun"
set category = "Admin.Events"
set name = "Create AI Triumvirate"
if(SSticker.current_state > GAME_STATE_PREGAME)
@@ -180,10 +180,12 @@
button.screen_loc = DEFAULT_BLOODSPELLS
button.moved = DEFAULT_BLOODSPELLS
button.ordered = FALSE
/datum/action/bloodsucker/passive/Destroy()
if(owner)
Remove(owner)
target = null
return ..()
/////////////////////////////////// TARGETTED POWERS ///////////////////////////////////
@@ -456,6 +456,7 @@
/obj/structure/bloodsucker/candelabrum/Destroy()
STOP_PROCESSING(SSobj, src)
return ..() //return a hint
/obj/structure/bloodsucker/candelabrum/update_icon_state()
icon_state = "candelabrum[lit ? "_lit" : ""]"
@@ -38,8 +38,9 @@
var/mimicing = ""
var/canrespec = 0
var/changeling_speak = 0
var/loudfactor = 0 //Used for blood tests. At 4, blood tests will succeed. At 10, blood tests will result in an explosion.
var/bloodtestwarnings = 0 //Used to track if the ling has been notified that they will pass blood tests.
var/loudfactor = 0 //Used for blood tests. This is is the average loudness of the ling's abilities calculated with the below two vars
var/loudtotal = 0 //Used to keep track of the sum of the ling's loudness
var/totalpurchases = 0 //Used to keep track of how many purchases the ling's made after free abilities have been added
var/datum/dna/chosen_dna
var/obj/effect/proc_holder/changeling/sting/chosen_sting
var/datum/cellular_emporium/cellular_emporium
@@ -139,8 +140,6 @@
/datum/antagonist/changeling/proc/reset_powers()
if(purchasedpowers)
remove_changeling_powers()
loudfactor = 0
bloodtestwarnings = 0
//Repurchase free powers.
for(var/path in all_powers)
var/obj/effect/proc_holder/changeling/S = new path()
@@ -148,6 +147,9 @@
if(!has_sting(S))
purchasedpowers += S
S.on_purchase(owner.current,TRUE)
loudfactor = 0
loudtotal = 0
totalpurchases = 0
/datum/antagonist/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power)
for(var/obj/effect/proc_holder/changeling/P in purchasedpowers)
@@ -192,13 +194,18 @@
geneticpoints -= thepower.dna_cost
purchasedpowers += thepower
thepower.on_purchase(owner.current)
loudfactor += thepower.loudness
if(loudfactor >= 4 && !bloodtestwarnings)
to_chat(owner.current, "<span class='warning'>Our blood is growing flammable. Our blood will react violently to heat.</span>")
bloodtestwarnings = 1
if(loudfactor >= 10 && bloodtestwarnings < 2)
to_chat(owner.current, "<span class='warning'>Our blood has grown extremely flammable. Our blood will react explosively to heat.</span>")
bloodtestwarnings = 2
loudtotal += thepower.loudness
totalpurchases++
var/oldloudness = loudfactor
loudfactor = loudtotal/max(totalpurchases,1)
if(loudfactor >= LINGBLOOD_DETECTION_THRESHOLD && oldloudness < LINGBLOOD_DETECTION_THRESHOLD)
to_chat(owner.current, "<span class='warning'>Our blood has grown flammable. Our blood will now react violently to heat.</span>")
else if(loudfactor < LINGBLOOD_DETECTION_THRESHOLD && oldloudness >= LINGBLOOD_DETECTION_THRESHOLD)
to_chat(owner.current, "<span class='notice'>Our blood has stabilized, and will no longer react violently to heat.</span>")
if(loudfactor > LINGBLOOD_EXPLOSION_THRESHOLD && oldloudness <= LINGBLOOD_EXPLOSION_THRESHOLD)
to_chat(owner.current, "<span class='warning'>Our blood has grown extremely flammable. Our blood will now react explosively to heat.</span>")
else if(loudfactor <= LINGBLOOD_EXPLOSION_THRESHOLD && oldloudness > LINGBLOOD_EXPLOSION_THRESHOLD)
to_chat(owner.current, "<span class='notice'>Our blood has slightly stabilized, and will no longer explode when exposed to heat.</span>")
/datum/antagonist/changeling/proc/readapt()
if(!ishuman(owner.current))
@@ -247,7 +247,8 @@
if(LH.target && LH.target.stat == DEAD)
to_chat(carbon_user,"<span class='danger'>Your patrons accepts your offer...</span>")
var/mob/living/carbon/human/H = LH.target
H.become_husk()
H.become_husk("burn") //Husks the target with removable husking, but causes a bunch of additional burn damage to prevent it from being 'too easy' to do
H.adjustFireLoss(200)
LH.target = null
var/datum/antagonist/heretic/EC = carbon_user.mind.has_antag_datum(/datum/antagonist/heretic)
@@ -390,7 +390,7 @@
if(old_key)
for(var/mob/M in GLOB.dead_mob_list)
if(M.client && M.client.key == old_key) //Only recreates the mob if the mob the client is in is dead
M.transfer_ckey(revenant.key, FALSE)
M.transfer_ckey(revenant, FALSE)
key_of_revenant = TRUE
break
if(!key_of_revenant)
@@ -403,7 +403,7 @@
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return
var/mob/C = pick(candidates)
C.transfer_ckey(revenant.key, FALSE)
C.transfer_ckey(revenant, FALSE)
if(!revenant.key)
qdel(revenant)
message_admins("No ckey was found for the new revenant. Oh well!")
@@ -411,8 +411,8 @@
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return
message_admins("[key_of_revenant] has been [old_key == revenant.key ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was [old_key == revenant.key ? "re":""]made as a revenant by reforming ectoplasm.")
message_admins("[revenant.key] has been [old_key == revenant.key ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[revenant.key] was [old_key == revenant.key ? "re":""]made as a revenant by reforming ectoplasm.")
visible_message("<span class='revenboldnotice'>[src] suddenly rises into the air before fading away.</span>")
revenant.essence = essence
@@ -134,6 +134,19 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture/proc/set_volume(new_volume)
/datum/gas_mixture/proc/get_moles(gas_type)
/datum/gas_mixture/proc/set_moles(gas_type, moles)
// VV WRAPPERS - EXTOOLS HOOKED PROCS DO NOT TAKE ARGUMENTS FROM CALL() FOR SOME REASON.
/datum/gas_mixture/proc/vv_set_moles(gas_type, moles)
return set_moles(gas_type, moles)
/datum/gas_mixture/proc/vv_get_moles(gas_type)
return get_moles(gas_type)
/datum/gas_mixture/proc/vv_set_temperature(new_temp)
return set_temperature(new_temp)
/datum/gas_mixture/proc/vv_set_volume(new_volume)
return set_volume(new_volume)
/datum/gas_mixture/proc/vv_react(datum/holder)
return react(holder)
/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, list/gases)
/datum/gas_mixture/proc/mark_immutable()
/datum/gas_mixture/proc/get_gases()
+1 -1
View File
@@ -12,7 +12,7 @@
/client/proc/centcom_podlauncher() //Creates a verb for admins to open up the ui
set name = "Config/Launch Supplypod"
set desc = "Configure and launch a CentCom supplypod full of whatever your heart desires!"
set category = "Admin"
set category = "Admin.Events"
var/datum/centcom_podlauncher/plaunch = new(usr)//create the datum
plaunch.ui_interact(usr)//datum has a tgui component, here we open the window
+4
View File
@@ -351,6 +351,10 @@
name = "Black Carpet Single-Pack"
contains = list(/obj/item/stack/tile/carpet/black/fifty)
/datum/supply_pack/misc/carpet/arcade
name = "Arcade Carpet Single-Pack"
contains = list(/obj/item/stack/tile/carpet/arcade/fifty)
/datum/supply_pack/misc/carpet/premium
name = "Monochrome Carpet Single-Pack"
desc = "Exotic carpets for all your decorating needs. This 30 units stack of extra soft carpet will tie any room together."
+41 -28
View File
@@ -98,6 +98,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/use_custom_skin_tone = FALSE
var/left_eye_color = "000000" //Eye color
var/right_eye_color = "000000"
var/eye_type = DEFAULT_EYES_TYPE //Eye type
var/split_eye_colors = FALSE
var/datum/species/pref_species = new /datum/species/human() //Mutant race
var/list/features = list("mcolor" = "FFFFFF",
@@ -287,7 +288,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
/datum/preferences/proc/ShowChoices(mob/user)
if(!user || !user.client)
return
update_preview_icon(current_tab != 2)
update_preview_icon(current_tab)
var/list/dat = list("<center>")
dat += "<a href='?_src_=prefs;preference=tab;tab=0' [current_tab == 0 ? "class='linkOn'" : ""]>Character Settings</a>"
@@ -474,25 +475,28 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if (CONFIG_GET(number/body_size_min) != CONFIG_GET(number/body_size_max))
dat += "<b>Sprite Size:</b> <a href='?_src_=prefs;preference=body_size;task=input'>[features["body_size"]*100]%</a><br>"
if((EYECOLOR in pref_species.species_traits) && !(NOEYES in pref_species.species_traits))
if(!use_skintones && !mutant_colors)
dat += APPEARANCE_CATEGORY_COLUMN
if(left_eye_color != right_eye_color)
split_eye_colors = TRUE
dat += "<h3>Heterochromia</h3>"
dat += "</b><a style='display:block;width:100px' href='?_src_=prefs;preference=toggle_split_eyes;task=input'>[split_eye_colors ? "Enabled" : "Disabled"]</a>"
if(!split_eye_colors)
dat += "<h3>Eye Color</h3>"
dat += "<span style='border: 1px solid #161616; background-color: #[left_eye_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=eyes;task=input'>Change</a>"
if(!(NOEYES in pref_species.species_traits))
dat += "<h3>Eye Type</h3>"
dat += "</b><a style='display:block;width:100px' href='?_src_=prefs;preference=eye_type;task=input'>[eye_type]</a><BR>"
if((EYECOLOR in pref_species.species_traits))
if(!use_skintones && !mutant_colors)
dat += APPEARANCE_CATEGORY_COLUMN
if(left_eye_color != right_eye_color)
split_eye_colors = TRUE
dat += "<h3>Heterochromia</h3>"
dat += "</b><a style='display:block;width:100px' href='?_src_=prefs;preference=toggle_split_eyes;task=input'>[split_eye_colors ? "Enabled" : "Disabled"]</a>"
if(!split_eye_colors)
dat += "<h3>Eye Color</h3>"
dat += "<span style='border: 1px solid #161616; background-color: #[left_eye_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=eyes;task=input'>Change</a>"
dat += "</td>"
else
dat += "<h3>Left Eye Color</h3>"
dat += "<span style='border: 1px solid #161616; background-color: #[left_eye_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=eye_left;task=input'>Change</a>"
dat += "<h3>Right Eye Color</h3>"
dat += "<span style='border: 1px solid #161616; background-color: #[right_eye_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=eye_right;task=input'>Change</a><BR>"
dat += "</td>"
else if(use_skintones || mutant_colors)
dat += "</td>"
else
dat += "<h3>Left Eye Color</h3>"
dat += "<span style='border: 1px solid #161616; background-color: #[left_eye_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=eye_left;task=input'>Change</a>"
dat += "<h3>Right Eye Color</h3>"
dat += "<span style='border: 1px solid #161616; background-color: #[right_eye_color];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=eye_right;task=input'>Change</a><BR>"
dat += "</td>"
else if(use_skintones || mutant_colors)
dat += "</td>"
dat += APPEARANCE_CATEGORY_COLUMN
dat += "<h2>Speech preferences</h2>"
@@ -1584,6 +1588,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(new_eyes)
right_eye_color = sanitize_hexcolor(new_eyes, 6)
if("eye_type")
var/new_eye_type = input(user, "Choose your character's eye type.", "Character Preference") as null|anything in GLOB.eye_types
if(new_eye_type)
eye_type = new_eye_type
if("toggle_split_eyes")
split_eye_colors = !split_eye_colors
right_eye_color = left_eye_color
@@ -1617,6 +1626,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(features["mcolor3"] == "#000000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
features["mcolor3"] = pref_species.default_color
//switch to the type of eyes the species uses
eye_type = pref_species.eye_type
if("custom_species")
var/new_species = reject_bad_name(input(user, "Choose your species subtype, if unique. This will show up on examinations and health scans. Do not abuse this:", "Character Preference", custom_species) as null|text)
if(new_species)
@@ -1630,7 +1642,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor"] = pref_species.default_color
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor"] = sanitize_hexcolor(new_mutantcolor, 6)
else
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1641,7 +1653,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor2"] = pref_species.default_color
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor2"] = sanitize_hexcolor(new_mutantcolor, 6)
else
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1652,7 +1664,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor3"] = pref_species.default_color
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor3"] = sanitize_hexcolor(new_mutantcolor, 6)
else
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -1968,7 +1980,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_cockcolor)
if(new_cockcolor == "#000000")
features["cock_color"] = pref_species.default_color
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3])
features["cock_color"] = sanitize_hexcolor(new_cockcolor, 6)
else
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -2008,7 +2020,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_ballscolor)
if(new_ballscolor == "#000000")
features["balls_color"] = pref_species.default_color
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3])
features["balls_color"] = sanitize_hexcolor(new_ballscolor, 6)
else
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -2035,7 +2047,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_breasts_color)
if(new_breasts_color == "#000000")
features["breasts_color"] = pref_species.default_color
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3])
features["breasts_color"] = sanitize_hexcolor(new_breasts_color, 6)
else
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -2057,7 +2069,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/temp_hsv = RGBtoHSV(new_vagcolor)
if(new_vagcolor == "#000000")
features["vag_color"] = pref_species.default_color
else if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3])
features["vag_color"] = sanitize_hexcolor(new_vagcolor, 6)
else
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
@@ -2601,6 +2613,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character.dna.features = features.Copy()
character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE)
character.dna.species.eye_type = eye_type
if(chosen_limb_id && (chosen_limb_id in character.dna.species.allowed_limb_ids))
character.dna.species.mutant_bodyparts["limbs_id"] = chosen_limb_id
character.dna.real_name = character.real_name
@@ -2639,9 +2652,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//limb stuff, only done when initially spawning in
if(initial_spawn)
//delete any existing prosthetic limbs to make sure no remnant prosthetics are left over
//delete any existing prosthetic limbs to make sure no remnant prosthetics are left over - But DO NOT delete those that are species-related
for(var/obj/item/bodypart/part in character.bodyparts)
if(part.status == BODYPART_ROBOTIC)
if(part.status == BODYPART_ROBOTIC && !part.render_like_organic)
qdel(part)
character.regenerate_limbs() //regenerate limbs so now you only have normal limbs
for(var/modified_limb in modified_limbs)
+14 -2
View File
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
#define SAVEFILE_VERSION_MAX 36
#define SAVEFILE_VERSION_MAX 37
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -204,10 +204,19 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(S["species"] == "lizard")
features["mam_snouts"] = features["snout"]
if(current_version < 36)
if(current_version < 36) //introduction of heterochromia
left_eye_color = S["eye_color"]
right_eye_color = S["eye_color"]
if(current_version < 37) //introduction of chooseable eye types/sprites
if(S["species"] == "insect")
left_eye_color = "#000000"
right_eye_color = "#000000"
if(chosen_limb_id == "moth" || chosen_limb_id == "moth_not_greyscale") //these actually have slightly different eyes!
eye_type = "moth"
else
eye_type = "insect"
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
return
@@ -509,6 +518,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["age"] >> age
S["hair_color"] >> hair_color
S["facial_hair_color"] >> facial_hair_color
S["eye_type"] >> eye_type
S["left_eye_color"] >> left_eye_color
S["right_eye_color"] >> right_eye_color
S["use_custom_skin_tone"] >> use_custom_skin_tone
@@ -692,6 +702,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age))
hair_color = sanitize_hexcolor(hair_color, 6, FALSE)
facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE)
eye_type = sanitize_inlist(eye_type, GLOB.eye_types, DEFAULT_EYES_TYPE)
left_eye_color = sanitize_hexcolor(left_eye_color, 6, FALSE)
right_eye_color = sanitize_hexcolor(right_eye_color, 6, FALSE)
@@ -822,6 +833,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["age"] , age)
WRITE_FILE(S["hair_color"] , hair_color)
WRITE_FILE(S["facial_hair_color"] , facial_hair_color)
WRITE_FILE(S["eye_type"] , eye_type)
WRITE_FILE(S["left_eye_color"] , left_eye_color)
WRITE_FILE(S["right_eye_color"] , right_eye_color)
WRITE_FILE(S["use_custom_skin_tone"] , use_custom_skin_tone)
+5 -5
View File
@@ -386,7 +386,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
//Admin Preferences
/client/proc/toggleadminhelpsound()
set name = "Hear/Silence Adminhelps"
set category = "Preferences"
set category = "Preferences.Admin"
set desc = "Toggle hearing a notification when admin PMs are received"
if(!holder)
return
@@ -397,7 +397,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
/client/proc/toggleannouncelogin()
set name = "Do/Don't Announce Login"
set category = "Preferences"
set category = "Preferences.Admin"
set desc = "Toggle if you want an announcement to admins when you login during a round"
if(!holder)
return
@@ -408,7 +408,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
/client/proc/toggle_hear_radio()
set name = "Show/Hide Radio Chatter"
set category = "Preferences"
set category = "Preferences.Admin"
set desc = "Toggle seeing radiochatter from nearby radios and speakers"
if(!holder)
return
@@ -419,7 +419,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
/client/proc/deadchat()
set name = "Show/Hide Deadchat"
set category = "Preferences"
set category = "Preferences.Admin"
set desc ="Toggles seeing deadchat"
prefs.chat_toggles ^= CHAT_DEAD
prefs.save_preferences()
@@ -428,7 +428,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
/client/proc/toggleprayers()
set name = "Show/Hide Prayers"
set category = "Preferences"
set category = "Preferences.Admin"
set desc = "Toggles seeing prayers"
prefs.chat_toggles ^= CHAT_PRAYER
prefs.save_preferences()
+3 -3
View File
@@ -111,16 +111,16 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8")
/client/proc/set_ooc(newColor as color)
set name = "Set Player OOC Color"
set desc = "Modifies player OOC Color"
set category = "Fun"
set category = "Admin.Fun"
GLOB.OOC_COLOR = sanitize_ooccolor(newColor)
/client/proc/reset_ooc()
set name = "Reset Player OOC Color"
set desc = "Returns player OOC Color to default"
set category = "Fun"
set category = "Admin.Fun"
GLOB.OOC_COLOR = null
/client/verb/colorooc()
/client/verb/colorooc() //this is admin and people who bought byond.
set name = "Set Your OOC Color"
set category = "Preferences"
+1 -1
View File
@@ -190,7 +190,7 @@
/obj/item/clothing/head/wig
name = "wig"
desc = "A bunch of hair without a head attached."
icon = 'icons/mob/human_face.dmi' // default icon for all hairs
icon = 'icons/mob/hair.dmi' // default icon for all hairs
icon_state = "hair_vlong"
flags_inv = HIDEHAIR
color = "#000"
@@ -130,9 +130,13 @@
/obj/item/reagent_containers/pill = 2,
/obj/item/clothing/shoes = 8,
/obj/item/clothing/head = 3,
/obj/item/reagent_containers/food/snacks = 3,
/obj/item/reagent_containers/food/snacks = 5,
/obj/item/reagent_containers/syringe/dart = 2,
/obj/item/reagent_containers/food/drinks/soda_cans = 5)
/obj/item/reagent_containers/food/drinks/soda_cans = 5,
/obj/item/reagent_containers/food/drinks/drinkingglass = 4,
/obj/item/reagent_containers/food/drinks = 6,
/obj/item/reagent_containers/food/snacks/grown/apple = 1,
/obj/item/reagent_containers/food/snacks/grown/banana = 2)
if(length >= 5)
return TRUE
//var/metalist = pickweight(GLOB.maintenance_loot)
+109 -25
View File
@@ -48,8 +48,8 @@
var/progression = list() //Keep track of where people are in the story.
var/active = TRUE //Turn this to false to keep normal mob behavour
var/cached_z
/// I'm busy chatting, don't move.
var/busy_chatting = FALSE
/// I'm busy, don't move.
var/busy = FALSE
/mob/living/simple_animal/jacq/Initialize()
..()
@@ -68,11 +68,14 @@
playsound(loc, 'sound/spookoween/ahaha.ogg', 100, 0.25)
var/mob/living/simple_animal/jacq/Jacq = new src.type(loc)
Jacq.progression = progression
if(ckey) //transfer over any ghost posessions
Jacq.key = key
..()
/mob/living/simple_animal/jacq/death() //What is alive may never die
visible_message("<b>[src]</b> cackles, <span class='spooky'>\"You'll nae get rid a me that easily!\"</span>")
playsound(loc, 'sound/spookoween/ahaha.ogg', 100, 0.25)
fully_heal(FALSE)
health = 25
poof()
@@ -81,9 +84,9 @@
say("Hello there [gender_check(M)]!")
return ..()
if(!ckey)
busy_chatting = FALSE
stopmove()
chit_chat(M)
busy_chatting = TRUE
canmove()
..()
/mob/living/simple_animal/jacq/attack_paw(mob/living/carbon/monkey/M)
@@ -91,11 +94,28 @@
say("Hello there [gender_check(M)]!")
return ..()
if(!ckey)
busy_chatting = FALSE
stopmove()
chit_chat(M)
busy_chatting = TRUE
canmove()
..()
/mob/living/simple_animal/jacq/proc/canmove()
busy = FALSE
update_mobility()
/mob/living/simple_animal/jacq/proc/stopmove()
if(ckey) //if someone is in her, don't disable her movement!
canmove()
return
busy = TRUE
update_mobility()
/mob/living/simple_animal/jacq/proc/jacqrunes(message, mob/living/carbon/C) //Displays speechtext over Jacq for the user only.
var/atom/hearer = C
var/list/spans = list("spooky")
new /datum/chatmessage(message, src, hearer, spans)
/mob/living/simple_animal/jacq/proc/poof()
last_poof = world.realtime
var/datum/reagents/R = new/datum/reagents(100)//Hey, just in case.
@@ -104,7 +124,7 @@
s.set_up(R, 0, loc)
s.start()
visible_message("<b>[src]</b> disappears in a puff of smoke!")
busy_chatting = TRUE
canmove()
health = 25
//Try to go to populated areas
@@ -120,7 +140,7 @@
continue
targets += H
if(!targets)
if(!targets.len)
targets = GLOB.generic_event_spawns
for(var/i in 1 to 6) //Attempts a jump up to 6 times.
@@ -151,14 +171,16 @@
if(!progression["[C.real_name]"] || !(progression["[C.real_name]"] & JACQ_HELLO))
visible_message("<b>[src]</b> smiles ominously at [C], <span class='spooky'>\"Well halo there [gender]! Ah'm Jacqueline, tae great Pumpqueen, great tae meet ye.\"</span>")
jacqrunes("Well halo there [gender]! Ah'm Jacqueline, tae great Pumpqueen, great tae meet ye.", C)
sleep(20)
visible_message("<b>[src]</b> continues, <span class='spooky'>\"Ah'm sure yae well stunned, but ah've got nae taem fer that. Ah'm after the candies around this station. If yae get mae enoof o the wee buggers, Ah'll give ye a treat, or if yae feeling bold, Ah ken trick ye instead.</span>\" giving [C] a wide grin.")
jacqrunes("Ah'm sure yae well stunned, but ah've got nae taem fer that. Ah'm after the candies around this station. If yae get mae enoof o the wee buggers, Ah'll give ye a treat, or if yae feeling bold, Ah ken trick ye instead.", C)
if(!progression["[C.real_name]"])
progression["[C.real_name]"] = NONE //TO MAKE SURE THAT THE LIST ENTRY EXISTS.
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_HELLO
var/choices = list("Trick", "Treat", "How do I get candies?")
var/choices = list("Trick", "Treat", "How do I get candies?", "Do I know you from somewhere?")
var/choice = input(C, "Trick or Treat?", "Trick or Treat?") in choices
switch(choice)
if("Trick")
@@ -168,14 +190,20 @@
if(check_candies(C))
treat(C, gender)
else
visible_message("<b>[src]</b> raises an eyebrow, <span class='spooky'>\"You've nae got any candies Ah want! They're the orange round ones, now bugger off an go get em first.\"</span>")
visible_message("<b>[src]</b> raises aneyebrow, <span class='spooky'>\"You've nae got any candies Ah want! They're the orange round ones, now bugger off an go get em first.\"</span>")
jacqrunes("You've nae got any candies Ah want! They're the orange round ones, now bugger off an go get em first.", C)
return
if("How do I get candies?")
visible_message("<b>[src]</b> says, <span class='spooky'>\"Gae find my familiar; Bartholomew. Ee's tendin the cauldron which ken bring oot t' magic energy in items scattered aroond. Knowing him, ee's probably gone tae somewhere with books.\"</span>")
jacqrunes("Gae find my familiar; Bartholomew. Ee's tendin the cauldron which ken bring oot t' magic energy in items scattered aroond. Knowing him, ee's probably gone tae somewhere with books.", C)
return
if("Do I know you from somewhere?")
visible_message("<b>[src]</b> says, <span class='spooky'>\"Aye ye micht dae, ah was kicking aboot round 'ere aboot a year ago when ah had a wee... altercation wit the witch academy n' ran oot here tae crash oan me sis's floor. Course she pushed me tae git it a' sorted oot lik', bit nae before ah hud a wee bit o' fun oan this station. Or maybe ye jest recognise me ma's prized pumpkin atop me nonce.\"</span>")
jacqrunes("Aye ye micht dae, ah was kicking aboot round 'ere aboot a year ago when ah had a wee... altercation wit the witch academy n' ran oot here tae crash oan me sis's floor. Course she pushed me tae git it a' sorted oot lik', bit nae before ah hud a wee bit o' fun oan this station. Or maybe ye jest recognise me ma's prized pumpkin atop me nonce.", C)
/mob/living/simple_animal/jacq/proc/treat(mob/living/carbon/C, gender)
visible_message("<b>[src]</b> gives off a glowing smile, <span class='spooky'>\"What ken Ah offer ye? I can magic up an object, a potion or a plushie fer ye.\"</span>")
jacqrunes("What ken Ah offer ye? I can magic up an object, a potion or a plushie fer ye.", C)
var/choices_reward = list("Object - 3 candies", "Potion - 2 candies", "Jacqueline Tracker - 2 candies", "Plushie - 1 candy", "Can I get to know you instead?", "Become a pumpkinhead dullahan (perma) - 4 candies")
var/choice_reward = input(usr, "Trick or Treat?", "Trick or Treat?") in choices_reward
@@ -184,8 +212,10 @@
if("Become a pumpkinhead dullahan (perma) - 4 candies")
if(!take_candies(C, 4))
visible_message("<b>[src]</b> raises an eyebrown, <span class='spooky'>\"It's 4 candies for that [gender]! Thems the rules!\"</span>")
jacqrunes("It's 4 candies for that [gender]! Thems the rules!", C)
return
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"Off comes your head, a pumpkin taking it's stead!\"</span>")
jacqrunes("Off comes your head, a pumpkin taking it's stead!", C)
C.reagents.add_reagent(/datum/reagent/mutationtoxin/pumpkinhead, 5)
sleep(20)
poof()
@@ -194,6 +224,7 @@
if("Object - 3 candies")
if(!take_candies(C, 3))
visible_message("<b>[src]</b> raises an eyebrown, <span class='spooky'>\"It's 3 candies per trinket [gender]! Thems the rules!\"</span>")
jacqrunes("It's 3 candies per trinket [gender]! Thems the rules!", C)
return
var/new_obj = pick(subtypesof(/obj))
@@ -203,36 +234,43 @@
var/reward = new new_obj(C.loc)
C.put_in_hands(reward)
visible_message("<b>[src]</b> waves her hands, magicking up a [reward] from thin air, <span class='spooky'>\"There ye are [gender], enjoy! \"</span>")
jacqrunes("There ye are [gender], enjoy!", C)
sleep(20)
poof()
return
if("Potion - 2 candies")
if(!take_candies(C, 2))
visible_message("<b>[src]</b> raises an eyebrow, <span class='spooky'>\"It's 2 candies per potion [gender]! Thems the rules!\"</span>")
jacqrunes("It's 2 candies per potion [gender]! Thems the rules!", C)
return
var/reward = new /obj/item/reagent_containers/potion_container(C.loc)
C.put_in_hands(reward)
visible_message("<b>[src]</b> waves her hands, magicking up a [reward] from thin air, <span class='spooky'>\"There ye are [gender], enjoy! \"</span>")
jacqrunes("There ye are [gender], enjoy!", C)
sleep(20)
poof()
return
if("Plushie - 1 candy")
if(!take_candies(C, 1))
visible_message("<b>[src]</b> raises an eyebrow, <span class='spooky'>\"It's 1 candy per plushie [gender]! Thems the rules!\"</span>")
jacqrunes("It's 1 candy per plushie [gender]! Thems the rules!", C)
return
new /obj/item/toy/plush/random(C.loc)
visible_message("<b>[src]</b> waves her hands, magicking up a plushie from thin air, <span class='spooky'>\"There ye are [gender], enjoy! \"</span>")
jacqrunes("There ye are [gender], enjoy!", C)
sleep(20)
poof()
return
if("Jacqueline Tracker - 2 candies")
if(!take_candies(C, 2))
visible_message("<b>[src]</b> raises an eyebrow, <span class='spooky'>\"It's 1 candy per plushie [gender]! Thems the rules!\"</span>")
jacqrunes("It's 1 candy per plushie [gender]! Thems the rules!", C)
return
new /obj/item/pinpointer/jacq(C.loc)
visible_message("<b>[src]</b> waves her hands, magicking up a tracker from thin air, <span class='spooky'>\"Feels weird to magic up a tracker fer meself but, here ye are [gender], enjoy! \"</span>")
jacqrunes("Feels weird to magic up a tracker fer meself but, here ye are [gender], enjoy!", C)
sleep(20)
poof()
return
@@ -252,7 +290,7 @@
choices += "What is that on your head?"
if(!(progression["[C.real_name]"] & JACQ_EXPELL))
if(progression["[C.real_name]"] & JACQ_WITCH)
choices += "So you got ex-spell-ed?"
choices += "What is it like being a witch?"
else
choices += "Are you a witch?"
@@ -270,47 +308,79 @@
//If you've nothing to ask
if(!LAZYLEN(choices))
visible_message("<b>[src]</b> sighs, <span class='spooky'>\"Ah'm all questioned oot fer noo, [gender].\"</span>")
jacqrunes("Ah'm all questioned oot fer noo, [gender]", C)
return
//Otherwise, lets go!
visible_message("<b>[src]</b> says, <span class='spooky'>\"A question? Sure, it'll cost you a candy though!\"</span>")
jacqrunes("A question? Sure, it'll cost you a candy though!", C)
choices += "Nevermind"
//Candies for chitchats
var/choice = input(C, "What do you want to ask?", "What do you want to ask?") in choices
if(!take_candies(C, 1))
visible_message("<b>[src]</b> raises an eyebrow, <span class='spooky'>\"It's a candy per question [gender]! Thems the rules!\"</span>")
jacqrunes("It's a candy per question [gender]! Thems the rules!", C)
return
//Talking
switch(choice)
if("Why do you want the candies?")
visible_message("<b>[src]</b> says, <span class='spooky'>\"Ave ye tried them? They're full of all sorts of reagents. Ah'm after them so ah ken magic em up an hopefully find rare stuff fer me brews. Honestly it's a lot easier magicking up tatt fer ye lot than runnin aroond on me own like. I'd ask me familiars but most a my familiars are funny fellows 'n constantly bugger off on adventures when given simple objectives like; Go grab me a tea cake or watch over me cauldron. Ah mean, ye might run into Bartholomew my cat. Ee's supposed tae be tending my cauldron, but I've nae idea where ee's got tae.\"</span>")
jacqrunes("Ave ye tried them? They're full of all sorts of reagents. Ah'm after them so ah ken magic em up an hopefully find rare stuff fer me brews. Honestly it's a lot easier magicking up tatt fer ye lot than runnin aroond on me own like. I'd ask me familiars but most a my familiars are funny fellows 'n constantly bugger off on adventures when given simple objectives like; Go grab me a tea cake or watch over me cauldron. Ah mean, ye might run into Bartholomew my cat. Ee's supposed tae be tending my cauldron, but I've nae idea where ee's got tae.", C)
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_CANDIES
sleep(30)
if("You really came all this way for candy?")
visible_message("<b>[src]</b> l ooks tae the side sheepishly, <span class='spooky'>\"Aye, well, tae be honest, Ah'm here tae see me sis, but dunnae let her knew that. She's an alchemist too like, but she dunnae use a caldron like mae, she buggered off like tae her posh ivory tower tae learn bloody chemistry instead!\"</span> <b>[src]</b> scowls, <span class='spooky'>\"She's tae black sheep o' the family too, so we dunnae see eye tae eye sometimes on alchemy. Ah mean, she puts <i> moles </i> in her brews! Ye dunnae put moles in yer brews! Yae threw your brews at tae wee bastards an blew em up!\"</span> <b>[src]</b> sighs, <span class='spooky'>\"But she's a heart o gold so.. Ah wanted tae see her an check up oon her, make sure she's okay.\"</span>")
visible_message("<b>[src]</b> looks to the side sheepishly, <span class='spooky'>\"Aye, well, tae be honest, Ah'm here tae see me sis, but dunnae let her knew that. She's an alchemist too like, but she dunnae use a caldron like mae, she buggered off like tae her posh ivory tower tae learn bloody chemistry instead!\"</span> <b>[src]</b> scowls, <span class='spooky'>\"She's tae black sheep o' the family too, so we dunnae see eye tae eye sometimes on alchemy. Ah mean, she puts <i> moles </i> in her brews! Ye dunnae put moles in yer brews! Yae threw your brews at tae wee bastards an blew em up!\"</span> <b>[src]</b> sighs, <span class='spooky'>\"But she's a heart o gold so.. Ah wanted tae see her an check up oon her, make sure she's okay.\"</span>")
jacqrunes("Aye, well, tae be honest, Ah'm here tae see me sis, but dunnae let her knew that. She's an alchemist too like, but she dunnae use a caldron like mae, she buggered off like tae her posh ivory tower tae learn bloody chemistry instead", C)
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_FAR
sleep(30)
sleep(10)
jacqrunes("She's tae black sheep o' the family too, so we dunnae see eye tae eye sometimes on alchemy. Ah mean, she puts moles in her brews! Ye dunnae put moles in yer brews! Yae threw your brews at tae wee bastards an blew em up!", C)
sleep(10)
jacqrunes("But she's a heart o gold so.. Ah wanted tae see her an check up oon her, make sure she's okay.", C)
sleep(10)
if("What is that on your head?")
visible_message("<b>[src]</b> pats the pumpkin atop her head, <span class='spooky'>\"This thing? This ain't nae ordinary pumpkin! Me Ma grew this monster ooer a year o love, dedication an hard work. Honestly it felt like she loved this thing more than any of us, which Ah knew ain't true an it's not like she was hartless or anything but.. well, we had a falling oot when Ah got back home with all me stuff in tow. An all she had done is sent me owl after owl over t' last year aboot this bloody pumpkin and ah had enough. So ah took it, an put it on me head. You know, as ye do. Ah am the great Pumpqueen after all, Ah deserve this.\"</span>")
visible_message("<b>[src]</b> pats the pumpkin atop her head, <span class='spooky'>\"This thing? This ain't nae ordinary pumpkin! Me Ma grew this monster ooer a year o love, dedication an hard work. Honestly I got bloody sick o'er harpin' on aboot it, all she had done is sent me owl after owl over aboot this bloody pumpkin since i left the nest and ah had enough after a ... mild altercation like. So I nabbed it last halloween. Caught bloody hell fer it ah did, course me sis talked to me ma and, well, simmered her doon. We've all but made up noo, but seein' as ah'm the great Pumpqueen after all, I cannae be seen withoot it like.\"</span>")
jacqrunes("This thing? This ain't nae ordinary pumpkin! Me Ma grew this monster ooer a year o love, dedication an hard work. Honestly I got bloody sick o'er harpin' on aboot it, all she had done is sent me owl after owl over aboot this bloody pumpkin since i left the nest and ah had enough after a ... mild altercation like. So I nabbed it last halloween. Caught bloody hell fer it ah did, course me sis talked to me ma and, well, simmered her doon. We've all but made up noo, but seein' as ah'm the great Pumpqueen after all, I cannae be seen withoot it like.", C)
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_HEAD
sleep(30)
//Year 1 answer: for anyone who is interested!
/*This thing? This ain't nae ordinary pumpkin! Me Ma grew this monster ooer a year o love, dedication an hard work. Honestly it felt like she loved this thing more than any of us, which Ah knew ain't true an it's not like she was hartless or anything but.. well, we had a falling oot when Ah got back home with all me stuff in tow. An all she had done is sent me owl after owl over t' last year aboot this bloody pumpkin and ah had enough. So ah took it, an put it on me head. You know, as ye do. Ah am the great Pumpqueen after all, Ah deserve this.*/
if("Are you a witch?")
visible_message("<b>[src]</b> grumbles, <span class='spooky'>\"If ye must know, Ah got kicked oot of the witch academy fer being too much of a \"loose cannon\". A bloody loose cannon? Nae they were just pissed off Ah had the brass tae proclaim myself as the Pumpqueen! And also maybe the time Ah went and blew up one of the towers by trying tae make a huge batch of astrogen might've had something tae do with it. Ah mean it would've worked fine if the cauldrons weren't so shite and were actually upgraded by the faculty. So technically no, I'm not a witch.\"</span>")
visible_message("<b>[src]</b> smirks, <span class='spooky'>\"Weel, after getting kicked oot over a <i>very minor</i> explosion last year, ah wis able tae git back in 'n' finish me witching degree thanks tae me sis! 'twas bloody brutal finishing th' degree though, ah will tell ye, ye take a peek o'er at t' other witches all prim 'n' proper like 'n' it gets in yer heid, ye'r nae as guid. But ah bloody well ended up summoning Nar'Sie last year for the lot o' yous. Aye a'm a loose cannon - but ah get results.\"</span> thumping her chest with pride as she finishes speaking.")
jacqrunes("Weel, after getting kicked oot over a very minor explosion last year, ah wis able tae git back in 'n' finish me witching degree thanks tae me sis! 'twas bloody brutal finishing th' degree though, ah will tell ye, ye take a peek o'er at t' other witches all prim 'n' proper like 'n' it gets in yer heid, ye'r nae as guid. But ah bloody well ended up summoning Nar'Sie last year for the lot o' yous. Aye a'm a loose cannon - but ah get results." , C)
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_WITCH
sleep(30)
if("So you got ex-spell-ed?")
visible_message("<b>[src]</b> Gives you a blank look at the pun, before continuing, <span class='spooky'>\"Not quite, Ah know Ah ken get back into the academy, it's only an explosion, they happen all the time, but, tae be fair it's my fault that things came tae their explosive climax. You don't know what it's like when you're after a witch doctorate, everyone else is doing well, everyone's making new spells and the like, and I'm just good at making explosions really, or fireworks. So, Ah did something Ah knew was dangerous, because Ah had tae do something tae stand oot, but Ah know this life ain't fer me, Ah don't want tae be locked up in dusty towers, grinding reagent after reagent together, trying tae find new reactions, some of the wizards in there haven't left fer years. Ah want tae live, Ah want tae fly around on a broom, turn people into cats fer a day and disappear cackling! That's what got me into witchcraft!\"</span> she throws her arms up in the arm, spinning the pumpkin upon her head slightly. She carefully spins it back to face you, giving oot a soft sigh, <span class='spooky'>\"Ah know my mother's obsession with this dumb thing on my head is just her trying tae fill the void of me and my sis moving oot, and it really shouldn't be on my head. And Ah know that I'm really here tae get help from my sis.. She's the sensible one, and she gives good hugs.\"</span>")
sleep(30)
//Year 1 answer for anyone who is interested:
/* Are you a witch?
If ye must know, Ah got kicked oot of the witch academy fer being too much of a \"loose cannon\". A bloody loose cannon? Nae they were just pissed off Ah had the brass tae proclaim myself as the Pumpqueen! And also maybe the time Ah went and blew up one of the towers by trying tae make a huge batch of astrogen might've had something tae do with it. Ah mean it would've worked fine if the cauldrons weren't so shite and were actually upgraded by the faculty. So technically no, I'm not a witch.*/
if("What is it like being a witch?") //What is it like being a witch?
visible_message("<b>[src]</b> says, <span class='spooky'>\"Tae be honest, ah dunnae. Ah mean ah have a piece o paper that implies that am, n a few folk who seem keen in shoving me back in their magic tower, but I dont know if thats fer me really.\" </span> she gives the back of her pumpkin a quick scratch as she continues <span class='spooky'> \"What draws me tae witchcraft is the chaos, ah live tae see th utter madness that comes fae the spells ah cast n th like, n ah know you do tae, its why youre ere, aye? Ah kin conjure some utterly chaotic things, and ah love tae do it, just tae see what Ill git! Its why visiting here is so fun, ye wee lot scurrying about, getting me candies, hoping Ill conjure up something utterly chaotic!\" </span> she throws her arms up in the arm with a laugh, spinning the pumpkin upon her head slightly. She carefully spins it back to face you, <span class='spooky'> \"But o course life aint that easy, ye cant just go around being a pure agent o chaos, n ah feel like the reality o the world be trying tae dull me, to shove me in a boring dusty auld room where ah spend t rest o me days researching some boggin magic till ah die. Ah want tae bloody well change t world, ah want to do something that leaves an impact, but ah dunnae want t kill people doing it.\"</span> she gives out a soft sigh, \"Who knows, maybe Ill bugger off n make some pumkinmobiles or something daft like that.\" </span>")
jacqrunes("Tae be honest, ah dunnae. Ah mean ah have a piece o paper that implies that am, n a few folk who seem keen in shoving me back in their magic tower, but I dont know if thats fer me really." , C)
sleep(10)
jacqrunes("What draws me tae witchcraft is the chaos, ah live tae see th utter madness that comes fae the spells ah cast n th like, n ah know you do tae, its why youre ere, aye? Ah kin conjure some utterly chaotic things, and ah love tae do it, just tae see what Ill git! Its why visiting here is so fun, ye wee lot scurrying about, getting me candies, hoping Ill conjure up something utterly chaotic!" , C)
sleep(10)
jacqrunes("But o course life aint that easy, ye cant just go around being a pure agent o chaos, n ah feel like the reality o the world be trying tae dull me, to shove me in a boring dusty auld room where ah spend t rest o me days researching some boggin magic till ah die. Ah want tae bloody well change t world, ah want to do something that leaves an impact, but ah dunnae want t kill people doing it.", C)
sleep(10)
jacqrunes("Who knows, maybe Ill bugger off n make some pumkinmobiles or something daft like that.", C)
sleep(25)
visible_message("<b>[src]</b> says, <span class='spooky'>\"Thanks [C], Ah guess Ah didn't realise Ah needed someone tae talk tae but, I'm glad ye spent all your candies talking tae me. Funny how things seem much worse in yer head.\"</span>")
jacqrunes("Thanks [C], Ah guess Ah didn't realise Ah needed someone tae talk tae but, I'm glad ye spent all your candies talking tae me. Funny how things seem much worse in yer head." , C)
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_EXPELL
sleep(30)
//Year 1 answer for anyone who is interested:
/*"So you got ex-spell-ed?"
Gives you a blank look at the pun, before continuing, <span class='spooky'>\"Not quite, Ah know Ah ken get back into the academy, it's only an explosion, they happen all the time, but, tae be fair it's my fault that things came tae their explosive climax. You don't know what it's like when you're after a witch doctorate, everyone else is doing well, everyone's making new spells and the like, and I'm just good at making explosions really, or fireworks. So, Ah did something Ah knew was dangerous, because Ah had tae do something tae stand oot, but Ah know this life ain't fer me, Ah don't want tae be locked up in dusty towers, grinding reagent after reagent together, trying tae find new reactions, some of the wizards in there haven't left fer years. Ah want tae live, Ah want tae fly around on a broom, turn people into cats fer a day and disappear cackling! That's what got me into witchcraft!\"</span> she throws her arms up in the arm, spinning the pumpkin upon her head slightly. She carefully spins it back to face you, giving oot a soft sigh, <span class='spooky'>\"Ah know my mother's obsession with this dumb thing on my head is just her trying tae fill the void of me and my sis moving oot, and it really shouldn't be on my head. And Ah know that I'm really here tae get help from my sis.. She's the sensible one, and she gives good hugs.
*/
if("Can I take you out on a date?")
visible_message("<b>[src]</b> blushes, <span class='spooky'>\"...You want tae ask me oot on a date? Me? After all that nonsense Ah just said? It seems a waste of a candy honestly.\"</span>")
//progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_DATE
jacqrunes("...You want tae ask me oot on a date? Me? After all that nonsense Ah just said? It seems a waste of a candy honestly." , C)
visible_message("<b>[src]</b> looks to the side, deep in thought.</span>")
dating_start(C, gender)
@@ -328,15 +398,18 @@
switch(option)
if(1)
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"Hocus pocus, making friends is now your focus!\"</span>")
jacqrunes("Hocus pocus, making friends is now your focus!", C)
var/message = pick("make a tasty sandwich for", "compose a poem for", "aquire a nice outfit to give to", "strike up a conversation about pumpkins with", "write a letter and deliver it to", "give a nice hat to")
var/mob/living/L2 = pick(GLOB.player_list)
message += " [L2.name]."
to_chat(C, "<span class='big warning'> You feel an overwhelming desire to [message]")
if(2)
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"If only you had a better upbringing, your ears are now full of my singing!\"</span>")
C.client.tgui_panel?.play_music("https://puu.sh/ExBbv.mp4")
jacqrunes("If only you had a better upbringing, your ears are now full of my singing!", C)
C.client.tgui_panel?.play_music("https://katlin.dog/v/spooky.mp4")
if(3)
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"You're cute little bumpkin, On your head is a pumpkin!\"</span>")
jacqrunes("You're cute little bumpkin, On your head is a pumpkin!", C)
if(C.head)
var/obj/item/W = C.head
C.dropItemToGround(W, TRUE)
@@ -344,12 +417,15 @@
C.equip_to_slot(jaqc_latern, SLOT_HEAD, 1, 1)
if(4)
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"In your body there's something amiss, you'll find it's a chem made by my sis!\"</span>")
jacqrunes("In your body there's something amiss, you'll find it's a chem made by my sis!", C)
C.reagents.add_reagent(/datum/reagent/fermi/eigenstate, 30)
if(5)
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"A new familiar for me, and you'll see it's thee!\"</span>")
C.reagents.add_reagent("secretcatchem", 30)
jacqrunes("A new familiar for me, and you'll see it's thee!", C)
C.reagents.add_reagent(/datum/reagent/fermi/secretcatchem, 30)
if(6)
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"While you may not be a ghost, for this sheet you'll always be it's host.\"</span>")
jacqrunes("While you may not be a ghost, for this sheet you'll always be it's host.", C)
var/mob/living/carbon/human/H = C
if(H.wear_suit)
var/obj/item/W = H.wear_suit
@@ -370,22 +446,30 @@
message_admins("[C2]/[C2.key] has agreed to go on a date with [C] as Jacqueline.")
log_game("HALLOWEEN: [C2]/[C2.key] has agreed to go on a date with [C] as Jacqueline")
to_chat(src, "<span class='big spooky'>You are Jacqueline the great pumpqueen, witch Extraordinaire! You're a very Scottish lass with a kind heart, but also a little crazy. You also blew up the wizarding school and you're suspended for a while, so you visited the station before heading home. On your head lies the prize pumpkin of your Mother's pumpkin patch. You're currently on a date with [C] and well, I didn't think anyone would get this far. <i> Please be good so I can do events like this in the future. </i> </span>")
return
canmove()
return TRUE
else
candies =- C2
visible_message("<b>[src]</b> looks to the side, <span class='spooky'>\"Look, Ah like ye but, Ah don't think Ah can right now. If ye can't tell, the stations covered in volatile candies, I've a few other laddies and lassies running after me treats, and tae top it all off, I've the gods breathing down me neck, watching every treat Ah make fer the lot of yous.\" she sighs, \"But that's not a no, right? That's.. just a nae right noo.\"</span>")
jacqrunes("Look, Ah like ye but, Ah don't think Ah can right now. If ye can't tell, the stations covered in volatile candies, I've a few other laddies and lassies running after me treats, and tae top it all off, I've the gods breathing down me neck, watching every treat Ah make fer the lot of yous.", C)
sleep(20)
jacqrunes("But that's not a no, right? That's.. just a nae right noo.", C)
visible_message("<b>[src]</b> takes off the pumpkin on her head, a rich blush on her cheeks. She leans over planting a kiss upon your forehead quickly befere popping the pumpkin back on her head.")
sleep(10)
sleep(20)
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"There, that aught tae be worth a candy.\"</span>")
jacqrunes("There, that aught tae be worth a candy.", C)
sleep(20)
poof()
/mob/living/simple_animal/jacq/update_mobility()
. = ..()
if(busy_chatting)
if(busy)
DISABLE_BITFIELD(., MOBILITY_MOVE)
mobility_flags = .
else
ENABLE_BITFIELD(., MOBILITY_MOVE)
mobility_flags = .
/obj/item/clothing/head/hardhat/pumpkinhead/jaqc
name = "Jacq o' latern"
@@ -50,7 +50,7 @@
plantname = "Fairygrass"
product = /obj/item/reagent_containers/food/snacks/grown/grass/fairy
icon_grow = "fairygrass-grow"
icon_dead = "fairygrass-dead"
icon_dead = "grass-dead"
genes = list(/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/glow/blue)
mutatelist = list (/obj/item/seeds/grass/carpet)
reagents_add = list(/datum/reagent/consumable/nutriment = 0.02, /datum/reagent/hydrogen = 0.05, /datum/reagent/drug/space_drugs = 0.15)
@@ -193,6 +193,8 @@
growthstages = 3
genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism)
growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi'
icon_grow = "chanter-grow"
icon_dead = "chanter-dead"
reagents_add = list(/datum/reagent/consumable/nutriment = 0.1)
mutatelist = list(/obj/item/seeds/chanterelle/jupitercup)
+1 -1
View File
@@ -285,7 +285,7 @@
else
plant_overlay.icon_state = myseed.icon_harvest
else
var/t_growthstate = min(round((age / myseed.maturation) * myseed.growthstages), myseed.growthstages)
var/t_growthstate = clamp(round((age / myseed.maturation) * myseed.growthstages), 1, myseed.growthstages)
plant_overlay.icon_state = "[myseed.icon_grow][t_growthstate]"
add_overlay(plant_overlay)
+1 -1
View File
@@ -154,7 +154,7 @@
/datum/keybinding/living/toggle_sprint/down(client/user)
var/mob/living/L = user.mob
L.default_toggle_sprint(TRUE)
L.default_toggle_sprint()
return TRUE
/datum/keybinding/mob/toggle_move_intent
+9 -5
View File
@@ -134,12 +134,13 @@
return num;
}
window.onload = function() {
var datas = \[[jointext(datas, ",")]]
if(!window.HTMLCanvasElement){
//something has gone horribly wrong!
if(!window.HTMLCanvasElement) {
var label = document.getElementById("label-1");
label.textContent = "<h1>WARNING! HTMLCanvasElement not found!</h1>"
return false
}
for(var i = 0; i < [length(minimaps)]; i++){
var datas = \[[jointext(datas, ",")]]
for(var i = 0; i < [length(minimaps)]; i++) {
//the fuck is this wrapped?
var data = datas\[i];
var img = document.getElementById("map-" + (i + 1));
@@ -160,13 +161,16 @@
ctx.drawImage(document.getElementById("map-" + (i+1) + "-meta"), 0, 0);
var imagedata = ctx.getImageData(0, 0, img.width, img.height);
var label = document.getElementById("label-" + (i+1));
canvas.onmousemove = function(e){
var rect = canvas.getBoundingClientRect();
var x = Math.floor(e.offsetX * img.width / rect.width);
var y = Math.floor(e.offsetY * img.height / rect.height);
var color_idx = x * 4 + (y * 4 * imagedata.width);
var color = "#" + hexify(imagedata.data\[color_idx]) + hexify(imagedata.data\[color_idx+1]) + hexify(imagedata.data\[color_idx+2]);
var label = document.getElementById("label-" + (i+1)); //label-String(n)
label.textContent = data\[color];
canvas.title = data\[color];
}
@@ -11,8 +11,8 @@
/obj/item/survivalcapsule
name = "bluespace shelter capsule"
desc = "An emergency shelter stored within a pocket of bluespace."
icon_state = "capsule"
icon = 'icons/obj/mining.dmi'
icon_state = "capsule"
w_class = WEIGHT_CLASS_TINY
var/template_id = "shelter_alpha"
var/datum/map_template/shelter/template
@@ -72,9 +72,10 @@
/obj/item/survivalcapsule/luxury
name = "luxury bluespace shelter capsule"
desc = "An exorbitantly expensive luxury suite stored within a pocket of bluespace."
icon_state = "capsule-lux"
template_id = "shelter_beta"
/obj/item/survivalcapsule/luxuryelite
/obj/item/survivalcapsule/luxury/elitebar
name = "luxury elite bar capsule"
desc = "A luxury bar in a capsule. Bartender required and not included."
template_id = "shelter_charlie"
+17 -10
View File
@@ -42,7 +42,7 @@
new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1000),
new /datum/data/mining_equipment("Lazarus Injector", /obj/item/lazarus_injector, 1000),
new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/pickaxe/silver, 1000),
new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000),
new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining/conscript, 1000),
new /datum/data/mining_equipment("1000 Point Transfer Card", /obj/item/card/mining_point_card/mp1000, 1000),
new /datum/data/mining_equipment("1500 Point Transfer Card", /obj/item/card/mining_point_card/mp1500, 1500),
new /datum/data/mining_equipment("2000 Point Transfer Card", /obj/item/card/mining_point_card/mp2000, 2000),
@@ -55,7 +55,7 @@
new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500),
new /datum/data/mining_equipment("Ice hiking boots", /obj/item/clothing/shoes/winterboots/ice_boots, 2500),
new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 3000),
new /datum/data/mining_equipment("Luxury Bar Capsule", /obj/item/survivalcapsule/luxuryelite, 10000),
new /datum/data/mining_equipment("Luxury Bar Capsule", /obj/item/survivalcapsule/luxury/elitebar, 10000),
new /datum/data/mining_equipment("Nanotrasen Minebot", /mob/living/simple_animal/hostile/mining_drone, 800),
new /datum/data/mining_equipment("Minebot Melee Upgrade", /obj/item/mine_bot_upgrade, 400),
new /datum/data/mining_equipment("Minebot Armor Upgrade", /obj/item/mine_bot_upgrade/health, 400),
@@ -70,9 +70,10 @@
new /datum/data/mining_equipment("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000),
new /datum/data/mining_equipment("KA Cooldown Decrease", /obj/item/borg/upgrade/modkit/cooldown, 1000),
new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000),
new /datum/data/mining_equipment("Miner Full Replacement", /obj/item/storage/backpack/duffelbag/mining_cloned, 3000),
new /datum/data/mining_equipment("Miner Full Replacement", /obj/item/storage/backpack/duffelbag/mining/cloned, 3000),
new /datum/data/mining_equipment("Premium Accelerator", /obj/item/gun/energy/kinetic_accelerator/premiumka, 8000),
new /datum/data/mining_equipment("Kinetic Glaive", /obj/item/kinetic_crusher/glaive, 2250),
new /datum/data/mining_equipment("Kinetic Glaive Kit", /obj/item/storage/backpack/duffelbag/mining/glaivekit, 2250),
new /datum/data/mining_equipment("Survival Dagger", /obj/item/kitchen/knife/combat/survival/knuckledagger, 550),
)
/datum/data/mining_equipment
@@ -222,7 +223,7 @@
new /obj/item/extinguisher/mini(drop_location)
new /obj/item/kinetic_crusher(drop_location)
if("Mining Conscription Kit")
new /obj/item/storage/backpack/duffelbag/mining_conscript(drop_location)
new /obj/item/storage/backpack/duffelbag/mining/conscript(drop_location)
SSblackbox.record_feedback("tally", "mining_voucher_redeemed", 1, selection)
qdel(voucher)
@@ -328,11 +329,11 @@
to_chat(user, "You upgrade [I] with mining access.")
qdel(src)
/obj/item/storage/backpack/duffelbag/mining_conscript
/obj/item/storage/backpack/duffelbag/mining/conscript
name = "mining conscription kit"
desc = "A kit containing everything a crewmember needs to support a shaft miner in the field."
/obj/item/storage/backpack/duffelbag/mining_conscript/PopulateContents()
/obj/item/storage/backpack/duffelbag/mining/conscript/PopulateContents()
new /obj/item/pickaxe/mini(src)
new /obj/item/clothing/glasses/meson(src)
new /obj/item/t_scanner/adv_mining_scanner/lesser(src)
@@ -347,11 +348,11 @@
//CITADEL ADDITIONS BELOW
/obj/item/storage/backpack/duffelbag/mining_cloned
/obj/item/storage/backpack/duffelbag/mining/cloned
name = "mining replacement kit"
desc = "A large bag that has advance tools and a spare jumpsuit, boots, and gloves for a newly cloned miner to get back in the field. Even has a new ID!"
desc = "A large bag that has advanced tools and a spare jumpsuit, boots, and gloves for a newly cloned miner to get back in the field. Even has a new ID!"
/obj/item/storage/backpack/duffelbag/mining_cloned/PopulateContents()
/obj/item/storage/backpack/duffelbag/mining/cloned/PopulateContents()
new /obj/item/pickaxe/mini(src)
new /obj/item/clothing/under/rank/cargo/miner/lavaland(src)
new /obj/item/clothing/shoes/workboots/mining(src)
@@ -369,6 +370,12 @@
new /obj/item/storage/bag/ore(src)
new /obj/item/clothing/glasses/meson/prescription(src)
/obj/item/storage/backpack/duffelbag/mining/glaivekit
/obj/item/storage/backpack/duffelbag/mining/glaivekit/PopulateContents()
new /obj/item/kinetic_crusher/glaive(src)
new /obj/item/kitchen/knife/combat/survival/knuckledagger(src)
/obj/machinery/mineral/equipment_vendor/proc/RedeemSVoucher(obj/item/suit_voucher/voucher, mob/redeemer)
var/items = list( "Exo-suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "exo"),
"SEVA suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "seva"))
@@ -26,7 +26,8 @@
features = random_features(pref_species?.id, gender)
age = rand(AGE_MIN,AGE_MAX)
/datum/preferences/proc/update_preview_icon(equip_job = TRUE)
/datum/preferences/proc/update_preview_icon(current_tab)
var/equip_job = (current_tab != 2)
// Determine what job is marked as 'High' priority, and dress them up as such.
var/datum/job/previewJob = get_highest_job()
@@ -45,9 +46,13 @@
mannequin.add_overlay(mutable_appearance('modular_citadel/icons/ui/backgrounds.dmi', bgstate, layer = SPACE_LAYER))
copy_to(mannequin, initial_spawn = TRUE)
if(previewJob && equip_job)
mannequin.job = previewJob.title
previewJob.equip(mannequin, TRUE, preference_source = parent)
if(current_tab == 3)
//give it its loadout if not on the appearance tab
SSjob.equip_loadout(parent.mob, mannequin, FALSE, bypass_prereqs = TRUE, can_drop = FALSE)
else
if(previewJob && equip_job)
mannequin.job = previewJob.title
previewJob.equip(mannequin, TRUE, preference_source = parent)
COMPILE_OVERLAYS(mannequin)
parent.show_character_previews(new /mutable_appearance(mannequin))
@@ -2,7 +2,7 @@
// Facial Hair Definitions //
/////////////////////////////
/datum/sprite_accessory/facial_hair
icon = 'icons/mob/human_face.dmi'
icon = 'icons/mob/hair.dmi'
gender = MALE // barf (unless you're a dorf, dorfs dig chix w/ beards :P)
// please make sure they're sorted alphabetically and categorized
@@ -2,7 +2,7 @@
// Hair Definitions //
//////////////////////
/datum/sprite_accessory/hair
icon = 'icons/mob/human_face.dmi' // default icon for all hairs
icon = 'icons/mob/hair.dmi' // default icon for all hairs
// please make sure they're sorted alphabetically and, where needed, categorized
// try to capitalize the names please~
@@ -117,6 +117,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//the ids you can use for your species, if empty, it means default only and not changeable
var/list/allowed_limb_ids
//the type of eyes this species has
var/eye_type = "normal"
///////////
// PROCS //
///////////
@@ -512,7 +515,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/mutable_appearance/hair_overlay = mutable_appearance(layer = -HAIR_LAYER)
if(!hair_hidden && !H.getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain
if(!(NOBLOOD in species_traits))
hair_overlay.icon = 'icons/mob/human_face.dmi'
hair_overlay.icon = 'icons/mob/hair.dmi'
hair_overlay.icon_state = "debrained"
else if(H.hair_style && (HAIR in species_traits))
@@ -571,7 +574,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(HD && !(HAS_TRAIT(H, TRAIT_HUSK)))
// lipstick
if(H.lip_style && (LIPS in species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[H.lip_style]", -BODY_LAYER)
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/lips.dmi', "lips_[H.lip_style]", -BODY_LAYER)
lip_overlay.color = H.lip_color
if(OFFSET_LIPS in H.dna.species.offset_features)
@@ -584,10 +587,17 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!(NOEYES in species_traits))
var/has_eyes = H.getorganslot(ORGAN_SLOT_EYES)
if(!has_eyes)
standing += mutable_appearance('icons/mob/human_face.dmi', "eyes_missing", -BODY_LAYER)
standing += mutable_appearance('icons/mob/eyes.dmi', "eyes_missing", -BODY_LAYER)
else
var/mutable_appearance/left_eye = mutable_appearance('icons/mob/human_face.dmi', "left_eye", -BODY_LAYER)
var/mutable_appearance/right_eye = mutable_appearance('icons/mob/human_face.dmi', "right_eye", -BODY_LAYER)
var/left_state = DEFAULT_LEFT_EYE_STATE
var/right_state = DEFAULT_RIGHT_EYE_STATE
message_admins("okay so our eye type is [eye_type] and we can index it to know [GLOB.eye_types[eye_type]]")
if(eye_type in GLOB.eye_types)
message_admins("to know that it's in!")
left_state = eye_type + "_left_eye"
right_state = eye_type + "_right_eye"
var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER)
var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER)
if((EYECOLOR in species_traits) && has_eyes)
left_eye.color = "#" + H.left_eye_color
right_eye.color = "#" + H.right_eye_color
@@ -21,3 +21,5 @@
species_type = "insect"
allowed_limb_ids = list("insect","apid","moth","moth_not_greyscale")
eye_type = "insect"
@@ -292,7 +292,17 @@
\"steps out\" of [H.p_them()].</span>",
"<span class='notice'>...and after a moment of disorentation, \
you're besides yourself!</span>")
if(H != spare && isslimeperson(spare) && isslimeperson(H))
// transfer the swap-body ui if it's open
var/datum/action/innate/swap_body/this_swap = origin_datum.swap_body
var/datum/action/innate/swap_body/other_swap = spare_datum.swap_body
var/datum/tgui/ui = SStgui.get_open_ui(H, this_swap, "main") || SStgui.get_open_ui(spare, this_swap, "main")
if(ui)
SStgui.on_close(ui) // basically removes it from lists is all this proc does.
ui.user = spare
ui.src_object = other_swap
SStgui.on_open(ui) // stick it back on the lists
ui.process(force = TRUE)
/datum/action/innate/swap_body
name = "Swap Body"
@@ -345,6 +355,8 @@
stat = "Conscious"
if(UNCONSCIOUS)
stat = "Unconscious"
if(SOFT_CRIT)
stat = "Barely Conscious"
if(DEAD)
stat = "Dead"
var/occupied
@@ -391,7 +403,6 @@
var/mob/living/carbon/human/selected = locate(params["ref"]) in SS.bodies
if(!can_swap(selected))
return
SStgui.close_uis(src)
swap_to_dupe(H.mind, selected)
/datum/action/innate/swap_body/proc/can_swap(mob/living/carbon/human/dupe)
@@ -425,6 +436,7 @@
/datum/action/innate/swap_body/proc/swap_to_dupe(datum/mind/M, mob/living/carbon/human/dupe)
if(!can_swap(dupe)) //sanity check
return
var/mob/living/carbon/human/old = M.current
if(M.current.stat == CONSCIOUS)
M.current.visible_message("<span class='notice'>[M.current] \
stops moving and starts staring vacantly into space.</span>",
@@ -436,7 +448,20 @@
dupe.visible_message("<span class='notice'>[dupe] blinks and looks \
around.</span>",
"<span class='notice'>...and move this one instead.</span>")
if(old != M.current && dupe == M.current && isslimeperson(dupe))
var/datum/species/jelly/slime/other_spec = dupe.dna.species
var/datum/action/innate/swap_body/other_swap = other_spec.swap_body
// theoretically the transfer_to proc is supposed to transfer the ui from the mob.
// so I try to get the UI from one of the two mobs and schlump it over to the new action button
var/datum/tgui/ui = SStgui.get_open_ui(old, src, "main") || SStgui.get_open_ui(dupe, src, "main")
if(ui)
// transfer the UI over. This code is slightly hacky but it fixes the problem
// I'd use SStgui.on_transfer but that doesn't let you transfer the src_object as well s
SStgui.on_close(ui) // basically removes it from lists is all this proc does.
ui.user = dupe
ui.src_object = other_swap
SStgui.on_open(ui) // stick it back on the lists
ui.process(force = TRUE)
////////////////////////////////////////////////////////Round Start Slimes///////////////////////////////////////////////////////////////////
@@ -484,7 +509,7 @@
var/new_color = input(owner, "Choose your skin color:", "Race change","#"+H.dna.features["mcolor"]) as color|null
if(new_color)
var/temp_hsv = RGBtoHSV(new_color)
if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright
if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright
H.dna.features["mcolor"] = sanitize_hexcolor(new_color, 6)
H.update_body()
H.update_hair()
@@ -735,54 +735,62 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if
// Only renders the head of the human
/mob/living/carbon/human/proc/update_body_parts_head_only()
if (!dna)
if(!dna)
return
if (!dna.species)
if(!dna.species)
return
if(dna.species.should_render())
var/obj/item/bodypart/HD = get_bodypart("head")
return
var/obj/item/bodypart/HD = get_bodypart("head")
if(!istype(HD))
return
if (!istype(HD))
return
HD.update_limb()
HD.update_limb()
add_overlay(HD.get_limb_icon())
update_damage_overlays()
add_overlay(HD.get_limb_icon())
update_damage_overlays()
if(HD && !(HAS_TRAIT(src, TRAIT_HUSK)))
// lipstick
if(lip_style && (LIPS in dna.species.species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/lips.dmi', "lips_[lip_style]", -BODY_LAYER)
lip_overlay.color = lip_color
if(OFFSET_LIPS in dna.species.offset_features)
lip_overlay.pixel_x += dna.species.offset_features[OFFSET_LIPS][1]
lip_overlay.pixel_y += dna.species.offset_features[OFFSET_LIPS][2]
add_overlay(lip_overlay)
if(HD && !(HAS_TRAIT(src, TRAIT_HUSK)))
// lipstick
if(lip_style && (LIPS in dna.species.species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[lip_style]", -BODY_LAYER)
lip_overlay.color = lip_color
if(OFFSET_LIPS in dna.species.offset_features)
lip_overlay.pixel_x += dna.species.offset_features[OFFSET_LIPS][1]
lip_overlay.pixel_y += dna.species.offset_features[OFFSET_LIPS][2]
add_overlay(lip_overlay)
// eyes
if(!(NOEYES in dna.species.species_traits))
var/has_eyes = getorganslot(ORGAN_SLOT_EYES)
if(!has_eyes)
add_overlay(mutable_appearance('icons/mob/human_face.dmi', "eyes_missing", -BODY_LAYER))
else
var/mutable_appearance/left_eye = mutable_appearance('icons/mob/human_face.dmi', "left_eye", -BODY_LAYER)
var/mutable_appearance/right_eye = mutable_appearance('icons/mob/human_face.dmi', "right_eye", -BODY_LAYER)
if((EYECOLOR in dna.species.species_traits) && has_eyes)
left_eye.color = "#" + left_eye_color
right_eye.color = "#" + right_eye_color
if(OFFSET_EYES in dna.species.offset_features)
left_eye.pixel_x += dna.species.offset_features[OFFSET_EYES][1]
left_eye.pixel_y += dna.species.offset_features[OFFSET_EYES][2]
right_eye.pixel_x += dna.species.offset_features[OFFSET_EYES][1]
right_eye.pixel_y += dna.species.offset_features[OFFSET_EYES][2]
add_overlay(left_eye)
add_overlay(right_eye)
// eyes
if(!(NOEYES in dna.species.species_traits))
var/has_eyes = getorganslot(ORGAN_SLOT_EYES)
if(!has_eyes)
add_overlay(mutable_appearance('icons/mob/eyes.dmi', "eyes_missing", -BODY_LAYER))
else
var/left_state = DEFAULT_LEFT_EYE_STATE
var/right_state = DEFAULT_RIGHT_EYE_STATE
if(dna.species)
var/eye_type = dna.species.eye_type
if(GLOB.eye_types[eye_type])
left_state = eye_type + "_left_eye"
right_state = eye_type + "_right_eye"
var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER)
var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER)
if((EYECOLOR in dna.species.species_traits) && has_eyes)
left_eye.color = "#" + left_eye_color
right_eye.color = "#" + right_eye_color
if(OFFSET_EYES in dna.species.offset_features)
left_eye.pixel_x += dna.species.offset_features[OFFSET_EYES][1]
left_eye.pixel_y += dna.species.offset_features[OFFSET_EYES][2]
right_eye.pixel_x += dna.species.offset_features[OFFSET_EYES][1]
right_eye.pixel_y += dna.species.offset_features[OFFSET_EYES][2]
add_overlay(left_eye)
add_overlay(right_eye)
dna.species.handle_hair(src)
dna.species.handle_hair(src)
update_inv_head()
update_inv_wear_mask()
update_inv_head()
update_inv_wear_mask()
@@ -34,7 +34,7 @@
hair_hidden = 1
if(!hair_hidden)
if(!getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain
overlays_standing[HAIR_LAYER] = mutable_appearance('icons/mob/human_face.dmi', "debrained", -HAIR_LAYER)
overlays_standing[HAIR_LAYER] = mutable_appearance('icons/mob/human_parts.dmi', "debrained", -HAIR_LAYER)
apply_overlay(HAIR_LAYER)
@@ -244,7 +244,14 @@
if((return_list[BLOCK_RETURN_MITIGATION_PERCENT] >= 100) || (damage <= 0))
. |= BLOCK_SUCCESS
var/list/effect_text
if(efficiency >= data.parry_efficiency_to_counterattack)
var/pacifist_counter_check = TRUE
if(HAS_TRAIT(src, TRAIT_PACIFISM))
switch(parrying)
if(ITEM_PARRY)
pacifist_counter_check = (!active_parry_item.force || active_parry_item.damtype == STAMINA)
else
pacifist_counter_check = FALSE //Both martial and unarmed counter attacks generally are harmful, so no need to have the same line twice.
if(efficiency >= data.parry_efficiency_to_counterattack && pacifist_counter_check)
effect_text = run_parry_countereffects(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency)
if(data.parry_flags & PARRY_DEFAULT_HANDLE_FEEDBACK)
handle_parry_feedback(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency, effect_text)
@@ -454,10 +454,12 @@
if(U.action(src))
to_chat(user, "<span class='notice'>You apply the upgrade to [src].</span>")
if(U.one_use)
U.afterInstall(src)
qdel(U)
else
U.forceMove(src)
upgrades += U
U.afterInstall(src)
else
to_chat(user, "<span class='danger'>Upgrade error.</span>")
U.forceMove(drop_location())
@@ -22,7 +22,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
icon_state = "magicbase"
icon_living = "magicbase"
icon_dead = "magicbase"
speed = 0
speed = -0.5
blood_volume = 0
a_intent = INTENT_HARM
stop_automated_movement = 1
@@ -511,7 +511,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
var/used_message = "<span class='holoparasite'>All the cards seem to be blank now.</span>"
var/failure_message = "<span class='holoparasite bold'>..And draw a card! It's...blank? Maybe you should try again later.</span>"
var/ling_failure = "<span class='holoparasite bold'>The deck refuses to respond to a souless creature such as you.</span>"
var/list/possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
var/list/possible_guardians = list("Assassin", "Chaos", "Gravitokinetic", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
var/random = TRUE
var/allowmultiple = FALSE
var/allowling = TRUE
@@ -559,6 +559,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
if("Chaos")
pickedtype = /mob/living/simple_animal/hostile/guardian/fire
if("Gravitokinetic")
pickedtype = /mob/living/simple_animal/hostile/guardian/gravitokinetic
if("Standard")
pickedtype = /mob/living/simple_animal/hostile/guardian/punch
@@ -615,10 +618,10 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
random = FALSE
/obj/item/guardiancreator/choose/dextrous
possible_guardians = list("Assassin", "Chaos", "Charger", "Dextrous", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
possible_guardians = list("Assassin", "Chaos", "Gravitokinetic", "Charger", "Dextrous", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
/obj/item/guardiancreator/choose/wizard
possible_guardians = list("Assassin", "Chaos", "Charger", "Dextrous", "Explosive", "Lightning", "Protector", "Ranged", "Standard")
possible_guardians = list("Assassin", "Chaos", "Gravitokinetic", "Charger", "Dextrous", "Explosive", "Lightning", "Protector", "Ranged", "Standard")
allowmultiple = TRUE
/obj/item/guardiancreator/tech
@@ -634,7 +637,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
ling_failure = "<span class='holoparasite bold'>The holoparasites recoil in horror. They want nothing to do with a creature like you.</span>"
/obj/item/guardiancreator/tech/choose/traitor
possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
possible_guardians = list("Assassin", "Chaos", "Gravitokinetic", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
allowling = FALSE
/obj/item/guardiancreator/tech/choose/traitor/check_uplink_validity()
@@ -644,10 +647,10 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
random = FALSE
/obj/item/guardiancreator/tech/choose/dextrous
possible_guardians = list("Assassin", "Chaos", "Charger", "Dextrous", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
possible_guardians = list("Assassin", "Chaos", "Gravitokinetic", "Charger", "Dextrous", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
/obj/item/guardiancreator/tech/choose/nukie // lacks support and protector as encouraging nukies to play turtle isnt fun and dextrous is epic
possible_guardians = list("Assassin", "Chaos", "Charger", "Dextrous", "Explosive", "Lightning", "Ranged", "Standard")
possible_guardians = list("Assassin", "Chaos", "Gravitokinetic", "Charger", "Dextrous", "Explosive", "Lightning", "Ranged", "Standard")
/obj/item/guardiancreator/tech/choose/nukie/check_uplink_validity()
return !used
@@ -666,6 +669,8 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
<br>
<b>Explosive</b>: High damage resist and medium power attack that may explosively teleport targets. Can turn any object, including objects too large to pick up, into a bomb, dealing explosive damage to the next person to touch it. The object will return to normal after the trap is triggered or after a delay.<br>
<br>
<b>Gravitokinetic</b>: Attacks will apply crushing gravity to the target. Can target the ground as well to slow targets advancing on you, but this will affect the user.<br>
<br>
<b>Lightning</b>: Attacks apply lightning chains to targets. Has a lightning chain to the user. Lightning chains shock everything near them, doing constant damage.<br>
<br>
<b>Protector</b>: Causes you to teleport to it when out of range, unlike other parasites. Has two modes; Combat, where it does and takes medium damage, and Protection, where it does and takes almost no damage but moves slightly slower.<br>
@@ -695,6 +700,8 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
<br>
<b>Explosive</b>: High damage resist and medium power attack that may explosively teleport targets. Can turn any object, including objects too large to pick up, into a bomb, dealing explosive damage to the next person to touch it. The object will return to normal after the trap is triggered or after a delay.<br>
<br>
<b>Gravitokinetic</b>: Attacks will apply crushing gravity to the target. Can target the ground as well to slow targets advancing on you, but this will affect the user.<br>
<br>
<b>Lightning</b>: Attacks apply lightning chains to targets. Has a lightning chain to the user. Lightning chains shock everything near them, doing constant damage.<br>
<br>
<b>Protector</b>: Causes you to teleport to it when out of range, unlike other parasites. Has two modes; Combat, where it does and takes medium damage, and Protection, where it does and takes almost no damage but moves slightly slower.<br>
@@ -720,6 +727,8 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
<br>
<b>Explosive</b>: High damage resist and medium power attack that may explosively teleport targets. Can turn any object, including objects too large to pick up, into a bomb, dealing explosive damage to the next person to touch it. The object will return to normal after the trap is triggered or after a delay.<br>
<br>
<b>Gravitokinetic</b>: Attacks will apply crushing gravity to the target. Can target the ground as well to slow targets advancing on you, but this will affect the user.<br>
<br>
<b>Lightning</b>: Attacks apply lightning chains to targets. Has a lightning chain to the user. Lightning chains shock everything near them, doing constant damage.<br>
<br>
<b>Ranged</b>: Has two modes. Ranged; which fires a constant stream of weak, armor-ignoring projectiles. Scout; Cannot attack, but can move through walls and is quite hard to see. Can lay surveillance snares, which alert it when crossed, in either mode.<br>
@@ -1,5 +1,7 @@
//Assassin
/mob/living/simple_animal/hostile/guardian/assassin
melee_damage_lower = 15
melee_damage_upper = 15
attack_verb_continuous = "slashes"
attack_verb_simple = "slash"
attack_sound = 'sound/weapons/bladeslice.ogg'
@@ -1,8 +1,11 @@
//Charger
/mob/living/simple_animal/hostile/guardian/charger
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1 //technically
ranged_message = "charges"
ranged_cooldown_time = 20
speed = -1
damage_coeff = list(BRUTE = 0.2, BURN = 0.5, TOX = 0.5, CLONE = 0.5, STAMINA = 0, OXY = 0.5)
playstyle_string = "<span class='holoparasite'>As a <b>charger</b> type you do medium damage, take half damage, have near immunity to brute damage, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Hunter, an alien master of rapid assault.</span>"
@@ -1,5 +1,7 @@
//Bomb
/mob/living/simple_animal/hostile/guardian/bomb
melee_damage_lower = 15
melee_damage_upper = 15
damage_coeff = list(BRUTE = 0.6, BURN = 0.6, TOX = 0.6, CLONE = 0.6, STAMINA = 0, OXY = 0.6)
playstyle_string = "<span class='holoparasite'>As an <b>explosive</b> type, you have moderate close combat abilities, take half damage, may explosively teleport targets on attack, and are capable of converting nearby items and objects into disguised bombs via alt click.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Scientist, master of explosive death.</span>"
@@ -0,0 +1,73 @@
//gravitokinetic
/mob/living/simple_animal/hostile/guardian/gravitokinetic
melee_damage_lower = 15
melee_damage_upper = 15
damage_coeff = list(BRUTE = 0.75, BURN = 0.75, TOX = 0.75, CLONE = 0.75, STAMINA = 0, OXY = 0.75)
playstyle_string = "<span class='holoparasite'>As a <b>gravitokinetic</b> type, you can alt click to make the gravity on the ground stronger, and punching applies this effect to a target.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Singularity, an anomalous force of terror.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Gravitokinetic modules loaded. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one! It's a gravitokinetic carp! Now do you understand the gravity of the situation?</span>"
var/list/gravito_targets = list()
var/gravity_power_range = 10 //how close the stand must stay to the target to keep the heavy gravity
///Removes gravity from affected mobs upon guardian death to prevent permanent effects
/mob/living/simple_animal/hostile/guardian/gravitokinetic/death()
. = ..()
for(var/i in gravito_targets)
remove_gravity(i)
/mob/living/simple_animal/hostile/guardian/gravitokinetic/AttackingTarget()
. = ..()
if(isliving(target) && target != src && target != summoner)
to_chat(src, "<span class='danger'><B>Your punch has applied heavy gravity to [target]!</span></B>")
add_gravity(target, 5)
to_chat(target, "<span class='userdanger'>Everything feels really heavy!</span>")
/mob/living/simple_animal/hostile/guardian/gravitokinetic/AltClickOn(atom/A)
if(isopenturf(A) && is_deployed() && stat != DEAD && in_range(src, A) && !incapacitated())
var/turf/T = A
if(isspaceturf(T))
to_chat(src, "<span class='warning'>You cannot add gravity to space!</span>")
return
visible_message("<span class='danger'>[src] slams their fist into the [T]!</span>", "<span class='notice'>You modify the gravity of the [T].</span>")
do_attack_animation(T)
add_gravity(T, 3)
return
return ..()
/mob/living/simple_animal/hostile/guardian/gravitokinetic/Recall(forced)
. = ..()
to_chat(src, "<span class='danger'><B>You have released your gravitokinetic powers!</span></B>")
for(var/i in gravito_targets)
remove_gravity(i)
/mob/living/simple_animal/hostile/guardian/gravitokinetic/Manifest(forced)
. = ..()
//just make sure to reapply a gravity immunity wherever you summon. it can be overridden but not by you at least
summoner.AddElement(/datum/element/forced_gravity, 1)
AddElement(/datum/element/forced_gravity, 1)
/mob/living/simple_animal/hostile/guardian/gravitokinetic/Moved(oldLoc, dir)
. = ..()
for(var/i in gravito_targets)
if(get_dist(src, i) > gravity_power_range)
remove_gravity(i)
/mob/living/simple_animal/hostile/guardian/gravitokinetic/proc/add_gravity(atom/A, new_gravity = 3)
if(gravito_targets[A])
return
A.AddElement(/datum/element/forced_gravity, new_gravity)
gravito_targets[A] = new_gravity
RegisterSignal(A, COMSIG_MOVABLE_MOVED, .proc/__distance_check)
playsound(src, 'sound/effects/gravhit.ogg', 100, TRUE)
/mob/living/simple_animal/hostile/guardian/gravitokinetic/proc/remove_gravity(atom/target)
if(isnull(gravito_targets[target]))
return
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
target.RemoveElement(/datum/element/forced_gravity, gravito_targets[target])
gravito_targets -= target
/mob/living/simple_animal/hostile/guardian/gravitokinetic/proc/__distance_check(atom/movable/AM, OldLoc, Dir, Forced)
if(get_dist(src, AM) > gravity_power_range)
remove_gravity(AM)
@@ -1,5 +1,7 @@
//Protector
/mob/living/simple_animal/hostile/guardian/protector
melee_damage_lower = 15
melee_damage_upper = 15
range = 15 //worse for it due to how it leashes
damage_coeff = list(BRUTE = 0.4, BURN = 0.4, TOX = 0.4, CLONE = 0.4, STAMINA = 0, OXY = 0.4)
playstyle_string = "<span class='holoparasite'>As a <b>protector</b> type you cause your summoner to leash to you instead of you leashing to them and have two modes; Combat Mode, where you do and take medium damage, and Protection Mode, where you do and take almost no damage, but move slightly slower.</span>"
@@ -31,9 +33,10 @@
cooldown = world.time + 10
if(toggle)
cut_overlays()
melee_damage_lower = 15
melee_damage_upper = 15
speed = 0
add_overlay(cooloverlay) //readd the guardian's colors
melee_damage_lower = initial(melee_damage_lower)
melee_damage_upper = initial(melee_damage_upper)
speed = initial(speed)
damage_coeff = list(BRUTE = 0.4, BURN = 0.4, TOX = 0.4, CLONE = 0.4, STAMINA = 0, OXY = 0.4)
to_chat(src, "<span class='danger'><B>You switch to combat mode.</span></B>")
toggle = FALSE
@@ -4,6 +4,8 @@
friendly_verb_continuous = "heals"
friendly_verb_simple = "heal"
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
melee_damage_lower = 15
melee_damage_upper = 15
playstyle_string = "<span class='holoparasite'>As a <b>support</b> type, you have 30% damage reduction and may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent object or mob will warp them to your bluespace beacon after a short delay.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the CMO, a potent force of life... and death.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught a support carp. It's a kleptocarp!</span>"
@@ -43,15 +45,15 @@
if(src.loc == summoner)
if(toggle)
a_intent = INTENT_HARM
speed = 0
speed = initial(speed)
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
melee_damage_lower = 15
melee_damage_upper = 15
melee_damage_lower = initial(melee_damage_lower)
melee_damage_upper = initial(melee_damage_upper)
to_chat(src, "<span class='danger'><B>You switch to combat mode.</span></B>")
toggle = FALSE
else
a_intent = INTENT_HELP
speed = 1
speed = initial(speed)
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
melee_damage_lower = 0
melee_damage_upper = 0

Some files were not shown because too many files have changed in this diff Show More