Merge remote-tracking branch 'ParadiseSS13/master' into toml-config

This commit is contained in:
AffectedArc07
2021-05-16 13:22:14 +01:00
124 changed files with 868 additions and 542 deletions
+1 -1
View File
@@ -363,7 +363,7 @@
#define INVESTIGATE_BOMB "bombs"
// The SQL version required by this version of the code
#define SQL_VERSION 22
#define SQL_VERSION 23
// Vending machine stuff
#define CAT_NORMAL 1
+1 -1
View File
@@ -94,7 +94,7 @@
#define EXP_TYPE_SERVICE "Service"
#define EXP_TYPE_WHITELIST "Whitelist"
#define EXP_DEPT_TYPE_LIST list(EXP_TYPE_SERVICE, EXP_TYPE_MEDICAL, EXP_TYPE_ENGINEERING, EXP_TYPE_SCIENCE, EXP_TYPE_SECURITY, EXP_TYPE_COMMAND, EXP_TYPE_SILICON, EXP_TYPE_SPECIAL)
#define EXP_DEPT_TYPE_LIST list(EXP_TYPE_SUPPLY, EXP_TYPE_SERVICE, EXP_TYPE_MEDICAL, EXP_TYPE_ENGINEERING, EXP_TYPE_SCIENCE, EXP_TYPE_SECURITY, EXP_TYPE_COMMAND, EXP_TYPE_SILICON, EXP_TYPE_SPECIAL, EXP_TYPE_GHOST)
// Defines just for parallax because its levels make storing it in the regular prefs a pain in the ass
// These dont need to be bitflags because there isnt going to be more than one at a time of these active
-1
View File
@@ -92,7 +92,6 @@ GLOBAL_VAR(map_name) // Self explanatory
GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) // Station datacore, manifest, etc
GLOBAL_VAR_INIT(panic_bunker_enabled, FALSE) // Is the panic bunker enabled
GLOBAL_VAR_INIT(pending_server_update, FALSE)
GLOBAL_LIST_EMPTY(ability_verbs) // Create-level abilities
GLOBAL_LIST_INIT(pipe_colors, list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "purple" = PIPE_COLOR_PURPLE))
+1 -1
View File
@@ -65,7 +65,7 @@ SUBSYSTEM_DEF(blackbox)
sqlversion = versions[FV.key]
var/datum/db_query/query_feedback_save = SSdbcore.NewQuery({"
INSERT DELAYED IGNORE INTO [format_table_name("feedback")] (datetime, round_id, key_name, key_type, version, json)
INSERT IGNORE INTO [format_table_name("feedback")] (datetime, round_id, key_name, key_type, version, json)
VALUES (NOW(), :rid, :keyname, :keytype, :version, :json)"}, list(
"rid" = text2num(GLOB.round_id),
"keyname" = FV.key,
+3
View File
@@ -383,6 +383,9 @@
/datum/action/item_action/hands_free/activate
name = "Activate"
/datum/action/item_action/hands_free/activate/always
check_flags = null
/datum/action/item_action/toggle_research_scanner
name = "Toggle Research Scanner"
button_icon_state = "scan_mode"
+2
View File
@@ -111,6 +111,8 @@
for(var/path in backpack_contents)
var/number = backpack_contents[path]
if(!number)
number = 1
for(var/i in 1 to number)
H.equip_or_collect(new path(H), slot_in_backpack)
+83 -20
View File
@@ -3,7 +3,7 @@
/datum/outfit/admin/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
. = ..()
if(!visualsOnly)
if(!visualsOnly && H.mind)
H.mind.assigned_role = name
H.job = name
@@ -627,6 +627,10 @@
/obj/item/implanter/death_alarm = 1,
)
implants = list(/obj/item/implant/mindshield,
/obj/item/implant/death_alarm
)
/datum/outfit/admin/solgov_rep/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
. = ..()
if(visualsOnly)
@@ -634,33 +638,43 @@
var/obj/item/card/id/I = H.wear_id
if(istype(I))
apply_to_card(I, H, get_all_accesses(), name, "lifetimeid")
apply_to_card(I, H, get_all_centcom_access(), name, "lifetimeid")
I.assignment = "Solar Federation Representative"
/datum/outfit/admin/solgov
name = "Solar Federation Marine"
uniform = /obj/item/clothing/under/solgov
suit = /obj/item/clothing/suit/armor/bulletproof
back = /obj/item/storage/backpack/security
belt = /obj/item/storage/belt/military/assault
head = /obj/item/clothing/head/soft/solgov
glasses = /obj/item/clothing/glasses/hud/security/night
belt = /obj/item/storage/belt/military/assault/marines/full
head = /obj/item/clothing/head/soft/solgov/marines
glasses = /obj/item/clothing/glasses/night
gloves = /obj/item/clothing/gloves/combat
shoes = /obj/item/clothing/shoes/combat
l_ear = /obj/item/radio/headset/ert
id = /obj/item/card/id
l_hand = /obj/item/gun/projectile/automatic/ar
l_hand = /obj/item/gun/projectile/automatic/shotgun/bulldog
suit_store = /obj/item/gun/projectile/automatic/pistol/m1911
r_pocket = /obj/item/flashlight/seclite
pda = /obj/item/pda
backpack_contents = list(
/obj/item/storage/box/responseteam = 1,
/obj/item/ammo_box/magazine/m556 = 3,
/obj/item/clothing/shoes/magboots = 1,
/obj/item/gun/projectile/automatic/pistol/m1911 = 1,
/obj/item/ammo_box/magazine/m45 = 2
/obj/item/whetstone = 1,
/obj/item/clothing/mask/gas/explorer/marines = 1,
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1
)
var/is_tsf_lieutenant = FALSE
cybernetic_implants = list(
/obj/item/organ/internal/cyberimp/arm/flash,
/obj/item/organ/internal/cyberimp/chest/nutriment,
/obj/item/organ/internal/cyberimp/eyes/hud/security
)
implants = list(/obj/item/implant/mindshield,
/obj/item/implant/death_alarm
)
var/is_solgov_lieutenant = FALSE
/datum/outfit/admin/solgov/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
@@ -668,31 +682,80 @@
if(visualsOnly)
return
if(is_tsf_lieutenant)
if(is_solgov_lieutenant)
H.real_name = "Lieutenant [pick(GLOB.last_names)]"
else
H.real_name = "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(GLOB.last_names)]"
H.name = H.real_name
var/obj/item/card/id/I = H.wear_id
if(istype(I))
apply_to_card(I, H, get_all_accesses(), name, "lifetimeid")
I.assignment = name
if(istype(I) && is_solgov_lieutenant)
apply_to_card(I, H, get_centcom_access("Emergency Response Team Leader"), name, "lifetimeid")
else if(istype(I))
apply_to_card(I, H, get_centcom_access("Emergency Response Team Member"), name, "lifetimeid")
H.sec_hud_set_ID()
/datum/outfit/admin/solgov/lieutenant
name = "Solar Federation Lieutenant"
uniform = /obj/item/clothing/under/solgov/command
head = /obj/item/clothing/head/soft/solgov/command
head = /obj/item/clothing/head/beret/solgov/command
glasses = /obj/item/clothing/glasses/night
back = /obj/item/storage/backpack/satchel
l_ear = /obj/item/radio/headset/ert/alt/commander
l_hand = null
belt = /obj/item/melee/baton/loaded
suit_store = /obj/item/gun/projectile/automatic/pistol/deagle
l_pocket = /obj/item/pinpointer/advpinpointer
backpack_contents = list(
/obj/item/storage/box/responseteam = 1,
/obj/item/melee/classic_baton/telescopic = 1,
/obj/item/storage/box/handcuffs = 1,
/obj/item/clothing/shoes/magboots/advance = 1,
/obj/item/gun/projectile/automatic/pistol/deagle = 1,
/obj/item/ammo_box/magazine/m50 = 2
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1,
/obj/item/clothing/mask/gas/explorer/marines = 1,
/obj/item/ammo_box/magazine/m50 = 3
)
is_tsf_lieutenant = TRUE
is_solgov_lieutenant = TRUE
/datum/outfit/admin/solgov/elite
name = "Solar Federation Specops Marine"
uniform = /obj/item/clothing/under/solgov/elite
head = /obj/item/clothing/head/soft/solgov/marines/elite
belt = /obj/item/storage/belt/military/assault/marines/elite/full
l_hand = /obj/item/gun/projectile/automatic/ar
backpack_contents = list(
/obj/item/storage/box/responseteam = 1,
/obj/item/clothing/shoes/magboots/advance = 1,
/obj/item/whetstone = 1,
/obj/item/clothing/mask/gas/explorer/marines = 1,
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1
)
cybernetic_implants = list(
/obj/item/organ/internal/cyberimp/eyes/hud/security,
/obj/item/organ/internal/cyberimp/chest/nutriment,
/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened,
/obj/item/organ/internal/cyberimp/arm/flash,
/obj/item/organ/internal/eyes/cybernetic/shield
)
/datum/outfit/admin/solgov/elite/lieutenant
name = "Solar Federation Specops Lieutenant"
uniform = /obj/item/clothing/under/solgov/command/elite
head = /obj/item/clothing/head/beret/solgov/command/elite
glasses = /obj/item/clothing/glasses/night
back = /obj/item/storage/backpack/satchel
belt = /obj/item/melee/baton/loaded
l_hand = null
suit_store = /obj/item/gun/projectile/automatic/pistol/deagle
l_pocket = /obj/item/pinpointer/advpinpointer
l_ear = /obj/item/radio/headset/ert/alt/commander
backpack_contents = list(
/obj/item/storage/box/responseteam = 1,
/obj/item/storage/box/handcuffs = 1,
/obj/item/clothing/shoes/magboots/advance = 1,
/obj/item/clothing/mask/gas/explorer/marines = 1,
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1,
/obj/item/ammo_box/magazine/m50 = 3
)
is_solgov_lieutenant = TRUE
/datum/outfit/admin/sol_trader
name = "Sol Trader"
+8 -3
View File
@@ -49,7 +49,7 @@
/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone
name = "Summon Soulstone"
desc = "This spell reaches into Nar'Sie's realm, summoning one of the legendary fragments across time and space"
desc = "This spell reaches into Redspace, summoning one of the legendary fragments across time and space"
action_icon_state = "summonsoulstone"
action_background_icon_state = "bg_cult"
school = "conjuration"
@@ -68,7 +68,7 @@
/obj/effect/proc_holder/spell/aoe_turf/conjure/pylon
name = "Cult Pylon"
desc = "This spell conjures a fragile crystal from Nar'Sie's realm. Makes for a convenient light source."
desc = "This spell conjures a fragile crystal from Redspace. Makes for a convenient light source."
action_icon_state = "pylon"
action_background_icon_state = "bg_cult"
school = "conjuration"
@@ -118,7 +118,12 @@
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/do_jaunt(mob/living/target)
target.set_light(0)
..()
target.set_light(2, 3, l_color = SSticker.cultdat ? SSticker.cultdat.construct_glow : LIGHT_COLOR_BLOOD_MAGIC)
if(isconstruct(target))
var/mob/living/simple_animal/hostile/construct/C = target
if(C.holy)
C.set_light(3, 5, LIGHT_COLOR_DARK_BLUE)
else
C.set_light(2, 3, l_color = SSticker.cultdat ? SSticker.cultdat.construct_glow : LIGHT_COLOR_BLOOD_MAGIC)
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/jaunt_steam(mobloc)
return
+26 -12
View File
@@ -1,39 +1,53 @@
/// Will our restart be slower?
GLOBAL_VAR_INIT(slower_restart, FALSE)
/proc/server_announce_global(announcement_text)
to_chat(world, "<span style='color: #ff00ff'>\[Server] [announcement_text]</span>")
/proc/server_announce_adminonly(announcement_text)
to_chat(GLOB.admins, "<span style='color: #ff00ff'>\[Server] \[Admin] [announcement_text]</span>")
/datum/tgs_event_handler/impl
var/datum/timedevent/reattach_timer
/datum/tgs_event_handler/impl/HandleEvent(event_code, ...)
switch(event_code)
if(TGS_EVENT_REBOOT_MODE_CHANGE)
var/list/reboot_mode_lookup = list ("[TGS_REBOOT_MODE_NORMAL]" = "be normal", "[TGS_REBOOT_MODE_SHUTDOWN]" = "shutdown the server", "[TGS_REBOOT_MODE_RESTART]" = "hard restart the server")
var/old_reboot_mode = args[2]
var/new_reboot_mode = args[3]
message_admins("\[Server]\[Info] Reboot will no longer [reboot_mode_lookup["[old_reboot_mode]"]], it will instead [reboot_mode_lookup["[new_reboot_mode]"]]")
if(new_reboot_mode == TGS_REBOOT_MODE_SHUTDOWN)
GLOB.slower_restart = TRUE
else
GLOB.slower_restart = FALSE
server_announce_adminonly("\[Info] Reboot will no longer [reboot_mode_lookup["[old_reboot_mode]"]], it will instead [reboot_mode_lookup["[new_reboot_mode]"]]")
if(TGS_EVENT_PORT_SWAP)
message_admins("\[Server]\[Info] Changing port from [world.port] to [args[2]]")
server_announce_adminonly("\[Info] Changing port from [world.port] to [args[2]]")
if(TGS_EVENT_INSTANCE_RENAMED)
message_admins("\[Server]\[Info] Instance renamed to from [world.TgsInstanceName()] to [args[2]]")
server_announce_adminonly("\[Info] Instance renamed to from [world.TgsInstanceName()] to [args[2]]")
if(TGS_EVENT_COMPILE_START)
message_admins("\[Server]\[Info] Code deployment started, new game version incoming next round...")
server_announce_adminonly("\[Info] Code deployment started, new game version incoming next round...")
if(TGS_EVENT_COMPILE_CANCELLED)
message_admins("\[Server]\[Warning] Code deployment cancelled!")
server_announce_adminonly("\[Warning] Code deployment cancelled! Consult a maintainer/host to see if this was intentional!")
if(TGS_EVENT_COMPILE_FAILURE)
message_admins("\[Server]\[Error] Code deployment failed! Inform a maintainer/host immediately!")
server_announce_adminonly("\[Error] Code deployment failed! Inform a maintainer/host immediately!")
if(TGS_EVENT_DEPLOYMENT_COMPLETE)
message_admins("\[Server]\[Info] Code deployment complete!")
to_chat(world, "<span class='boldannounce'>Server updated, changes will be applied on the next round...</span>")
server_announce_adminonly("\[Info] Code deployment complete!")
server_announce_global("Server update complete. Changes will be applied on the next round.")
if(TGS_EVENT_WATCHDOG_DETACH)
message_admins("\[Server]\[Info] Server manager restarting...")
server_announce_adminonly("\[Info] Server manager restarting...")
reattach_timer = addtimer(CALLBACK(src, .proc/LateOnReattach), 1 MINUTES, TIMER_STOPPABLE)
if(TGS_EVENT_WATCHDOG_REATTACH)
var/datum/tgs_version/old_version = world.TgsVersion()
var/datum/tgs_version/new_version = args[2]
if(!old_version.Equals(new_version))
message_admins("\[Server]\[Info] Manager back online. TGS has been updated to v[new_version.deprefixed_parameter]")
server_announce_adminonly("\[Info] Server manager back online. TGS has been updated to v[new_version.deprefixed_parameter]")
else
message_admins("\[Server]\[Info] Manager back online")
server_announce_adminonly("\[Info] Server manager back online")
if(reattach_timer)
deltimer(reattach_timer)
reattach_timer = null
/datum/tgs_event_handler/impl/proc/LateOnReattach()
message_admins("\[Server]\[Warning] TGS hasn't notified us of it coming back for a full minute! Is there a problem?")
server_announce_adminonly("\[Warning] TGS hasn't notified us of it coming back for a full minute! Is there a problem?")
+30 -30
View File
@@ -1108,7 +1108,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/engine/equipmentstorage
name = "\improper Engineering Equipment Storage"
name = "Engineering Equipment Storage"
icon_state = "storage"
sound_environment = SOUND_AREA_SMALL_ENCLOSED
@@ -1260,7 +1260,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/medical/biostorage
name = "\improper Medical Storage"
name = "Medical Storage"
icon_state = "medbaysecstorage"
/area/medical/reception
@@ -1285,19 +1285,19 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "patientsward"
/area/medical/patient_a
name = "\improper Isolation A"
name = "Isolation A"
icon_state = "medbayisoa"
/area/medical/patient_b
name = "\improper Isolation B"
name = "Isolation B"
icon_state = "medbayisob"
/area/medical/patient_c
name = "\improper Isolation C"
name = "Isolation C"
icon_state = "medbayisoc"
/area/medical/iso_access
name = "\improper Isolation Access"
name = "Isolation Access"
icon_state = "medbayisoaccess"
/area/medical/cmo
@@ -1305,15 +1305,15 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "CMO"
/area/medical/cmostore
name = "\improper Medical Secondary Storage"
name = "Medical Secondary Storage"
icon_state = "medbaysecstorage"
/area/medical/robotics
name = "\improper Robotics"
name = "Robotics"
icon_state = "medresearch"
/area/medical/research
name = "\improper Medical Research"
name = "Medical Research"
icon_state = "medresearch"
/area/medical/research_shuttle_dock
@@ -1321,7 +1321,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "medresearch"
/area/medical/virology
name = "\improper Virology"
name = "Virology"
icon_state = "virology"
/area/medical/virology/lab
@@ -1336,7 +1336,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/medical/chemistry
name = "\improper Chemistry"
name = "Chemistry"
icon_state = "chem"
/area/medical/surgery
@@ -1344,19 +1344,19 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "surgery"
/area/medical/surgery1
name = "\improper Surgery 1"
name = "Surgery 1"
icon_state = "surgery1"
/area/medical/surgery2
name = "\improper Surgery 2"
name = "Surgery 2"
icon_state = "surgery2"
/area/medical/surgeryobs
name = "\improper Surgery Observation"
name = "Surgery Observation"
icon_state = "surgery"
/area/medical/cryo
name = "\improper Cryogenics"
name = "Cryogenics"
icon_state = "cryo"
/area/medical/exam_room
@@ -1376,7 +1376,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "exam_room"
/area/medical/paramedic
name = "\improper Paramedic"
name = "Paramedic"
icon_state = "medbay"
//Security
@@ -1441,22 +1441,22 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "brig"
/area/security/execution
name = "\improper Execution"
name = "Execution"
icon_state = "execution"
can_get_auto_cryod = FALSE
/area/security/processing
name = "\improper Prisoner Processing"
name = "Prisoner Processing"
icon_state = "prisonerprocessing"
can_get_auto_cryod = FALSE
/area/security/interrogation
name = "\improper Interrogation"
name = "Interrogation"
icon_state = "interrogation"
can_get_auto_cryod = FALSE
/area/security/seceqstorage
name = "\improper Security Equipment Storage"
name = "Security Equipment Storage"
icon_state = "securityequipmentstorage"
/area/security/interrogationhallway
@@ -1469,7 +1469,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
sound_environment = SOUND_AREA_LARGE_ENCLOSED
/area/security/interrogationobs
name = "\improper Interrogation Observation"
name = "Interrogation Observation"
icon_state = "security"
can_get_auto_cryod = FALSE
@@ -1530,11 +1530,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "nuke_storage"
/area/security/customs
name = "\improper Customs"
name = "Customs"
icon_state = "checkpoint1"
/area/security/customs2
name = "\improper Customs"
name = "Customs"
icon_state = "security"
/area/security/checkpoint
@@ -1601,7 +1601,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "mining"
/area/quartermaster/miningstorage
name = "\improper Mining Storage"
name = "Mining Storage"
icon_state = "green"
/area/quartermaster/mechbay
@@ -1614,7 +1614,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
sound_environment = SOUND_AREA_SMALL_ENCLOSED
/area/hydroponics
name = "\improper Hydroponics"
name = "Hydroponics"
icon_state = "hydro"
sound_environment = SOUND_AREA_STANDARD_STATION
@@ -1629,7 +1629,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
sound_environment = SOUND_AREA_STANDARD_STATION
/area/toxins/lab
name = "\improper Research and Development"
name = "Research and Development"
icon_state = "toxlab"
/area/toxins/hallway
@@ -1650,7 +1650,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
xenobiology_compatible = TRUE
/area/toxins/xenobiology/xenoflora_storage
name = "\improper Xenoflora Storage"
name = "Xenoflora Storage"
icon_state = "toxlab"
/area/toxins/xenobiology/xenoflora
@@ -1658,7 +1658,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "toxlab"
/area/toxins/storage
name = "\improper Toxins Storage"
name = "Toxins Storage"
icon_state = "toxstorage"
/area/toxins/test_area
@@ -1671,7 +1671,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "toxmix"
/area/toxins/launch
name = "Toxins Launch Room"
name = "\improper Toxins Launch Room"
icon_state = "toxlaunch"
/area/toxins/misc_lab
@@ -1739,7 +1739,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "auxstorage"
/area/storage/office
name = "\improper Office Supplies"
name = "Office Supplies"
icon_state = "office_supplies"
// ENGIE OUTPOST
+1
View File
@@ -14,6 +14,7 @@ GLOBAL_LIST_INIT(assigned_mutation_blocks, new(DNA_SE_LENGTH))
// Used to determine what each block means (admin hax and species stuff on /vg/, mostly)
GLOBAL_LIST_INIT(assigned_blocks, new(DNA_SE_LENGTH))
/// Assoc list. Key = type of the mutation, value = the mutation
GLOBAL_LIST_EMPTY(dna_mutations)
GLOBAL_LIST_EMPTY(good_blocks)
+3 -6
View File
@@ -3,7 +3,8 @@
// M: Mob to mess with
// flags: See below, bitfield.
/proc/domutcheck(mob/living/M, flags = 0)
for(var/datum/mutation/mutation in GLOB.dna_mutations)
for(var/mutation_type in GLOB.dna_mutations)
var/datum/mutation/mutation = GLOB.dna_mutations[mutation_type]
if(!M || !M.dna)
return
if(!mutation.block)
@@ -32,7 +33,7 @@
var/mutation_active = M.dna.GetSEState(mutation.block)
// Sanity checks, don't skip.
if(!mutation.can_activate(M, flags) && mutation_active)
if(mutation_active && !mutation.can_activate(M, flags))
//testing("[M] - Failed to activate [gene.name] (can_activate fail).")
return FALSE
@@ -46,11 +47,7 @@
if(mutation_active)
//testing("[gene.name] activated!")
mutation.activate(M)
if(M)
M.active_mutations |= mutation.type
// If Gene is NOT active:
else
//testing("[gene.name] deactivated!")
mutation.deactivate(M)
if(M)
M.active_mutations -= mutation.type
+4
View File
@@ -31,7 +31,9 @@
// Called when the gene activates. Do your magic here.
/datum/mutation/proc/activate(mob/living/M)
SHOULD_CALL_PARENT(TRUE)
M.gene_stability -= instability
M.active_mutations |= type // |= is probably not required but just in case
for(var/thing in traits_to_add)
ADD_TRAIT(M, thing, GENETIC_MUTATION)
if(length(activation_messages))
@@ -42,7 +44,9 @@
// Called when the gene deactivates. Undo your magic here.
// Only called when the block is deactivated.
/datum/mutation/proc/deactivate(mob/living/M)
SHOULD_CALL_PARENT(TRUE)
M.gene_stability += instability
M.active_mutations -= type
for(var/thing in traits_to_add)
REMOVE_TRAIT(M, thing, GENETIC_MUTATION)
if(length(deactivation_messages))
+2
View File
@@ -9,6 +9,7 @@
return ishuman(M)
/datum/mutation/monkey/activate(mob/living/carbon/human/H)
..()
if(!istype(H))
return
if(issmall(H))
@@ -42,6 +43,7 @@
return H
/datum/mutation/monkey/deactivate(mob/living/carbon/human/H)
..()
if(!istype(H))
return
if(!issmall(H))
+1
View File
@@ -103,6 +103,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
to_chat(blob.current, "<b>Find a good location to spawn the core and then take control and overwhelm the station!</b>")
to_chat(blob.current, "<b>When you have found a location, wait until you spawn; this will happen automatically and you cannot speed up the process.</b>")
to_chat(blob.current, "<b>If you go outside of the station level, or in space, then you will die; make sure your location has lots of ground to cover.</b>")
to_chat(blob.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Blob)</span>")
SEND_SOUND(blob.current, sound('sound/magic/mutate.ogg'))
return
@@ -147,6 +147,7 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
for(var/datum/objective/objective in changeling.objectives)
to_chat(changeling.current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
obj_count++
to_chat(changeling.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Changeling)</span>")
return
/datum/game_mode/proc/remove_changeling(datum/mind/changeling_mind)
+48 -43
View File
@@ -249,7 +249,7 @@
/datum/action/innate/cult/blood_spell/horror/Destroy()
var/obj/effect/proc_holder/horror/destroy = PH
. = ..()
if(destroy && !QDELETED(destroy))
if(!QDELETED(destroy))
QDEL_NULL(destroy)
/datum/action/innate/cult/blood_spell/horror/Activate()
@@ -264,7 +264,7 @@
/obj/effect/proc_holder/horror/Destroy()
var/datum/action/innate/cult/blood_spell/AA = attached_action
. = ..()
if(AA && !QDELETED(AA))
if(!QDELETED(AA))
QDEL_NULL(AA)
/obj/effect/proc_holder/horror/proc/toggle(mob/user)
@@ -464,9 +464,15 @@
var/list/potential_runes = list()
var/list/teleportnames = list()
var/list/duplicaterunecount = list()
var/atom/movable/teleportee
if(!iscultist(target) || !proximity)
to_chat(user, "<span class='warning'>You can only teleport adjacent cultists with this spell!</span>")
return
if(user != target) // So that the teleport effect shows on the correct mob
teleportee = target
else
teleportee = user
for(var/R in GLOB.teleport_runes)
var/obj/effect/rune/teleport/T = R
var/resultkey = T.listkey
@@ -487,16 +493,15 @@
log_game("Teleport spell failed - user in away mission")
return
var/mob/living/L = target
var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked
var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to?
if(!src || QDELETED(src) || !user || user.l_hand != src && user.r_hand != src || user.incapacitated() || !actual_selected_rune)
if(QDELETED(src) || !user || user.l_hand != src && user.r_hand != src || user.incapacitated() || !actual_selected_rune)
return
uses--
var/turf/origin = get_turf(user)
var/turf/origin = get_turf(teleportee)
var/turf/destination = get_turf(actual_selected_rune)
INVOKE_ASYNC(actual_selected_rune, /obj/effect/rune/.proc/teleport_effect, user, origin, destination)
INVOKE_ASYNC(actual_selected_rune, /obj/effect/rune/.proc/teleport_effect, teleportee, origin, destination)
if(is_mining_level(user.z) && !is_mining_level(destination.z)) //No effect if you stay on lavaland
actual_selected_rune.handle_portal("lava")
@@ -510,7 +515,7 @@
target.visible_message("<span class='warning'>Dust flows from [user]'s hand, and [target] disappears in a flash of red light!</span>", \
"<span class='cultitalic'>You suddenly find yourself somewhere else!</span>")
destination.visible_message("<span class='warning'>There is a boom of outrushing air as something appears above the rune!</span>", null, "<i>You hear a boom.</i>")
L.forceMove(destination)
teleportee.forceMove(destination)
return ..()
//Shackles
@@ -658,7 +663,7 @@
/obj/item/melee/blood_magic/empower/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
if(proximity_flag)
//Shielded suit
// Shielded suit
if(istype(target, /obj/item/clothing/suit/hooded/cultrobes/cult_shield))
var/obj/item/clothing/suit/hooded/cultrobes/cult_shield/C = target
if(C.current_charges < 3)
@@ -672,7 +677,7 @@
to_chat(user, "<span class='warning'>[target] is already at full charge!</span>")
return
//Plasteel to runed metal
// Veil Shifter
else if(istype(target, /obj/item/cult_shift))
var/obj/item/cult_shift/S = target
if(S.uses < 4)
@@ -846,39 +851,6 @@
var/list/options = list("Blood Orb (50)", "Blood Recharge (75)", "Blood Spear (150)", "Blood Bolt Barrage (300)")
var/choice = input(user, "Choose a greater blood rite...", "Greater Blood Rites") as null|anything in options
switch(choice)
if("Blood Spear (150)")
if(uses < BLOOD_SPEAR_COST)
to_chat(user, "<span class='warning'>You need [BLOOD_SPEAR_COST] charges to perform this rite.</span>")
else
uses -= BLOOD_SPEAR_COST
var/turf/T = get_turf(user)
qdel(src)
var/datum/action/innate/cult/spear/S = new(user)
var/obj/item/twohanded/cult_spear/rite = new(T)
S.Grant(user, rite)
rite.spear_act = S
if(user.put_in_hands(rite))
to_chat(user, "<span class='cult'>A [rite.name] appears in your hand!</span>")
else
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>", \
"<span class='cult'>A [rite.name] materializes at your feet.</span>")
if("Blood Bolt Barrage (300)")
if(uses < BLOOD_BARRAGE_COST)
to_chat(user, "<span class='cultitalic'>You need [BLOOD_BARRAGE_COST] charges to perform this rite.</span>")
else
var/obj/rite = new /obj/item/gun/projectile/shotgun/boltaction/enchanted/arcane_barrage/blood()
uses -= BLOOD_BARRAGE_COST
qdel(src)
user.swap_hand()
user.drop_item()
if(user.put_in_hands(rite))
to_chat(user, "<span class='cult'>Both of your hands glow with power!</span>")
else
to_chat(user, "<span class='warning'>You need a free hand for this rite!</span>")
uses += BLOOD_BARRAGE_COST // Refund the charges
qdel(rite)
if("Blood Orb (50)")
if(uses < BLOOD_ORB_COST)
to_chat(user, "<span class='warning'>You need [BLOOD_ORB_COST] charges to perform this rite.</span>")
@@ -898,7 +870,7 @@
if(user.put_in_hands(rite))
to_chat(user, "<span class='cult'>A [rite.name] appears in your hand!</span>")
else
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>", \
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>",
"<span class='cult'>A [rite.name] materializes at your feet.</span>")
if("Blood Recharge (75)")
@@ -914,3 +886,36 @@
to_chat(user, "<span class='warning'>You need a free hand for this rite!</span>")
uses += BLOOD_RECHARGE_COST // Refund the charges
qdel(rite)
if("Blood Spear (150)")
if(uses < BLOOD_SPEAR_COST)
to_chat(user, "<span class='warning'>You need [BLOOD_SPEAR_COST] charges to perform this rite.</span>")
else
uses -= BLOOD_SPEAR_COST
var/turf/T = get_turf(user)
qdel(src)
var/datum/action/innate/cult/spear/S = new(user)
var/obj/item/twohanded/cult_spear/rite = new(T)
S.Grant(user, rite)
rite.spear_act = S
if(user.put_in_hands(rite))
to_chat(user, "<span class='cult'>A [rite.name] appears in your hand!</span>")
else
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>",
"<span class='cult'>A [rite.name] materializes at your feet.</span>")
if("Blood Bolt Barrage (300)")
if(uses < BLOOD_BARRAGE_COST)
to_chat(user, "<span class='cultitalic'>You need [BLOOD_BARRAGE_COST] charges to perform this rite.</span>")
else
var/obj/rite = new /obj/item/gun/projectile/shotgun/boltaction/enchanted/arcane_barrage/blood()
uses -= BLOOD_BARRAGE_COST
qdel(src)
user.swap_hand()
user.drop_item()
if(user.put_in_hands(rite))
to_chat(user, "<span class='cult'>Both of your hands glow with power!</span>")
else
to_chat(user, "<span class='warning'>You need a free hand for this rite!</span>")
uses += BLOOD_BARRAGE_COST // Refund the charges
qdel(rite)
+82 -67
View File
@@ -85,6 +85,9 @@ GLOBAL_LIST_EMPTY(all_cults)
to_chat(cult_mind.current, CULT_GREETING)
equip_cultist(cult_mind.current)
cult_mind.current.faction |= "cult"
var/datum/objective/servecult/obj = new
obj.owner = cult_mind
cult_mind.objectives += obj
if(cult_mind.assigned_role == "Clown")
to_chat(cult_mind.current, "<span class='cultitalic'>A dark power has allowed you to overcome your clownish nature, letting you wield weapons without harming yourself.</span>")
@@ -96,54 +99,11 @@ GLOBAL_LIST_EMPTY(all_cults)
add_cult_actions(cult_mind)
update_cult_icons_added(cult_mind)
cult_objs.study(cult_mind.current)
to_chat(cult_mind.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Cultist)</span>")
cult_threshold_check()
addtimer(CALLBACK(src, .proc/cult_threshold_check), 2 MINUTES) // Check again in 2 minutes for latejoiners
..()
/**
* Decides at the start of the round how many conversions are needed to rise/ascend.
*
* The number is decided by (Percentage * (Players - Cultists)), so for example at 110 players it would be 11 conversions for rise. (0.1 * (110 - 4))
* These values change based on population because 20 cultists are MUCH more powerful if there's only 50 players, compared to 120.
*
* Below 100 players, [CULT_RISEN_LOW] and [CULT_ASCENDANT_LOW] are used.
* Above 100 players, [CULT_RISEN_HIGH] and [CULT_ASCENDANT_HIGH] are used.
*/
/datum/game_mode/proc/cult_threshold_check()
var/players = length(GLOB.player_list)
var/cultists = get_cultists() // Don't count the starting cultists towards the number of needed conversions
if(players >= CULT_POPULATION_THRESHOLD)
// Highpop
ascend_percent = CULT_ASCENDANT_HIGH
rise_number = round(CULT_RISEN_HIGH * (players - cultists))
ascend_number = round(CULT_ASCENDANT_HIGH * (players - cultists))
else
// Lowpop
ascend_percent = CULT_ASCENDANT_LOW
rise_number = round(CULT_RISEN_LOW * (players - cultists))
ascend_number = round(CULT_ASCENDANT_LOW * (players - cultists))
/**
* Returns the current number of cultists and constructs.
*
* Returns the number of cultists and constructs in a list ([1] = Cultists, [2] = Constructs), or as one combined number.
*
* * separate - Should the number be returned in two separate values (Humans and Constructs) or as one?
*/
/datum/game_mode/proc/get_cultists(separate = FALSE)
var/cultists = 0
var/constructs = 0
for(var/I in cult)
var/datum/mind/M = I
if(ishuman(M.current) && !M.current.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST))
cultists++
else if(isconstruct(M.current))
constructs++
if(separate)
return list(cultists, constructs)
else
return cultists + constructs
/datum/game_mode/proc/equip_cultist(mob/living/carbon/human/H, metal = TRUE)
if(!istype(H))
return
@@ -207,8 +167,84 @@ GLOBAL_LIST_EMPTY(all_cults)
ascend(cult_mind.current)
check_cult_size()
cult_objs.study(cult_mind.current)
to_chat(cult_mind.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Cultist)</span>")
return TRUE
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = TRUE, remove_gear = FALSE)
if(!(cult_mind in cult)) // Not actually a cultist in the first place
return
var/mob/cultist = cult_mind.current
cult -= cult_mind
cultist.faction -= "cult"
cult_mind.special_role = null
for(var/datum/objective/servecult/S in cult_mind.objectives)
cult_mind.objectives -= S
qdel(S)
for(var/datum/action/innate/cult/C in cultist.actions)
qdel(C)
update_cult_icons_removed(cult_mind)
if(ishuman(cultist))
var/mob/living/carbon/human/H = cultist
REMOVE_TRAIT(H, CULT_EYES, null)
H.change_eye_color(H.original_eye_color, FALSE)
H.update_eyes()
H.remove_overlay(HALO_LAYER)
H.update_body()
if(remove_gear) // No flagellants robe for non-cultists
for(var/I in H.contents)
if(is_type_in_list(I, CULT_CLOTHING))
H.unEquip(I)
check_cult_size()
if(show_message)
cultist.visible_message("<span class='cult'>[cultist] looks like [cultist.p_they()] just reverted to [cultist.p_their()] old faith!</span>",
"<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of [SSticker.cultdat ? SSticker.cultdat.entity_title1 : "Nar'Sie"] and the memories of your time as their servant with it.</span>")
/**
* Decides at the start of the round how many conversions are needed to rise/ascend.
*
* The number is decided by (Percentage * (Players - Cultists)), so for example at 110 players it would be 11 conversions for rise. (0.1 * (110 - 4))
* These values change based on population because 20 cultists are MUCH more powerful if there's only 50 players, compared to 120.
*
* Below 100 players, [CULT_RISEN_LOW] and [CULT_ASCENDANT_LOW] are used.
* Above 100 players, [CULT_RISEN_HIGH] and [CULT_ASCENDANT_HIGH] are used.
*/
/datum/game_mode/proc/cult_threshold_check()
var/players = length(GLOB.player_list)
var/cultists = get_cultists() // Don't count the starting cultists towards the number of needed conversions
if(players >= CULT_POPULATION_THRESHOLD)
// Highpop
ascend_percent = CULT_ASCENDANT_HIGH
rise_number = round(CULT_RISEN_HIGH * (players - cultists))
ascend_number = round(CULT_ASCENDANT_HIGH * (players - cultists))
else
// Lowpop
ascend_percent = CULT_ASCENDANT_LOW
rise_number = round(CULT_RISEN_LOW * (players - cultists))
ascend_number = round(CULT_ASCENDANT_LOW * (players - cultists))
/**
* Returns the current number of cultists and constructs.
*
* Returns the number of cultists and constructs in a list ([1] = Cultists, [2] = Constructs), or as one combined number.
*
* * separate - Should the number be returned as a list with two separate values (Humans and Constructs) or as one number.
*/
/datum/game_mode/proc/get_cultists(separate = FALSE)
var/cultists = 0
var/constructs = 0
for(var/I in cult)
var/datum/mind/M = I
if(ishuman(M.current) && !M.current.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST))
cultists++
else if(isconstruct(M.current))
constructs++
if(separate)
return list(cultists, constructs)
else
return cultists + constructs
/datum/game_mode/proc/check_cult_size()
if(cult_ascendant)
@@ -238,6 +274,8 @@ GLOBAL_LIST_EMPTY(all_cults)
/datum/game_mode/proc/rise(cultist)
if(ishuman(cultist) && iscultist(cultist))
var/mob/living/carbon/human/H = cultist
if(!H.original_eye_color)
H.original_eye_color = H.get_eye_color()
H.change_eye_color(BLOODCULT_EYE, FALSE)
H.update_eyes()
ADD_TRAIT(H, CULT_EYES, CULT_TRAIT)
@@ -249,29 +287,6 @@ GLOBAL_LIST_EMPTY(all_cults)
new /obj/effect/temp_visual/cult/sparks(get_turf(H), H.dir)
H.update_halo_layer()
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = TRUE)
if(cult_mind in cult)
var/mob/cultist = cult_mind.current
cult -= cult_mind
cultist.faction -= "cult"
cult_mind.special_role = null
for(var/datum/action/innate/cult/C in cultist.actions)
qdel(C)
update_cult_icons_removed(cult_mind)
if(ishuman(cultist))
var/mob/living/carbon/human/H = cultist
REMOVE_TRAIT(H, CULT_EYES, null)
H.change_eye_color(H.original_eye_color, FALSE)
H.update_eyes()
H.remove_overlay(HALO_LAYER)
H.update_body()
check_cult_size()
if(show_message)
cultist.visible_message("<span class='cult'>[cultist] looks like [cultist.p_they()] just reverted to [cultist.p_their()] old faith!</span>",
"<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of [SSticker.cultdat ? SSticker.cultdat.entity_title1 : "Nar'Sie"] and the memories of your time as their servant with it.</span>")
/datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind)
var/datum/atom_hud/antag/culthud = GLOB.huds[ANTAG_HUD_CULT]
if(cult_mind.current)
+12 -16
View File
@@ -316,7 +316,8 @@
var/mob/living/carbon/C = user
if(C.pulling)
var/atom/movable/pulled = C.pulling
pulled.forceMove(T)
var/turf/turf_behind = get_turf(get_step(T, turn(C.dir, 180)))
pulled.forceMove(turf_behind)
. = pulled
/obj/item/cult_shift/attack_self(mob/user)
@@ -324,7 +325,7 @@
to_chat(user, "<span class='warning'>[src] is dull and unmoving in your hands.</span>")
return
if(!iscultist(user))
user.unEquip(src, 1)
user.unEquip(src, TRUE)
step(src, pick(GLOB.alldirs))
to_chat(user, "<span class='warning'>[src] flickers out of your hands, too eager to move!</span>")
return
@@ -332,36 +333,31 @@
var/outer_tele_radius = 9
var/mob/living/carbon/C = user
var/turf/mobloc = get_turf(C)
var/list/turfs = new/list()
for(var/turf/T in range(user, outer_tele_radius))
var/list/turfs = list()
for(var/turf/T in orange(user, outer_tele_radius))
if(!is_teleport_allowed(T.z))
break
if(get_dir(C, T) != C.dir)
if(get_dir(C, T) != C.dir) // This seems like a very bad way to do this
continue
if(T == mobloc)
continue
if(istype(T, /turf/space))
if(isspaceturf(T))
continue
if(T.x > world.maxx-outer_tele_radius || T.x < outer_tele_radius)
continue //putting them at the edge is dumb
if(T.y > world.maxy-outer_tele_radius || T.y < outer_tele_radius)
continue
turfs += T
if(turfs)
if(length(turfs))
uses--
var/turf/mobloc = get_turf(C)
var/turf/destination = pick(turfs)
if(uses <= 0)
icon_state ="shifter_drained"
playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
icon_state = "shifter_drained"
playsound(src, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
new /obj/effect/temp_visual/dir_setting/cult/phase/out(mobloc, C.dir)
var/atom/movable/pulled = handle_teleport_grab(destination, C)
handle_teleport_grab(destination, C)
C.forceMove(destination)
if(pulled)
C.start_pulling(pulled) //forcemove resets pulls, so we need to re-pull
new /obj/effect/temp_visual/dir_setting/cult/phase(destination, C.dir)
playsound(destination, 'sound/effects/phasein.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
+2 -2
View File
@@ -133,13 +133,13 @@
for(var/mob/living/carbon/human/H in GLOB.player_list)
if(is_admin_level(H.z)) //We can't sacrifice people that are on the centcom z-level
continue
if(H.mind && !is_convertable_to_cult(H.mind) && (H.stat != DEAD) && (H.mind.offstation_role != TRUE))
if(H.mind && !iscultist(H) && !is_convertable_to_cult(H.mind) && (H.stat != DEAD) && !H.mind.offstation_role)
target_candidates += H.mind
if(!length(target_candidates)) //There are no living unconvertables on the station. Looking for a Sacrifice Target among the ordinary crewmembers
for(var/mob/living/carbon/human/H in GLOB.player_list)
if(is_admin_level(H.z)) //We can't sacrifice people that are on the centcom z-level
continue
if(H.mind && !iscultist(H) && (H.stat != DEAD) && (H.mind.offstation_role != TRUE))
if(H.mind && !iscultist(H) && (H.stat != DEAD) && !H.mind.offstation_role) // Same checks, but add them even if they could be converted
target_candidates += H.mind
if(length(target_candidates))
target = pick(target_candidates)
+9 -3
View File
@@ -84,6 +84,10 @@
/obj/item/melee/cultblade/dagger/proc/can_scribe(mob/living/user)
if(!src || !user || loc != user || user.incapacitated())
return FALSE
if(drawing_rune)
to_chat(user, "<span class='warning'>You're already drawing a rune!</span>")
return FALSE
var/turf/T = get_turf(user)
if(isspaceturf(T))
return FALSE
@@ -135,12 +139,12 @@
to_chat(user, "<span class='cultitalic'>The veil is not weak enough here to summon a cultist, you must be on station!</span>")
return
var/old_color = user.color // we'll temporarily redden the user for better feedback to fellow cultists. Store this to revert them back.
var/old_color = user.color // we'll temporarily redden the user for better feedback to fellow cultists. Store this to revert them back.
if(narsie_rune)
if(!narsie_rune_check(user, A))
return // don't do shit
var/list/summon_areas = gamemode.cult_objs.obj_summon.summon_spots
if(!(A in summon_areas)) // Check again to make sure they didn't move
if(!(A in summon_areas)) // Check again to make sure they didn't move
to_chat(user, "<span class='cultlarge'>The ritual can only begin where the veil is weak - in [english_list(summon_areas)]!</span>")
return
GLOB.command_announcement.Announce("Figments from an eldritch god are being summoned into the [A.map_name] from an unknown dimension. Disrupt the ritual at all costs, before the station is destroyed! Space law and SOP are suspended. The entire crew must kill cultists on sight.", "Central Command Higher Dimensional Affairs", 'sound/AI/spanomalies.ogg')
@@ -148,7 +152,7 @@
var/turf/T = I
var/obj/machinery/shield/cult/narsie/N = new(T)
shields |= N
user.color = "red"
user.color = COLOR_RED
// Draw the rune
var/mob/living/carbon/human/H = user
@@ -161,12 +165,14 @@
user.visible_message(others_message,
"<span class='cultitalic'>You slice open your body and begin drawing a sigil of [SSticker.cultdat.entity_title3].</span>")
drawing_rune = TRUE // Only one at a time
var/scribe_successful = do_after(user, initial(rune.scribe_delay) * scribe_multiplier, target = runeturf)
for(var/V in shields) // Only used for the 'Tear Veil' rune
var/obj/machinery/shield/S = V
if(S && !QDELETED(S))
qdel(S)
user.color = old_color
drawing_rune = FALSE
if(!scribe_successful)
return
+8 -3
View File
@@ -263,6 +263,8 @@ structure_check() searches for nearby cultist structures required for the invoca
var/turf/T = get_turf(src)
for(var/mob/living/M in T)
if(!iscultist(M) || (M.mind && is_sacrifice_target(M.mind)))
if(isconstruct(M)) // No offering constructs please
continue
offer_targets += M
// Offering a head/brain
@@ -418,6 +420,8 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/teleport/Destroy()
GLOB.teleport_runes -= src
QDEL_NULL(inner_portal)
QDEL_NULL(outer_portal)
return ..()
/obj/effect/rune/teleport/invoke(list/invokers)
@@ -452,7 +456,7 @@ structure_check() searches for nearby cultist structures required for the invoca
var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked
var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to?
if(!src || !Adjacent(user) || QDELETED(src) || user.incapacitated() || !actual_selected_rune)
if(QDELETED(src) || QDELETED(actual_selected_rune) ||!Adjacent(user) || user.incapacitated())
fail_invoke()
return
@@ -685,7 +689,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultists[M.current.real_name] = M.current
var/input = input(user, "Who do you wish to call to [src]?", "Acolytes") as null|anything in cultists
var/mob/living/cultist_to_summon = cultists[input]
if(!src || QDELETED(src) || !Adjacent(user) || user.incapacitated())
if(QDELETED(src) || !Adjacent(user) || user.incapacitated())
return
if(!cultist_to_summon)
log_game("Summon Cultist rune failed - no target")
@@ -882,6 +886,7 @@ structure_check() searches for nearby cultist structures required for the invoca
var/mob/living/carbon/human/new_human = new(T)
new_human.real_name = ghost_to_spawn.real_name
new_human.key = ghost_to_spawn.key
new_human.gender = ghost_to_spawn.gender
new_human.alpha = 150 //Makes them translucent
new_human.equipOutfit(/datum/outfit/ghost_cultist) //give them armor
new_human.apply_status_effect(STATUS_EFFECT_SUMMONEDGHOST) //ghosts can't summon more ghosts, also lets you see actual ghosts
@@ -999,7 +1004,7 @@ structure_check() searches for nearby cultist structures required for the invoca
//BEGIN THE SUMMONING
gamemode.cult_objs.succesful_summon()
used = TRUE
color = rgb(255, 0, 0)
color = COLOR_RED
..()
SEND_SOUND(world, sound('sound/effects/dimensional_rend.ogg'))
to_chat(world, "<span class='cultitalic'><b>The veil... <span class='big'>is...</span> <span class='reallybig'>TORN!!!--</span></b></span>")
+1
View File
@@ -181,6 +181,7 @@ GLOBAL_LIST_EMPTY(cortical_stacks) //Stacks for 'leave nobody behind' objective.
to_chat(raider.current, "<span class='notice'>Vox are cowardly and will flee from larger groups, but corner one or find them en masse and they are vicious.</span>")
to_chat(raider.current, "<span class='notice'>Use :V to voxtalk, :H to talk on your encrypted channel, and don't forget to turn on your nitrogen internals!</span>")
to_chat(raider.current, "<span class='notice'>Choose to accomplish your objectives by either raiding the crew and taking what you need, or by attempting to trade with them.</span>")
to_chat(raider.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Vox_Raider)</span>")
spawn(25)
show_objectives(raider)
@@ -158,6 +158,7 @@
to_chat(abductor.current, "<span class='notice'>You are an agent of [team_name]!</span>")
to_chat(abductor.current, "<span class='notice'>With the help of your teammate, kidnap and experiment on station crew members!</span>")
to_chat(abductor.current, "<span class='notice'>Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve.</span>")
to_chat(abductor.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Abductor)</span>")
abductor.announce_objectives()
@@ -170,6 +171,7 @@
to_chat(abductor.current, "<span class='notice'>You are a scientist of [team_name]!</span>")
to_chat(abductor.current, "<span class='notice'>With the help of your teammate, kidnap and experiment on station crew members!</span>")
to_chat(abductor.current, "<span class='notice'>Use your tool and ship consoles to support the agent and retrieve human specimens.</span>")
to_chat(abductor.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Abductor)</span>")
abductor.announce_objectives()
@@ -837,6 +837,7 @@
to_chat(src, "You are a brain slug that worms its way into the head of its victim. Use stealth, persuasion and your powers of mind control to keep you, your host and your eventual spawn safe and warm.")
to_chat(src, "Sugar nullifies your abilities, avoid it at all costs!")
to_chat(src, "You can speak to your fellow borers by prefixing your messages with ':bo'. Check out your Borer tab to see your abilities.")
to_chat(src, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Cortical_Borer)</span>")
/proc/create_borer_mind(key)
var/datum/mind/M = new /datum/mind(key)
@@ -21,7 +21,7 @@
roundstart = FALSE
important_info = "Follow your objectives, do not make the station inhospitable or try and kill crew."
flavour_text = "You are a swarmer, a weapon of a long dead civilization. Until further orders from your original masters are received, you must continue to consume and replicate."
description = {" Your goal is to create more of yourself by consuming the station. Clicking on any object will try to consume it, either deconstructing it into its components, destroying it, or integrating any materials it has into you if successful. Ctrl-Clicking on a mob will attempt to remove it from the area and place it in a safe environment for storage.
description = {"Your goal is to create more of yourself by consuming the station. Clicking on any object will try to consume it, either deconstructing it into its components, destroying it, or integrating any materials it has into you if successful. Ctrl-Clicking on a mob will attempt to remove it from the area and place it in a safe environment for storage.
Objectives:
1. Consume resources and replicate until there are no more resources left.
2. Ensure that this location is fit for invasion at a later date; do not perform actions that would render it dangerous or inhospitable.
@@ -112,6 +112,7 @@
to_chat(src, "1. Consume resources and replicate until there are no more resources left.")
to_chat(src, "2. Ensure that the station is fit for invasion at a later date, do not perform actions that would render it dangerous or inhospitable.")
to_chat(src, "3. Biological and sentient resources will be harvested at a later date, do not harm them.")
to_chat(src, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Swarmer)</span>")
/mob/living/simple_animal/hostile/swarmer/New()
..()
@@ -343,6 +343,7 @@
to_chat(G, "You are capable of manifesting or recalling to your master with verbs in the Guardian tab. You will also find a verb to communicate with them privately there.")
to_chat(G, "While personally invincible, you will die if [user.real_name] does, and any damage dealt to you will have a portion passed on to them as you feed upon them to sustain yourself.")
to_chat(G, "[G.playstyle_string]")
to_chat(G, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Guardian)</span>")
G.faction = user.faction
var/color = pick(color_list)
@@ -26,6 +26,7 @@
player_mind.special_role = SPECIAL_ROLE_MORPH
SSticker.mode.traitors |= player_mind
to_chat(S, S.playstyle_string)
to_chat(S, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Morph)</span>")
SEND_SOUND(S, sound('sound/magic/mutate.ogg'))
message_admins("[key_of_morph] has been made into morph by an event.")
log_game("[key_of_morph] was spawned as a morph by an event.")
@@ -168,7 +168,7 @@
to_chat(src, "<b>You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.</b>")
to_chat(src, "<b>To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.</b>")
to_chat(src, "<b><i>You do not remember anything of your past lives, nor will you remember anything about this one after your death.</i></b>")
to_chat(src, "<b>Be sure to read the wiki page at http://www.paradisestation.org/wiki/index.php/Revenant to learn more.</b>")
to_chat(src, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Revenant)</span>")
var/datum/objective/revenant/objective = new
objective.owner = mind
mind.objectives += objective
@@ -92,6 +92,7 @@
mind.objectives += fluffObjective
to_chat(src, "<B>Objective #[1]</B>: [objective.explanation_text]")
to_chat(src, "<B>Objective #[2]</B>: [fluffObjective.explanation_text]")
to_chat(src, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Slaughter_Demon)</span>")
/obj/effect/decal/cleanable/blood/innards
+3 -3
View File
@@ -245,6 +245,7 @@
for(var/datum/objective/objective in syndicate.objectives)
to_chat(syndicate.current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
obj_count++
to_chat(syndicate.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Nuclear_Agent)</span>")
return
@@ -452,10 +453,9 @@
for(var/obj/machinery/nuclearbomb/nuke in GLOB.machines)
if(nuke.r_code == "Nope") continue
var/turf/T = get_turf(nuke)
var/area/A = T.loc
var/area/A = get_area(nuke)
var/list/thousand_penalty = list(/area/wizard_station, /area/solar, /area)
var/list/thousand_penalty = list(/area/solar)
var/list/fiftythousand_penalty = list(/area/security/main, /area/security/brig, /area/security/armoury, /area/security/checkpoint2)
if(is_type_in_list(A, thousand_penalty))
+3 -2
View File
@@ -359,8 +359,9 @@ GLOBAL_VAR(bomb_set)
var/off_station = 0
var/turf/bomb_location = get_turf(src)
var/area/A = get_area(src)
if( bomb_location && is_station_level(bomb_location.z) )
if( (bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE)) )
if( (bomb_location.x < (128 - NUKERANGE)) || (bomb_location.x > (128 + NUKERANGE)) || (bomb_location.y < (128 - NUKERANGE)) || (bomb_location.y > (128 + NUKERANGE)) && (!(A in GLOB.the_station_areas)))
off_station = 1
else
off_station = 2
@@ -383,7 +384,7 @@ GLOBAL_VAR(bomb_set)
else
to_chat(world, "<b>The station was destoyed by the nuclear blast!</b>")
SSticker.mode.station_was_nuked = (off_station<2) //offstation==1 is a draw. the station becomes irradiated and needs to be evacuated.
SSticker.mode.station_was_nuked = (off_station < 2) //offstation==1 is a draw. the station becomes irradiated and needs to be evacuated.
//kinda shit but I couldn't get permission to do what I wanted to do.
if(!SSticker.mode.check_finished())//If the mode does not deal with the nuke going off so just reboot because everyone is stuck as is
@@ -110,6 +110,7 @@
to_chat(rev_mind.current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
rev_mind.special_role = SPECIAL_ROLE_HEAD_REV
obj_count++
to_chat(rev_mind.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Revolution)</span>")
/////////////////////////////////////////////////////////////////////////////////
//This are equips the rev heads with their gear, and makes the clown not clumsy//
+7 -4
View File
@@ -114,18 +114,21 @@
if(G.block)
if(G.block in blocks_assigned)
warning("DNA2: Gene [G.name] trying to use already-assigned block [G.block] (used by [english_list(blocks_assigned[G.block])])")
GLOB.dna_mutations.Add(G)
GLOB.dna_mutations[mutation_type] = G
var/list/assignedToBlock[0]
if(blocks_assigned[G.block])
assignedToBlock=blocks_assigned[G.block]
assignedToBlock = blocks_assigned[G.block]
assignedToBlock.Add(G.name)
blocks_assigned[G.block]=assignedToBlock
blocks_assigned[G.block] = assignedToBlock
//testing("DNA2: Gene [G.name] assigned to block [G.block].")
else
qdel(G)
// I WILL HAVE A LIST OF MUTATIONS THAT MATCHES THE RANDOMIZED BLOCKS GODDAMNIT!
for(var/block in 1 to DNA_SE_LENGTH)
var/name = GLOB.assigned_blocks[block]
for(var/datum/mutation/mutation in GLOB.dna_mutations)
for(var/mutation_type in GLOB.dna_mutations)
var/datum/mutation/mutation = GLOB.dna_mutations[mutation_type]
if(mutation.name == name || mutation.block == block)
if(mutation.block in GLOB.assigned_mutation_blocks)
warning("DNA2: Mutation [mutation.name] trying to add to already assigned gene block list (used by [english_list(GLOB.assigned_mutation_blocks[block])])")
+2 -2
View File
@@ -126,8 +126,7 @@ Made by Xhuis
to_chat(shadow.current, "<b>Currently, you are disguised as an employee aboard [world.name].</b>")
to_chat(shadow.current, "<b>In your limited state, you have two abilities: Hatch and Shadowling Hivemind (:8).</b>")
to_chat(shadow.current, "<b>Any other shadowlings are your allies. You must assist them as they shall assist you.</b>")
to_chat(shadow.current, "<b>If you are new to shadowling, or want to read about abilities, check the wiki page at https://www.paradisestation.org/wiki/index.php/Shadowling</b><br>")
to_chat(shadow.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Shadowling)</span>")
/datum/game_mode/proc/process_shadow_objectives(datum/mind/shadow_mind)
@@ -169,6 +168,7 @@ Made by Xhuis
to_chat(new_thrall_mind.current, "<span class='shadowling'>Your body has been irreversibly altered. The attentive can see this - you may conceal it by wearing a mask.</span>")
to_chat(new_thrall_mind.current, "<span class='shadowling'>Though not nearly as powerful as your masters, you possess some weak powers. These can be found in the Thrall Abilities tab.</span>")
to_chat(new_thrall_mind.current, "<span class='shadowling'>You may communicate with your allies by speaking in the Shadowling Hivemind (:8).</span>")
to_chat(new_thrall_mind.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Shadowling)</span>")
if(jobban_isbanned(new_thrall_mind.current, ROLE_SHADOWLING) || jobban_isbanned(new_thrall_mind.current, ROLE_SYNDICATE))
replace_jobbanned_player(new_thrall_mind.current, ROLE_SHADOWLING)
if(!victory_warning_announced && (length(shadowling_thralls) >= warning_threshold))//are the slings very close to winning?
+1 -1
View File
@@ -193,8 +193,8 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
for(var/datum/objective/objective in vampire.objectives)
to_chat(vampire.current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
obj_count++
to_chat(vampire.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Vampire)</span>")
return
/datum/vampire
var/bloodtotal = 0 // CHANGE TO ZERO WHEN PLAYTESTING HAPPENS
var/bloodusable = 0 // CHANGE TO ZERO WHEN PLAYTESTING HAPPENS
+5 -6
View File
@@ -323,6 +323,7 @@
var/mob/living/simple_animal/hostile/construct/C = new picked_class(shell.loc)
C.init_construct(shade, src, shell)
to_chat(C, C.playstyle_string)
to_chat(C, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Construct)</span>")
else
to_chat(user, "<span class='danger'>Creation failed!</span>: The soul stone is empty! Go kill someone!")
@@ -339,13 +340,11 @@
if(shade.mind)
shade.mind.transfer_to(src)
if(SS.purified)
set_light(3, 5, LIGHT_COLOR_DARK_BLUE)
name = "Holy [name]"
real_name = "Holy [real_name]"
make_holy()
// Replace regular soulstone summoning with purified soulstones
RemoveSpell(/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone)
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone/holy)
if(is_type_in_list(/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone, mob_spell_list))
RemoveSpell(/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone)
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone/holy)
else if(iscultist(src)) // Re-grant cult actions, lost in the transfer
var/datum/action/innate/cult/comm/CC = new
+21 -14
View File
@@ -88,7 +88,7 @@
if(!S)
S = new spell_type()
var/dat =""
dat += "<b>[initial(S.name)]</b>"
dat += "<b>[name]</b>"
if(S.charge_type == "recharge")
dat += " Cooldown:[S.charge_max/10]"
dat += " Cost:[cost]<br>"
@@ -172,18 +172,6 @@
log_name = "IG"
category = "Offensive"
/datum/spellbook_entry/sacred_flame
name = "Sacred Flame"
spell_type = /obj/effect/proc_holder/spell/targeted/sacred_flame
cost = 1
log_name = "SF"
refundable = 0 //You get fire immunity out of it, no.
/datum/spellbook_entry/sacred_flame/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, obj/effect/proc_holder/spell/newspell)
..()
user.dna.SetSEState(GLOB.coldblock, 1)
singlemutcheck(user, GLOB.coldblock, MUTCHK_FORCED)
//Defensive
/datum/spellbook_entry/disabletech
name = "Disable Tech"
@@ -239,6 +227,25 @@
log_name = "TS"
category = "Defensive"
/datum/spellbook_entry/sacred_flame
name = "Sacred Flame and Fire Immunity"
spell_type = /obj/effect/proc_holder/spell/targeted/sacred_flame
cost = 1
log_name = "SF"
category = "Defensive"
/datum/spellbook_entry/sacred_flame/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, obj/effect/proc_holder/spell/newspell)
to_chat(user, "<span class='notice'>You feel fireproof.</span>")
ADD_TRAIT(user, TRAIT_RESISTHEAT, MAGIC_TRAIT)
ADD_TRAIT(user, TRAIT_RESISTHIGHPRESSURE, MAGIC_TRAIT)
return ..()
/datum/spellbook_entry/sacred_flame/Refund(mob/living/carbon/human/user, obj/item/spellbook/book)
to_chat(user, "<span class='warning'>You no longer feel fireproof.</span>")
REMOVE_TRAIT(user, TRAIT_RESISTHEAT, MAGIC_TRAIT)
REMOVE_TRAIT(user, TRAIT_RESISTHIGHPRESSURE, MAGIC_TRAIT)
return ..()
//Mobility
/datum/spellbook_entry/knock
name = "Knock"
@@ -431,7 +438,7 @@
category = "Artefacts"
/datum/spellbook_entry/item/voice_of_god
name = "Voice of god"
name = "Voice of God"
desc = "A magical vocal cord that can be used to yell out with the voice of a god, be it to harm, help, or confuse the target."
item_path = /obj/item/organ/internal/vocal_cords/colossus/wizard
log_name = "VG"
+1
View File
@@ -108,6 +108,7 @@
for(var/datum/objective/objective in wizard.objectives)
to_chat(wizard.current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
obj_count++
to_chat(wizard.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Wizard)</span>")
return
/datum/game_mode/proc/equip_wizard(mob/living/carbon/human/wizard_mob)
+9 -18
View File
@@ -400,6 +400,9 @@
/proc/get_all_centcom_jobs()
return list("VIP Guest","Custodian","Thunderdome Overseer","Emergency Response Team Member","Emergency Response Team Leader","Intel Officer","Medical Officer","Death Commando","Research Officer","Deathsquad Officer","Special Operations Officer","Nanotrasen Navy Representative","Nanotrasen Navy Officer","Nanotrasen Navy Captain","Supreme Commander")
/proc/get_all_solgov_jobs()
return list("Solar Federation Lieutenant","Solar Federation Specops Lieutenant","Solar Federation Marine","Solar Federation Specops Marine","Solar Federation Representative","Sol Trader")
//gets the actual job rank (ignoring alt titles)
//this is used solely for sechuds
/obj/proc/GetJobRealName()
@@ -424,24 +427,6 @@
return "Unknown"
//gets the alt title, failing that the actual job rank
//this is unused
// THEN WHY IS IT STILL HERE?? -AA07, 2020-07-31
/obj/proc/sdsdsd() //GetJobDisplayName
if(!istype(src, /obj/item/pda) && !istype(src,/obj/item/card/id))
return
var/assignment
if(istype(src, /obj/item/pda))
if(src:id)
assignment = src:id:assignment
else if(istype(src, /obj/item/card/id))
assignment = src:assignment
if(assignment)
return assignment
return "Unknown"
/proc/GetIdCard(mob/living/carbon/human/H)
if(H.wear_id)
@@ -499,12 +484,18 @@
var/job_icons = get_all_job_icons()
var/centcom = get_all_centcom_jobs()
var/solgov = get_all_solgov_jobs()
if(assignmentName in centcom) //Return with the NT logo if it is a Centcom job
return "Centcom"
if(rankName in centcom)
return "Centcom"
if(assignmentName in solgov) //Return with the SolGov logo if it is a SolGov job
return "solgov"
if(rankName in solgov)
return "solgov"
if(assignmentName in job_icons) //Check if the job has a hud icon
return assignmentName
if(rankName in job_icons)
@@ -532,6 +532,9 @@
L.throw_at(throwtarget, 5, 1,src)
return FALSE
/obj/machinery/door/airlock/cult/screwdriver_act(mob/user, obj/item/I)
return
/obj/machinery/door/airlock/cult/cult_conceal()
icon = stealth_icon
overlays_file = stealth_overlays
@@ -0,0 +1,128 @@
/**
* Can be used to group spawners together so you ensure a certain amount of things are spawned but can be spawned on multiple locations.
*
* How to use:
* Either place the base grouped_spawner in the map and define the group_id to
* determine which spawners belong to one another.
* Or make a child instance of the grouped_spawner and define the values there.
*
* When using the base version be sure to define both total_amount and max_per_spawner on
* at least one of the spawners of the group.
* A mismatch between instances of the same group between these values will lead to a runtime.
* So either leave it empty for the rest or have the rest have the same values
**/
/obj/effect/spawner/grouped_spawner
name = "grouped spawner"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x2"
/// Which path will be used to spawn.
var/path_to_spawn
/// How many will spawn. Set this in the map edit tool or in a child instance to set it for all the other instances.
var/total_amount
/// How many will spawn maximum per spawner. Set this in the map edit tool or in a child instance to set it for all the other instances.
var/max_per_spawner
/// The id of the group this spawner belongs to. If left empty it'll use the type as id. Define this for map instances if you want to link different spawners up or want to use the base version.
var/group_id
/// The assoc list of grouped spawners. Key = group_id, value = list of spawners with that key
var/static/list/spawner_groups
/// Which spawners are chosen to spawn the objects
var/static/list/chosen_spawners
/// The list which holds the total_amount values for each spawner group
var/static/list/total_amount_for_spawners
/// The list which holds the max_per_spawner values for each spawner group
var/static/list/max_per_spawner_for_spawners
/obj/effect/spawner/grouped_spawner/Initialize(mapload)
. = INITIALIZE_HINT_QDEL // For crash handling
if(!mapload)
CRASH("[src] of type [type] was made post mapload")
var/turf/T = get_turf(src)
if(!T)
CRASH("Spawner placed in nullspace!")
if(isnull(group_id)) // Set the group_id if null
group_id = type
if(group_id == /obj/effect/spawner/grouped_spawner) // Not allowed to use the base type as group_id
CRASH("group_id was not set for [src] of type '[type]'")
..()
save_spawn_values()
LAZYADDASSOC(spawner_groups, group_id, src)
return INITIALIZE_HINT_LATELOAD
/obj/effect/spawner/grouped_spawner/LateInitialize()
..()
if(LAZYACCESS(spawner_groups, group_id) && !LAZYACCESS(chosen_spawners, group_id)) // Not yet picked the spawners
pick_spawners()
var/list/CS = LAZYACCESS(chosen_spawners, group_id)
if(!LAZYACCESS(CS, src)) // I'm not one of the chosen ones ;(
qdel(src)
return
get_spawn_values()
var/turf/T = get_turf(src)
spawn_objects(T, CS[src])
qdel(src)
/obj/effect/spawner/grouped_spawner/Destroy()
. = ..()
LAZYREMOVEASSOC(chosen_spawners, group_id, src)
if(!LAZYACCESS(chosen_spawners, group_id)) // Last instance that uses these values
LAZYREMOVE(total_amount_for_spawners, group_id)
LAZYREMOVE(max_per_spawner_for_spawners, group_id)
/**
* Saves the spawn values. Will only pick the first defined version of this group_id
*/
/obj/effect/spawner/grouped_spawner/proc/save_spawn_values()
if(!isnull(total_amount))
if(LAZYACCESS(total_amount_for_spawners, group_id) && total_amount_for_spawners[group_id] != total_amount)
stack_trace("total_amount mismatch for type [type]. Possible duplicate total_amount definition in the map")
else
LAZYSET(total_amount_for_spawners, group_id, total_amount)
if(!isnull(max_per_spawner))
if(LAZYACCESS(max_per_spawner_for_spawners, group_id) && max_per_spawner_for_spawners[group_id] != max_per_spawner)
stack_trace("max_per_spawner mismatch for type [type]. Possible duplicate total_amount definition in the map")
else
LAZYSET(max_per_spawner_for_spawners, group_id, max_per_spawner)
/**
* Sets the spawn values to the values of the first defined instance of this group_id
*/
/obj/effect/spawner/grouped_spawner/proc/get_spawn_values()
total_amount = total_amount_for_spawners[group_id]
max_per_spawner = max_per_spawner_for_spawners[group_id]
/obj/effect/spawner/grouped_spawner/proc/spawn_objects(turf/T, amount)
for(var/i in 1 to amount)
new path_to_spawn(T)
/obj/effect/spawner/grouped_spawner/proc/pick_spawners()
var/list/pickable_spawners = spawner_groups[group_id]
LAZYSET(chosen_spawners, group_id, list())
var/list/spawners = chosen_spawners[group_id]
for(var/i in 1 to total_amount)
if(!length(pickable_spawners))
return // No more to pick from
var/obj/effect/spawner/grouped_spawner/S = pick(pickable_spawners)
if(++spawners[S] >= max_per_spawner)
pickable_spawners -= S
// Clean up
pickable_spawners.Cut()
LAZYREMOVE(spawner_groups, group_id)
// Example grouped spawner
/obj/effect/spawner/grouped_spawner/duck_spawn
name = "grouped rubberducky spawner"
path_to_spawn = /obj/item/bikehorn/rubberducky
max_per_spawner = 2
total_amount = 5
@@ -83,7 +83,7 @@
/obj/effect/temp_visual/dir_setting/wraith
name = "blood"
icon = 'icons/mob/mob.dmi'
icon = 'icons/mob/cult.dmi'
icon_state = "phase_shift2"
duration = 12
+5
View File
@@ -174,6 +174,11 @@
colourName = "purple"
..()
/obj/item/toy/crayon/black
icon_state = "crayonblack"
colour = "#000000"
colourName = "black"
/obj/item/toy/crayon/white
icon_state = "crayonwhite"
colour = "#FFFFFF"
@@ -190,14 +190,14 @@
ks2type = /obj/item/encryptionkey/heads/captain
/obj/item/radio/headset/heads/captain/alt
name = "\proper the captain's bowman headset"
name = "captain's bowman headset"
desc = "The headset of the boss. Protects ears from flashbangs."
flags = EARBANGPROTECT
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
/obj/item/radio/headset/heads/rd
name = "Research Director's headset"
name = "research director's headset"
desc = "Headset of the researching God."
icon_state = "com_headset"
item_state = "headset"
@@ -211,7 +211,7 @@
ks2type = /obj/item/encryptionkey/heads/hos
/obj/item/radio/headset/heads/hos/alt
name = "\proper the head of security's bowman headset"
name = "head of security's bowman headset"
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs."
flags = EARBANGPROTECT
icon_state = "com_headset_alt"
@@ -272,7 +272,7 @@
ks2type = /obj/item/encryptionkey/heads/magistrate
/obj/item/radio/headset/heads/magistrate/alt
name = "\proper magistrate's bowman headset"
name = "magistrate's bowman headset"
desc = "The headset of the Magistrate. Protects ears from flashbangs."
flags = EARBANGPROTECT
icon_state = "com_headset_alt"
@@ -286,7 +286,7 @@
ks2type = /obj/item/encryptionkey/heads/blueshield
/obj/item/radio/headset/heads/blueshield/alt
name = "\proper blueshield's bowman headset"
name = "blueshield's bowman headset"
desc = "The headset of the Blueshield. Protects ears from flashbangs."
flags = EARBANGPROTECT
icon_state = "com_headset_alt"
@@ -314,7 +314,7 @@
instant = TRUE
/obj/item/radio/headset/centcom
name = "\proper centcom officer's bowman headset"
name = "centcom officer's bowman headset"
desc = "The headset of final authority. Protects ears from flashbangs. Can transmit even if telecomms are down."
flags = EARBANGPROTECT
icon_state = "com_headset_alt"
@@ -106,8 +106,8 @@
name = "light tiles"
gender = PLURAL
singular_name = "light floor tile"
desc = "A floor tile, made out off glass. Use a multitool on it to change its color."
icon_state = "tile_light blue"
desc = "A floor tile made of glass, with an integrated light. Use a multitool on it to change its color."
icon_state = "tile_white"
force = 3
throwforce = 5
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
@@ -471,7 +471,7 @@
if(target.mind)
if(iscultist(target))
SSticker.mode.remove_cultist(target.mind) // This proc will handle message generation.
SSticker.mode.remove_cultist(target.mind, TRUE, TRUE) // This proc will handle message generation.
praying = FALSE
return
@@ -3,6 +3,7 @@
desc = "And boom goes the weasel."
icon_state = "explosive"
origin_tech = "materials=2;combat=3;biotech=4;syndicate=4"
actions_types = list(/datum/action/item_action/hands_free/activate/always)
var/weak = 2
var/medium = 0.8
var/heavy = 0.4
@@ -135,6 +136,7 @@
desc = "An alarm which monitors host vital signs, transmitting a radio message and dusting the corpse on death."
icon = 'icons/effects/blood.dmi'
icon_state = "remains"
actions_types = list(/datum/action/item_action/hands_free/activate/always)
/obj/item/implant/dust/get_data()
var/dat = {"<b>Implant Specifications:</b><BR>
@@ -366,6 +366,22 @@
item_state = "assault"
storage_slots = 6
/obj/item/storage/belt/military/assault/marines/full/populate_contents()
new /obj/item/ammo_box/magazine/m12g(src)
new /obj/item/ammo_box/magazine/m12g(src)
new /obj/item/ammo_box/magazine/m12g(src)
new /obj/item/ammo_box/magazine/m12g(src)
new /obj/item/ammo_box/magazine/m45(src)
new /obj/item/ammo_box/magazine/m45(src)
update_icon()
/obj/item/storage/belt/military/assault/marines/elite/full/populate_contents()
new /obj/item/ammo_box/magazine/m556/arg(src)
new /obj/item/ammo_box/magazine/m556/arg(src)
new /obj/item/ammo_box/magazine/m556/arg(src)
new /obj/item/ammo_box/magazine/m45(src)
new /obj/item/ammo_box/magazine/m45(src)
update_icon()
/obj/item/storage/belt/janitor
name = "janibelt"
desc = "A belt used to hold most janitorial supplies."
@@ -121,19 +121,21 @@
icon = 'icons/obj/crayons.dmi'
icon_state = "crayonbox"
w_class = WEIGHT_CLASS_SMALL
storage_slots = 6
storage_slots = 8
icon_type = "crayon"
can_hold = list(
/obj/item/toy/crayon
)
/obj/item/storage/fancy/crayons/populate_contents()
new /obj/item/toy/crayon/white(src)
new /obj/item/toy/crayon/red(src)
new /obj/item/toy/crayon/orange(src)
new /obj/item/toy/crayon/yellow(src)
new /obj/item/toy/crayon/green(src)
new /obj/item/toy/crayon/blue(src)
new /obj/item/toy/crayon/purple(src)
new /obj/item/toy/crayon/black(src)
update_icon()
/obj/item/storage/fancy/crayons/update_icon()
@@ -76,6 +76,10 @@
if(!cell)
return
cell.use(amount)
if(cell.rigged)
cell = null
turned_on = FALSE
update_icon()
if(cell.charge < (hitcost)) // If after the deduction the baton doesn't have enough charge for a stun hit it turns off.
turned_on = FALSE
update_icon()
+1 -1
View File
@@ -402,7 +402,7 @@ GLOBAL_LIST_EMPTY(safes)
for(var/safe in GLOB.safes)
var/obj/structure/safe/S = safe
if(owner in S.known_by)
info += "<br> The combination for the safe located in the [get_area(S).name] is: [S.get_combination()]<br>"
info += "<br> The combination for the safe located in the [get_area_name(S, TRUE)] is: [S.get_combination()]<br>"
info_links = info
update_icon()
+3 -6
View File
@@ -1,12 +1,9 @@
//This is so damaged or burnt tiles or platings don't get remembered as the default tile
GLOBAL_LIST_INIT(icons_to_ignore_at_floor_init, list("damaged1","damaged2","damaged3","damaged4",
"damaged5","panelscorched","floorscorched1","floorscorched2","platingdmg1","platingdmg2",
"platingdmg3","plating","light_on","light_on_flicker1","light_on_flicker2",
"warnplate", "warnplatecorner","metalfoam", "ironfoam",
"light_on_clicker3","light_on_clicker4","light_on_clicker5","light_broken",
"light_on_broken","light_off","wall_thermite","grass1","grass2","grass3","grass4",
"asteroid","asteroid_dug",
"asteroid0","asteroid1","asteroid2","asteroid3","asteroid4",
"platingdmg3","plating","light_on","warnplate", "warnplatecorner","metalfoam", "ironfoam",
"light_off","wall_thermite","grass1","grass2","grass3","grass4",
"asteroid","asteroid_dug","asteroid0","asteroid1","asteroid2","asteroid3","asteroid4",
"asteroid5","asteroid6","asteroid7","asteroid8","asteroid9","asteroid10","asteroid11","asteroid12",
"oldburning","light-on-r","light-on-y","light-on-g","light-on-b", "wood", "wood-broken", "carpet",
"carpetcorner", "carpetside", "carpet", "ironsand1", "ironsand2", "ironsand3", "ironsand4", "ironsand5",
+25 -86
View File
@@ -1,23 +1,14 @@
#define LIGHTFLOOR_ON 1
#define LIGHTFLOOR_WHITE 2
#define LIGHTFLOOR_RED 3
#define LIGHTFLOOR_GREEN 4
#define LIGHTFLOOR_YELLOW 5
#define LIGHTFLOOR_BLUE 6
#define LIGHTFLOOR_PURPLE 7
#define LIGHTFLOOR_GENERICCYCLE 8
#define LIGHTFLOOR_CYCLEA 9
#define LIGHTFLOOR_CYCLEB 10
/turf/simulated/floor/light
name = "\improper light floor"
light_range = 5
icon_state = "light_on"
floor_tile = /obj/item/stack/tile/light
broken_states = list("light_broken")
broken_states = list("light_off")
/// Are we on
var/on = TRUE
var/state = LIGHTFLOOR_ON
/// Are we broken
var/light_broken = FALSE
/// Can we modify a colour
var/can_modify_colour = TRUE
/turf/simulated/floor/light/Initialize(mapload)
@@ -27,43 +18,11 @@
/turf/simulated/floor/light/update_icon()
..()
if(on)
switch(state)
if(LIGHTFLOOR_ON)
icon_state = "light_on"
set_light(5, null,LIGHT_COLOR_LIGHTBLUE)
if(LIGHTFLOOR_WHITE)
icon_state = "light_on-w"
set_light(5, null,LIGHT_COLOR_WHITE)
if(LIGHTFLOOR_RED)
icon_state = "light_on-r"
set_light(5, null,LIGHT_COLOR_RED)
if(LIGHTFLOOR_GREEN)
icon_state = "light_on-g"
set_light(5, null,LIGHT_COLOR_PURE_GREEN)
if(LIGHTFLOOR_YELLOW)
icon_state = "light_on-y"
set_light(5, null,"#FFFF00")
if(LIGHTFLOOR_BLUE)
icon_state = "light_on-b"
set_light(5, null,LIGHT_COLOR_DARKBLUE)
if(LIGHTFLOOR_PURPLE)
icon_state = "light_on-p"
set_light(5, null,LIGHT_COLOR_PURPLE)
if(LIGHTFLOOR_GENERICCYCLE)
icon_state = "light_on-cycle_all"
set_light(5, null,LIGHT_COLOR_WHITE)
if(LIGHTFLOOR_CYCLEA)
icon_state = "light_on-dancefloor_A"
set_light(5,null,LIGHT_COLOR_RED)
if(LIGHTFLOOR_CYCLEB)
icon_state = "light_on-dancefloor_B"
set_light(5, null,LIGHT_COLOR_DARKBLUE)
else
icon_state = "light_off"
set_light(0)
icon_state = "light_on"
set_light(5, null, color)
else
set_light(0)
icon_state = "light_off"
set_light(0)
/turf/simulated/floor/light/BeforeChange()
set_light(0)
@@ -76,9 +35,9 @@
/turf/simulated/floor/light/attackby(obj/item/C, mob/user, params)
if(istype(C, /obj/item/light/bulb)) //only for light tiles
if(!state)
if(!light_broken)
qdel(C)
state = LIGHTFLOOR_ON
light_broken = FALSE
update_icon()
to_chat(user, "<span class='notice'>You replace the light bulb.</span>")
else
@@ -92,11 +51,21 @@
return
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(state != 0)
if(state < LIGHTFLOOR_PURPLE)
state++
else
state = LIGHTFLOOR_ON
if(!light_broken)
var/new_color = input(user, "Select a bulb color", "Select a bulb color", color) as color|null
if(!new_color)
return
// Cancel if they walked away
if(!Adjacent(user, src))
return
// Now lets make sure it cant go fully black. Yes I know this is more dense than my skull.
var/list/hsl = rgb2hsl(hex2num(copytext(new_color, 2, 4)), hex2num(copytext(new_color, 4, 6)), hex2num(copytext(new_color, 6, 8)))
hsl[3] = max(hsl[3], 0.4)
var/list/rgb = hsl2rgb(arglist(hsl))
color = "#[num2hex(rgb[1], 2)][num2hex(rgb[2], 2)][num2hex(rgb[3], 2)]"
to_chat(user, "<span class='notice'>You change [src]'s light bulb color.</span>")
update_icon()
else
@@ -111,33 +80,3 @@
/turf/simulated/floor/light/extinguish_light()
toggle_light(FALSE)
visible_message("<span class='danger'>[src] flickers and falls dark.</span>")
//Cycles through all of the colours
/turf/simulated/floor/light/colour_cycle
state = LIGHTFLOOR_GENERICCYCLE
can_modify_colour = FALSE
//Two different "dancefloor" types so that you can have a checkered pattern
// (also has a longer delay than colour_cycle between cycling colours)
/turf/simulated/floor/light/colour_cycle/dancefloor_a
name = "dancefloor"
desc = "Funky floor."
state = LIGHTFLOOR_CYCLEA
/turf/simulated/floor/light/colour_cycle/dancefloor_b
name = "dancefloor"
desc = "Funky floor."
state = LIGHTFLOOR_CYCLEB
#undef LIGHTFLOOR_ON
#undef LIGHTFLOOR_WHITE
#undef LIGHTFLOOR_RED
#undef LIGHTFLOOR_GREEN
#undef LIGHTFLOOR_YELLOW
#undef LIGHTFLOOR_BLUE
#undef LIGHTFLOOR_PURPLE
#undef LIGHTFLOOR_GENERICCYCLE
#undef LIGHTFLOOR_CYCLEA
#undef LIGHTFLOOR_CYCLEB
+3 -3
View File
@@ -150,11 +150,11 @@ GLOBAL_LIST_EMPTY(world_topic_handlers)
return
#endif
// If we had an update or pending TM, set a 60 second timeout
// If the server has been gracefully shutdown in TGS, have a 60 seconds grace period for SQL updates and stuff
var/secs_before_auto_reconnect = 10
if(GLOB.pending_server_update)
if(GLOB.slower_restart)
secs_before_auto_reconnect = 60
to_chat(world, "<span class='boldannounce'>Reboot will take a little longer, due to pending updates.</span>")
server_announce_global("Reboot will take a little longer due to pending backend changes.")
// Send the reboot banner to all players
for(var/client/C in GLOB.clients)
+1 -1
View File
@@ -2630,7 +2630,7 @@
fax_panel(usr)
else if(href_list["getplaytimewindow"])
if(!check_rights(R_ADMIN))
if(!check_rights(R_ADMIN | R_MOD | R_MENTOR))
return
var/mob/M = locateUID(href_list["getplaytimewindow"])
if(!istype(M, /mob))
@@ -248,6 +248,7 @@
owner.announce_objectives()
if(should_give_codewords)
give_codewords()
to_chat(owner.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Traitor)</span>")
/datum/antagonist/traitor/proc/update_traitor_icons_added(datum/mind/traitor_mind)
@@ -440,7 +440,7 @@
"f_style" = f_style,
"markingstyleslist" = markingstyleslist,
"ha_style" = ha_style,
"alt_head" = alt_head || "",
"alt_head" = (alt_head ? alt_head : ""), // This it intentional. It wont work without it!
"e_colour" = e_colour,
"underwear" = underwear,
"undershirt" = undershirt,
+1 -1
View File
@@ -78,7 +78,7 @@
desc = "These gloves are fire-resistant."
icon_state = "black"
item_state = "bgloves"
item_color="brown"
item_color="black"
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
+16
View File
@@ -198,3 +198,19 @@
desc = "A cap coroners wear during autopsies. Keeps their hair from falling into the cadavers. It is as dark as the coroner's humor."
icon_state = "surgcap_black"
dog_fashion = /datum/dog_fashion/head/surgery
//Special Roles
/obj/item/clothing/head/beret/solgov/command
name = "\improper Trans-Solar Federation Lieutenant's beret"
desc = "A beret worn by marines of the Trans-Solar Federation. The insignia signifies the wearer bears the rank of a Lieutenant."
icon_state = "solgovcberet"
item_color = "solgovc"
dog_fashion = null
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 60)
strip_delay = 80
/obj/item/clothing/head/beret/solgov/command/elite
name = "\improper Trans-Solar Federation Specops Lieutenant's beret"
desc = "A beret worn by marines of the Trans-Solar Federation Psiops division. The insignia signifies the wearer bears the rank of a Lieutenant."
icon_state = "solgovceliteberet"
item_color = "solgovcelite"
+22 -2
View File
@@ -124,9 +124,29 @@
item_color = "solgov"
dog_fashion = null
/obj/item/clothing/head/soft/solgov/command
/obj/item/clothing/head/soft/solgov/marines
armor = list("melee" = 35, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 50)
strip_delay = 60
icon_state = "solgovsoft_flipped"
flipped = TRUE
/obj/item/clothing/head/soft/solgov/marines/elite
name = "\improper Trans-Solar Federation Specops marine cap"
desc = "A soft cap worn by marines of the Trans-Solar Federation Specops division."
icon_state = "solgovelitesoft_flipped"
item_color = "solgovelite"
/obj/item/clothing/head/soft/solgov/marines/command
name = "\improper Trans-Solar Federation lieutenant's cap"
desc = "A soft cap worn by marines of the Trans-Solar Federation. The insignia signifies the wearer bears the rank of a Lieutenant."
icon_state = "solgovcsoft"
icon_state = "solgovcsoft_flipped"
item_color = "solgovc"
dog_fashion = null
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 60)
strip_delay = 80
/obj/item/clothing/head/soft/solgov/marines/command/elite
name = "\improper Trans-Solar Federation Specops Lieutenant's cap"
desc = "A soft cap worn by marines of the Trans-Solar Federation Specops division. The insignia signifies the wearer bears the rank of a Lieutenant."
icon_state = "solgovcelitesoft"
item_color = "solgovcelite"
+3
View File
@@ -58,6 +58,9 @@
"Grey" = 'icons/mob/species/grey/mask.dmi'
)
/obj/item/clothing/mask/gas/explorer/marines
name = "military gas mask"
/obj/item/clothing/mask/gas/explorer/attack_self(mob/user)
adjustmask(user)
+12 -1
View File
@@ -68,14 +68,25 @@
item_color = "solgov"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
displays_id = 0
/obj/item/clothing/under/solgov/elite
name = "\improper Trans-Solar Federation Specops marine uniform"
desc = "A comfortable and durable combat uniform worn by Trans-Solar Federation Specops Marine Forces."
icon_state = "solgovelite"
item_color = "solgovelite"
/obj/item/clothing/under/solgov/command
name = "\improper Trans-Solar Federation Lieutenant's uniform"
desc = "A comfortable and durable combat uniform worn by Trans-Solar Federation Marine Forces. This one has additional insignia on its shoulders."
desc = "A comfortable and durable combat uniform worn by Trans-Solar Federation Marine Forces. This one has additional insignia on its shoulders and cuffs."
icon_state = "solgovc"
item_color = "solgovc"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
/obj/item/clothing/under/solgov/command/elite
name = "\improper Trans-Solar Federation Specops Lieutenant's uniform"
desc = "A comfortable and durable combat uniform worn by Trans-Solar Federation Specops Marine Forces. This one has additional insignia on its shoulders and cuffs."
icon_state = "solgovcelite"
item_color = "solgovcelite"
/obj/item/clothing/under/solgov/rep
name = "\improper Trans-Solar Federation representative's uniform"
desc = "A formal uniform worn by the diplomatic representatives of the Trans-Solar Federation."
+1
View File
@@ -30,5 +30,6 @@
SSticker.mode.update_blob_icons_added(B.mind)
to_chat(B, "<span class='userdanger'>You are now a mouse, infected with blob spores. Find somewhere isolated... before you burst and become the blob! Use ventcrawl (alt-click on vents) to move around.</span>")
to_chat(B, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Blob)</span>")
notify_ghosts("Infected Mouse has appeared in [get_area(B)].", source = B)
successSpawn = TRUE
+1
View File
@@ -56,6 +56,7 @@
var/mob/living/simple_animal/hostile/poison/terror_spider/S = new spider_type(vent.loc)
var/mob/M = pick_n_take(candidates)
S.key = M.key
to_chat(S, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Terror_Spider)</span>")
spawncount--
successSpawn = TRUE
@@ -178,7 +178,7 @@
return
if(queen_bee)
visible_message("<span class='notice'>[user] sets [qb] down inside the apiary, making it [user.p_their()] new home.</span>")
visible_message("<span class='notice'>[user] sets [qb] down inside the apiary, making it [qb.p_their()] new home.</span>")
var/relocated = 0
for(var/b in bees)
var/mob/living/simple_animal/hostile/poison/bees/B = b
@@ -77,15 +77,15 @@
user.set_machine(src)
var/dat = {"<table>
<tr><td><B>Left Hand:</B></td><td><A href='?src=[UID()];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Right Hand:</B></td><td><A href='?src=[UID()];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Left Hand:</B></td><td><A href='?src=[UID()];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? html_encode(l_hand) : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Right Hand:</B></td><td><A href='?src=[UID()];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? html_encode(r_hand) : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td>&nbsp;</td></tr>"}
dat += "<tr><td><B>Head:</B></td><td><A href='?src=[UID()];item=[slot_head]'>[(head && !(head.flags&ABSTRACT)) ? head : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Head:</B></td><td><A href='?src=[UID()];item=[slot_head]'>[(head && !(head.flags&ABSTRACT)) ? html_encode(head) : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td>&nbsp;</td></tr>"
dat += "<tr><td><B>Exosuit:</B></td><td><A href='?src=[UID()];item=[slot_wear_suit]'>[(wear_suit && !(wear_suit.flags&ABSTRACT)) ? wear_suit : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Exosuit:</B></td><td><A href='?src=[UID()];item=[slot_wear_suit]'>[(wear_suit && !(wear_suit.flags&ABSTRACT)) ? html_encode(wear_suit) : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Pouches:</B></td><td><A href='?src=[UID()];item=pockets'>[((l_store && !(l_store.flags&ABSTRACT)) || (r_store && !(r_store.flags&ABSTRACT))) ? "Full" : "<font color=grey>Empty</font>"]</A>"
dat += {"</table>
@@ -99,6 +99,7 @@
new_xeno.mind.assigned_role = SPECIAL_ROLE_XENOMORPH
new_xeno.mind.special_role = SPECIAL_ROLE_XENOMORPH
new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100)//To get the player's attention
to_chat(new_xeno, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Xenomorph)</span>")
if(gib_on_success)
owner.gib()
+5 -5
View File
@@ -667,19 +667,19 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
user.set_machine(src)
var/dat = {"<table>
<tr><td><B>Left Hand:</B></td><td><A href='?src=[UID()];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Right Hand:</B></td><td><A href='?src=[UID()];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Left Hand:</B></td><td><A href='?src=[UID()];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? html_encode(l_hand) : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Right Hand:</B></td><td><A href='?src=[UID()];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? html_encode(r_hand) : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td>&nbsp;</td></tr>"}
dat += "<tr><td><B>Back:</B></td><td><A href='?src=[UID()];item=[slot_back]'>[(back && !(back.flags&ABSTRACT)) ? back : "<font color=grey>Empty</font>"]</A>"
dat += "<tr><td><B>Back:</B></td><td><A href='?src=[UID()];item=[slot_back]'>[(back && !(back.flags&ABSTRACT)) ? html_encode(back) : "<font color=grey>Empty</font>"]</A>"
if(istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/tank))
dat += "&nbsp;<A href='?src=[UID()];internal=[slot_back]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
dat += "</td></tr><tr><td>&nbsp;</td></tr>"
dat += "<tr><td><B>Head:</B></td><td><A href='?src=[UID()];item=[slot_head]'>[(head && !(head.flags&ABSTRACT)) ? head : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Head:</B></td><td><A href='?src=[UID()];item=[slot_head]'>[(head && !(head.flags&ABSTRACT)) ? html_encode(head) : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=[UID()];item=[slot_wear_mask]'>[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=[UID()];item=[slot_wear_mask]'>[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? html_encode(wear_mask) : "<font color=grey>Empty</font>"]</A></td></tr>"
if(istype(wear_mask, /obj/item/clothing/mask/muzzle))
var/obj/item/clothing/mask/muzzle/M = wear_mask
@@ -202,7 +202,7 @@
H.ha_style = "None"
update_head_accessory()
/mob/living/carbon/human/proc/change_eye_color(colour = "#000000", update_dna = 1)
/mob/living/carbon/human/proc/change_eye_color(colour = "#000000", update_dna = TRUE)
// Update the main DNA datum, then sync the change across the organs
var/obj/item/organ/internal/eyes/eyes_organ = get_int_organ(/obj/item/organ/internal/eyes)
if(eyes_organ)
@@ -215,10 +215,16 @@
if(update_dna)
update_dna()
sync_organ_dna(assimilate=0)
sync_organ_dna(assimilate = FALSE)
update_eyes()
update_body()
return 1
return TRUE
/mob/living/carbon/human/proc/get_eye_color()
var/obj/item/organ/internal/eyes/E = get_int_organ(/obj/item/organ/internal/eyes)
if(E)
return E.eye_color
return FALSE
/mob/living/carbon/human/proc/change_hair_color(colour = "#000000", secondary)
var/obj/item/organ/external/head/H = get_organ("head")
+16 -16
View File
@@ -284,17 +284,17 @@
var/list/obscured = check_obscured_slots()
var/dat = {"<table>
<tr><td><B>Left Hand:</B></td><td><A href='?src=[UID()];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Right Hand:</B></td><td><A href='?src=[UID()];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Left Hand:</B></td><td><A href='?src=[UID()];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? html_encode(l_hand) : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Right Hand:</B></td><td><A href='?src=[UID()];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? html_encode(r_hand) : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td>&nbsp;</td></tr>"}
dat += "<tr><td><B>Back:</B></td><td><A href='?src=[UID()];item=[slot_back]'>[(back && !(back.flags&ABSTRACT)) ? back : "<font color=grey>Empty</font>"]</A>"
dat += "<tr><td><B>Back:</B></td><td><A href='?src=[UID()];item=[slot_back]'>[(back && !(back.flags&ABSTRACT)) ? html_encode(back) : "<font color=grey>Empty</font>"]</A>"
if(has_breathable_mask && istype(back, /obj/item/tank))
dat += "&nbsp;<A href='?src=[UID()];internal=[slot_back]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
dat += "</td></tr><tr><td>&nbsp;</td></tr>"
dat += "<tr><td><B>Head:</B></td><td><A href='?src=[UID()];item=[slot_head]'>[(head && !(head.flags&ABSTRACT)) ? head : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Head:</B></td><td><A href='?src=[UID()];item=[slot_head]'>[(head && !(head.flags&ABSTRACT)) ? html_encode(head) : "<font color=grey>Empty</font>"]</A></td></tr>"
var/obj/item/organ/internal/headpocket/C = get_int_organ(/obj/item/organ/internal/headpocket)
if(C)
@@ -309,7 +309,7 @@
if(slot_wear_mask in obscured)
dat += "<tr><td><font color=grey><B>Mask:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
else
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=[UID()];item=[slot_wear_mask]'>[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "<font color=grey>Empty</font>"]</A>"
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=[UID()];item=[slot_wear_mask]'>[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? html_encode(wear_mask) : "<font color=grey>Empty</font>"]</A>"
if(istype(wear_mask, /obj/item/clothing/mask/muzzle))
var/obj/item/clothing/mask/muzzle/M = wear_mask
@@ -322,23 +322,23 @@
if(slot_glasses in obscured)
dat += "<tr><td><font color=grey><B>Eyes:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
else
dat += "<tr><td><B>Eyes:</B></td><td><A href='?src=[UID()];item=[slot_glasses]'>[(glasses && !(glasses.flags&ABSTRACT)) ? glasses : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Eyes:</B></td><td><A href='?src=[UID()];item=[slot_glasses]'>[(glasses && !(glasses.flags&ABSTRACT)) ? html_encode(glasses) : "<font color=grey>Empty</font>"]</A></td></tr>"
if(slot_l_ear in obscured)
dat += "<tr><td><font color=grey><B>Left Ear:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
else
dat += "<tr><td><B>Left Ear:</B></td><td><A href='?src=[UID()];item=[slot_l_ear]'>[(l_ear && !(l_ear.flags&ABSTRACT)) ? l_ear : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Left Ear:</B></td><td><A href='?src=[UID()];item=[slot_l_ear]'>[(l_ear && !(l_ear.flags&ABSTRACT)) ? html_encode(l_ear) : "<font color=grey>Empty</font>"]</A></td></tr>"
if(slot_r_ear in obscured)
dat += "<tr><td><font color=grey><B>Right Ear:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
else
dat += "<tr><td><B>Right Ear:</B></td><td><A href='?src=[UID()];item=[slot_r_ear]'>[(r_ear && !(r_ear.flags&ABSTRACT)) ? r_ear : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Right Ear:</B></td><td><A href='?src=[UID()];item=[slot_r_ear]'>[(r_ear && !(r_ear.flags&ABSTRACT)) ? html_encode(r_ear) : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td>&nbsp;</td></tr>"
dat += "<tr><td><B>Exosuit:</B></td><td><A href='?src=[UID()];item=[slot_wear_suit]'>[(wear_suit && !(wear_suit.flags&ABSTRACT)) ? wear_suit : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Exosuit:</B></td><td><A href='?src=[UID()];item=[slot_wear_suit]'>[(wear_suit && !(wear_suit.flags&ABSTRACT)) ? html_encode(wear_suit) : "<font color=grey>Empty</font>"]</A></td></tr>"
if(wear_suit)
dat += "<tr><td>&nbsp;&#8627;<B>Suit Storage:</B></td><td><A href='?src=[UID()];item=[slot_s_store]'>[(s_store && !(s_store.flags&ABSTRACT)) ? s_store : "<font color=grey>Empty</font>"]</A>"
dat += "<tr><td>&nbsp;&#8627;<B>Suit Storage:</B></td><td><A href='?src=[UID()];item=[slot_s_store]'>[(s_store && !(s_store.flags&ABSTRACT)) ? html_encode(s_store) : "<font color=grey>Empty</font>"]</A>"
if(has_breathable_mask && istype(s_store, /obj/item/tank))
dat += "&nbsp;<A href='?src=[UID()];internal=[slot_s_store]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
dat += "</td></tr>"
@@ -348,17 +348,17 @@
if(slot_shoes in obscured)
dat += "<tr><td><font color=grey><B>Shoes:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
else
dat += "<tr><td><B>Shoes:</B></td><td><A href='?src=[UID()];item=[slot_shoes]'>[(shoes && !(shoes.flags&ABSTRACT)) ? shoes : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Shoes:</B></td><td><A href='?src=[UID()];item=[html_encode(slot_shoes)]'>[(shoes && !(shoes.flags&ABSTRACT)) ? html_encode(shoes) : "<font color=grey>Empty</font>"]</A></td></tr>"
if(slot_gloves in obscured)
dat += "<tr><td><font color=grey><B>Gloves:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
else
dat += "<tr><td><B>Gloves:</B></td><td><A href='?src=[UID()];item=[slot_gloves]'>[(gloves && !(gloves.flags&ABSTRACT)) ? gloves : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Gloves:</B></td><td><A href='?src=[UID()];item=[slot_gloves]'>[(gloves && !(gloves.flags&ABSTRACT)) ? html_encode(gloves) : "<font color=grey>Empty</font>"]</A></td></tr>"
if(slot_w_uniform in obscured)
dat += "<tr><td><font color=grey><B>Uniform:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
else
dat += "<tr><td><B>Uniform:</B></td><td><A href='?src=[UID()];item=[slot_w_uniform]'>[(w_uniform && !(w_uniform.flags&ABSTRACT)) ? w_uniform : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Uniform:</B></td><td><A href='?src=[UID()];item=[slot_w_uniform]'>[(w_uniform && !(w_uniform.flags&ABSTRACT)) ? html_encode(w_uniform) : "<font color=grey>Empty</font>"]</A></td></tr>"
if((w_uniform == null && !(dna && dna.species.nojumpsuit)) || (slot_w_uniform in obscured))
dat += "<tr><td><font color=grey>&nbsp;&#8627;<B>Pockets:</B></font></td></tr>"
@@ -367,7 +367,7 @@
dat += "<tr><td><font color=grey>&nbsp;&#8627;<B>Suit Sensors:</B></font></td></tr>"
dat += "<tr><td><font color=grey>&nbsp;&#8627;<B>PDA:</B></font></td></tr>"
else
dat += "<tr><td>&nbsp;&#8627;<B>Belt:</B></td><td><A href='?src=[UID()];item=[slot_belt]'>[(belt && !(belt.flags&ABSTRACT)) ? belt : "<font color=grey>Empty</font>"]</A>"
dat += "<tr><td>&nbsp;&#8627;<B>Belt:</B></td><td><A href='?src=[UID()];item=[slot_belt]'>[(belt && !(belt.flags&ABSTRACT)) ? html_encode(belt) : "<font color=grey>Empty</font>"]</A>"
if(has_breathable_mask && istype(belt, /obj/item/tank))
dat += "&nbsp;<A href='?src=[UID()];internal=[slot_belt]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
dat += "</td></tr>"
@@ -387,8 +387,8 @@
else
dat += "<font color=grey>Right (Empty)</font>"
dat += "</A></td></tr>"
dat += "<tr><td>&nbsp;&#8627;<B>ID:</B></td><td><A href='?src=[UID()];item=[slot_wear_id]'>[(wear_id && !(wear_id.flags&ABSTRACT)) ? wear_id : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td>&nbsp;&#8627;<B>PDA:</B></td><td><A href='?src=[UID()];item=[slot_wear_pda]'>[(wear_pda && !(wear_pda.flags&ABSTRACT)) ? wear_pda : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td>&nbsp;&#8627;<B>ID:</B></td><td><A href='?src=[UID()];item=[slot_wear_id]'>[(wear_id && !(wear_id.flags&ABSTRACT)) ? html_encode(wear_id) : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td>&nbsp;&#8627;<B>PDA:</B></td><td><A href='?src=[UID()];item=[slot_wear_pda]'>[(wear_pda && !(wear_pda.flags&ABSTRACT)) ? html_encode(wear_pda) : "<font color=grey>Empty</font>"]</A></td></tr>"
if(istype(w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = w_uniform
+7 -24
View File
@@ -170,11 +170,10 @@
emote("drool")
/mob/living/carbon/human/handle_mutations_and_radiation()
for(var/datum/mutation/mutation in GLOB.dna_mutations)
if(!mutation.block)
continue
if(mutation.is_active(src))
mutation.on_life(src)
for(var/mutation_type in active_mutations)
var/datum/mutation/mutation = GLOB.dna_mutations[mutation_type]
mutation.on_life(src)
if(!ignore_gene_stability && gene_stability < GENETIC_DAMAGE_STAGE_1)
var/instability = DEFAULT_GENE_STABILITY - gene_stability
if(prob(instability * 0.1))
@@ -366,6 +365,9 @@
bodytemperature += (BODYTEMP_HEATING_MAX + (fire_stacks * 12))
/mob/living/carbon/human/proc/get_thermal_protection()
if(HAS_TRAIT(src, TRAIT_RESISTHEAT))
return FIRE_IMMUNITY_MAX_TEMP_PROTECT
var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures
if(wear_suit)
if(wear_suit.max_heat_protection_temperature >= FIRE_SUIT_MAX_TEMP_PROTECT)
@@ -590,26 +592,7 @@
to_chat(src, "<span class='notice'>You no longer feel vigorous.</span>")
metabolism_efficiency = 1
if(drowsyness)
AdjustDrowsy(-1)
EyeBlurry(2)
if(prob(5))
AdjustSleeping(1)
Paralyse(5)
if(confused)
AdjustConfused(-1)
// decrement dizziness counter, clamped to 0
if(resting)
if(dizziness)
AdjustDizzy(-15)
if(jitteriness)
AdjustJitter(-15)
else
if(dizziness)
AdjustDizzy(-3)
if(jitteriness)
AdjustJitter(-3)
if(NO_INTORGANS in dna.species.species_traits)
return
+3 -5
View File
@@ -152,11 +152,9 @@
verb = pick("whinnies", "neighs", "says")
if(dna)
for(var/datum/mutation/mutation in GLOB.dna_mutations)
if(!mutation.block)
continue
if(mutation.is_active(src))
S.message = mutation.on_say(src, S.message)
for(var/mutation_type in active_mutations)
var/datum/mutation/mutation = GLOB.dna_mutations[mutation_type]
S.message = mutation.on_say(src, S.message)
var/braindam = getBrainLoss()
if(braindam >= 60)
@@ -450,14 +450,13 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
if(gender == FEMALE)
g = "f"
// DNA2 - Drawing underlays.
for(var/datum/mutation/mutation in GLOB.dna_mutations)
if(!mutation.block)
continue
if(mutation.is_active(src))
var/underlay = mutation.on_draw_underlays(src, g)
if(underlay)
standing.underlays += underlay
add_image = 1
for(var/mutation_type in active_mutations)
var/datum/mutation/mutation = GLOB.dna_mutations[mutation_type]
var/underlay = mutation.on_draw_underlays(src, g)
if(underlay)
standing.underlays += underlay
add_image = TRUE
if(HAS_TRAIT(src, TRAIT_LASEREYES))
standing.overlays += "lasereyes_s"
add_image = 1
+1 -1
View File
@@ -973,7 +973,7 @@
M.LAssailant = usr
/mob/living/proc/check_pull()
if(pulling && !(pulling in orange(1)))
if(pulling && !pulling.Adjacent(src))
stop_pulling()
/mob/living/proc/update_z(new_z) // 1+ to register, null to unregister
@@ -4,9 +4,10 @@
mob_biotypes = NONE
speak_emote = list("hisses")
emote_hear = list("wails","screeches")
response_help = "thinks better of touching"
response_help = "thinks better of touching"
response_disarm = "flails at"
response_harm = "punches"
response_harm = "punches"
icon = 'icons/mob/cult.dmi'
icon_dead = "shade_dead"
speed = 0
a_intent = INTENT_HARM
@@ -26,6 +27,9 @@
deathmessage = "collapses in a shattered heap."
var/construct_type = "shade"
var/list/construct_spells = list()
/// Is this a holy/purified construct?
var/holy = FALSE
/// Message to send to the construct when they are created, containing information about their role.
var/playstyle_string = "<b>You are a generic construct! Your job is to not exist, and you should probably adminhelp this.</b>"
/mob/living/simple_animal/hostile/construct/New()
@@ -98,7 +102,6 @@
name = "Juggernaut"
real_name = "Juggernaut"
desc = "A possessed suit of armour driven by the will of the restless dead"
icon = 'icons/mob/mob.dmi'
icon_state = "behemoth"
icon_living = "behemoth"
maxHealth = 250
@@ -149,7 +152,6 @@
name = "Wraith"
real_name = "Wraith"
desc = "A wicked bladed shell contraption piloted by a bound spirit"
icon = 'icons/mob/mob.dmi'
icon_state = "floating"
icon_living = "floating"
maxHealth = 75
@@ -174,7 +176,6 @@
name = "Artificer"
real_name = "Artificer"
desc = "A bulbous construct dedicated to building and maintaining Cult armies."
icon = 'icons/mob/mob.dmi'
icon_state = "artificer"
icon_living = "artificer"
maxHealth = 50
@@ -254,7 +255,6 @@
name = "Behemoth"
real_name = "Behemoth"
desc = "The pinnacle of occult technology, Behemoths are the ultimate weapon in the Cult's arsenal."
icon = 'icons/mob/mob.dmi'
icon_state = "behemoth"
icon_living = "behemoth"
maxHealth = 750
@@ -288,7 +288,6 @@
name = "Harvester"
real_name = "Harvester"
desc = "A harbinger of enlightenment. It'll be all over soon."
icon = 'icons/mob/mob.dmi'
icon_state = "harvester"
icon_living = "harvester"
maxHealth = 60
@@ -316,6 +315,17 @@
AIStatus = AI_ON
environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP
/mob/living/simple_animal/hostile/construct/proc/make_holy()
if(holy) // Already holy-fied
return
holy = TRUE
set_light(3, 5, LIGHT_COLOR_DARK_BLUE)
name = "Holy [name]"
real_name = "Holy [real_name]"
faction.Remove("cult")
///ui stuff
/mob/living/simple_animal/hostile/construct/armoured/update_health_hud()
@@ -140,8 +140,8 @@
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
dat += "<br><B>Head:</B> <A href='?src=[UID()];[inventory_head ? "remove_inv=head'>[inventory_head]" : "add_inv=head'>Nothing"]</A>"
dat += "<br><B>Back:</B> <A href='?src=[UID()];[inventory_back ? "remove_inv=back'>[inventory_back]" : "add_inv=back'>Nothing"]</A>"
dat += "<br><B>Head:</B> <A href='?src=[UID()];[inventory_head ? "remove_inv=head'>[html_encode(inventory_head)]" : "add_inv=head'>Nothing"]</A>"
dat += "<br><B>Back:</B> <A href='?src=[UID()];[inventory_back ? "remove_inv=back'>[html_encode(inventory_back)]" : "add_inv=back'>Nothing"]</A>"
dat += "<br><B>Collar:</B> <A href='?src=[UID()];[pcollar ? "remove_inv=collar'>[pcollar]" : "add_inv=collar'>Nothing"]</A>"
var/datum/browser/popup = new(user, "mob[UID()]", "[src]", 440, 250)
@@ -265,6 +265,7 @@
icon_state = "queen_item"
item_state = ""
icon = 'icons/mob/bees.dmi'
gender = FEMALE
var/mob/living/simple_animal/hostile/poison/bees/queen/queen
@@ -419,11 +419,13 @@
back = /obj/item/tank/internals/oxygen
mask = /obj/item/clothing/mask/breath
if("Cultist")
uniform = /obj/item/clothing/under/roman
suit = /obj/item/clothing/suit/hooded/cultrobes
suit_store = /obj/item/tome
r_pocket = /obj/item/restraints/legcuffs/bola/cult
uniform = /obj/item/clothing/under/color/black
back = /obj/item/storage/backpack/cultpack
suit = /obj/item/clothing/suit/hooded/cultrobes/alt
if(prob(40))
suit_store = /obj/item/melee/cultblade
l_pocket = /obj/item/melee/cultblade/dagger
glasses = /obj/item/clothing/glasses/hud/health/night
backpack_contents = list(/obj/item/reagent_containers/food/drinks/bottle/unholywater = 1, /obj/item/cult_shift = 1, /obj/item/flashlight/flare = 1, /obj/item/stack/sheet/runed_metal = 15)
if(prob(60))
r_pocket = /obj/item/reagent_containers/food/drinks/bottle/unholywater
backpack_contents = list(/obj/item/tome = 1, /obj/item/restraints/legcuffs/bola/cult = 1, /obj/item/stack/sheet/runed_metal = 15)
. = ..()
@@ -42,5 +42,6 @@
to_chat(user, "<span class='notice'>Someone else already took this spider.</span>")
return
key = user.key
to_chat(src, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Terror_Spider)</span>")
for(var/mob/dead/observer/G in GLOB.player_list)
G.show_message("<i>A ghost has taken control of <b>[src]</b>. ([ghost_follow_link(src, ghost=G)]).</i>")
@@ -137,10 +137,10 @@
var/dat = {"<table>"}
dat += "<tr><td><B>Headset:</B></td><td><A href='?src=[UID()];[ears?"remove_inv":"add_inv"]=ears'>[(ears && !(ears.flags&ABSTRACT)) ? ears : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Headset:</B></td><td><A href='?src=[UID()];[ears?"remove_inv":"add_inv"]=ears'>[(ears && !(ears.flags&ABSTRACT)) ? html_encode(ears) : "<font color=grey>Empty</font>"]</A></td></tr>"
if(can_collar)
dat += "<tr><td>&nbsp;</td></tr>"
dat += "<tr><td><B>Collar:</B></td><td><A href='?src=[UID()];[pcollar ? "remove_inv" : "add_inv"]=collar'>[(pcollar && !(pcollar.flags&ABSTRACT)) ? pcollar : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += "<tr><td><B>Collar:</B></td><td><A href='?src=[UID()];[pcollar ? "remove_inv" : "add_inv"]=collar'>[(pcollar && !(pcollar.flags&ABSTRACT)) ? html_encode(pcollar) : "<font color=grey>Empty</font>"]</A></td></tr>"
dat += {"</table>
<A href='?src=[user.UID()];mach_close=mob\ref[src]'>Close</A>
@@ -2,7 +2,7 @@
name = "Shade"
real_name = "Shade"
desc = "A bound spirit"
icon = 'icons/mob/mob.dmi'
icon = 'icons/mob/cult.dmi'
icon_state = "shade"
icon_living = "shade"
icon_dead = "shade_dead"
@@ -34,6 +34,10 @@
deathmessage = "lets out a contented sigh as their form unwinds."
var/holy = FALSE
/mob/living/simple_animal/shade/cult/Initialize(mapload)
. = ..()
icon_state = SSticker.cultdat?.shade_icon_state
/mob/living/simple_animal/shade/death(gibbed)
. = ..()
SSticker.mode.remove_cultist(mind, FALSE)
@@ -48,11 +52,6 @@
/mob/living/simple_animal/shade/Process_Spacemove()
return TRUE
/mob/living/simple_animal/shade/cult/Initialize(mapload)
. = ..()
icon_state = SSticker.cultdat?.shade_icon_state
/mob/living/simple_animal/shade/holy
holy = TRUE
icon_state = "shade_angelic"
@@ -474,7 +474,7 @@
return
user.set_machine(src)
var/dat = "<table><tr><td><B>Collar:</B></td><td><A href='?src=[UID()];item=[slot_collar]'>[(pcollar && !(pcollar.flags & ABSTRACT)) ? pcollar : "<font color=grey>Empty</font>"]</A></td></tr></table>"
var/dat = "<table><tr><td><B>Collar:</B></td><td><A href='?src=[UID()];item=[slot_collar]'>[(pcollar && !(pcollar.flags & ABSTRACT)) ? html_encode(pcollar) : "<font color=grey>Empty</font>"]</A></td></tr></table>"
dat += "<A href='?src=[user.UID()];mach_close=mob\ref[src]'>Close</A>"
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 250)
@@ -645,4 +645,3 @@
/mob/living/simple_animal/Login()
..()
walk(src, 0) // if mob is moving under ai control, then stop AI movement
+1 -1
View File
@@ -86,7 +86,7 @@
/mob/living/update_canmove(delay_action_updates = 0)
var/fall_over = !can_stand()
var/buckle_lying = !(buckled && !buckled.buckle_lying)
if(fall_over || resting || stunned)
if(fall_over || resting || stunned || (buckled && buckle_lying != 0))
drop_r_hand()
drop_l_hand()
else
+2 -2
View File
@@ -560,8 +560,8 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
/mob/proc/show_inv(mob/user)
user.set_machine(src)
var/dat = {"<table>
<tr><td><B>Left Hand:</B></td><td><A href='?src=[UID()];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Right Hand:</B></td><td><A href='?src=[UID()];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Left Hand:</B></td><td><A href='?src=[UID()];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? html_encode(l_hand) : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Right Hand:</B></td><td><A href='?src=[UID()];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? html_encode(r_hand) : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td>&nbsp;</td></tr>"}
dat += {"</table>
<A href='?src=[user.UID()];mach_close=mob\ref[src]'>Close</A>
+1
View File
@@ -174,6 +174,7 @@
var/stance_damage = 0 //Whether this mob's ability to stand has been affected
/// List of the active mutation types
var/list/active_mutations = list()
var/last_movement = -100 // Last world.time the mob actually moved of its own accord.
+2
View File
@@ -193,6 +193,8 @@
/obj/item/grab/proc/adjust_position()
if(affecting.buckled)
return
if(!assailant.Adjacent(affecting)) // To prevent teleportation via grab
return
if(affecting.lying && state != GRAB_KILL)
animate(affecting, pixel_x = 0, pixel_y = 0, 5, 1, LINEAR_EASING)
return //KJK
+2 -1
View File
@@ -198,7 +198,8 @@
QDEL_NULL(mind)
GLOB.respawnable_list += observer
qdel(src)
return 1
return TRUE
return FALSE
if(href_list["tos"])
privacy_consent()
return FALSE
+2 -1
View File
@@ -114,7 +114,8 @@
dat += "<br><i>There is a small scribble near the end of this page... It reads: \"[scribble]\"</i>"
dat+= "<hr><div style='float:left;'><a href='?src=[UID()];prev_page=1'>Previous Page</a></div>"
else
dat += "i'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
// No trailing punctuation so that it's easy to copy and paste the address
dat += "We're sorry to break your immersion, but there has been an error with the newscaster. Please report this error, along with any more information you have, to [config.githuburl]/issues/new?template=bug_report.md"
dat += "<br><hr><div align='center'>[curr_page+1]</div>"
human_user << browse(dat, "window=newspaper_main;size=300x400")
@@ -375,6 +375,10 @@
max_ammo = 30
multiple_sprites = 2
/obj/item/ammo_box/magazine/m556/arg
name = "ARG magazine (5.56mm)"
icon_state = "arg"
/obj/item/ammo_box/magazine/m12g
name = "shotgun magazine (12g slugs)"
desc = "A drum magazine."
@@ -240,7 +240,7 @@
item_state = "arg"
slot_flags = 0
origin_tech = "combat=6;engineering=4"
mag_type = /obj/item/ammo_box/magazine/m556
mag_type = /obj/item/ammo_box/magazine/m556/arg
fire_sound = 'sound/weapons/gunshots/gunshot_mg.ogg'
magin_sound = 'sound/weapons/gun_interactions/batrifle_magin.ogg'
magout_sound = 'sound/weapons/gun_interactions/batrifle_magout.ogg'
@@ -328,7 +328,11 @@
name = "double-barreled shotgun"
desc = "A true classic."
icon_state = "dshotgun"
item_state = "shotgun"
item_state = "shotgun_db"
lefthand_file = 'icons/mob/inhands/64x64_guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/64x64_guns_righthand.dmi'
inhand_x_dimension = 64
inhand_y_dimension = 64
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_HEAVY
force = 10
@@ -358,8 +362,10 @@
var/obj/item/melee/energy/W = A
if(W.active)
sawoff(user)
item_state = "ishotgun_sawn"
if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
sawoff(user)
item_state = "ishotgun_sawn"
else
return ..()
@@ -389,7 +395,11 @@
name = "improvised shotgun"
desc = "Essentially a tube that aims shotgun shells."
icon_state = "ishotgun"
item_state = "shotgun"
item_state = "ishotgun"
lefthand_file = 'icons/mob/inhands/64x64_guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/64x64_guns_righthand.dmi'
inhand_x_dimension = 64
inhand_y_dimension = 64
w_class = WEIGHT_CLASS_BULKY
force = 10
slot_flags = null
@@ -406,6 +416,7 @@
if(C.use(10))
slot_flags = SLOT_BACK
icon_state = "ishotgunsling"
item_state = "ishotgunsling"
to_chat(user, "<span class='notice'>You tie the lengths of cable to the shotgun, making a sling.</span>")
slung = 1
update_icon()
@@ -420,6 +431,7 @@
if(slung && (slot_flags & SLOT_BELT) )
slung = 0
icon_state = "ishotgun-sawn"
item_state = "ishotgun_sawn"
/obj/item/gun/projectile/revolver/doublebarrel/improvised/sawoff(mob/user)
. = ..()
@@ -436,6 +448,8 @@
icon = 'icons/obj/items.dmi'
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
inhand_x_dimension = 32
inhand_y_dimension = 32
icon_state = "cane"
item_state = "stick"
sawn_state = SAWN_OFF
@@ -3,6 +3,10 @@
desc = "A traditional shotgun with wood furniture and a four-shell capacity underneath."
icon_state = "shotgun"
item_state = "shotgun"
lefthand_file = 'icons/mob/inhands/64x64_guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/64x64_guns_righthand.dmi'
inhand_x_dimension = 64
inhand_y_dimension = 64
w_class = WEIGHT_CLASS_BULKY
force = 10
flags = CONDUCT
@@ -80,6 +84,7 @@
name = "riot shotgun"
desc = "A sturdy shotgun with a longer magazine and a fixed tactical stock designed for non-lethal riot control."
icon_state = "riotshotgun"
item_state = "shotgun_riot"
mag_type = /obj/item/ammo_box/magazine/internal/shot/riot
sawn_desc = "Come with me if you want to live."
sawn_state = SAWN_INTACT
@@ -131,7 +136,7 @@
desc = sawn_desc
w_class = WEIGHT_CLASS_NORMAL
current_skin = "riotshotgun-short"
item_state = "gun" //phil235 is it different with different skin?
item_state = "shotgun_assault" //phil235 is it different with different skin?
slot_flags &= ~SLOT_BACK //you can't sling it on your back
slot_flags |= SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally)
sawn_state = SAWN_OFF
@@ -208,6 +213,10 @@
desc = "This piece of junk looks like something that could have been used 700 years ago."
icon_state = "moistnugget"
item_state = "moistnugget"
lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/guns_righthand.dmi'
inhand_x_dimension = 32
inhand_y_dimension = 32
slot_flags = 0 //no SLOT_BACK sprite, alas
mag_type = /obj/item/ammo_box/magazine/internal/boltaction
fire_sound = 'sound/weapons/gunshots/gunshot_rifle.ogg'
@@ -305,6 +314,7 @@
name = "combat shotgun"
desc = "A semi automatic shotgun with tactical furniture and a six-shell capacity underneath."
icon_state = "cshotgun"
item_state = "shotgun_combat"
origin_tech = "combat=6"
mag_type = /obj/item/ammo_box/magazine/internal/shot/com
w_class = WEIGHT_CLASS_HUGE
@@ -315,6 +325,11 @@
name = "cycler shotgun"
desc = "An advanced shotgun with two separate magazine tubes, allowing you to quickly toggle between ammo types."
icon_state = "cycler"
inhand_x_dimension = 32
inhand_y_dimension = 32
lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/guns_righthand.dmi'
item_state = "bulldog"
origin_tech = "combat=4;materials=2"
mag_type = /obj/item/ammo_box/magazine/internal/shot/tube
w_class = WEIGHT_CLASS_HUGE
@@ -265,16 +265,11 @@
M.SetConfused(0)
return
if(iscultist(M))
SSticker.mode.remove_cultist(M.mind)
SSticker.mode.remove_cultist(M.mind, TRUE, TRUE)
holder.remove_reagent(id, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
M.SetJitter(0)
M.SetStuttering(0)
M.SetConfused(0)
if(ishuman(M)) // Unequip all cult clothing
var/mob/living/carbon/human/H = M
for(var/I in H.contents)
if(is_type_in_list(I, CULT_CLOTHING))
H.unEquip(I)
return
if(ishuman(M) && M.mind && M.mind.vampire && !M.mind.vampire.get_ability(/datum/vampire_passive/full) && prob(80))
var/mob/living/carbon/V = M
+32 -21
View File
@@ -3,14 +3,19 @@
desc = "..."
icon = 'icons/obj/objects.dmi'
icon_state = "watertank"
density = 1
anchored = 0
density = TRUE
anchored = TRUE
pressure_resistance = 2*ONE_ATMOSPHERE
container_type = DRAINABLE | AMOUNT_VISIBLE
max_integrity = 300
var/tank_volume = 1000 //In units, how much the dispenser can hold
var/reagent_id = "water" //The ID of the reagent that the dispenser uses
var/lastrigger = "" // The last person to rig this fuel tank - Stored with the object. Only the last person matter for investigation
/// How much this dispenser can hold (In units)
var/tank_volume = 1000
/// The ID of the reagent that the dispenser uses
var/reagent_id = "water"
/// The last person to rig this fuel tank - Stored with the object. Only the last person matters for investigation
var/lastrigger = ""
/// Can this tank be unwrenched
var/can_be_unwrenched = TRUE
/obj/structure/reagent_dispensers/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
@@ -28,6 +33,19 @@
create_reagents(tank_volume)
reagents.add_reagent(reagent_id, tank_volume)
/obj/structure/reagent_dispensers/wrench_act(mob/user, obj/item/I)
if(!can_be_unwrenched)
return
. = TRUE
if(!I.tool_use_check(user, 0))
return
default_unfasten_wrench(user, I)
/obj/structure/reagent_dispensers/examine(mob/user)
. = ..()
if(can_be_unwrenched)
. += "<span class='notice'>The wheels look like they can be <b>[anchored ? "unlocked" : "locked in place"]</b> with a <b>wrench</b>."
/obj/structure/reagent_dispensers/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..()
if(reagents)
@@ -206,8 +224,8 @@
name = "pepper spray refiller"
desc = "Contains condensed capsaicin for use in law \"enforcement.\""
icon_state = "pepper"
anchored = 1
density = 0
density = FALSE
can_be_unwrenched = FALSE
reagent_id = "condensedcapsaicin"
/obj/structure/reagent_dispensers/water_cooler
@@ -215,7 +233,6 @@
desc = "A machine that dispenses liquid to drink."
icon = 'icons/obj/vending.dmi'
icon_state = "water_cooler"
anchored = 1
tank_volume = 500
reagent_id = "water"
var/paper_cups = 25 //Paper cups left from the cooler
@@ -234,12 +251,6 @@
user.put_in_hands(S)
paper_cups--
/obj/structure/reagent_dispensers/water_cooler/wrench_act(mob/user, obj/item/I)
. = TRUE
if(!I.tool_use_check(user, 0))
return
default_unfasten_wrench(user, I, 40)
/obj/structure/reagent_dispensers/beerkeg
name = "beer keg"
desc = "Beer is liquid bread, it's good for you..."
@@ -263,22 +274,22 @@
name = "virus food dispenser"
desc = "A dispenser of low-potency virus mutagenic."
icon_state = "virus_food"
anchored = 1
density = 0
can_be_unwrenched = FALSE
density = FALSE
reagent_id = "virusfood"
/obj/structure/reagent_dispensers/spacecleanertank
name = "space cleaner refiller"
desc = "Refills space cleaner bottles."
icon_state = "cleaner"
anchored = 1
density = 0
can_be_unwrenched = FALSE
density = FALSE
tank_volume = 5000
reagent_id = "cleaner"
/obj/structure/reagent_dispensers/fueltank/chem
icon_state = "fuel_chem"
anchored = 1
density = 0
accepts_rig = 0
can_be_unwrenched = FALSE
density = FALSE
accepts_rig = FALSE
tank_volume = 1000
@@ -78,6 +78,7 @@
new_spawn.rename_character(new_spawn.real_name, new_spawn.dna.species.get_random_name(new_spawn.gender))
to_chat(new_spawn, "<b>Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Glory to the Necropolis!</b>")
to_chat(new_spawn, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Ash_Walker)</span>")
/obj/effect/mob_spawn/human/ash_walker/New()
. = ..()
+3
View File
@@ -11,6 +11,9 @@
/obj/item/weldingtool = 30
)
if(M == user)
return // no self surgery
if(istype(M, /mob/living/carbon/human))
H = M
affecting = H.get_organ(check_zone(selected_zone))
+1 -1
View File
@@ -17,7 +17,7 @@
var/tint = 0
var/flash_protect = FLASH_PROTECTION_NONE
var/see_invisible = SEE_INVISIBLE_LIVING
var/lighting_alpha
var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
/obj/item/organ/internal/eyes/proc/update_colour()
dna.write_eyes_attributes(src)
-3
View File
@@ -4,8 +4,5 @@
/datum/world_topic_handler/announce/execute(list/input, key_valid)
var/prtext = input["announce"]
var/pr_substring = copytext(prtext, 1, 23)
if(pr_substring == "Pull Request merged by")
GLOB.pending_server_update = TRUE
for(var/client/C in GLOB.clients)
to_chat(C, "<span class='announce'>PR: [prtext]</span>")
-7
View File
@@ -1,7 +0,0 @@
/datum/world_topic_handler/hostannounce
topic_key = "hostannounce"
requires_commskey = TRUE
/datum/world_topic_handler/hostannounce/execute(list/input, key_valid)
GLOB.pending_server_update = TRUE
to_chat(world, "<hr><span style='color: #12A5F4'><b>Server Announcement:</b> [input["message"]]</span><hr>")