mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-09 16:07:40 +00:00
Tg 2 11 sync (#215)
* first series of updates * datums * games folder * admin and atmosia stuffs * moar * mob updates borg riding * sprites and stuff * fixes for various things * oops. some missed fixes
This commit is contained in:
@@ -349,21 +349,3 @@ CREATE TABLE `messages` (
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Mentor stufs
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `mentor`;
|
||||
CREATE TABLE `mentor` (
|
||||
`ckey` text NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
DROP TABLE IF EXISTS `mentor_memo`;
|
||||
CREATE TABLE `mentor_memo` (
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`memotext` text NOT NULL,
|
||||
`timestamp` datetime NOT NULL,
|
||||
`last_editor` varchar(32) DEFAULT NULL,
|
||||
`edits` text,
|
||||
PRIMARY KEY (`ckey`)
|
||||
|
||||
@@ -20993,6 +20993,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
|
||||
dir = 5
|
||||
},
|
||||
/obj/structure/chair/stool,
|
||||
/turf/open/floor/plasteel/redyellow,
|
||||
/area/crew_quarters/bar/atrium)
|
||||
"aMI" = (
|
||||
@@ -24027,6 +24028,7 @@
|
||||
/area/crew_quarters/bar/atrium)
|
||||
"aRI" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/structure/chair/stool,
|
||||
/turf/open/floor/plasteel/redyellow,
|
||||
/area/crew_quarters/bar/atrium)
|
||||
"aRJ" = (
|
||||
@@ -78208,7 +78210,7 @@
|
||||
/turf/closed/wall,
|
||||
/area/maintenance/electrical)
|
||||
"cHL" = (
|
||||
/obj/machinery/atmospherics/pipe/manifold/supply/visible{
|
||||
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
|
||||
tag = "icon-manifold (NORTH)";
|
||||
icon_state = "manifold";
|
||||
dir = 1
|
||||
@@ -107878,15 +107880,6 @@
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/machinery/doorButtons/access_button{
|
||||
dir = 1;
|
||||
idDoor = "virology_airlock_exterior";
|
||||
idSelf = "virology_airlock_control";
|
||||
name = "Virology Access Button";
|
||||
pixel_x = 0;
|
||||
pixel_y = -24;
|
||||
req_access_txt = "39"
|
||||
},
|
||||
/turf/open/floor/plasteel/whitegreen/corner{
|
||||
dir = 8
|
||||
},
|
||||
@@ -108190,6 +108183,15 @@
|
||||
name = "Virology Exterior Airlock";
|
||||
req_access_txt = "39"
|
||||
},
|
||||
/obj/machinery/doorButtons/access_button{
|
||||
dir = 1;
|
||||
idDoor = "virology_airlock_exterior";
|
||||
idSelf = "virology_airlock_control";
|
||||
name = "Virology Access Button";
|
||||
pixel_x = -24;
|
||||
pixel_y = -2;
|
||||
req_access_txt = "39"
|
||||
},
|
||||
/turf/open/floor/plasteel{
|
||||
tag = "icon-plasteel_warn_side (EAST)"
|
||||
},
|
||||
@@ -108660,6 +108662,12 @@
|
||||
/turf/open/floor/plating,
|
||||
/area/medical/virology)
|
||||
"dKi" = (
|
||||
/obj/item/weapon/twohanded/required/kirbyplants{
|
||||
icon_state = "plant-21";
|
||||
layer = 4.1;
|
||||
pixel_x = -3;
|
||||
pixel_y = 3
|
||||
},
|
||||
/turf/open/floor/plasteel/whitegreen/corner{
|
||||
dir = 1
|
||||
},
|
||||
@@ -109068,6 +109076,14 @@
|
||||
name = "Virology Interior Airlock";
|
||||
req_access_txt = "39"
|
||||
},
|
||||
/obj/machinery/doorButtons/access_button{
|
||||
idDoor = "virology_airlock_interior";
|
||||
idSelf = "virology_airlock_control";
|
||||
name = "Virology Access Button";
|
||||
pixel_x = 0;
|
||||
pixel_y = 22;
|
||||
req_access_txt = "39"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/medical/virology)
|
||||
"dKZ" = (
|
||||
@@ -118113,8 +118129,8 @@
|
||||
},
|
||||
/area/crew_quarters/electronic_marketing_den)
|
||||
"ecc" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/turf/closed/wall,
|
||||
/obj/structure/closet/wardrobe/grey,
|
||||
/turf/open/floor/plasteel/neutral,
|
||||
/area/crew_quarters/electronic_marketing_den)
|
||||
"ecd" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
@@ -118148,23 +118164,29 @@
|
||||
/turf/open/floor/plasteel,
|
||||
/area/hydroponics/Abandoned_Garden)
|
||||
"ech" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber{
|
||||
dir = 4;
|
||||
on = 1;
|
||||
scrub_Toxins = 0
|
||||
/obj/machinery/button/door{
|
||||
id = "Dorm2";
|
||||
name = "Dormitory Door Lock";
|
||||
normaldoorcontrol = 1;
|
||||
pixel_x = -26;
|
||||
pixel_y = 7;
|
||||
req_access_txt = "0";
|
||||
specialfunctions = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/hydrofloor,
|
||||
/area/hydroponics/Abandoned_Garden)
|
||||
/turf/open/floor/wood,
|
||||
/area/crew_quarters/sleep)
|
||||
"eci" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
|
||||
tag = "icon-manifold (EAST)";
|
||||
icon_state = "manifold";
|
||||
dir = 4
|
||||
/obj/machinery/button/door{
|
||||
id = "Dorm4";
|
||||
name = "Dormitory Door Lock";
|
||||
normaldoorcontrol = 1;
|
||||
pixel_x = -26;
|
||||
pixel_y = 7;
|
||||
req_access_txt = "0";
|
||||
specialfunctions = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/hydrofloor,
|
||||
/area/hydroponics/Abandoned_Garden)
|
||||
/turf/open/floor/wood,
|
||||
/area/crew_quarters/sleep)
|
||||
"ecj" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/turf/open/floor/plasteel/hydrofloor,
|
||||
@@ -118500,102 +118522,51 @@
|
||||
/obj/machinery/deepfryer,
|
||||
/turf/open/floor/plasteel/red,
|
||||
/area/crew_quarters/kitchen)
|
||||
"ecc" = (
|
||||
/obj/structure/closet/wardrobe/green,
|
||||
/turf/open/floor/plasteel/neutral/side,
|
||||
/area/shuttle/arrival)
|
||||
"ecd" = (
|
||||
/obj/machinery/doorButtons/access_button{
|
||||
"edc" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/turf/closed/wall,
|
||||
/area/crew_quarters/electronic_marketing_den)
|
||||
"edd" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber{
|
||||
dir = 4;
|
||||
idDoor = "virology_airlock_interior";
|
||||
idSelf = "virology_airlock_control";
|
||||
name = "Virology Access Button";
|
||||
pixel_x = -10;
|
||||
pixel_y = 0;
|
||||
req_access_txt = "39"
|
||||
on = 1;
|
||||
scrub_Toxins = 0
|
||||
},
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/medical/virology)
|
||||
"ece" = (
|
||||
/obj/structure/cable/white{
|
||||
d2 = 2;
|
||||
icon_state = "0-2";
|
||||
tag = "icon-0-2"
|
||||
},
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/medical/virology)
|
||||
"ecf" = (
|
||||
/obj/structure/cable/white{
|
||||
tag = "icon-4-8";
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/structure/cable/white{
|
||||
tag = "icon-2-4";
|
||||
icon_state = "2-4"
|
||||
},
|
||||
/obj/structure/cable/white{
|
||||
tag = "icon-1-4";
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 2
|
||||
/turf/open/floor/plasteel/hydrofloor,
|
||||
/area/hydroponics/Abandoned_Garden)
|
||||
"ede" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
|
||||
tag = "icon-manifold (EAST)";
|
||||
icon_state = "manifold";
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/hydrofloor,
|
||||
/area/hydroponics/Abandoned_Garden)
|
||||
"edf" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/clothing/head/hardhat/cakehat,
|
||||
/turf/open/floor/plasteel/redyellow,
|
||||
/area/crew_quarters/bar/atrium)
|
||||
"edg" = (
|
||||
/obj/machinery/doorButtons/airlock_controller{
|
||||
idExterior = "virology_airlock_exterior";
|
||||
idInterior = "virology_airlock_interior";
|
||||
idSelf = "virology_airlock_control";
|
||||
name = "Virology Access Console";
|
||||
pixel_x = 0;
|
||||
pixel_y = 22;
|
||||
pixel_x = -10;
|
||||
pixel_y = 24;
|
||||
req_access_txt = "39"
|
||||
},
|
||||
/obj/structure/cable/white{
|
||||
tag = "icon-4-8";
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/open/floor/plasteel{
|
||||
tag = "icon-plasteel_warn_side (WEST)"
|
||||
},
|
||||
/area/medical/virology)
|
||||
"ecg" = (
|
||||
/obj/structure/cable/white,
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/medical/virology)
|
||||
"ech" = (
|
||||
/obj/machinery/button/door{
|
||||
id = "Dorm2";
|
||||
name = "Dormitory Door Lock";
|
||||
normaldoorcontrol = 1;
|
||||
pixel_x = -26;
|
||||
pixel_y = 7;
|
||||
req_access_txt = "0";
|
||||
specialfunctions = 4
|
||||
},
|
||||
/turf/open/floor/wood,
|
||||
/area/crew_quarters/sleep)
|
||||
"eci" = (
|
||||
/obj/machinery/button/door{
|
||||
id = "Dorm4";
|
||||
name = "Dormitory Door Lock";
|
||||
normaldoorcontrol = 1;
|
||||
pixel_x = -26;
|
||||
pixel_y = 7;
|
||||
req_access_txt = "0";
|
||||
specialfunctions = 4
|
||||
},
|
||||
/turf/open/floor/wood,
|
||||
/area/crew_quarters/sleep)
|
||||
"ecj" = (
|
||||
/obj/item/weapon/reagent_containers/food/condiment/saltshaker{
|
||||
pixel_x = -8;
|
||||
pixel_y = 5
|
||||
},
|
||||
/obj/item/weapon/reagent_containers/food/condiment/peppermill{
|
||||
pixel_x = -8
|
||||
},
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/clothing/head/hardhat/cakehat{
|
||||
pixel_x = 4;
|
||||
pixel_y = 3
|
||||
},
|
||||
/turf/open/floor/plasteel/redyellow,
|
||||
/area/crew_quarters/bar/atrium)
|
||||
|
||||
(1,1,1) = {"
|
||||
aaa
|
||||
@@ -149776,7 +149747,7 @@ aic
|
||||
awb
|
||||
awX
|
||||
ayh
|
||||
ech
|
||||
edd
|
||||
azo
|
||||
azo
|
||||
aCw
|
||||
@@ -150024,7 +149995,7 @@ alb
|
||||
amb
|
||||
anl
|
||||
aoj
|
||||
ecc
|
||||
edc
|
||||
aUJ
|
||||
ecd
|
||||
asz
|
||||
@@ -150033,7 +150004,7 @@ auT
|
||||
awc
|
||||
ecf
|
||||
ecg
|
||||
eci
|
||||
ede
|
||||
ecj
|
||||
eck
|
||||
aCx
|
||||
@@ -155695,7 +155666,7 @@ aEf
|
||||
aFB
|
||||
aGX
|
||||
aGY
|
||||
aGY
|
||||
aJA
|
||||
aKZ
|
||||
aMI
|
||||
aGY
|
||||
@@ -155950,7 +155921,7 @@ aBF
|
||||
aCP
|
||||
aEg
|
||||
aFC
|
||||
aGY
|
||||
aGX
|
||||
aGY
|
||||
aJA
|
||||
aLa
|
||||
@@ -156213,9 +156184,9 @@ aJA
|
||||
aLb
|
||||
aMK
|
||||
aGY
|
||||
ecj
|
||||
edf
|
||||
aRH
|
||||
aGY
|
||||
aJA
|
||||
aGY
|
||||
aGZ
|
||||
aYv
|
||||
@@ -165305,7 +165276,7 @@ dGR
|
||||
cKs
|
||||
cKs
|
||||
dJl
|
||||
ecd
|
||||
dJp
|
||||
dKY
|
||||
dJp
|
||||
dJp
|
||||
@@ -165562,9 +165533,9 @@ dGS
|
||||
cDe
|
||||
aaa
|
||||
aaa
|
||||
ece
|
||||
ecf
|
||||
ecg
|
||||
dJp
|
||||
edg
|
||||
dJp
|
||||
aaa
|
||||
aaa
|
||||
dJp
|
||||
@@ -168866,8 +168837,8 @@ cEq
|
||||
cGb
|
||||
cHs
|
||||
cvP
|
||||
cCg
|
||||
eci
|
||||
cCg
|
||||
cNS
|
||||
cxw
|
||||
cvP
|
||||
|
||||
@@ -87,9 +87,9 @@ var/global/list/all_scripture = list() //a list containing scripture instances;
|
||||
|
||||
#define CLOCKCULT_ESCAPE "escape"
|
||||
|
||||
#define CLOCKCULT_SILICONS "silicons"
|
||||
|
||||
//misc clockcult stuff
|
||||
#define MARAUDER_EMERGE_THRESHOLD 65 //marauders cannot emerge unless host is at this% or less health
|
||||
|
||||
#define SIGIL_ACCESS_RANGE 2 //range at which transmission sigils can access power
|
||||
|
||||
#define PROSELYTIZER_REPAIR_PER_TICK 4 //how much a proselytizer repairs each tick, and also how many deciseconds each tick is
|
||||
|
||||
@@ -408,4 +408,4 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
|
||||
#define TURF_DECAL_PAINT "paint"
|
||||
#define TURF_DECAL_DAMAGE "damage"
|
||||
#define TURF_DECAL_DIRT "dirt"
|
||||
#define TURF_DECAL_DIRT "dirt"
|
||||
|
||||
@@ -35,4 +35,4 @@
|
||||
#define MONKEY_HUNT_FRUSTRATION_LIMIT 8 // Chase after an enemy before giving up
|
||||
#define MONKEY_DISPOSE_FRUSTRATION_LIMIT 16 // Dispose of a body before giving up
|
||||
|
||||
#define MONKEY_AGGRESSIVE_MVM_PROB 1 // If you mass edit monkies to be aggressive. there is a small chance of in-fighting
|
||||
#define MONKEY_AGGRESSIVE_MVM_PROB 0 // If you mass edit monkies to be aggressive. there is a small chance of in-fighting
|
||||
@@ -465,3 +465,4 @@
|
||||
#define LAZYADD(L, I) if(!L) { L = list(); } L += I;
|
||||
#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= L.len ? L[I] : null) : L[I]) : null)
|
||||
#define LAZYLEN(L) length(L)
|
||||
#define LAZYCLEARLIST(L) if(L) L.Cut()
|
||||
@@ -38,6 +38,8 @@
|
||||
var/turf_visible
|
||||
if(pixel_turf)
|
||||
turf_visible = cameranet.checkTurfVis(pixel_turf)
|
||||
if(istype(loc, /obj/item/device/aicard) && (pixel_turf in view(client.view, loc)))
|
||||
turf_visible = TRUE
|
||||
if(!turf_visible)
|
||||
log_admin("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)])")
|
||||
message_admins("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))")
|
||||
@@ -184,4 +186,4 @@
|
||||
//
|
||||
|
||||
/mob/living/silicon/ai/TurfAdjacent(var/turf/T)
|
||||
return (cameranet && cameranet.checkTurfVis(T))
|
||||
return (cameranet && cameranet.checkTurfVis(T))
|
||||
@@ -20,8 +20,8 @@
|
||||
var/name = "Configuration" // datum name
|
||||
|
||||
var/server_name = null // server name (the name of the game window)
|
||||
var/server_sql_name = null // short form server name used for the DB
|
||||
var/station_name = null // station name (the name of the station in-game)
|
||||
var/server_suffix = 0 // generate numeric suffix based on server port
|
||||
var/lobby_countdown = 120 // In between round countdown.
|
||||
var/round_end_countdown = 25 // Post round murder death kill countdown
|
||||
var/hub = 0
|
||||
@@ -78,8 +78,7 @@
|
||||
|
||||
var/forbid_singulo_possession = 0
|
||||
var/useircbot = 0
|
||||
var/announce_watchlist = 0
|
||||
var/announce_adminhelps = 0
|
||||
|
||||
var/check_randomizer = 0
|
||||
|
||||
var/allow_panic_bunker_bounce = 0 //Send new players somewhere else
|
||||
@@ -95,6 +94,11 @@
|
||||
|
||||
var/mentors_mobname_only = 0 // Only display mob name to mentors in mentorhelps
|
||||
var/mentor_legacy_system = 0 // Whether to use the legacy mentor system (flat file) instead of SQL
|
||||
// Discord crap.
|
||||
var/discord_url = "hfdksjhfa.com"
|
||||
var/discord_password
|
||||
var/announce_watchlist = 0
|
||||
var/announce_adminhelps = 0
|
||||
|
||||
var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt
|
||||
var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt
|
||||
@@ -242,10 +246,6 @@
|
||||
|
||||
var/list/gamemode_cache = null
|
||||
|
||||
// Discord crap.
|
||||
var/discord_url = "hfdksjhfa.com"
|
||||
var/discord_password
|
||||
|
||||
var/minutetopiclimit
|
||||
var/secondtopiclimit
|
||||
|
||||
@@ -359,10 +359,10 @@
|
||||
config.respawn = 0
|
||||
if("servername")
|
||||
config.server_name = value
|
||||
if("serversqlname")
|
||||
config.server_sql_name = 1
|
||||
if("stationname")
|
||||
config.station_name = value
|
||||
if("serversuffix")
|
||||
config.server_suffix = 1
|
||||
if("hostedby")
|
||||
config.hostedby = value
|
||||
if("server")
|
||||
@@ -499,16 +499,16 @@
|
||||
config.client_error_version = text2num(value)
|
||||
if("client_error_message")
|
||||
config.client_error_message = value
|
||||
if("minute_topic_limit")
|
||||
config.minutetopiclimit = text2num(value)
|
||||
if("second_topic_limit")
|
||||
config.secondtopiclimit = text2num(value)
|
||||
if("announce_adminhelps")
|
||||
config.announce_adminhelps = 1
|
||||
if("discord_url")
|
||||
config.discord_url = value
|
||||
if("discord_password")
|
||||
config.discord_password = value
|
||||
if("minute_topic_limit")
|
||||
config.minutetopiclimit = text2num(value)
|
||||
if("second_topic_limit")
|
||||
config.secondtopiclimit = text2num(value)
|
||||
else
|
||||
diary << "Unknown setting in configuration: '[name]'"
|
||||
|
||||
|
||||
@@ -322,6 +322,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
SS_flags = SS.flags
|
||||
if (SS_flags & SS_NO_FIRE)
|
||||
subsystemstocheck -= SS
|
||||
continue
|
||||
if (!(SS_flags & SS_TICKER) && (SS_flags & SS_KEEP_TIMING) && SS.last_fire + (SS.wait * 0.75) > world.time)
|
||||
continue
|
||||
SS.enqueue()
|
||||
|
||||
@@ -39,28 +39,34 @@ var/datum/subsystem/air/SSair
|
||||
var/list/currentrun = list()
|
||||
var/currentpart = SSAIR_PIPENETS
|
||||
|
||||
var/map_loading = TRUE
|
||||
var/list/queued_for_activation
|
||||
|
||||
/datum/subsystem/air/New()
|
||||
NEW_SS_GLOBAL(SSair)
|
||||
|
||||
/datum/subsystem/air/stat_entry(msg)
|
||||
msg += "C:{"
|
||||
msg += "AT:[round(cost_turfs)]|"
|
||||
msg += "EG:[round(cost_groups)]|"
|
||||
msg += "HP:[round(cost_highpressure)]|"
|
||||
msg += "HS:[round(cost_hotspots)]|"
|
||||
msg += "SC:[round(cost_superconductivity)]|"
|
||||
msg += "PN:[round(cost_pipenets)]|"
|
||||
msg += "AM:[round(cost_atmos_machinery)]"
|
||||
msg += "AT:[round(cost_turfs,1)]|"
|
||||
msg += "EG:[round(cost_groups,1)]|"
|
||||
msg += "HP:[round(cost_highpressure,1)]|"
|
||||
msg += "HS:[round(cost_hotspots,1)]|"
|
||||
msg += "SC:[round(cost_superconductivity,1)]|"
|
||||
msg += "PN:[round(cost_pipenets,1)]|"
|
||||
msg += "AM:[round(cost_atmos_machinery,1)]"
|
||||
msg += "} "
|
||||
msg += "AT:[active_turfs.len]|"
|
||||
msg += "EG:[excited_groups.len]|"
|
||||
msg += "HS:[hotspots.len]|"
|
||||
msg += "AS:[active_super_conductivity.len]"
|
||||
msg += "AT:[active_turfs.len]|"
|
||||
msg += "EG:[excited_groups.len]|"
|
||||
msg += "HS:[hotspots.len]|"
|
||||
msg += "PN:[networks.len]|"
|
||||
msg += "HP:[high_pressure_delta.len]|"
|
||||
msg += "AS:[active_super_conductivity.len]|"
|
||||
msg += "AT/MS:[round((cost ? active_turfs.len/cost : 0),0.1)]"
|
||||
..(msg)
|
||||
|
||||
|
||||
/datum/subsystem/air/Initialize(timeofday)
|
||||
map_loading = FALSE
|
||||
setup_allturfs()
|
||||
setup_atmos_machinery()
|
||||
setup_pipenets()
|
||||
@@ -244,7 +250,6 @@ var/datum/subsystem/air/SSair
|
||||
if(T.excited_group)
|
||||
T.excited_group.garbage_collect()
|
||||
|
||||
|
||||
/datum/subsystem/air/proc/add_to_active(turf/open/T, blockchanges = 1)
|
||||
if(istype(T) && T.air)
|
||||
T.excited = 1
|
||||
@@ -253,10 +258,25 @@ var/datum/subsystem/air/SSair
|
||||
currentrun |= T
|
||||
if(blockchanges && T.excited_group)
|
||||
T.excited_group.garbage_collect()
|
||||
else
|
||||
else if(T.initialized)
|
||||
for(var/turf/S in T.atmos_adjacent_turfs)
|
||||
add_to_active(S)
|
||||
else if(map_loading)
|
||||
if(queued_for_activation)
|
||||
queued_for_activation[T] = T
|
||||
return
|
||||
else
|
||||
T.requires_activation = TRUE
|
||||
|
||||
/datum/subsystem/air/proc/begin_map_load()
|
||||
LAZYINITLIST(queued_for_activation)
|
||||
map_loading = TRUE
|
||||
|
||||
/datum/subsystem/air/proc/end_map_load()
|
||||
map_loading = FALSE
|
||||
for(var/T in queued_for_activation)
|
||||
add_to_active(T)
|
||||
queued_for_activation.Cut()
|
||||
|
||||
/datum/subsystem/air/proc/setup_allturfs()
|
||||
var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz))
|
||||
|
||||
@@ -27,26 +27,52 @@ var/datum/subsystem/objects/SSobj
|
||||
/datum/subsystem/objects/proc/InitializeAtoms(list/objects = null)
|
||||
if(initialized == INITIALIZATION_INSSOBJ)
|
||||
return
|
||||
|
||||
var/list/late_loaders
|
||||
|
||||
initialized = INITIALIZATION_INNEW_MAPLOAD
|
||||
|
||||
if(objects)
|
||||
for(var/I in objects)
|
||||
var/atom/A = I
|
||||
if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
|
||||
var/start_tick = world.time
|
||||
A.Initialize(TRUE)
|
||||
if(A.Initialize(TRUE))
|
||||
LAZYADD(late_loaders, A)
|
||||
if(start_tick != world.time)
|
||||
WARNING("[A]: [A.type] slept during it's Initialize!")
|
||||
CHECK_TICK
|
||||
testing("Initialized [objects.len] atoms")
|
||||
else
|
||||
#ifdef TESTING
|
||||
var/count = 0
|
||||
#endif
|
||||
for(var/atom/A in world)
|
||||
if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
|
||||
var/start_tick = world.time
|
||||
A.Initialize(TRUE)
|
||||
if(A.Initialize(TRUE))
|
||||
LAZYADD(late_loaders, A)
|
||||
#ifdef TESTING
|
||||
else
|
||||
++count
|
||||
#endif TESTING
|
||||
if(start_tick != world.time)
|
||||
WARNING("[A]: [A.type] slept during it's Initialize!")
|
||||
CHECK_TICK
|
||||
testing("Roundstart initialized [count] atoms")
|
||||
|
||||
initialized = INITIALIZATION_INNEW_REGULAR
|
||||
|
||||
if(late_loaders)
|
||||
for(var/I in late_loaders)
|
||||
var/atom/A = I
|
||||
var/start_tick = world.time
|
||||
A.Initialize(FALSE)
|
||||
if(start_tick != world.time)
|
||||
WARNING("[A]: [A.type] slept during it's Initialize!")
|
||||
CHECK_TICK
|
||||
testing("Late-initialized [late_loaders.len] atoms")
|
||||
|
||||
/datum/subsystem/objects/proc/map_loader_begin()
|
||||
old_initialized = initialized
|
||||
initialized = INITIALIZATION_INSSOBJ
|
||||
|
||||
@@ -66,11 +66,11 @@ var/datum/subsystem/throwing/SSthrowing
|
||||
/datum/thrownthing/proc/tick()
|
||||
var/atom/movable/AM = thrownthing
|
||||
if (!isturf(AM.loc) || !AM.throwing)
|
||||
finialize()
|
||||
finalize()
|
||||
return
|
||||
|
||||
if (dist_travelled && hitcheck()) //to catch sneaky things moving on our tile while we slept
|
||||
finialize()
|
||||
finalize()
|
||||
return
|
||||
|
||||
var/atom/step
|
||||
@@ -79,7 +79,7 @@ var/datum/subsystem/throwing/SSthrowing
|
||||
var/tilestomove = round(min(((((world.time+world.tick_lag) - start_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait))
|
||||
while (tilestomove-- > 0)
|
||||
if ((dist_travelled >= maxrange || AM.loc == target_turf) && AM.has_gravity(AM.loc))
|
||||
finialize()
|
||||
finalize()
|
||||
return
|
||||
|
||||
if (dist_travelled <= max(dist_x, dist_y)) //if we haven't reached the target yet we home in on it, otherwise we use the initial direction
|
||||
@@ -93,47 +93,52 @@ var/datum/subsystem/throwing/SSthrowing
|
||||
diagonal_error += (diagonal_error < 0) ? dist_x/2 : -dist_y
|
||||
|
||||
if (!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
|
||||
finialize()
|
||||
finalize()
|
||||
return
|
||||
|
||||
AM.Move(step, get_dir(AM, step))
|
||||
|
||||
if (!AM.throwing) // we hit something during our move
|
||||
finialize(hit = TRUE)
|
||||
finalize(hit = TRUE)
|
||||
return
|
||||
|
||||
dist_travelled++
|
||||
|
||||
if (dist_travelled > MAX_THROWING_DIST)
|
||||
finialize()
|
||||
finalize()
|
||||
return
|
||||
|
||||
/datum/thrownthing/proc/finialize(hit = FALSE)
|
||||
/datum/thrownthing/proc/finalize(hit = FALSE)
|
||||
set waitfor = 0
|
||||
SSthrowing.processing -= thrownthing
|
||||
//done throwing, either because it hit something or it finished moving
|
||||
thrownthing.throwing = 0
|
||||
thrownthing.throwing = null
|
||||
if (!hit)
|
||||
for (var/thing in get_turf(thrownthing)) //looking for our target on the turf we land on.
|
||||
var/atom/A = thing
|
||||
if (A == target)
|
||||
hit = 1
|
||||
thrownthing.throw_impact(A)
|
||||
thrownthing.throw_impact(A, src)
|
||||
break
|
||||
if (!hit)
|
||||
thrownthing.throw_impact(get_turf(thrownthing)) // we haven't hit something yet and we still must, let's hit the ground.
|
||||
thrownthing.throw_impact(get_turf(thrownthing), src) // we haven't hit something yet and we still must, let's hit the ground.
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
else
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
if (callback)
|
||||
callback.Invoke()
|
||||
|
||||
/datum/thrownthing/proc/hit_atom(atom/A)
|
||||
thrownthing.throw_impact(A, src)
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
finalize(TRUE)
|
||||
|
||||
/datum/thrownthing/proc/hitcheck()
|
||||
for (var/thing in get_turf(thrownthing))
|
||||
var/atom/movable/AM = thing
|
||||
if (AM == thrownthing)
|
||||
continue
|
||||
if (AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags & ON_BORDER))
|
||||
thrownthing.throwing = 0
|
||||
thrownthing.throw_impact(AM)
|
||||
return 1
|
||||
thrownthing.throwing = null
|
||||
thrownthing.throw_impact(AM, src)
|
||||
return TRUE
|
||||
|
||||
@@ -9,7 +9,10 @@ var/global/datum/getrev/revdata = new()
|
||||
/datum/getrev/New()
|
||||
var/head_file = return_file_text(".git/logs/HEAD")
|
||||
if(SERVERTOOLS && fexists("..\\prtestjob.lk"))
|
||||
testmerge = file2list("..\\prtestjob.lk")
|
||||
var/list/tmp = file2list("..\\prtestjob.lk")
|
||||
for(var/I in tmp)
|
||||
if(I)
|
||||
testmerge |= I
|
||||
var/testlen = max(testmerge.len - 1, 0)
|
||||
var/regex/head_log = new("(\\w{40}) .+> (\\d{10}).+(?=(\n.*(\\w{40}).*){[testlen]}\n*\\Z)")
|
||||
head_log.Find(head_file)
|
||||
@@ -81,4 +84,4 @@ var/global/datum/getrev/revdata = new()
|
||||
if(config.probabilities[ctag] > 0)
|
||||
var/percentage = round(config.probabilities[ctag] / sum * 100, 0.1)
|
||||
src << "[ctag] [percentage]%"
|
||||
return
|
||||
return
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
for(var/L in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]),
|
||||
locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])))
|
||||
var/turf/B = L
|
||||
atoms += B
|
||||
for(var/A in B)
|
||||
atoms += A
|
||||
if(istype(A,/obj/structure/cable))
|
||||
@@ -43,6 +44,7 @@
|
||||
SSobj.InitializeAtoms(atoms)
|
||||
SSmachine.setup_template_powernets(cables)
|
||||
SSair.setup_template_machinery(atmos_machines)
|
||||
SSair.end_map_load()
|
||||
|
||||
/datum/map_template/proc/load(turf/T, centered = FALSE)
|
||||
if(centered)
|
||||
@@ -54,8 +56,10 @@
|
||||
if(T.y+height > world.maxy)
|
||||
return
|
||||
|
||||
SSair.begin_map_load()
|
||||
var/list/bounds = maploader.load_map(get_file(), T.x, T.y, T.z, cropMap=TRUE)
|
||||
if(!bounds)
|
||||
SSair.end_map_load()
|
||||
return 0
|
||||
|
||||
//initialize things that are normally initialized after map load
|
||||
|
||||
@@ -297,3 +297,75 @@
|
||||
handle_vehicle_offsets()
|
||||
else
|
||||
user << "<span class='notice'>You'll need something to guide the [ridden.name].</span>"
|
||||
|
||||
//CYBORGS. NO, THEY ARE NOT ANIMALS.
|
||||
/datum/riding/cyborg
|
||||
keytype = null
|
||||
vehicle_move_delay = 1
|
||||
|
||||
/datum/riding/cyborg/proc/ride_check(mob/user)
|
||||
if(user.incapacitated())
|
||||
var/kick = TRUE
|
||||
if(istype(ridden, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = ridden
|
||||
if(R.module && R.module.ride_allow_incapacitated)
|
||||
kick = FALSE
|
||||
if(kick)
|
||||
user << "<span class='userdanger'>You fall off of [ridden]!</span>"
|
||||
ridden.unbuckle_mob(user)
|
||||
return
|
||||
if(istype(user, /mob/living/carbon))
|
||||
var/mob/living/carbon/carbonuser = user
|
||||
if(!carbonuser.get_num_arms())
|
||||
ridden.unbuckle_mob(user)
|
||||
user << "<span class='userdanger'>You can't grab onto [ridden] with no hands!</span>"
|
||||
return
|
||||
|
||||
/datum/riding/cyborg/handle_vehicle_layer()
|
||||
if(ridden.dir == SOUTH)
|
||||
ridden.layer = ABOVE_MOB_LAYER
|
||||
else
|
||||
ridden.layer = OBJ_LAYER
|
||||
if(!ridden.buckled_mobs)
|
||||
ridden.layer = MOB_LAYER
|
||||
|
||||
/datum/riding/cyborg/handle_vehicle_offsets()
|
||||
if(ridden.has_buckled_mobs())
|
||||
for(var/mob/living/M in ridden.buckled_mobs)
|
||||
M.setDir(ridden.dir)
|
||||
if(iscyborg(ridden))
|
||||
var/mob/living/silicon/robot/R = ridden
|
||||
if(istype(R.module))
|
||||
M.pixel_x = R.module.ride_offset_x[dir2text(ridden.dir)]
|
||||
M.pixel_y = R.module.ride_offset_y[dir2text(ridden.dir)]
|
||||
else
|
||||
switch(ridden.dir)
|
||||
if(NORTH)
|
||||
M.pixel_x = 0
|
||||
M.pixel_y = 4
|
||||
if(SOUTH)
|
||||
M.pixel_x = 0
|
||||
M.pixel_y = 4
|
||||
if(EAST)
|
||||
M.pixel_x = -6
|
||||
M.pixel_y = 3
|
||||
if(WEST)
|
||||
M.pixel_x = 6
|
||||
M.pixel_y = 3
|
||||
|
||||
/datum/riding/cyborg/proc/on_vehicle_move()
|
||||
for(var/mob/living/M in ridden.buckled_mobs)
|
||||
ride_check(M)
|
||||
handle_vehicle_offsets()
|
||||
handle_vehicle_layer()
|
||||
|
||||
/datum/riding/cyborg/proc/force_dismount()
|
||||
for(var/mob/living/M in ridden.buckled_mobs)
|
||||
ridden.unbuckle_mob(M)
|
||||
var/turf/target = get_edge_target_turf(ridden, ridden.dir)
|
||||
var/turf/targetm = get_step(get_turf(ridden), ridden.dir)
|
||||
M.Move(targetm)
|
||||
M.visible_message("<span class='boldwarning'>[M] is thrown clear of [ridden] by rapid spinning!</span>")
|
||||
M.throw_at(target, 14, 5, ridden)
|
||||
M.Weaken(3)
|
||||
|
||||
|
||||
@@ -73,6 +73,19 @@
|
||||
admin_notes = "Due to the limited space for non paying crew, this shuttle may cause a riot."
|
||||
credit_cost = 10000
|
||||
|
||||
|
||||
/datum/map_template/shuttle/emergency/arena
|
||||
suffix = "arena"
|
||||
name = "The Arena"
|
||||
description = "The crew must pass through an otherworldy arena to board this shuttle. Expect massive casualties. The source of the Bloody Signal must be tracked down and eliminated to unlock this shuttle."
|
||||
admin_notes = "RIP AND TEAR."
|
||||
credit_cost = 10000
|
||||
|
||||
/datum/map_template/shuttle/emergency/arena/prerequisites_met()
|
||||
if("bubblegum" in SSshuttle.shuttle_purchase_requirements_met)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/map_template/shuttle/emergency/birdboat
|
||||
suffix = "birdboat"
|
||||
name = "Birdboat Station Emergency Shuttle"
|
||||
@@ -104,7 +117,6 @@
|
||||
\n\
|
||||
Contains contraband armory guns, maintenance loot, and abandoned crates!"
|
||||
admin_notes = "Due to origin as a solo piloted secure vessel, has an active GPS onboard labeled STV5."
|
||||
credit_cost = -7500
|
||||
|
||||
/datum/map_template/shuttle/emergency/meta
|
||||
suffix = "meta"
|
||||
@@ -160,8 +172,8 @@
|
||||
/datum/map_template/shuttle/emergency/goon
|
||||
suffix = "goon"
|
||||
name = "NES Port"
|
||||
description = "The Nanotrasen Emergency Shuttle Port(NES Port for short) is a shuttle used at other less known nanotrasen facilities and has a more open inside for larger crowds."
|
||||
credit_cost = 3000
|
||||
description = "The Nanotrasen Emergency Shuttle Port(NES Port for short) is a shuttle used at other less known Nanotrasen facilities and has a more open inside for larger crowds, but fewer onboard shuttle facilities."
|
||||
credit_cost = 500
|
||||
|
||||
/datum/map_template/shuttle/emergency/wabbajack
|
||||
suffix = "wabbajack"
|
||||
@@ -219,4 +231,4 @@
|
||||
name = "Delta Station Emergency Shuttle"
|
||||
description = "A large shuttle for a large station, this shuttle can comfortably fit all your overpopulation and crowding needs. Complete with all facilities plus additional equipment."
|
||||
admin_notes = "Go big or go home."
|
||||
credit_cost = 7500
|
||||
credit_cost = 7500
|
||||
@@ -41,11 +41,26 @@
|
||||
if(luminosity)
|
||||
light = new(src)
|
||||
|
||||
var/initialized = SSobj.initialized
|
||||
if(initialized > INITIALIZATION_INSSOBJ)
|
||||
Initialize(initialized == INITIALIZATION_INNEW_MAPLOAD)
|
||||
var/do_initialize = SSobj.initialized
|
||||
if(do_initialize > INITIALIZATION_INSSOBJ)
|
||||
Initialize(do_initialize == INITIALIZATION_INNEW_MAPLOAD)
|
||||
//. = ..() //uncomment if you are dumb enough to add a /datum/New() proc
|
||||
|
||||
//Called after New if the map is being loaded. mapload = TRUE
|
||||
//Called from base of New if the map is being loaded. mapload = FALSE
|
||||
//This base must be called or derivatives must set initialized to TRUE to prevent repeat calls
|
||||
//Derivatives must not sleep
|
||||
//Returning TRUE while mapload is TRUE will cause the object to be initialized again with mapload = FALSE when everything else is done
|
||||
//(Useful for things that requires turfs to have air). This base may only be called once, however
|
||||
|
||||
//Note: the following functions don't call the base for optimization and must copypasta:
|
||||
// /turf/Initialize
|
||||
// /turf/open/space/Initialize
|
||||
/atom/proc/Initialize(mapload)
|
||||
if(initialized)
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
initialized = TRUE
|
||||
|
||||
/atom/Destroy()
|
||||
if(alternate_appearances)
|
||||
for(var/aakey in alternate_appearances)
|
||||
@@ -435,17 +450,6 @@ var/list/blood_splatter_icons = list()
|
||||
sleep(1)
|
||||
stoplag()
|
||||
|
||||
//Called after New if the world is not loaded with TRUE
|
||||
//Called from base of New if the world is loaded with FALSE
|
||||
//This base must be called or derivatives must set initialized to TRUE to prevent repeat calls
|
||||
//Derivatives must not sleep
|
||||
/atom/proc/Initialize(mapload)
|
||||
#ifdef TESTING
|
||||
if(initialized)
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
#endif
|
||||
initialized = TRUE
|
||||
|
||||
//the vision impairment to give to the mob whose perspective is set to that atom (e.g. an unfocused camera giving you an impaired vision when looking through it)
|
||||
/atom/proc/get_remote_view_fullscreens(mob/user)
|
||||
return
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer = OBJ_LAYER
|
||||
var/last_move = null
|
||||
var/anchored = 0
|
||||
var/throwing = 0
|
||||
var/datum/thrownthing/throwing = null
|
||||
var/throw_speed = 2 //How many tiles to move per ds when being thrown. Float values are fully supported
|
||||
var/throw_range = 7
|
||||
var/mob/pulledby = null
|
||||
@@ -130,14 +130,12 @@
|
||||
/atom/movable/Bump(atom/A, yes) //the "yes" arg is to differentiate our Bump proc from byond's, without it every Bump() call would become a double Bump().
|
||||
if((A && yes))
|
||||
if(throwing)
|
||||
throwing = 0
|
||||
throw_impact(A)
|
||||
throwing.hit_atom(A)
|
||||
. = 1
|
||||
if(!A || QDELETED(A))
|
||||
return
|
||||
A.Bumped(src)
|
||||
|
||||
|
||||
/atom/movable/proc/forceMove(atom/destination)
|
||||
if(destination)
|
||||
if(pulledby)
|
||||
@@ -222,7 +220,7 @@
|
||||
/atom/movable/proc/checkpass(passflag)
|
||||
return pass_flags&passflag
|
||||
|
||||
/atom/movable/proc/throw_impact(atom/hit_atom)
|
||||
/atom/movable/proc/throw_impact(atom/hit_atom, throwingdatum)
|
||||
return hit_atom.hitby(src)
|
||||
|
||||
/atom/movable/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked)
|
||||
@@ -297,7 +295,7 @@
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
|
||||
throwing = 1
|
||||
throwing = TT
|
||||
if(spin)
|
||||
SpinAnimation(5, 1)
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
E.sight_flags -= SEE_MOBS
|
||||
E.flash_protect = 2
|
||||
user << "We adjust our eyes to protect them from bright lights."
|
||||
user.update_sight()
|
||||
else
|
||||
user << "We can't adjust our eyes if we don't have any!"
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "arm_blade"
|
||||
item_state = "arm_blade"
|
||||
flags = ABSTRACT | NODROP
|
||||
flags = ABSTRACT | NODROP | DROPDEL
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
force = 25
|
||||
throwforce = 0 //Just to be on the safe side
|
||||
@@ -203,7 +203,6 @@
|
||||
..()
|
||||
if(can_drop)
|
||||
new /obj/item/weapon/melee/synthetic_arm_blade(get_turf(user))
|
||||
qdel(src)
|
||||
|
||||
/***************************************\
|
||||
|***********COMBAT TENTACLES*************|
|
||||
@@ -303,11 +302,10 @@
|
||||
for(var/obj/item/I in H.held_items)
|
||||
if(I.is_sharp())
|
||||
C.visible_message("<span class='danger'>[H] impales [C] with [H.p_their()] [I.name]!</span>", "<span class='userdanger'>[H] impales you with [H.p_their()] [I.name]!</span>")
|
||||
C.apply_damage(I.force*2, BRUTE, "chest")
|
||||
C.apply_damage(I.force, BRUTE, "chest")
|
||||
H.do_item_attack_animation(C, used_item = I)
|
||||
H.add_mob_blood(C)
|
||||
playsound(get_turf(H),I.hitsound,75,1)
|
||||
C.Weaken(4)
|
||||
return
|
||||
|
||||
/obj/item/projectile/tentacle/on_hit(atom/target, blocked = 0)
|
||||
@@ -355,7 +353,6 @@
|
||||
|
||||
if(INTENT_HARM)
|
||||
C.visible_message("<span class='danger'>[L] is thrown towards [H] by a tentacle!</span>","<span class='userdanger'>A tentacle grabs you and throws you towards [H]!</span>")
|
||||
C.Weaken(3)
|
||||
C.throw_at(get_step_towards(H,C), 8, 2, callback=CALLBACK(src, .proc/tentacle_stab, H, C))
|
||||
return 1
|
||||
else
|
||||
|
||||
@@ -84,8 +84,6 @@ Credit where due:
|
||||
|
||||
/datum/game_mode
|
||||
var/list/servants_of_ratvar = list() //The Enlightened servants of Ratvar
|
||||
var/required_escapees = 0 //How many servants need to escape, if applicable
|
||||
var/required_silicon_converts = 0 //How many robotic lifeforms need to be converted, if applicable
|
||||
var/clockwork_objective = CLOCKCULT_GATEWAY //The objective that the servants must fulfill
|
||||
var/clockwork_explanation = "Construct a Gateway to the Celestial Derelict and free Ratvar." //The description of the current objective
|
||||
|
||||
@@ -141,20 +139,12 @@ Credit where due:
|
||||
|
||||
/datum/game_mode/clockwork_cult/proc/forge_clock_objectives() //Determine what objective that Ratvar's servants will fulfill
|
||||
var/list/possible_objectives = list(CLOCKCULT_ESCAPE, CLOCKCULT_GATEWAY)
|
||||
var/silicons_possible = FALSE
|
||||
for(var/mob/living/silicon/ai/S in living_mob_list)
|
||||
silicons_possible = TRUE
|
||||
if(silicons_possible)
|
||||
possible_objectives += CLOCKCULT_SILICONS
|
||||
clockwork_objective = pick(possible_objectives)
|
||||
switch(clockwork_objective)
|
||||
if(CLOCKCULT_ESCAPE)
|
||||
required_escapees = round(max(1, roundstart_player_count / 3)) //33% of the player count must be cultists
|
||||
clockwork_explanation = "Ensure that [required_escapees] servants of Ratvar escape from [station_name()]."
|
||||
clockwork_explanation = "Construct a Gateway to the Celestial Derelict and proselytize the entire station."
|
||||
if(CLOCKCULT_GATEWAY)
|
||||
clockwork_explanation = "Construct a Gateway to the Celestial Derelict and free Ratvar."
|
||||
if(CLOCKCULT_SILICONS)
|
||||
clockwork_explanation = "Ensure that all active silicon-based lifeforms on [station_name()] are servants of Ratvar and Application scripture is unlocked."
|
||||
return 1
|
||||
|
||||
/datum/game_mode/clockwork_cult/proc/greet_servant(mob/M) //Description of their role
|
||||
@@ -199,27 +189,8 @@ Credit where due:
|
||||
/datum/game_mode/clockwork_cult/proc/check_clockwork_victory()
|
||||
switch(clockwork_objective)
|
||||
if(CLOCKCULT_ESCAPE)
|
||||
var/surviving_servants = 0
|
||||
for(var/datum/mind/M in servants_of_ratvar)
|
||||
if(M.current && M.current.stat != DEAD && (M.current.onCentcom() || M.current.onSyndieBase()))
|
||||
surviving_servants++
|
||||
clockwork_explanation = "Ensure that [required_escapees] servant(s) of Ratvar escape from [station_name()].<br><i><b>[surviving_servants]</b> managed to escape!</i>"
|
||||
if(surviving_servants >= required_escapees)
|
||||
ticker.news_report = CULT_ESCAPE
|
||||
return TRUE
|
||||
if(CLOCKCULT_SILICONS)
|
||||
var/total_silicons = 0
|
||||
var/valid_silicons = 0
|
||||
for(var/mob/living/silicon/S in mob_list) //Only check robots and AIs
|
||||
if(isAI(S) || iscyborg(S))
|
||||
total_silicons++
|
||||
if(is_servant_of_ratvar(S) || S.stat == DEAD)
|
||||
valid_silicons++
|
||||
clockwork_explanation = "Ensure that all active silicon-based lifeforms on [station_name()] are servants of Ratvar and Application scripture is unlocked.<br>\
|
||||
<i><b>[valid_silicons]/[total_silicons]</b> silicons were killed or converted!"
|
||||
var/list/scripture_states = scripture_unlock_check()
|
||||
if(valid_silicons >= total_silicons && scripture_states[SCRIPTURE_APPLICATION])
|
||||
ticker.news_report = CLOCK_SILICONS
|
||||
if(clockwork_gateway_activated)
|
||||
ticker.news_report = CLOCK_PROSELYTIZATION
|
||||
return TRUE
|
||||
if(CLOCKCULT_GATEWAY)
|
||||
if(ratvar_awakens)
|
||||
@@ -241,18 +212,16 @@ Credit where due:
|
||||
feedback_set_details("round_end_result", "win - servants completed their objective ([clockwork_objective])")
|
||||
else
|
||||
var/half_victory = FALSE
|
||||
if(clockwork_objective == CLOCKCULT_GATEWAY)
|
||||
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = locate() in all_clockwork_objects
|
||||
if(G)
|
||||
half_victory = TRUE
|
||||
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = locate() in all_clockwork_objects
|
||||
if(G)
|
||||
half_victory = TRUE
|
||||
if(half_victory)
|
||||
text += "<span class='large_brass'><b>The crew escaped before Ratvar could rise, but the gateway was successfully constructed!</b></span>"
|
||||
text += "<span class='large_brass'><b>The crew escaped before [clockwork_objective == CLOCKCULT_GATEWAY ? "Ratvar could rise":"the station could be proselytized"], but the gateway \
|
||||
was successfully constructed!</b></span>"
|
||||
feedback_set_details("round_end_result", "halfwin - round ended before the gateway finished")
|
||||
else
|
||||
text += "<span class='userdanger'>Ratvar's servants have failed!</span>"
|
||||
feedback_set_details("round_end_result", "loss - servants failed their objective ([clockwork_objective])")
|
||||
if(clockwork_gateway_activated && clockwork_objective != CLOCKCULT_GATEWAY)
|
||||
ticker.news_report = CLOCK_PROSELYTIZATION
|
||||
text += "<br><b>The servants' objective was:</b> <br>[clockwork_explanation]"
|
||||
text += "<br>Ratvar's servants had <b>[clockwork_caches]</b> Tinkerer's Caches."
|
||||
text += "<br><b>Construction Value(CV)</b> was: <b>[clockwork_construction_value]</b>"
|
||||
|
||||
@@ -159,11 +159,10 @@
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/accession/post_channel(mob/living/L)
|
||||
if(L.isloyal())
|
||||
var/mob/living/carbon/C = L
|
||||
delete_on_finish = TRUE
|
||||
C.visible_message("<span class='warning'>[C] visibly trembles!</span>", \
|
||||
L.visible_message("<span class='warning'>[L] visibly trembles!</span>", \
|
||||
"<span class='sevtug'>[text2ratvar("You will be mine and his. This puny trinket will not stop me.")]</span>")
|
||||
for(var/obj/item/weapon/implant/mindshield/M in C.implants)
|
||||
for(var/obj/item/weapon/implant/mindshield/M in L.implants)
|
||||
qdel(M)
|
||||
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
/obj/item/stack/tile/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(source)
|
||||
return FALSE
|
||||
return list("operation_time" = amount, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_FLOOR), "spawn_dir" = SOUTH)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_FLOOR), "spawn_dir" = SOUTH)
|
||||
|
||||
//Airlock conversion
|
||||
/obj/machinery/door/airlock/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
@@ -263,42 +263,18 @@
|
||||
//Hitting a clockwork structure will try to repair it.
|
||||
/obj/structure/destructible/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
. = TRUE
|
||||
if(!can_be_repaired)
|
||||
user << "<span class='warning'>[src] cannot be repaired!</span>"
|
||||
return
|
||||
if(obj_integrity >= max_integrity)
|
||||
user << "<span class='warning'>[src] is at maximum integrity!</span>"
|
||||
return
|
||||
var/amount_to_heal = max_integrity - obj_integrity
|
||||
var/healing_for_cycle = min(amount_to_heal, repair_amount)
|
||||
var/power_required = round(healing_for_cycle*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)
|
||||
if(!healing_for_cycle || (!proselytizer.can_use_power(RATVAR_POWER_CHECK) && !proselytizer.can_use_power(power_required)))
|
||||
user << "<span class='warning'>You need at least <b>[power_required]W</b> power to start repairing [src], and at least \
|
||||
<b>[round(amount_to_heal*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)]W</b> to fully repair it!</span>"
|
||||
var/list/repair_values = list()
|
||||
if(!proselytizer.proselytizer_repair_checks(repair_values, src, user))
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user]'s [proselytizer.name] starts covering [src] in glowing orange energy...</span>", \
|
||||
"<span class='alloy'>You start repairing [src]...</span>")
|
||||
//hugeass while because we need to re-check after the do_after
|
||||
proselytizer.repairing = src
|
||||
while(proselytizer && user && src && obj_integrity < max_integrity)
|
||||
amount_to_heal = max_integrity - obj_integrity
|
||||
if(amount_to_heal <= 0)
|
||||
while(proselytizer && user && src)
|
||||
if(!do_after(user, repair_values["healing_for_cycle"] * proselytizer.speed_multiplier, target = src, \
|
||||
extra_checks = CALLBACK(proselytizer, /obj/item/clockwork/clockwork_proselytizer.proc/proselytizer_repair_checks, repair_values, src, user, TRUE)))
|
||||
break
|
||||
healing_for_cycle = min(amount_to_heal, repair_amount)
|
||||
power_required = round(healing_for_cycle*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)
|
||||
if(!healing_for_cycle || (!proselytizer.can_use_power(RATVAR_POWER_CHECK) && !proselytizer.can_use_power(power_required)) || \
|
||||
!do_after(user, healing_for_cycle * proselytizer.speed_multiplier, target = src) || \
|
||||
!proselytizer || (!proselytizer.can_use_power(RATVAR_POWER_CHECK) && !proselytizer.can_use_power(power_required)))
|
||||
break
|
||||
amount_to_heal = max_integrity - obj_integrity
|
||||
if(amount_to_heal <= 0)
|
||||
break
|
||||
healing_for_cycle = min(amount_to_heal, repair_amount)
|
||||
power_required = round(healing_for_cycle*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)
|
||||
if(!healing_for_cycle || (!proselytizer.can_use_power(RATVAR_POWER_CHECK) && !proselytizer.can_use_power(power_required)))
|
||||
break
|
||||
obj_integrity = Clamp(obj_integrity + healing_for_cycle, 0, max_integrity)
|
||||
proselytizer.modify_stored_power(-power_required)
|
||||
obj_integrity = Clamp(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity)
|
||||
proselytizer.modify_stored_power(-repair_values["power_required"])
|
||||
playsound(src, 'sound/machines/click.ogg', 50, 1)
|
||||
|
||||
if(proselytizer)
|
||||
@@ -309,42 +285,18 @@
|
||||
|
||||
//Proselytizer mob heal proc, to avoid as much copypaste as possible.
|
||||
/mob/living/proc/proselytizer_heal(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(!is_servant_of_ratvar(src))
|
||||
user << "<span class='warning'>[src] does not serve Ratvar!</span>"
|
||||
return FALSE
|
||||
if(health >= maxHealth || (flags & GODMODE))
|
||||
user << "<span class='warning'>[src == user ? "You" : "[src]"] [src == user ? "are" : "is"] at maximum health!</span>"
|
||||
return FALSE
|
||||
var/amount_to_heal = maxHealth - health
|
||||
var/healing_for_cycle = min(amount_to_heal, 4)
|
||||
var/power_required = round(healing_for_cycle*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)
|
||||
if(!healing_for_cycle || (!proselytizer.can_use_power(RATVAR_POWER_CHECK) && !proselytizer.can_use_power(power_required)))
|
||||
user << "<span class='warning'>You need at least <b>[power_required]W</b> power to start repairing[src == user ? " yourself" : " [src]"], and at least \
|
||||
<b>[round(amount_to_heal*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)]W</b> to fully repair [src == user ? "yourself" : "[p_them()]"]!</span>"
|
||||
return FALSE
|
||||
var/list/repair_values = list()
|
||||
if(!proselytizer.proselytizer_repair_checks(repair_values, src, user))
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user]'s [proselytizer.name] starts coverin[src == user ? "g [user.p_them()]" : "g [src]"] in glowing orange energy...</span>", \
|
||||
"<span class='alloy'>You start repairin[src == user ? "g yourself" : "g [src]"]...</span>")
|
||||
//hugeass while because we need to re-check after the do_after
|
||||
proselytizer.repairing = src
|
||||
while(proselytizer && user && src && health < maxHealth)
|
||||
amount_to_heal = maxHealth - health
|
||||
if(amount_to_heal <= 0)
|
||||
while(proselytizer && user && src)
|
||||
if(!do_after(user, repair_values["healing_for_cycle"] * proselytizer.speed_multiplier, target = src, \
|
||||
extra_checks = CALLBACK(proselytizer, /obj/item/clockwork/clockwork_proselytizer.proc/proselytizer_repair_checks, repair_values, src, user, TRUE)))
|
||||
break
|
||||
healing_for_cycle = min(amount_to_heal, 4)
|
||||
power_required = round(healing_for_cycle*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)
|
||||
if(!healing_for_cycle || (!proselytizer.can_use_power(RATVAR_POWER_CHECK) && !proselytizer.can_use_power(power_required)) || \
|
||||
!do_after(user, healing_for_cycle * proselytizer.speed_multiplier, target = src) || \
|
||||
!proselytizer || (!proselytizer.can_use_power(RATVAR_POWER_CHECK) && !proselytizer.can_use_power(power_required)))
|
||||
break
|
||||
amount_to_heal = maxHealth - health
|
||||
if(amount_to_heal <= 0)
|
||||
break
|
||||
healing_for_cycle = min(amount_to_heal, 4)
|
||||
power_required = round(healing_for_cycle*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)
|
||||
if(!healing_for_cycle || (!proselytizer.can_use_power(RATVAR_POWER_CHECK) && !proselytizer.can_use_power(power_required)))
|
||||
break
|
||||
proselytizer_heal_tick(healing_for_cycle)
|
||||
proselytizer.modify_stored_power(-power_required)
|
||||
proselytizer_heal_tick(repair_values["healing_for_cycle"])
|
||||
proselytizer.modify_stored_power(-repair_values["power_required"])
|
||||
playsound(src, 'sound/machines/click.ogg', 50, 1)
|
||||
|
||||
if(proselytizer)
|
||||
@@ -382,14 +334,17 @@
|
||||
if(health < maxHealth && !(flags & GODMODE))
|
||||
user.visible_message("<span class='notice'>[user]'s [proselytizer.name] starts coverin[src == user ? "g [user.p_them()]" : "g [src]"] in glowing orange energy...</span>", \
|
||||
"<span class='alloy'>You start repairin[src == user ? "g yourself" : "g [src]"]...</span>")
|
||||
proselytizer.repairing = src
|
||||
if(do_after(user,80*proselytizer.speed_multiplier, target=src))
|
||||
adjustHealth(-maxHealth)
|
||||
user.visible_message("<span class='notice'>[user]'s [proselytizer.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.</span>", \
|
||||
"<span class='alloy'>You finish repairin[src == user ? "g yourself" : "g [src]"].</span>")
|
||||
if(proselytizer)
|
||||
proselytizer.repairing = null
|
||||
else
|
||||
user << "<span class='warning'>[src == user ? "You" : "[src]"] [src == user ? "are" : "is"] at maximum health!</span>"
|
||||
|
||||
//Convert shards and replicant alloy directly to power
|
||||
//Convert shards and gear bits directly to power
|
||||
/obj/item/clockwork/alloy_shards/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "power_cost" = -POWER_STANDARD, "spawn_dir" = SOUTH)
|
||||
|
||||
@@ -404,6 +359,3 @@
|
||||
|
||||
/obj/item/clockwork/alloy_shards/small/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "power_cost" = -(CLOCKCULT_POWER_UNIT*0.02), "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/item/clockwork/component/replicant_alloy/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "power_cost" = -CLOCKCULT_POWER_UNIT, "spawn_dir" = SOUTH)
|
||||
|
||||
@@ -196,22 +196,17 @@
|
||||
if(proselytize_values["power_cost"] > 0)
|
||||
proselytize_values["power_cost"] *= 2
|
||||
|
||||
if(!can_use_power(proselytize_values["power_cost"]))
|
||||
if(stored_power - proselytize_values["power_cost"] < 0)
|
||||
user << "<span class='warning'>You need <b>[proselytize_values["power_cost"]]W</b> power to proselytize [target]!</span>"
|
||||
else if(stored_power - proselytize_values["power_cost"] > max_power)
|
||||
user << "<span class='warning'>Your [name] contains too much power to proselytize [target]!</span>"
|
||||
var/target_type = target.type
|
||||
|
||||
if(!proselytize_checks(proselytize_values, target, target_type, user))
|
||||
return FALSE
|
||||
|
||||
proselytize_values["operation_time"] *= speed_multiplier
|
||||
|
||||
playsound(target, 'sound/machines/click.ogg', 50, 1)
|
||||
if(proselytize_values["operation_time"])
|
||||
var/target_type = target.type
|
||||
user.visible_message("<span class='warning'>[user]'s [name] begins tearing apart [target]!</span>", "<span class='brass'>You begin proselytizing [target]...</span>")
|
||||
if(!do_after(user, proselytize_values["operation_time"], target = target))
|
||||
return FALSE
|
||||
if(repairing || !can_use_power(proselytize_values["power_cost"]) || !target || target.type != target_type) //Check again to prevent bypassing via spamclick
|
||||
if(!do_after(user, proselytize_values["operation_time"], target = target, extra_checks = CALLBACK(src, .proc/proselytize_checks, proselytize_values, target, target_type, user, TRUE)))
|
||||
return FALSE
|
||||
user.visible_message("<span class='warning'>[user]'s [name] covers [target] in golden energy!</span>", "<span class='brass'>You proselytize [target].</span>")
|
||||
else
|
||||
@@ -234,3 +229,64 @@
|
||||
if(no_table_check)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/proc/proselytize_checks(list/proselytize_values, atom/target, expected_type, mob/user, silent) //checked constantly while proselytizing
|
||||
if(!islist(proselytize_values) || !target || QDELETED(target) || !user)
|
||||
return FALSE
|
||||
if(repairing)
|
||||
return FALSE
|
||||
if(target.type != expected_type)
|
||||
return FALSE
|
||||
if(can_use_power(RATVAR_POWER_CHECK))
|
||||
proselytize_values["power_cost"] = 0
|
||||
if(!can_use_power(proselytize_values["power_cost"]))
|
||||
if(stored_power - proselytize_values["power_cost"] < 0)
|
||||
if(!silent)
|
||||
user << "<span class='warning'>You need <b>[proselytize_values["power_cost"]]W</b> power to proselytize [target]!</span>"
|
||||
else if(stored_power - proselytize_values["power_cost"] > max_power)
|
||||
if(!silent)
|
||||
user << "<span class='warning'>Your [name] contains too much power to proselytize [target]!</span>"
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//The repair check proc.
|
||||
//Is dark magic. Can probably kill you.
|
||||
/obj/item/clockwork/clockwork_proselytizer/proc/proselytizer_repair_checks(list/repair_values, atom/target, mob/user, silent) //Exists entirely to avoid an otherwise unreadable series of checks.
|
||||
if(!islist(repair_values) || !target || QDELETED(target) || !user)
|
||||
return FALSE
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(!is_servant_of_ratvar(L))
|
||||
if(!silent)
|
||||
user << "<span class='warning'>[L] does not serve Ratvar!</span>"
|
||||
return FALSE
|
||||
if(L.health >= L.maxHealth || (L.flags & GODMODE))
|
||||
if(!silent)
|
||||
user << "<span class='warning'>[L == user ? "You are" : "[L] is"] at maximum health!</span>"
|
||||
return FALSE
|
||||
repair_values["amount_to_heal"] = L.maxHealth - L.health
|
||||
else if(isobj(target))
|
||||
if(istype(target, /obj/structure/destructible/clockwork))
|
||||
var/obj/structure/destructible/clockwork/C = target
|
||||
if(!C.can_be_repaired)
|
||||
if(!silent)
|
||||
user << "<span class='warning'>[C] cannot be repaired!</span>"
|
||||
return FALSE
|
||||
var/obj/O = target
|
||||
if(O.obj_integrity >= O.max_integrity)
|
||||
if(!silent)
|
||||
user << "<span class='warning'>[O] is at maximum integrity!</span>"
|
||||
return FALSE
|
||||
repair_values["amount_to_heal"] = O.max_integrity - O.obj_integrity
|
||||
else
|
||||
return FALSE
|
||||
if(repair_values["amount_to_heal"] <= 0)
|
||||
return FALSE
|
||||
repair_values["healing_for_cycle"] = min(repair_values["amount_to_heal"], PROSELYTIZER_REPAIR_PER_TICK)
|
||||
repair_values["power_required"] = round(repair_values["healing_for_cycle"]*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)
|
||||
if(!can_use_power(RATVAR_POWER_CHECK) && !can_use_power(repair_values["power_required"]))
|
||||
if(!silent)
|
||||
user << "<span class='warning'>You need at least <b>[repair_values["power_required"]]W</b> power to start repairin[target == user ? "g yourself" : "g [target]"], and at least \
|
||||
<b>[round(repair_values["amount_to_heal"]*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)]W</b> to fully repair [target == user ? "yourself" : "[target.p_them()]"]!</span>"
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -179,7 +179,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
|
||||
if(!channel_time)
|
||||
return TRUE
|
||||
for(var/invocation in invocations)
|
||||
if(!check_special_requirements() || !do_after(invoker, channel_time / invocations.len, target = invoker) || !check_special_requirements())
|
||||
if(!do_after(invoker, channel_time / invocations.len, target = invoker, extra_checks = CALLBACK(src, .proc/check_special_requirements)))
|
||||
slab.busy = null
|
||||
return FALSE
|
||||
if(multiple_invokers_used)
|
||||
@@ -206,9 +206,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
|
||||
|
||||
/datum/clockwork_scripture/channeled/scripture_effects()
|
||||
for(var/i in 1 to chant_amount)
|
||||
if(!can_recite())
|
||||
break
|
||||
if(!do_after(invoker, chant_interval, target = invoker))
|
||||
if(!do_after(invoker, chant_interval, target = invoker, extra_checks = CALLBACK(src, .proc/can_recite)))
|
||||
break
|
||||
clockwork_say(invoker, text2ratvar(pick(chant_invocations)), whispered)
|
||||
if(!chant_effects(i))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
///////////////
|
||||
|
||||
//Ark of the Clockwork Justiciar: Creates a Gateway to the Celestial Derelict, either summoning ratvar or proselytizing everything.
|
||||
/datum/clockwork_scripture/ark_of_the_clockwork_justiciar
|
||||
/datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar
|
||||
descname = "Structure, Win Condition"
|
||||
name = "Ark of the Clockwork Justiciar"
|
||||
desc = "Tears apart a rift in spacetime to Reebe, the Celestial Derelict.\n\
|
||||
@@ -15,19 +15,21 @@
|
||||
consumed_components = list(BELLIGERENT_EYE = 10, VANGUARD_COGWHEEL = 10, GEIS_CAPACITOR = 10, REPLICANT_ALLOY = 10, HIEROPHANT_ANSIBLE = 10)
|
||||
invokers_required = 5
|
||||
multiple_invokers_used = TRUE
|
||||
object_path = /obj/structure/destructible/clockwork/massive/celestial_gateway
|
||||
creator_message = null
|
||||
usage_tip = "The gateway is completely vulnerable to attack during its five-minute duration. It will periodically give indication of its general position to everyone on the station \
|
||||
as well as being loud enough to be heard throughout the entire sector. Defend it with your life!"
|
||||
tier = SCRIPTURE_JUDGEMENT
|
||||
sort_priority = 1
|
||||
|
||||
/datum/clockwork_scripture/ark_of_the_clockwork_justiciar/New()
|
||||
/datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar/New()
|
||||
if(ticker && ticker.mode && ticker.mode.clockwork_objective != CLOCKCULT_GATEWAY)
|
||||
invocations = list("ARMORER! FRIGHT! AMPERAGE! VANGUARD! I CALL UPON YOU!!", \
|
||||
"THIS STATION WILL BE A BEACON OF HOPE IN THE DARKNESS OF SPACE!!", \
|
||||
"HELP US MAKE THIS SHOW ENGINE'S GLORY!!")
|
||||
..()
|
||||
|
||||
/datum/clockwork_scripture/ark_of_the_clockwork_justiciar/check_special_requirements()
|
||||
/datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar/check_special_requirements()
|
||||
if(!slab.no_cost)
|
||||
if(ratvar_awakens)
|
||||
invoker << "<span class='big_brass'>\"I am already here, idiot.\"</span>"
|
||||
@@ -47,11 +49,4 @@
|
||||
else
|
||||
invoker << "<span class='warning'>Ratvar's recent banishment renders him too weak to be wrung forth from Reebe!</span>"
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/clockwork_scripture/ark_of_the_clockwork_justiciar/scripture_effects()
|
||||
var/turf/T = get_turf(invoker)
|
||||
if(T)
|
||||
new/obj/structure/destructible/clockwork/massive/celestial_gateway(T)
|
||||
return TRUE
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
anchored = 1
|
||||
density = 1
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
var/repair_amount = 4 //how much a proselytizer can repair each cycle
|
||||
var/can_be_repaired = TRUE //if a proselytizer can repair it at all
|
||||
var/can_be_repaired = TRUE //if a proselytizer can repair it
|
||||
break_message = "<span class='warning'>The frog isn't a meme after all!</span>" //The message shown when a structure breaks
|
||||
break_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' //The sound played when a structure breaks
|
||||
debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
|
||||
@@ -72,9 +71,10 @@
|
||||
. *= min(max_integrity/max(obj_integrity, 1), 4)
|
||||
. = round(., 0.01)
|
||||
|
||||
/obj/structure/destructible/clockwork/can_be_unfasten_wrench(mob/user)
|
||||
/obj/structure/destructible/clockwork/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(anchored && obj_integrity <= round(max_integrity * 0.25, 1))
|
||||
user << "<span class='warning'>[src] is too damaged to unsecure!</span>"
|
||||
if(!silent)
|
||||
user << "<span class='warning'>[src] is too damaged to unsecure!</span>"
|
||||
return FAILED_UNFASTEN
|
||||
return ..()
|
||||
|
||||
@@ -158,9 +158,10 @@
|
||||
var/powered = total_accessable_power()
|
||||
return powered == PROCESS_KILL ? 25 : powered //make sure we don't accidentally return the arbitrary PROCESS_KILL define
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/can_be_unfasten_wrench(mob/user)
|
||||
/obj/structure/destructible/clockwork/powered/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(active)
|
||||
user << "<span class='warning'>[src] needs to be disabled before it can be unsecured!</span>"
|
||||
if(!silent)
|
||||
user << "<span class='warning'>[src] needs to be disabled before it can be unsecured!</span>"
|
||||
return FAILED_UNFASTEN
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -74,8 +74,6 @@
|
||||
hierophant_message("<span class='large_brass'><b>A gateway to the Celestial Derelict has been created in [gate_area.map_name]!</b></span>", FALSE, src)
|
||||
if(!objective_is_gateway)
|
||||
ratvar_portal = FALSE
|
||||
hierophant_message("<span class='big_brass'>This newly constructed gateway will not free Ratvar, \
|
||||
and will instead simply proselytize and convert everything and everyone on the station.</span>", TRUE)
|
||||
SSshuttle.registerHostileEnvironment(src)
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
@@ -210,13 +208,14 @@
|
||||
animate(glow, transform = matrix() * 3, alpha = 0, time = 5)
|
||||
var/turf/startpoint = get_turf(src)
|
||||
QDEL_IN(src, 3)
|
||||
clockwork_gateway_activated = TRUE
|
||||
if(ratvar_portal)
|
||||
sleep(3)
|
||||
clockwork_gateway_activated = TRUE
|
||||
new/obj/structure/destructible/clockwork/massive/ratvar(startpoint)
|
||||
else
|
||||
INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency.proc/request, null, 0) //call the shuttle immediately
|
||||
sleep(3)
|
||||
clockwork_gateway_activated = TRUE
|
||||
send_to_playing_players("<span class='ratvar'>\"[text2ratvar("Behold")]!\"</span>\n<span class='inathneq_large'>\"[text2ratvar("See Engine's mercy")]!\"</span>\n\
|
||||
<span class='sevtug_large'>\"[text2ratvar("Observe Engine's design skills")]!\"</span>\n<span class='nezbere_large'>\"[text2ratvar("Behold Engine's light")]!!\"</span>\n\
|
||||
<span class='nzcrentr_large'>\"[text2ratvar("Gaze upon Engine's power")]!\"</span>")
|
||||
@@ -234,13 +233,8 @@
|
||||
dist = FALSE
|
||||
T.ratvar_act(dist)
|
||||
CHECK_TICK
|
||||
for(var/mob/living/silicon/robot/R in silicon_mobs)
|
||||
if(R && R.stat != DEAD && !is_servant_of_ratvar(R))
|
||||
add_servant_of_ratvar(R)
|
||||
for(var/i in ai_list)
|
||||
var/mob/living/silicon/ai/A = i
|
||||
if(A && A.stat != DEAD && !is_servant_of_ratvar(A))
|
||||
add_servant_of_ratvar(A)
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
L.ratvar_act()
|
||||
for(var/I in all_clockwork_mobs)
|
||||
var/mob/M = I
|
||||
if(M.stat == CONSCIOUS)
|
||||
|
||||
@@ -25,9 +25,10 @@
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='nzcrentr_small'>It requires <b>[hierophant_cost]W</b> to broadcast over the Hierophant Network, and <b>[gateway_cost]W</b> to open a Spatial Gateway.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/can_be_unfasten_wrench(mob/user)
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(active)
|
||||
user << "<span class='warning'>[src] is currently sustaining a gateway!</span>"
|
||||
if(!silent)
|
||||
user << "<span class='warning'>[src] is currently sustaining a gateway!</span>"
|
||||
return FAILED_UNFASTEN
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -32,14 +32,16 @@
|
||||
/obj/structure/destructible/clockwork/ocular_warden/hulk_damage()
|
||||
return 25
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/can_be_unfasten_wrench(mob/user)
|
||||
/obj/structure/destructible/clockwork/ocular_warden/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(anchored)
|
||||
if(obj_integrity <= max_integrity * 0.25)
|
||||
user << "<span class='warning'>[src] is too damaged to unsecure!</span>"
|
||||
if(!silent)
|
||||
user << "<span class='warning'>[src] is too damaged to unsecure!</span>"
|
||||
return FAILED_UNFASTEN
|
||||
else
|
||||
for(var/obj/structure/destructible/clockwork/ocular_warden/W in orange(3, src))
|
||||
user << "<span class='neovgre'>You sense another ocular warden too near this location. Activating this one this close would cause them to fight.</span>"
|
||||
if(!silent)
|
||||
user << "<span class='neovgre'>You sense another ocular warden too near this location. Activating this one this close would cause them to fight.</span>"
|
||||
return FAILED_UNFASTEN
|
||||
return SUCCESSFUL_UNFASTEN
|
||||
|
||||
|
||||
@@ -498,9 +498,9 @@ var/list/teleport_runes = list()
|
||||
sleep(40)
|
||||
if(src)
|
||||
color = "#FF0000"
|
||||
new /obj/singularity/narsie/large(T) //Causes Nar-Sie to spawn even if the rune has been removed
|
||||
if(cult_mode)
|
||||
cult_mode.eldergod = 0
|
||||
new /obj/singularity/narsie/large(T) //Causes Nar-Sie to spawn even if the rune has been removed
|
||||
|
||||
/obj/effect/rune/narsie/attackby(obj/I, mob/user, params) //Since the narsie rune takes a long time to make, add logging to removal.
|
||||
if((istype(I, /obj/item/weapon/tome) && iscultist(user)))
|
||||
|
||||
@@ -196,9 +196,32 @@
|
||||
/obj/item/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
return S.Integrate(src)
|
||||
|
||||
/obj/item/proc/IntegrateAmount() //returns the amount of resources gained when eating this item
|
||||
if(materials[MAT_METAL] || materials[MAT_GLASS])
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/gun/swarmer_act()//Stops you from eating the entire armory
|
||||
return FALSE
|
||||
|
||||
/obj/item/clockwork/alloy_shards/IntegrateAmount()
|
||||
return 10
|
||||
|
||||
/obj/item/stack/tile/brass/IntegrateAmount()
|
||||
return 5
|
||||
|
||||
/obj/item/clockwork/alloy_shards/medium/gear_bit/large/IntegrateAmount()
|
||||
return 4
|
||||
|
||||
/obj/item/clockwork/alloy_shards/large/IntegrateAmount()
|
||||
return 3
|
||||
|
||||
/obj/item/clockwork/alloy_shards/medium/IntegrateAmount()
|
||||
return 2
|
||||
|
||||
/obj/item/clockwork/alloy_shards/small/IntegrateAmount()
|
||||
return 1
|
||||
|
||||
/turf/open/floor/swarmer_act()//ex_act() on turf calls it on its contents, this is to prevent attacking mobs by DisIntegrate()'ing the floor
|
||||
return FALSE
|
||||
|
||||
@@ -316,6 +339,10 @@
|
||||
S << "<span class='warning'>This communications relay should be preserved, it will be a useful resource to our masters in the future. Aborting.</span>"
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/deepfryer/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
S << "<span class='warning'>This kitchen appliance should be preserved, it will make delicious unhealthy snacks for our masters in the future. Aborting.</span>"
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/power/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
S << "<span class='warning'>Disrupting the power grid would bring no benefit to us. Aborting.</span>"
|
||||
return FALSE
|
||||
@@ -362,6 +389,10 @@
|
||||
S << "<span class='warning'>This object is receiving unactivated swarmer shells to help us. Aborting.</span>"
|
||||
return FALSE
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
S << "<span class='warning'>This object is multiplying existing resources. Aborting.</span>"
|
||||
return FALSE
|
||||
|
||||
/obj/structure/lattice/catwalk/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
. = ..()
|
||||
var/turf/here = get_turf(src)
|
||||
@@ -373,13 +404,12 @@
|
||||
|
||||
|
||||
/obj/item/device/unactivated_swarmer/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
if(S.resources + 50 > S.max_resources)
|
||||
S << "<span class='warning'>We have too many resources to reconsume this shell. Aborting.</span>"
|
||||
else
|
||||
..()
|
||||
S.resources += 49 //refund the whole thing
|
||||
..()
|
||||
return FALSE //would logically be TRUE, but we don't want AI swarmers eating player spawn chances.
|
||||
|
||||
/obj/item/device/unactivated_swarmer/IntegrateAmount()
|
||||
return 50
|
||||
|
||||
/obj/machinery/hydroponics/soil/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
S << "<span class='warning'>This object does not contain enough materials to work with.</span>"
|
||||
return FALSE
|
||||
@@ -396,13 +426,13 @@
|
||||
return 0
|
||||
return new fabrication_object(loc)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/swarmer/proc/Integrate(obj/item/target)
|
||||
if(resources >= max_resources)
|
||||
var/resource_gain = target.IntegrateAmount()
|
||||
if(resources + resource_gain > max_resources)
|
||||
src << "<span class='warning'>We cannot hold more materials!</span>"
|
||||
return TRUE
|
||||
if((target.materials[MAT_METAL]) || (target.materials[MAT_GLASS]))
|
||||
resources++
|
||||
if(resource_gain)
|
||||
resources += resource_gain
|
||||
do_attack_animation(target)
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
var/obj/effect/overlay/temp/swarmer/integrate/I = new /obj/effect/overlay/temp/swarmer/integrate(get_turf(target))
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
U.hidden_uplink.telecrystals = CHALLENGE_TELECRYSTALS
|
||||
U.hidden_uplink.set_gamemode(/datum/game_mode/nuclear)
|
||||
config.shuttle_refuel_delay = max(config.shuttle_refuel_delay, CHALLENGE_SHUTTLE_DELAY)
|
||||
feedback_set("nuclear_challenge_mode",1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/device/nuclear_challenge/proc/check_allowed(mob/living/user)
|
||||
|
||||
@@ -20,7 +20,7 @@ var/bomb_set
|
||||
density = 1
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
var/timer_set = 60
|
||||
var/timer_set = 90
|
||||
var/default_timer_set = 90
|
||||
var/minimum_timer_set = 90
|
||||
var/maximum_timer_set = 3600
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
/obj/machinery/door/firedoor/attack_hand(mob/user)
|
||||
if(operating || !density)
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
|
||||
user.visible_message("[user] bangs on \the [src].",
|
||||
"You bang on \the [src].")
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
return
|
||||
var/area/A = get_area(src)
|
||||
A.firealert(src)
|
||||
playsound(src.loc, 'sound/ambience/signal.ogg', 75, 0)
|
||||
playsound(src.loc, 'goon/sound/machinery/FireAlarm.ogg', 75, 0)
|
||||
|
||||
/obj/machinery/firealarm/proc/alarm_in(time)
|
||||
addtimer(CALLBACK(src, .proc/alarm), time)
|
||||
|
||||
@@ -356,13 +356,13 @@ Class Procs:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/proc/can_be_unfasten_wrench(mob/user)
|
||||
/obj/proc/can_be_unfasten_wrench(mob/user, silent) //if we can unwrench this object; returns SUCCESSFUL_UNFASTEN and FAILED_UNFASTEN, which are both TRUE, or CANT_UNFASTEN, which isn't.
|
||||
if(!isfloorturf(loc) && !anchored)
|
||||
user << "<span class='warning'>[src] needs to be on the floor to be secured!</span>"
|
||||
return FAILED_UNFASTEN
|
||||
return SUCCESSFUL_UNFASTEN
|
||||
|
||||
/obj/proc/default_unfasten_wrench(mob/user, obj/item/weapon/wrench/W, time = 20)
|
||||
/obj/proc/default_unfasten_wrench(mob/user, obj/item/weapon/wrench/W, time = 20) //try to unwrench an object in a WONDERFUL DYNAMIC WAY
|
||||
if(istype(W) && !(flags & NODECONSTRUCT))
|
||||
var/can_be_unfasten = can_be_unfasten_wrench(user)
|
||||
if(!can_be_unfasten || can_be_unfasten == FAILED_UNFASTEN)
|
||||
@@ -372,10 +372,7 @@ Class Procs:
|
||||
playsound(loc, W.usesound, 50, 1)
|
||||
var/prev_anchored = anchored
|
||||
//as long as we're the same anchored state and we're either on a floor or are anchored, toggle our anchored state
|
||||
if(!time || (do_after(user, time*W.toolspeed, target = src) && anchored == prev_anchored))
|
||||
can_be_unfasten = can_be_unfasten_wrench(user)
|
||||
if(!can_be_unfasten || can_be_unfasten == FAILED_UNFASTEN)
|
||||
return can_be_unfasten
|
||||
if(!time || do_after(user, time*W.toolspeed, target = src, extra_checks = CALLBACK(src, .proc/unfasten_wrench_check, prev_anchored, user)))
|
||||
user << "<span class='notice'>You [anchored ? "un" : ""]secure [src].</span>"
|
||||
anchored = !anchored
|
||||
playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
@@ -383,6 +380,13 @@ Class Procs:
|
||||
return FAILED_UNFASTEN
|
||||
return CANT_UNFASTEN
|
||||
|
||||
/obj/proc/unfasten_wrench_check(prev_anchored, mob/user) //for the do_after, this checks if unfastening conditions are still valid
|
||||
if(anchored != prev_anchored)
|
||||
return FALSE
|
||||
if(can_be_unfasten_wrench(user, TRUE) != SUCCESSFUL_UNFASTEN) //if we aren't explicitly successful, cancel the fuck out
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/proc/exchange_parts(mob/user, obj/item/weapon/storage/part_replacer/W)
|
||||
if(!istype(W))
|
||||
return
|
||||
|
||||
@@ -123,6 +123,8 @@
|
||||
switch(mode)
|
||||
if(1,2,4,5)
|
||||
user << "The display says:<br>\t<xmp>[message1]</xmp><br>\t<xmp>[message2]</xmp>"
|
||||
if(mode == 1 && SSshuttle.emergency)
|
||||
user << "Current Shuttle: [SSshuttle.emergency.name]"
|
||||
|
||||
|
||||
/obj/machinery/status_display/proc/set_message(m1, m2)
|
||||
|
||||
@@ -762,7 +762,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
|
||||
|
||||
/obj/machinery/vending/cigarette
|
||||
name = "\improper ShadyCigs Deluxe"
|
||||
desc = "If you want to get cancer, might as well do it in style"
|
||||
desc = "If you want to get cancer, might as well do it in style."
|
||||
product_slogans = "Space cigs taste good like a cigarette should.;I'd rather toolbox than switch.;Smoke!;Don't believe the reports - smoke today!"
|
||||
product_ads = "Probably not bad for you!;Don't believe the scientists!;It's good for you!;Don't quit, buy more!;Smoke!;Nicotine heaven.;Best cigarettes since 2150.;Award-winning cigs."
|
||||
icon_state = "cigs"
|
||||
|
||||
@@ -358,8 +358,11 @@
|
||||
occupant.throw_alert("mech damage", /obj/screen/alert/low_mech_integrity, 3)
|
||||
else
|
||||
occupant.clear_alert("mech damage")
|
||||
|
||||
if(occupant.loc != src) //something went wrong
|
||||
var/actual_loc = occupant.loc
|
||||
if(istype(actual_loc, /obj/item/device/mmi))
|
||||
var/obj/item/device/mmi/M = actual_loc
|
||||
actual_loc = M.mecha
|
||||
if(actual_loc != src) //something went wrong
|
||||
occupant.clear_alert("charge")
|
||||
occupant.clear_alert("mech damage")
|
||||
RemoveActions(occupant, human_occupant=1)
|
||||
@@ -859,57 +862,58 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/mecha/proc/mmi_move_inside(obj/item/device/mmi/mmi_as_oc,mob/user)
|
||||
/obj/mecha/proc/mmi_move_inside(obj/item/device/mmi/mmi_as_oc, mob/user)
|
||||
if(!mmi_as_oc.brainmob || !mmi_as_oc.brainmob.client)
|
||||
user << "<span class='warning'>Consciousness matrix not detected!</span>"
|
||||
return 0
|
||||
return FALSE
|
||||
else if(mmi_as_oc.brainmob.stat)
|
||||
user << "<span class='warning'>Beta-rhythm below acceptable level!</span>"
|
||||
return 0
|
||||
return FALSE
|
||||
else if(occupant)
|
||||
user << "<span class='warning'>Occupant detected!</span>"
|
||||
return 0
|
||||
else if(dna_lock && (!mmi_as_oc.brainmob.stored_dna || dna_lock!=mmi_as_oc.brainmob.stored_dna.unique_enzymes))
|
||||
return FALSE
|
||||
else if(dna_lock && (!mmi_as_oc.brainmob.stored_dna || (dna_lock != mmi_as_oc.brainmob.stored_dna.unique_enzymes)))
|
||||
user << "<span class='warning'>Access denied. [name] is secured with a DNA lock.</span>"
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
visible_message("<span class='notice'>[user] starts to insert an MMI into [name].</span>")
|
||||
|
||||
if(do_after(user, 40, target = src))
|
||||
if(!occupant)
|
||||
return mmi_moved_inside(mmi_as_oc,user)
|
||||
return mmi_moved_inside(mmi_as_oc, user)
|
||||
else
|
||||
user << "<span class='warning'>Occupant detected!</span>"
|
||||
else
|
||||
user << "<span class='notice'>You stop inserting the MMI.</span>"
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/obj/mecha/proc/mmi_moved_inside(obj/item/device/mmi/mmi_as_oc,mob/user)
|
||||
if(mmi_as_oc && user in range(1))
|
||||
if(!mmi_as_oc.brainmob || !mmi_as_oc.brainmob.client)
|
||||
user << "<span class='notice'>Consciousness matrix not detected!</span>"
|
||||
return 0
|
||||
else if(mmi_as_oc.brainmob.stat)
|
||||
user << "<span class='warning'>Beta-rhythm below acceptable level!</span>"
|
||||
return 0
|
||||
if(!user.transferItemToLoc(mmi_as_oc, src))
|
||||
user << "<span class='warning'>\the [mmi_as_oc] is stuck to your hand, you cannot put it in \the [src]!</span>"
|
||||
return
|
||||
var/mob/brainmob = mmi_as_oc.brainmob
|
||||
occupant = brainmob
|
||||
brainmob.forceMove(src) //should allow relaymove
|
||||
brainmob.reset_perspective(src)
|
||||
brainmob.canmove = 1
|
||||
mmi_as_oc.mecha = src
|
||||
icon_state = initial(icon_state)
|
||||
setDir(dir_in)
|
||||
log_message("[mmi_as_oc] moved in as pilot.")
|
||||
if(!internal_damage)
|
||||
occupant << sound('sound/mecha/nominal.ogg',volume=50)
|
||||
GrantActions(brainmob)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
/obj/mecha/proc/mmi_moved_inside(obj/item/device/mmi/mmi_as_oc, mob/user)
|
||||
if(!(Adjacent(mmi_as_oc) && Adjacent(user)))
|
||||
return FALSE
|
||||
if(!mmi_as_oc.brainmob || !mmi_as_oc.brainmob.client)
|
||||
user << "<span class='notice'>Consciousness matrix not detected!</span>"
|
||||
return FALSE
|
||||
else if(mmi_as_oc.brainmob.stat)
|
||||
user << "<span class='warning'>Beta-rhythm below acceptable level!</span>"
|
||||
return FALSE
|
||||
if(!user.transferItemToLoc(mmi_as_oc, src))
|
||||
user << "<span class='warning'>\the [mmi_as_oc] is stuck to your hand, you cannot put it in \the [src]!</span>"
|
||||
return FALSE
|
||||
var/mob/brainmob = mmi_as_oc.brainmob
|
||||
mmi_as_oc.mecha = src
|
||||
occupant = brainmob
|
||||
brainmob.forceMove(src) //should allow relaymove
|
||||
brainmob.reset_perspective(src)
|
||||
brainmob.remote_control = src
|
||||
brainmob.update_canmove()
|
||||
icon_state = initial(icon_state)
|
||||
update_icon()
|
||||
setDir(dir_in)
|
||||
log_message("[mmi_as_oc] moved in as pilot.")
|
||||
if(!internal_damage)
|
||||
occupant << sound('sound/mecha/nominal.ogg',volume=50)
|
||||
GrantActions(brainmob)
|
||||
return TRUE
|
||||
|
||||
/obj/mecha/container_resist(mob/living/user)
|
||||
go_out()
|
||||
@@ -1046,4 +1050,4 @@ var/year_integer = text2num(year) // = 2013???
|
||||
/obj/mecha/update_remote_sight(mob/living/user)
|
||||
if(occupant_sight_flags)
|
||||
if(user == occupant)
|
||||
user.sight |= occupant_sight_flags
|
||||
user.sight |= occupant_sight_flags
|
||||
@@ -43,10 +43,6 @@
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/mecha/working/ripley/mmi_moved_inside(obj/item/device/mmi/mmi_as_oc,mob/user)
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/mecha/working/ripley/update_icon()
|
||||
..()
|
||||
if (hides)
|
||||
@@ -178,4 +174,4 @@
|
||||
cargo -= O
|
||||
else
|
||||
if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
|
||||
user << "<span class='warning'>You fail to push [O] out of [src]!</span>"
|
||||
user << "<span class='warning'>You fail to push [O] out of [src]!</span>"
|
||||
@@ -104,9 +104,9 @@ list(name = "- Carbon Dioxide", desc = " This informational poster teaches the v
|
||||
icon = 'icons/obj/contraband.dmi'
|
||||
force = 0
|
||||
resistance_flags = FLAMMABLE
|
||||
var/serial_number = 0
|
||||
var/serial = 0
|
||||
var/obj/structure/sign/poster/resulting_poster = null //The poster that will be created is initialised and stored through contraband/poster's constructor
|
||||
var/official = 0
|
||||
var/rolled_official = 0
|
||||
|
||||
|
||||
/obj/item/weapon/poster/contraband
|
||||
@@ -118,20 +118,20 @@ list(name = "- Carbon Dioxide", desc = " This informational poster teaches the v
|
||||
name = "motivational poster"
|
||||
icon_state = "rolled_legit"
|
||||
desc = "An official Nanotrasen-issued poster to foster a compliant and obedient workforce. It comes with state-of-the-art adhesive backing, for easy pinning to any vertical surface."
|
||||
official = 1
|
||||
rolled_official = 1
|
||||
|
||||
/obj/item/weapon/poster/New(turf/loc, given_serial = 0)
|
||||
if(given_serial == 0)
|
||||
if(!official)
|
||||
serial_number = rand(1, NUM_OF_POSTER_DESIGNS)
|
||||
resulting_poster = new(serial_number,official)
|
||||
if(!rolled_official)
|
||||
serial = rand(1, NUM_OF_POSTER_DESIGNS)
|
||||
resulting_poster = new(serial,rolled_official)
|
||||
else
|
||||
serial_number = rand(1, NUM_OF_POSTER_DESIGNS_LEGIT)
|
||||
resulting_poster = new(serial_number,official)
|
||||
serial = rand(1, NUM_OF_POSTER_DESIGNS_LEGIT)
|
||||
resulting_poster = new(serial,rolled_official)
|
||||
else
|
||||
serial_number = given_serial
|
||||
serial = given_serial
|
||||
//We don't give it a resulting_poster because if we called it with a given_serial it means that we're rerolling an already used poster.
|
||||
name += " - No. [serial_number]"
|
||||
name += " - No. [serial]"
|
||||
..(loc)
|
||||
|
||||
|
||||
@@ -182,8 +182,10 @@ list(name = "- Carbon Dioxide", desc = " This informational poster teaches the v
|
||||
var/placespeed = 37 // don't change this, otherwise the animation will not sync to the progress bar
|
||||
|
||||
/obj/structure/sign/poster/New(serial,rolled_official)
|
||||
serial_number = serial
|
||||
official = rolled_official
|
||||
if (!serial_number)
|
||||
serial_number = serial
|
||||
if(!official)
|
||||
official = rolled_official
|
||||
if(serial_number == loc)
|
||||
if(!official)
|
||||
serial_number = rand(1, NUM_OF_POSTER_DESIGNS) //This is for the mappers that want individual posters without having to use rolled posters.
|
||||
@@ -259,7 +261,7 @@ list(name = "- Carbon Dioxide", desc = " This informational poster teaches the v
|
||||
var/temp_loc = get_turf(user)
|
||||
flick("poster_being_set",D)
|
||||
D.loc = src
|
||||
D.official = P.official
|
||||
D.official = P.rolled_official
|
||||
qdel(P) //delete it now to cut down on sanity checks afterwards. Agouri's code supports rerolling it anyway
|
||||
playsound(D.loc, 'sound/items/poster_being_created.ogg', 100, 1)
|
||||
|
||||
|
||||
@@ -234,7 +234,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
|
||||
var/obj/item/weapon/storage/S = loc
|
||||
S.remove_from_storage(src, user.loc)
|
||||
|
||||
throwing = 0
|
||||
if(throwing)
|
||||
throwing.finalize(FALSE)
|
||||
if(loc == user)
|
||||
if(!user.dropItemToGround(src))
|
||||
return
|
||||
@@ -255,7 +256,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
|
||||
var/obj/item/weapon/storage/S = loc
|
||||
S.remove_from_storage(src, user.loc)
|
||||
|
||||
throwing = 0
|
||||
if(throwing)
|
||||
throwing.finalize(FALSE)
|
||||
if(loc == user)
|
||||
if(!user.dropItemToGround(src))
|
||||
return
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define STATION_RENAME_TIME_LIMIT 3000
|
||||
|
||||
/obj/item/station_charter
|
||||
name = "station charter"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
@@ -33,7 +35,7 @@
|
||||
if(used)
|
||||
user << "This charter has already been used to name the station."
|
||||
return
|
||||
if(!ignores_timeout && (world.time-round_start_time > CHALLENGE_TIME_LIMIT)) //5 minutes
|
||||
if(!ignores_timeout && (world.time-round_start_time > STATION_RENAME_TIME_LIMIT)) //5 minutes
|
||||
user << "The crew has already settled into the shift. \
|
||||
It probably wouldn't be good to rename the station right now."
|
||||
return
|
||||
@@ -93,3 +95,5 @@
|
||||
|
||||
if(!unlimited_uses)
|
||||
used = TRUE
|
||||
|
||||
#undef STATION_RENAME_TIME_LIMIT
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
origin_tech = "engineering=2;bluespace=1"
|
||||
var/translate_binary = 0
|
||||
var/translate_hive = 0
|
||||
var/syndie = 0
|
||||
var/centcom = 0
|
||||
var/list/channels = list()
|
||||
|
||||
@@ -273,9 +273,6 @@
|
||||
if(keyslot2.translate_binary)
|
||||
src.translate_binary = 1
|
||||
|
||||
if(keyslot2.translate_hive)
|
||||
src.translate_hive = 1
|
||||
|
||||
if(keyslot2.syndie)
|
||||
src.syndie = 1
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
var/broadcasting = 0
|
||||
var/listening = 1
|
||||
var/translate_binary = 0
|
||||
var/translate_hive = 0
|
||||
var/freerange = 0 // 0 - Sanitize frequencies, 1 - Full range
|
||||
var/list/channels = list() //see communications.dm for full list. First channes is a "default" for :h
|
||||
var/obj/item/device/encryptionkey/keyslot //To allow the radio to accept encryption keys.
|
||||
@@ -58,7 +57,6 @@
|
||||
/obj/item/device/radio/proc/recalculateChannels()
|
||||
channels = list()
|
||||
translate_binary = 0
|
||||
translate_hive = 0
|
||||
syndie = 0
|
||||
centcom = 0
|
||||
|
||||
@@ -72,9 +70,6 @@
|
||||
if(keyslot.translate_binary)
|
||||
translate_binary = 1
|
||||
|
||||
if(keyslot.translate_hive)
|
||||
translate_hive = 1
|
||||
|
||||
if(keyslot.syndie)
|
||||
syndie = 1
|
||||
|
||||
|
||||
@@ -272,12 +272,17 @@
|
||||
|
||||
|
||||
/obj/item/device/tape/attackby(obj/item/I, mob/user, params)
|
||||
if(ruined && istype(I, /obj/item/weapon/screwdriver))
|
||||
user << "<span class='notice'>You start winding the tape back in...</span>"
|
||||
if(do_after(user, 120*I.toolspeed, target = src))
|
||||
user << "<span class='notice'>You wound the tape back in.</span>"
|
||||
fix()
|
||||
|
||||
if(ruined)
|
||||
var/delay = -1
|
||||
if (istype(I, /obj/item/weapon/screwdriver))
|
||||
delay = 120*I.toolspeed
|
||||
else if(istype(I, /obj/item/weapon/pen))
|
||||
delay = 120*1.5
|
||||
if (delay != -1)
|
||||
user << "<span class='notice'>You start winding the tape back in...</span>"
|
||||
if(do_after(user, delay, target = src))
|
||||
user << "<span class='notice'>You wound the tape back in.</span>"
|
||||
fix()
|
||||
|
||||
//Random colour tapes
|
||||
/obj/item/device/tape/random/New()
|
||||
|
||||
@@ -251,7 +251,7 @@
|
||||
//get amount from user
|
||||
var/min = 0
|
||||
var/max = src.get_amount()
|
||||
var/stackmaterial = input(user,"How many sheets do you wish to take out of this stack? (Maximum [max]") as num
|
||||
var/stackmaterial = round(input(user,"How many sheets do you wish to take out of this stack? (Maximum [max]") as num)
|
||||
if(stackmaterial == null || stackmaterial <= min || stackmaterial >= src.get_amount())
|
||||
return
|
||||
else
|
||||
|
||||
@@ -522,43 +522,39 @@ var/global/list/RPD_recipes=list(
|
||||
if(!user.IsAdvancedToolUser() || istype(A,/turf/open/space/transit))
|
||||
return ..()
|
||||
|
||||
//make sure what we're clicking is valid for the current mode
|
||||
var/is_paintable = (p_class == PAINT_MODE && istype(A, /obj/machinery/atmospherics/pipe))
|
||||
var/is_consumable = (p_class == EATING_MODE && (istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct)))
|
||||
var/can_make_pipe = ((p_class == ATMOS_MODE || p_class == METER_MODE || p_class == DISPOSALS_MODE) && isturf(A))
|
||||
|
||||
if(!is_paintable && !is_consumable && !can_make_pipe)
|
||||
return ..()
|
||||
|
||||
//So that changing the menu settings doesn't affect the pipes already being built.
|
||||
var/queued_p_type = p_type
|
||||
var/queued_p_dir = p_dir
|
||||
var/queued_p_flipped = p_flipped
|
||||
|
||||
. = FALSE
|
||||
switch(p_class)
|
||||
if(PAINT_MODE) // Paint pipes
|
||||
if(!istype(A,/obj/machinery/atmospherics/pipe))
|
||||
// Avoid spewing errors about invalid mode -2 when clicking on stuff that aren't pipes.
|
||||
user << "<span class='warning'>\The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?</span>"
|
||||
return
|
||||
switch(p_class) //if we've gotten this var, the target is valid
|
||||
if(PAINT_MODE) //Paint pipes
|
||||
var/obj/machinery/atmospherics/pipe/P = A
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
|
||||
P.add_atom_colour(paint_colors[paint_color], FIXED_COLOUR_PRIORITY)
|
||||
P.pipe_color = paint_colors[paint_color]
|
||||
user.visible_message("<span class='notice'>[user] paints \the [P] [paint_color].</span>","<span class='notice'>You paint \the [P] [paint_color].</span>")
|
||||
//P.update_icon()
|
||||
P.update_node_icon()
|
||||
return
|
||||
if(EATING_MODE) // Eating pipes
|
||||
// Must click on an actual pipe or meter.
|
||||
if(!(istype(A,/obj/item/pipe) || istype(A,/obj/item/pipe_meter) || istype(A,/obj/structure/disposalconstruct)))
|
||||
// Avoid spewing errors about invalid mode -1 when clicking on stuff that aren't pipes.
|
||||
user << "<span class='warning'>The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?</span>"
|
||||
return
|
||||
user << "<span class='notice'>You start destroying pipe...</span>"
|
||||
|
||||
if(EATING_MODE) //Eating pipes
|
||||
user << "<span class='notice'>You start destroying a pipe...</span>"
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
|
||||
if(do_after(user, 2, target = A))
|
||||
activate()
|
||||
qdel(A)
|
||||
|
||||
if(ATMOS_MODE)
|
||||
if(!isturf(A))
|
||||
user << "<span class='warning'>The [src]'s error light flickers!</span>"
|
||||
return
|
||||
user << "<span class='notice'>You start building pipes...</span>"
|
||||
if(ATMOS_MODE) //Making pipes
|
||||
user << "<span class='notice'>You start building a pipe...</span>"
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
|
||||
if(do_after(user, 2, target = A))
|
||||
activate()
|
||||
@@ -567,21 +563,18 @@ var/global/list/RPD_recipes=list(
|
||||
P.update()
|
||||
P.add_fingerprint(usr)
|
||||
|
||||
if(METER_MODE)
|
||||
if(!isturf(A))
|
||||
user << "<span class='warning'>The [src]'s error light flickers!</span>"
|
||||
return 0
|
||||
if(METER_MODE) //Making pipe meters
|
||||
user << "<span class='notice'>You start building a meter...</span>"
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
|
||||
if(do_after(user, 2, target = A))
|
||||
activate()
|
||||
new /obj/item/pipe_meter(A)
|
||||
|
||||
if(DISPOSALS_MODE)
|
||||
if(!isturf(A) || is_anchored_dense_turf(A))
|
||||
user << "<span class='warning'>The [src]'s error light flickers!</span>"
|
||||
if(DISPOSALS_MODE) //Making disposals pipes
|
||||
if(!is_anchored_dense_turf(A))
|
||||
user << "<span class='warning'>The [src]'s error light flickers; there's something in the way!</span>"
|
||||
return
|
||||
user << "<span class='notice'>You start building pipes...</span>"
|
||||
user << "<span class='notice'>You start building a disposals pipe...</span>"
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
|
||||
if(do_after(user, 20, target = A))
|
||||
var/obj/structure/disposalconstruct/C = new (A, queued_p_type ,queued_p_dir)
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
user.visible_message("[user] has thrown [src]. It lands on [result]. [comment]", \
|
||||
"<span class='notice'>You throw [src]. It lands on [result]. [comment]</span>", \
|
||||
"<span class='italics'>You hear [src] rolling, it sounds like a [fake_result].</span>")
|
||||
else if(src.throwing == 0) //Dice was thrown and is coming to rest
|
||||
else if(!src.throwing) //Dice was thrown and is coming to rest
|
||||
visible_message("<span class='notice'>[src] rolls to a stop, landing on [result]. [comment]</span>")
|
||||
|
||||
/obj/item/weapon/dice/d4/Crossed(mob/living/carbon/human/H)
|
||||
|
||||
@@ -37,12 +37,11 @@
|
||||
|
||||
//What does the implant do upon injection?
|
||||
//return 1 if the implant injects
|
||||
//return -1 if the implant fails to inject
|
||||
//return 0 if there is no room for implant
|
||||
//return 0 if there is no room for implant / it fails
|
||||
/obj/item/weapon/implant/proc/implant(mob/living/target, mob/user, silent = 0)
|
||||
LAZYINITLIST(target.implants)
|
||||
if(!target.can_be_implanted() || !can_be_implanted_in(target))
|
||||
return -1
|
||||
return 0
|
||||
for(var/X in target.implants)
|
||||
if(istype(X, type))
|
||||
var/obj/item/weapon/implant/imp_e = X
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
target.visible_message("<span class='warning'>[target] seems to resist the implant!</span>", "<span class='warning'>You feel the influence of your enemies try to invade your mind!</span>")
|
||||
|
||||
qdel(src)
|
||||
return -1
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/implanter/gang
|
||||
name = "implanter (gang)"
|
||||
|
||||
@@ -24,14 +24,14 @@
|
||||
target.visible_message("<span class='warning'>[target] seems to resist the implant!</span>", "<span class='warning'>You feel something interfering with your mental conditioning, but you resist it!</span>")
|
||||
removed(target, 1)
|
||||
qdel(src)
|
||||
return -1
|
||||
return 0
|
||||
if(target.mind in ticker.mode.get_gangsters())
|
||||
ticker.mode.remove_gangster(target.mind)
|
||||
if(!silent)
|
||||
target.visible_message("<span class='warning'>[src] was destroyed in the process!</span>", "<span class='notice'>You feel a sense of peace and security. You are now protected from brainwashing.</span>")
|
||||
removed(target, 1)
|
||||
qdel(src)
|
||||
return -1
|
||||
return 0
|
||||
if(target.mind in ticker.mode.revolutionaries)
|
||||
ticker.mode.remove_revolutionary(target.mind)
|
||||
if(!silent)
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
M.visible_message("[user] has implanted [M].", "<span class='notice'>[user] implants you.</span>")
|
||||
imp = null
|
||||
update_icon()
|
||||
else
|
||||
user << "<span class='warning'>[src] fails to implant [M].</span>"
|
||||
|
||||
/obj/item/weapon/implanter/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(istype(W, /obj/item/weapon/pen))
|
||||
|
||||
@@ -574,7 +574,6 @@
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
playsound(loc, "rustle", 50, 1, -5)
|
||||
user.visible_message("<span class='notice'>[user] hugs \the [src].</span>","<span class='notice'>You hug \the [src].</span>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/box/hug/medical/New()
|
||||
..()
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
new /obj/item/device/flashlight/flare(src)
|
||||
new /obj/item/device/radio/off(src)
|
||||
|
||||
/obj/item/weapon/storage/toolbox/emergency/old
|
||||
name = "rusty red toolbox"
|
||||
item_state = "toolbox_red_old"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/mechanical
|
||||
name = "mechanical toolbox"
|
||||
icon_state = "blue"
|
||||
@@ -48,6 +52,10 @@
|
||||
new /obj/item/device/analyzer(src)
|
||||
new /obj/item/weapon/wirecutters(src)
|
||||
|
||||
/obj/item/weapon/storage/toolbox/mechanical/old
|
||||
name = "rusty blue toolbox"
|
||||
item_state = "toolbox_blue_old"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/electrical
|
||||
name = "electrical toolbox"
|
||||
icon_state = "yellow"
|
||||
|
||||
@@ -306,3 +306,7 @@
|
||||
..()
|
||||
for(var/i in 1 to 3)
|
||||
new/obj/item/weapon/grenade/chem_grenade/ez_clean(src)
|
||||
|
||||
/obj/item/weapon/storage/box/hug/reverse_revolver/New()
|
||||
..()
|
||||
new /obj/item/weapon/gun/ballistic/revolver/reverse(src)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
var/gas_type = "o2"
|
||||
var/on = FALSE
|
||||
var/stabilizers = FALSE
|
||||
var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not
|
||||
var/datum/effect_system/trail_follow/ion/ion_trail
|
||||
|
||||
/obj/item/weapon/tank/jetpack/New()
|
||||
@@ -133,6 +134,7 @@
|
||||
volume = 1
|
||||
slot_flags = null
|
||||
gas_type = null
|
||||
full_speed = FALSE
|
||||
var/datum/gas_mixture/temp_air_contents
|
||||
var/obj/item/weapon/tank/internals/tank = null
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
if(throwing) // you keep some momentum when getting out of a thrown closet
|
||||
step(AM, dir)
|
||||
if(throwing)
|
||||
throwing = 0
|
||||
throwing.finalize(FALSE)
|
||||
|
||||
/obj/structure/closet/proc/take_contents()
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -438,3 +438,7 @@
|
||||
for(var/atom/A in contents)
|
||||
A.ex_act(severity, target)
|
||||
CHECK_TICK
|
||||
|
||||
/obj/structure/closet/singularity_act()
|
||||
dump_contents()
|
||||
..()
|
||||
|
||||
@@ -107,6 +107,15 @@
|
||||
cur_acc[cur_note] = "#" // so shift is never required
|
||||
else
|
||||
cur_oct[cur_note] = text2num(ni)
|
||||
if(user.dizziness > 0 && prob(user.dizziness / 2))
|
||||
cur_note = Clamp(cur_note + rand(round(-user.dizziness / 10), round(user.dizziness / 10)), 1, 7)
|
||||
if(user.dizziness > 0 && prob(user.dizziness / 5))
|
||||
if(prob(30))
|
||||
cur_acc[cur_note] = "#"
|
||||
else if(prob(42))
|
||||
cur_acc[cur_note] = "b"
|
||||
else if(prob(75))
|
||||
cur_acc[cur_note] = "n"
|
||||
playnote(cur_note, cur_acc[cur_note], cur_oct[cur_note])
|
||||
if(notes.len >= 2 && text2num(notes[2]))
|
||||
sleep(sanitize_tempo(tempo / text2num(notes[2])))
|
||||
|
||||
@@ -30,23 +30,20 @@
|
||||
/turf/closed/indestructible/splashscreen
|
||||
name = "Space Station 13"
|
||||
icon = 'icons/misc/fullscreen.dmi'
|
||||
icon_state = "title1"
|
||||
icon_state = "title"
|
||||
layer = FLY_LAYER
|
||||
var/titlescreen = TITLESCREEN
|
||||
|
||||
/turf/closed/indestructible/splashscreen/New()
|
||||
/turf/closed/indestructible/splashscreen/Initialize()
|
||||
..()
|
||||
icon_state = pick("title1","title2","title3","title4","title5")
|
||||
if(titlescreen)
|
||||
icon_state = titlescreen
|
||||
|
||||
/turf/closed/indestructible/riveted
|
||||
icon = 'icons/turf/walls/riveted.dmi'
|
||||
icon_state = "riveted"
|
||||
smooth = SMOOTH_TRUE
|
||||
|
||||
/turf/closed/indestructible/New()
|
||||
..()
|
||||
if(smooth)
|
||||
queue_smooth(src)
|
||||
|
||||
/turf/closed/indestructible/riveted/uranium
|
||||
icon = 'icons/turf/walls/uranium_wall.dmi'
|
||||
icon_state = "uranium"
|
||||
@@ -64,7 +61,7 @@
|
||||
smooth = SMOOTH_TRUE
|
||||
icon = 'icons/obj/smooth_structures/reinforced_window.dmi'
|
||||
|
||||
/turf/closed/indestructible/fakeglass/New()
|
||||
/turf/closed/indestructible/fakeglass/Initialize()
|
||||
..()
|
||||
icon_state = null //set the icon state to null, so our base state isn't visible
|
||||
var/image/I = image('icons/obj/structures.dmi', loc = src, icon_state = "grille")
|
||||
|
||||
@@ -29,22 +29,20 @@
|
||||
baseturf = /turf/open/indestructible/necropolis
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
|
||||
/turf/open/indestructible/necropolis/New()
|
||||
/turf/open/indestructible/necropolis/Initialize()
|
||||
..()
|
||||
if(prob(12))
|
||||
icon_state = "necro[rand(2,3)]"
|
||||
|
||||
/turf/open/indestructible/necropolis/air
|
||||
initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
|
||||
|
||||
/turf/open/indestructible/hierophant
|
||||
icon = 'icons/turf/floors/hierophant_floor.dmi'
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
baseturf = /turf/open/indestructible/hierophant
|
||||
smooth = SMOOTH_TRUE
|
||||
|
||||
/turf/open/indestructible/hierophant/New()
|
||||
..()
|
||||
if(smooth)
|
||||
queue_smooth(src)
|
||||
|
||||
/turf/open/indestructible/hierophant/two
|
||||
|
||||
/turf/open/indestructible/paper
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
L.adjustBruteLoss(30)
|
||||
|
||||
|
||||
/turf/open/chasm/straight_down/New()
|
||||
/turf/open/chasm/straight_down/Initialize()
|
||||
..()
|
||||
drop_x = x
|
||||
drop_y = y
|
||||
|
||||
@@ -33,7 +33,7 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
|
||||
var/list/broken_states
|
||||
var/list/burnt_states
|
||||
|
||||
/turf/open/floor/New()
|
||||
/turf/open/floor/Initialize(mapload)
|
||||
if (!broken_states)
|
||||
broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5")
|
||||
if (!burnt_states)
|
||||
@@ -43,6 +43,8 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
|
||||
icon_regular_floor = "floor"
|
||||
else
|
||||
icon_regular_floor = icon_state
|
||||
if(mapload)
|
||||
MakeDirty()
|
||||
|
||||
/turf/open/floor/ex_act(severity, target)
|
||||
var/shielded = is_shielded()
|
||||
@@ -179,10 +181,5 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
|
||||
if(.)
|
||||
ChangeTurf(/turf/open/floor/clockwork)
|
||||
|
||||
/turf/open/floor/Initialize(mapload)
|
||||
..()
|
||||
if(mapload)
|
||||
MakeDirty()
|
||||
|
||||
/turf/open/floor/acid_melt()
|
||||
ChangeTurf(baseturf)
|
||||
|
||||
@@ -36,10 +36,9 @@
|
||||
flags = NONE
|
||||
var/ore_type = /obj/item/weapon/ore/glass
|
||||
|
||||
/turf/open/floor/grass/New()
|
||||
/turf/open/floor/grass/Initialize()
|
||||
..()
|
||||
spawn(1)
|
||||
update_icon()
|
||||
update_icon()
|
||||
|
||||
/turf/open/floor/grass/attackby(obj/item/C, mob/user, params)
|
||||
if(istype(C, /obj/item/weapon/shovel) && params)
|
||||
@@ -76,7 +75,7 @@
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
slowdown = 0
|
||||
|
||||
/turf/open/floor/grass/snow/basalt/New()
|
||||
/turf/open/floor/grass/snow/basalt/Initialize()
|
||||
..()
|
||||
if(prob(15))
|
||||
icon_state = "basalt[rand(0, 12)]"
|
||||
@@ -96,10 +95,9 @@
|
||||
canSmoothWith = null
|
||||
flags = NONE
|
||||
|
||||
/turf/open/floor/carpet/New()
|
||||
/turf/open/floor/carpet/Initialize()
|
||||
..()
|
||||
spawn(1)
|
||||
update_icon()
|
||||
update_icon()
|
||||
|
||||
/turf/open/floor/carpet/update_icon()
|
||||
if(!..())
|
||||
@@ -131,6 +129,6 @@
|
||||
broken_states = list("damaged")
|
||||
plane = PLANE_SPACE
|
||||
|
||||
/turf/open/floor/fakespace/New()
|
||||
/turf/open/floor/fakespace/Initialize()
|
||||
..()
|
||||
icon_state = "[rand(0,25)]"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/can_modify_colour = TRUE
|
||||
|
||||
|
||||
/turf/open/floor/light/New()
|
||||
/turf/open/floor/light/Initialize()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
|
||||
|
||||
/turf/open/floor/mineral/New()
|
||||
/turf/open/floor/mineral/Initialize()
|
||||
broken_states = list("[initial(icon_state)]_dam")
|
||||
..()
|
||||
if (!icons)
|
||||
@@ -221,7 +221,7 @@
|
||||
floor_tile = /obj/item/stack/tile/mineral/abductor
|
||||
icons = list("alienpod1", "alienpod2", "alienpod3", "alienpod4", "alienpod5", "alienpod6", "alienpod7", "alienpod8", "alienpod9")
|
||||
|
||||
/turf/open/floor/mineral/abductor/New()
|
||||
/turf/open/floor/mineral/abductor/Initialize()
|
||||
..()
|
||||
icon_state = "alienpod[rand(1,9)]"
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
icon_state = "bcircuit"
|
||||
floor_tile = /obj/item/stack/tile/plasteel
|
||||
|
||||
/turf/open/floor/bluegrid/New()
|
||||
..()
|
||||
/turf/open/floor/bluegrid/Initialize()
|
||||
SSmapping.nuke_tiles += src
|
||||
..()
|
||||
|
||||
/turf/open/floor/bluegrid/Destroy()
|
||||
SSmapping.nuke_tiles -= src
|
||||
@@ -67,7 +67,7 @@
|
||||
icon_state = "plating"
|
||||
var/obj/effect/clockwork/overlay/floor/realappearence
|
||||
|
||||
/turf/open/floor/clockwork/New()
|
||||
/turf/open/floor/clockwork/Initialize()
|
||||
..()
|
||||
new /obj/effect/overlay/temp/ratvar/floor(src)
|
||||
new /obj/effect/overlay/temp/ratvar/beam(src)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
icon_state = "plating"
|
||||
intact = 0
|
||||
|
||||
/turf/open/floor/plating/New()
|
||||
/turf/open/floor/plating/Initialize()
|
||||
if (!broken_states)
|
||||
broken_states = list("platingdmg1", "platingdmg2", "platingdmg3")
|
||||
if (!burnt_states)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
var/sand_type = /obj/item/weapon/ore/glass
|
||||
var/floor_variance = 20 //probability floor has a different icon state
|
||||
|
||||
/turf/open/floor/plating/asteroid/New()
|
||||
/turf/open/floor/plating/asteroid/Initialize()
|
||||
var/proper_name = name
|
||||
..()
|
||||
name = proper_name
|
||||
@@ -117,7 +117,7 @@
|
||||
/turf/open/floor/plating/asteroid/basalt/airless
|
||||
initial_gas_mix = "TEMP=2.7"
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt/New()
|
||||
/turf/open/floor/plating/asteroid/basalt/Initialize()
|
||||
..()
|
||||
switch(icon_state)
|
||||
if("basalt1", "basalt2", "basalt3") //5 and 9 are too dark to glow and make the amount of glows in tunnels too high
|
||||
@@ -176,7 +176,7 @@
|
||||
/turf/open/floor/plating/asteroid/airless/cave/volcanic/has_data //subtype for producing a tunnel with given data
|
||||
has_data = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/New(loc)
|
||||
/turf/open/floor/plating/asteroid/airless/cave/Initialize()
|
||||
if (!mob_spawn_list)
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 1, /mob/living/simple_animal/hostile/asteroid/goliath = 5, /mob/living/simple_animal/hostile/asteroid/basilisk = 4, /mob/living/simple_animal/hostile/asteroid/hivelord = 3)
|
||||
if (!megafauna_spawn_list)
|
||||
@@ -186,7 +186,8 @@
|
||||
|
||||
if(!has_data)
|
||||
produce_tunnel_from_data()
|
||||
..()
|
||||
else
|
||||
..() //do not continue after changeturfing or we will do a double initialize
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/get_cave_data(set_length, exclude_dir = -1)
|
||||
// If set_length (arg1) isn't defined, get a random length; otherwise assign our length to the length arg.
|
||||
|
||||
@@ -7,12 +7,6 @@
|
||||
baseturf = /turf/open/floor/plating/lava //lava all the way down
|
||||
slowdown = 2
|
||||
luminosity = 1
|
||||
var/static/list/safeties_typecache = list(/obj/structure/lattice/catwalk)
|
||||
//if anything matching this typecache is found in the lava, we don't burn things
|
||||
|
||||
/turf/open/floor/plating/lava/New()
|
||||
..()
|
||||
safeties_typecache = typecacheof(safeties_typecache)
|
||||
|
||||
/turf/open/floor/plating/lava/ex_act()
|
||||
return
|
||||
@@ -51,7 +45,9 @@
|
||||
|
||||
|
||||
/turf/open/floor/plating/lava/proc/is_safe()
|
||||
var/list/found_safeties = typecache_filter_list(contents, safeties_typecache)
|
||||
//if anything matching this typecache is found in the lava, we don't burn things
|
||||
var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk))
|
||||
var/list/found_safeties = typecache_filter_list(contents, lava_safeties_typecache)
|
||||
return LAZYLEN(found_safeties)
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
name = "alien floor"
|
||||
icon_state = "alienpod1"
|
||||
|
||||
/turf/open/floor/plating/abductor/New()
|
||||
/turf/open/floor/plating/abductor/Initialize()
|
||||
..()
|
||||
icon_state = "alienpod[rand(1,9)]"
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
planetary_atmos = TRUE
|
||||
|
||||
/turf/open/floor/plating/ashplanet/New()
|
||||
/turf/open/floor/plating/ashplanet/Initialize()
|
||||
if(smooth)
|
||||
pixel_y = -4
|
||||
pixel_x = -4
|
||||
@@ -72,7 +72,7 @@
|
||||
icon_state = "wateryrock"
|
||||
slowdown = 2
|
||||
|
||||
/turf/open/floor/plating/ashplanet/wateryrock/New()
|
||||
/turf/open/floor/plating/ashplanet/wateryrock/Initialize()
|
||||
icon_state = "[icon_state][rand(1, 9)]"
|
||||
..()
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
name = "iron sand"
|
||||
desc = "Like sand, but more <i>metal</i>."
|
||||
|
||||
/turf/open/floor/plating/ironsand/New()
|
||||
/turf/open/floor/plating/ironsand/Initialize()
|
||||
..()
|
||||
icon_state = "ironsand[rand(1,15)]"
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
icon_state = "plating"
|
||||
var/obj/effect/clockwork/overlay/floor/bloodcult/realappearence
|
||||
|
||||
/turf/open/floor/engine/cult/New()
|
||||
/turf/open/floor/engine/cult/Initialize()
|
||||
..()
|
||||
new /obj/effect/overlay/temp/cult/turf/floor(src)
|
||||
realappearence = new /obj/effect/clockwork/overlay/floor/bloodcult(src)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
var/scan_state = null //Holder for the image we display when we're pinged by a mining scanner
|
||||
var/defer_change = 0
|
||||
|
||||
/turf/closed/mineral/New()
|
||||
/turf/closed/mineral/Initialize()
|
||||
if (!canSmoothWith)
|
||||
canSmoothWith = list(/turf/closed)
|
||||
pixel_y = -4
|
||||
@@ -139,7 +139,7 @@
|
||||
var/mineralChance = 13
|
||||
var/display_icon_state = "rock"
|
||||
|
||||
/turf/closed/mineral/random/New()
|
||||
/turf/closed/mineral/random/Initialize()
|
||||
if (!mineralSpawnChanceList)
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium = 5, /turf/closed/mineral/diamond = 1, /turf/closed/mineral/gold = 10,
|
||||
@@ -385,7 +385,7 @@
|
||||
var/activated_name = null
|
||||
var/activated_image = null
|
||||
|
||||
/turf/closed/mineral/gibtonite/New()
|
||||
/turf/closed/mineral/gibtonite/Initialize()
|
||||
det_time = rand(8,10) //So you don't know exactly when the hot potato will explode
|
||||
..()
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
sheet_amount = 1
|
||||
girder_type = /obj/structure/girder/cult
|
||||
|
||||
/turf/closed/wall/mineral/cult/New()
|
||||
/turf/closed/wall/mineral/cult/Initialize()
|
||||
new /obj/effect/overlay/temp/cult/turf(src)
|
||||
..()
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
var/obj/effect/clockwork/overlay/wall/realappearence
|
||||
var/obj/structure/destructible/clockwork/cache/linkedcache
|
||||
|
||||
/turf/closed/wall/clockwork/New()
|
||||
/turf/closed/wall/clockwork/Initialize()
|
||||
..()
|
||||
new /obj/effect/overlay/temp/ratvar/wall(src)
|
||||
new /obj/effect/overlay/temp/ratvar/beam(src)
|
||||
|
||||
@@ -15,15 +15,16 @@
|
||||
var/global/datum/gas_mixture/space/space_gas = new
|
||||
plane = PLANE_SPACE
|
||||
|
||||
/turf/open/space/New()
|
||||
/turf/open/space/Initialize()
|
||||
icon_state = SPACE_ICON_STATE
|
||||
air = space_gas
|
||||
|
||||
if(initialized)
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
initialized = TRUE
|
||||
|
||||
/turf/open/space/Destroy(force)
|
||||
if(force)
|
||||
. = ..()
|
||||
else
|
||||
return QDEL_HINT_LETMELIVE
|
||||
if(requires_activation)
|
||||
SSair.add_to_active(src)
|
||||
|
||||
/turf/open/space/attack_ghost(mob/dead/observer/user)
|
||||
if(destination_z)
|
||||
|
||||
@@ -61,14 +61,12 @@
|
||||
/turf/open/space/transit/attackby()
|
||||
return
|
||||
|
||||
/turf/open/space/transit/New()
|
||||
/turf/open/space/transit/Initialize()
|
||||
..()
|
||||
update_icon()
|
||||
for(var/atom/movable/AM in src)
|
||||
throw_atom(AM)
|
||||
|
||||
|
||||
|
||||
/turf/open/space/transit/proc/update_icon()
|
||||
var/p = 9
|
||||
var/angle = 0
|
||||
|
||||
@@ -23,14 +23,17 @@
|
||||
var/explosion_id = 0
|
||||
|
||||
var/list/decals
|
||||
var/requires_activation //add to air processing after initialize?
|
||||
|
||||
/turf/SDQL_update(const/var_name, new_value)
|
||||
if(var_name == "x" || var_name == "y" || var_name == "z")
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
/turf/New()
|
||||
..()
|
||||
/turf/Initialize()
|
||||
if(initialized)
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
initialized = TRUE
|
||||
|
||||
levelupdate()
|
||||
if(smooth)
|
||||
@@ -40,11 +43,17 @@
|
||||
for(var/atom/movable/AM in src)
|
||||
Entered(AM)
|
||||
|
||||
if(requires_activation)
|
||||
CalculateAdjacentTurfs()
|
||||
SSair.add_to_active(src)
|
||||
|
||||
/turf/proc/Initalize_Atmos(times_fired)
|
||||
CalculateAdjacentTurfs()
|
||||
|
||||
/turf/Destroy()
|
||||
visibilityChanged()
|
||||
initialized = FALSE
|
||||
requires_activation = FALSE
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
@@ -454,4 +463,4 @@
|
||||
/turf/proc/remove_decal(group)
|
||||
LAZYINITLIST(decals)
|
||||
overlays -= decals[group]
|
||||
decals[group] = null
|
||||
decals[group] = null
|
||||
|
||||
@@ -100,44 +100,6 @@
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Luxury Shuttle Blockers
|
||||
|
||||
/obj/effect/forcefield/luxury_shuttle
|
||||
var/threshhold = 500
|
||||
var/list/approved_passengers = list()
|
||||
|
||||
/obj/effect/forcefield/luxury_shuttle/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
if(mover in approved_passengers)
|
||||
return 1
|
||||
|
||||
if(!isliving(mover)) //No stowaways
|
||||
return 0
|
||||
|
||||
var/total_cash = 0
|
||||
var/list/counted_money = list()
|
||||
|
||||
for(var/obj/item/weapon/coin/C in mover)
|
||||
total_cash += C.value
|
||||
counted_money += C
|
||||
if(total_cash >= threshhold)
|
||||
break
|
||||
for(var/obj/item/stack/spacecash/S in mover)
|
||||
total_cash += S.value * S.amount
|
||||
counted_money += S
|
||||
if(total_cash >= threshhold)
|
||||
break
|
||||
|
||||
if(total_cash >= threshhold)
|
||||
for(var/obj/I in counted_money)
|
||||
qdel(I)
|
||||
|
||||
mover << "Thank you for your payment! Please enjoy your flight."
|
||||
approved_passengers += mover
|
||||
return 1
|
||||
else
|
||||
mover << "You don't have enough money to enter the main shuttle. You'll have to fly coach."
|
||||
return 0
|
||||
|
||||
//Shuttle Build
|
||||
|
||||
/obj/effect/shuttle_build
|
||||
@@ -149,4 +111,69 @@
|
||||
|
||||
/obj/effect/shuttle_build/New()
|
||||
SSshuttle.emergency.dock(SSshuttle.getDock("emergency_home"))
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
//Arena
|
||||
|
||||
/obj/effect/forcefield/arena_shuttle
|
||||
name = "portal"
|
||||
var/list/warp_points = list()
|
||||
|
||||
|
||||
/obj/effect/forcefield/arena_shuttle/Bumped(mob/M as mob|obj)
|
||||
if(!warp_points.len)
|
||||
warp_points = get_area_turfs(/area/shuttle/escape)
|
||||
for(var/turf/T in warp_points)
|
||||
for(var/atom/movable/AM in T)
|
||||
if(AM.density && AM.anchored)
|
||||
warp_points -= T
|
||||
break
|
||||
if(!isliving(M))
|
||||
return
|
||||
else
|
||||
var/mob/living/L = M
|
||||
if(L.pulling && istype(L.pulling, /obj/item/bodypart/head))
|
||||
L << "Your offering is accepted. You may pass."
|
||||
qdel(L.pulling)
|
||||
var/turf/LA = pick(warp_points)
|
||||
L.forceMove(LA)
|
||||
L.hallucination = 0
|
||||
L << "<span class='reallybig redtext'>The battle is won. Your bloodlust subsides.</span>"
|
||||
for(var/obj/item/weapon/twohanded/required/chainsaw/doomslayer/chainsaw in L)
|
||||
qdel(chainsaw)
|
||||
else
|
||||
L << "You are not yet worthy of passing. Drag a severed head to the barrier to be allowed entry to the hall of champions."
|
||||
|
||||
/obj/effect/landmark/shuttle_arena_safe
|
||||
name = "hall of champions"
|
||||
desc = "For the winners."
|
||||
|
||||
/obj/effect/landmark/shuttle_arena_entrance
|
||||
name = "the arena"
|
||||
desc = "A lava filled battlefield."
|
||||
|
||||
|
||||
/obj/effect/forcefield/arena_shuttle_entrance
|
||||
name = "portal"
|
||||
var/list/warp_points = list()
|
||||
|
||||
/obj/effect/forcefield/arena_shuttle_entrance/Bumped(mob/M as mob|obj)
|
||||
if(!warp_points.len)
|
||||
for(var/obj/effect/landmark/shuttle_arena_entrance/S in landmarks_list)
|
||||
warp_points |= S
|
||||
if(!isliving(M))
|
||||
return
|
||||
|
||||
var/obj/effect/landmark/LA = pick(warp_points)
|
||||
|
||||
M.forceMove(get_turf(LA))
|
||||
M << "<span class='reallybig redtext'>You're trapped in a deadly arena! To escape, you'll need to drag a severed head to the escape portals.</span>"
|
||||
spawn()
|
||||
var/obj/effect/mine/pickup/bloodbath/B = new(M)
|
||||
B.mineEffect(M)
|
||||
|
||||
|
||||
/area/shuttle_arena
|
||||
name = "arena"
|
||||
has_gravity = 1
|
||||
requires_power = 0
|
||||
|
||||
@@ -337,10 +337,40 @@
|
||||
dat += "Time limit: <a href='?_src_=holder;alter_midround_time_limit=1'>[config.midround_antag_time_check] minutes into round</a><BR>"
|
||||
dat += "Living crew limit: <a href='?_src_=holder;alter_midround_life_limit=1'>[config.midround_antag_life_check * 100]% of crew alive</a><BR>"
|
||||
dat += "If limits past: <a href='?_src_=holder;toggle_noncontinuous_behavior=1'>[ticker.mode.round_ends_with_antag_death ? "End The Round" : "Continue As Extended"]</a><BR>"
|
||||
|
||||
dat += "<BR>"
|
||||
dat += "<a href='?_src_=holder;end_round=\ref[usr]'>End Round Now</a><br>"
|
||||
dat += "<a href='?_src_=holder;delay_round_end=1'>[ticker.delay_end ? "End Round Normally" : "Delay Round End"]</a><br>"
|
||||
dat += "<a href='?_src_=holder;delay_round_end=1'>[ticker.delay_end ? "End Round Normally" : "Delay Round End"]</a>"
|
||||
var/connected_players = clients.len
|
||||
var/lobby_players = 0
|
||||
var/observers = 0
|
||||
var/observers_connected = 0
|
||||
var/living_players = 0
|
||||
var/living_players_connected = 0
|
||||
var/living_players_antagonist = 0
|
||||
var/other_players = 0
|
||||
for(var/mob/M in mob_list)
|
||||
if(M.ckey)
|
||||
if(isnewplayer(M))
|
||||
lobby_players++
|
||||
continue
|
||||
else if(M.stat != DEAD && M.mind && !isbrain(M))
|
||||
living_players++
|
||||
if(M.mind.special_role)
|
||||
living_players_antagonist++
|
||||
if(M.client)
|
||||
living_players_connected++
|
||||
else if((M.stat == DEAD )||(isobserver(M)))
|
||||
observers++
|
||||
if(M.client)
|
||||
observers_connected++
|
||||
else
|
||||
other_players++
|
||||
dat += "<BR><b><font color='blue' size='3'>Players:|[connected_players - lobby_players] ingame|[connected_players] connected|[lobby_players] lobby|</font></b>"
|
||||
dat += "<BR><b><font color='green'>Living Players:|[living_players_connected] active|[living_players - living_players_connected] disconnected|[living_players_antagonist] antagonists|</font></b>"
|
||||
dat += "<BR><b><font color='red'>Dead/Observing players:|[observers_connected] active|[observers - observers_connected] disconnected|</font></b>"
|
||||
if(other_players)
|
||||
dat += "<BR><span class='userdanger'>[other_players] players in invalid state or the statistics code is bugged!</span>"
|
||||
dat += "<BR>"
|
||||
|
||||
if(ticker.mode.syndicates.len)
|
||||
dat += "<br><table cellspacing=5><tr><td><B>Syndicates</B></td><td></td></tr>"
|
||||
for(var/datum/mind/N in ticker.mode.syndicates)
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
if(!timestamp)
|
||||
timestamp = SQLtime()
|
||||
if(!server)
|
||||
if (config && config.server_name)
|
||||
server = config.server_name
|
||||
if (config && config.server_sql_name)
|
||||
server = config.server_sql_name
|
||||
server = sanitizeSQL(server)
|
||||
if(isnull(secret))
|
||||
switch(alert("Hide note from being viewed by players?", "Secret note?","Yes","No","Cancel"))
|
||||
@@ -332,7 +332,7 @@ proc/get_message_output(type, target_ckey)
|
||||
return
|
||||
if("watchlist entry")
|
||||
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'>[key_name_admin(target_ckey)] is on the watchlist and has just connected - Reason: [text]</font>")
|
||||
// send2irc_adminless_only("Watchlist", "[key_name(target_ckey)] is on the watchlist and has just connected - Reason: [text]")
|
||||
send2irc_adminless_only("Watchlist", "[key_name(target_ckey)] is on the watchlist and has just connected - Reason: [text]")
|
||||
if("memo")
|
||||
output += "<span class='memo'>Memo by <span class='prefix'>[admin_ckey]</span> on [timestamp]"
|
||||
if(editor_ckey)
|
||||
@@ -352,8 +352,8 @@ proc/get_message_output(type, target_ckey)
|
||||
var/notetext
|
||||
notesfile >> notetext
|
||||
var/server
|
||||
if(config && config.server_name)
|
||||
server = config.server_name
|
||||
if(config && config.server_sql_name)
|
||||
server = config.server_sql_name
|
||||
var/regex/note = new("^(\\d{2}-\\w{3}-\\d{4}) \\| (.+) ~(\\w+)$", "i")
|
||||
note.Find(notetext)
|
||||
var/timestamp = note.group[1]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/proc/keywords_lookup(msg)
|
||||
/proc/keywords_lookup(msg,irc)
|
||||
|
||||
//This is a list of words which are ignored by the parser when comparing message contents for names. MUST BE IN LOWER CASE!
|
||||
var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","alien","as", "i")
|
||||
@@ -10,9 +10,11 @@
|
||||
var/list/surnames = list()
|
||||
var/list/forenames = list()
|
||||
var/list/ckeys = list()
|
||||
var/founds = ""
|
||||
for(var/mob/M in mob_list)
|
||||
var/list/indexing = list(M.real_name, M.name)
|
||||
if(M.mind) indexing += M.mind.name
|
||||
if(M.mind)
|
||||
indexing += M.mind.name
|
||||
|
||||
for(var/string in indexing)
|
||||
var/list/L = splittext(string, " ")
|
||||
@@ -52,9 +54,19 @@
|
||||
mobs_found += found
|
||||
if(!ai_found && isAI(found))
|
||||
ai_found = 1
|
||||
msg += "[original_word]<font size='1' color='black'>(<A HREF='?_src_=holder;adminmoreinfo=\ref[found]'>?</A>|<A HREF='?_src_=holder;adminplayerobservefollow=\ref[found]'>F</A>)</font> "
|
||||
var/is_antag = 0
|
||||
if(found.mind && found.mind.special_role)
|
||||
is_antag = 1
|
||||
founds += "Name: [found.name]([found.real_name]) Ckey: [found.ckey] [is_antag ? "(Antag)" : null] "
|
||||
msg += "[original_word]<font size='1' color='[is_antag ? "red" : "black"]'>(<A HREF='?_src_=holder;adminmoreinfo=\ref[found]'>?</A>|<A HREF='?_src_=holder;adminplayerobservefollow=\ref[found]'>F</A>)</font> "
|
||||
continue
|
||||
msg += "[original_word] "
|
||||
if(irc)
|
||||
if(founds == "")
|
||||
return "Search Failed"
|
||||
else
|
||||
return founds
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
@@ -78,7 +90,20 @@
|
||||
return
|
||||
if(src.handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||
return
|
||||
var/ref_mob = "\ref[mob]"
|
||||
|
||||
|
||||
//clean the input msg
|
||||
if(!msg)
|
||||
return
|
||||
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
if(!msg) return
|
||||
var/original_msg = msg
|
||||
|
||||
msg = keywords_lookup(msg)
|
||||
|
||||
if(!mob)
|
||||
return //this doesn't happen
|
||||
|
||||
var/ref_client = "\ref[src]"
|
||||
for(var/datum/adminticket/T in admintickets)
|
||||
if(T.permckey == src.ckey && T.resolved == "No")
|
||||
@@ -87,7 +112,7 @@
|
||||
if(T.admin == "N/A")
|
||||
usr << "<b>Due to the fact your Adminhelp had no assigned admin, admins have been pinged.</b>"
|
||||
message_admins("[src.ckey] has bumped their adminhelp #[T.ID], still no assigned admin!")
|
||||
msg = "<span class='adminnotice'><b><font color=red>HELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> [ADMIN_QUE(mob)] [ADMIN_PP(mob)] [ADMIN_VV(mob)] [ADMIN_SM(mob)] [ADMIN_FLW(mob)] [ADMIN_TP(mob)] (<A HREF='?_src_=holder;rejectadminhelp=[ref_client]'>REJT</A>) (<A HREF='?_src_=holder;icissue=[ref_client]'>IC</A>) (<A HREF='?_src_=holder;resolve=[T.ID]'>R</a>):</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'><b><font color=red>HELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> [ADMIN_QUE(mob)] [ADMIN_PP(mob)] [ADMIN_VV(mob)] [ADMIN_SM(mob)] [ADMIN_FLW(mob)] [ADMIN_TP(mob)] (<A HREF='?_src_=holder;rejectadminhelp=[ref_client]'>REJT</A>) (<A HREF='?_src_=holder;icissue=[ref_client]'>IC</A>) (<A HREF='?_src_=ticket;resolve=[T.ID]'>R</a>):</b> [msg]</span>"
|
||||
for(var/client/X in admins)
|
||||
if(X.prefs.toggles & SOUND_ADMINHELP)
|
||||
X << 'sound/effects/adminhelp.ogg'
|
||||
@@ -104,27 +129,10 @@
|
||||
src.verbs -= /client/verb/adminhelp
|
||||
adminhelptimerid = addtimer(CALLBACK(src, .proc/giveadminhelpverb), 1200, TIMER_STOPPABLE)
|
||||
|
||||
//clean the input msg
|
||||
if(!msg) return
|
||||
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
if(!msg) return
|
||||
var/original_msg = msg
|
||||
|
||||
msg = keywords_lookup(msg)
|
||||
|
||||
if(!mob) return //this doesn't happen
|
||||
for(var/datum/adminticket/T in admintickets)
|
||||
msg = "<span class='adminnotice'><b><font color=red>HELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> [ADMIN_QUE(mob)] [ADMIN_PP(mob)] [ADMIN_VV(mob)] [ADMIN_SM(mob)] [ADMIN_FLW(mob)] [ADMIN_TP(mob)] (<A HREF='?_src_=holder;rejectadminhelp=[ref_client]'>REJT</A>) (<A HREF='?_src_=holder;icissue=[ref_client]'>IC</A>) (<A HREF='?_src_=ticket;resolve=[T.ID]'>R</a>):</b> [msg]</span>"
|
||||
|
||||
createticket(src, msg, src.ckey, mob)
|
||||
|
||||
var/datum/adminticket/ticket
|
||||
|
||||
for(var/datum/adminticket/T in admintickets)
|
||||
if(T.permckey == src.ckey)
|
||||
ticket = T
|
||||
|
||||
msg = "<span class='adminnotice'><b><font color=red>ADMINHELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;traitor=[ref_mob]'>TP</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=[ref_mob]'>FLW</A>) (<a href='?src=\ref[ticket];resolve=\ref[ticket]'>R</a>):</b> [msg]</span>"
|
||||
|
||||
|
||||
//send this msg to all admins
|
||||
|
||||
for(var/client/X in admins)
|
||||
@@ -138,88 +146,72 @@
|
||||
src << "<span class='adminnotice'>PM to-<b>Admins</b>: [original_msg]</span>"
|
||||
|
||||
//send it to irc if nobody is on and tell us how many were on
|
||||
var/admin_number_present = send2irc_admin_notice_handler("adminhelp", ckey, original_msg)
|
||||
log_admin("ADMINHELP: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins who have +BAN.")
|
||||
var/admin_number_present = send2admindiscord(ckey,original_msg)
|
||||
log_admin("HELP: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins who have +BAN.")
|
||||
if(admin_number_present <= 0)
|
||||
src << "<span class='notice'>No active admins are online, your adminhelp was sent to the admin irc.</span>"
|
||||
feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
|
||||
/proc/calculate_admins(type, requiredflags = R_BAN)
|
||||
var/admin_number_total = 0 //Total number of admins
|
||||
var/admin_number_afk = 0 //Holds the number of admins who are afk
|
||||
var/admin_number_ignored = 0 //Holds the number of admins without +BAN (so admins who are not really admins)
|
||||
var/admin_number_decrease = 0 //Holds the number of admins with are afk, ignored or both
|
||||
/proc/get_admin_counts(requiredflags = R_BAN)
|
||||
. = list("total" = list(), "noflags" = list(), "afk" = list(), "stealth" = list(), "present" = list())
|
||||
for(var/client/X in admins)
|
||||
admin_number_total++;
|
||||
var/invalid = 0
|
||||
.["total"] += X
|
||||
if(requiredflags != 0 && !check_rights_for(X, requiredflags))
|
||||
admin_number_ignored++
|
||||
invalid = 1
|
||||
if(X.is_afk())
|
||||
admin_number_afk++
|
||||
invalid = 1
|
||||
if(X.holder.fakekey)
|
||||
admin_number_ignored++
|
||||
invalid = 1
|
||||
if(invalid)
|
||||
admin_number_decrease++
|
||||
switch(type)
|
||||
if("ignored")
|
||||
return admin_number_ignored
|
||||
if("total")
|
||||
return admin_number_total
|
||||
if("away")
|
||||
return admin_number_afk
|
||||
if("present")
|
||||
return admin_number_total - admin_number_decrease
|
||||
return 0
|
||||
.["noflags"] += X
|
||||
else if(X.is_afk())
|
||||
.["afk"] += X
|
||||
else if(X.holder.fakekey)
|
||||
.["stealth"] += X
|
||||
else
|
||||
.["present"] += X
|
||||
|
||||
/proc/send2irc_adminless_only(source, msg, requiredflags = R_BAN)
|
||||
var/list/adm = get_admin_counts(requiredflags)
|
||||
var/list/activemins = adm["present"]
|
||||
. = activemins.len
|
||||
if(. <= 0)
|
||||
var/final = ""
|
||||
var/list/afkmins = adm["afk"]
|
||||
var/list/stealthmins = adm["stealth"]
|
||||
var/list/powerlessmins = adm["noflags"]
|
||||
var/list/allmins = adm["total"]
|
||||
if(!afkmins.len && !stealthmins.len && !powerlessmins.len)
|
||||
final = "[msg] - No admins online"
|
||||
else
|
||||
final = "[msg] - All admins stealthed\[[english_list(stealthmins)]\], AFK\[[english_list(afkmins)]\], or lacks +BAN\[[english_list(powerlessmins)]\]! Total: [allmins.len] "
|
||||
send2irc(source,final)
|
||||
send2admindiscord(source,final)
|
||||
|
||||
/proc/send2irc_admin_notice_handler(type, source, msg)
|
||||
var/afk_admins = calculate_admins("away")
|
||||
var/total_admins = calculate_admins("total")
|
||||
var/ignored_admins = calculate_admins("ignored")
|
||||
var/admin_number_present = calculate_admins("present") //Number of admins who are neither afk nor invalid
|
||||
var/irc_message_afk = "[msg] - All admins AFK ([afk_admins]/[total_admins]) or skipped ([ignored_admins]/[total_admins])"
|
||||
var/irc_message_normal = "[msg] - heard by [admin_number_present] non-AFK admins who have +BAN."
|
||||
var/irc_message_adminless = "[msg] - No admins online"
|
||||
|
||||
switch(type)
|
||||
if("adminhelp")
|
||||
if(config.announce_adminhelps)
|
||||
send2irc(source, irc_message_normal)
|
||||
else
|
||||
if(admin_number_present <= 0)
|
||||
if(!afk_admins && !ignored_admins)
|
||||
send2admindiscord(source, irc_message_adminless)
|
||||
else if(afk_admins >= 1)
|
||||
send2admindiscord(source, irc_message_afk)
|
||||
else
|
||||
send2admindiscord(source, irc_message_normal)
|
||||
if("watchlist")
|
||||
if(config.announce_watchlist)
|
||||
send2irc(source, irc_message_normal)
|
||||
else
|
||||
if(admin_number_present <= 0)
|
||||
if(!afk_admins && !ignored_admins)
|
||||
send2admindiscord(source, irc_message_adminless)
|
||||
else if(afk_admins >= 1)
|
||||
send2admindiscord(source, irc_message_afk)
|
||||
else
|
||||
send2admindiscord(source, irc_message_normal)
|
||||
if("new_player")
|
||||
if(config.irc_first_connection_alert)
|
||||
send2irc(source, irc_message_normal)
|
||||
else
|
||||
if(admin_number_present <= 0)
|
||||
if(!afk_admins && !ignored_admins)
|
||||
send2admindiscord(source, irc_message_adminless)
|
||||
else if(afk_admins >= 1)
|
||||
send2admindiscord(source, irc_message_afk)
|
||||
else
|
||||
send2admindiscord(source, irc_message_normal)
|
||||
return admin_number_present
|
||||
|
||||
/proc/send2irc(msg,msg2)
|
||||
if(config.useircbot)
|
||||
shell("python nudge.py [msg] \"[msg2]\"")
|
||||
return
|
||||
shell("python nudge.py [msg] [msg2]")
|
||||
return
|
||||
|
||||
/proc/send2otherserver(source,msg,type = "Ahelp")
|
||||
if(global.cross_allowed)
|
||||
var/list/message = list()
|
||||
message["message_sender"] = source
|
||||
message["message"] = msg
|
||||
message["source"] = "([config.cross_name])"
|
||||
message["key"] = global.comms_key
|
||||
message["crossmessage"] = type
|
||||
|
||||
world.Export("[global.cross_address]?[list2params(message)]")
|
||||
|
||||
|
||||
/proc/ircadminwho()
|
||||
var/list/message = list("Admins: ")
|
||||
var/list/admin_keys = list()
|
||||
for(var/adm in admins)
|
||||
var/client/C = adm
|
||||
admin_keys += "[C][C.holder.fakekey ? "(Stealth)" : ""][C.is_afk() ? "(AFK)" : ""]"
|
||||
|
||||
for(var/admin in admin_keys)
|
||||
if(LAZYLEN(admin_keys) > 1)
|
||||
message += ", [admin]"
|
||||
else
|
||||
message += "[admin]"
|
||||
|
||||
return jointext(message, "")
|
||||
@@ -1,3 +1,5 @@
|
||||
#define IRCREPLYCOUNT 2
|
||||
|
||||
//allows right clicking mobs to send an admin PM to their client, forwards the selected mob's client to cmd_admin_pm
|
||||
/client/proc/cmd_admin_pm_context(mob/M in mob_list)
|
||||
set category = null
|
||||
@@ -5,7 +7,8 @@
|
||||
if(!holder)
|
||||
src << "<font color='red'>Error: Admin-PM-Context: Only administrators may use this command.</font>"
|
||||
return
|
||||
if( !ismob(M) || !M.client ) return
|
||||
if( !ismob(M) || !M.client )
|
||||
return
|
||||
cmd_admin_pm(M.client,null)
|
||||
feedback_add_details("admin_verb","APMM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -19,16 +22,15 @@
|
||||
var/list/client/targets[0]
|
||||
for(var/client/T)
|
||||
if(T.mob)
|
||||
if(istype(T.mob, /mob/new_player))
|
||||
if(isnewplayer(T.mob))
|
||||
targets["(New Player) - [T]"] = T
|
||||
else if(istype(T.mob, /mob/dead/observer))
|
||||
else if(isobserver(T.mob))
|
||||
targets["[T.mob.name](Ghost) - [T]"] = T
|
||||
else
|
||||
targets["[T.mob.real_name](as [T.mob.name]) - [T]"] = T
|
||||
else
|
||||
targets["(No Mob) - [T]"] = T
|
||||
var/list/sorted = sortList(targets)
|
||||
var/target = input(src,"To whom shall we send a message?","Admin PM",null) in sorted|null
|
||||
var/target = input(src,"To whom shall we send a message?","Admin PM",null) as null|anything in sortList(targets)
|
||||
cmd_admin_pm(targets[target],null)
|
||||
feedback_add_details("admin_verb","APM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -44,7 +46,8 @@
|
||||
else if(istype(whom,/client))
|
||||
C = whom
|
||||
if(!C)
|
||||
if(holder) src << "<font color='red'>Error: Admin-PM: Client not found.</font>"
|
||||
if(holder)
|
||||
src << "<font color='red'>Error: Admin-PM: Client not found.</font>"
|
||||
return
|
||||
|
||||
var/datum/adminticket/ticket
|
||||
@@ -205,4 +208,51 @@
|
||||
//we don't use message_admins here because the sender/receiver might get it too
|
||||
for(var/client/X in admins)
|
||||
if(X.key!=key && X.key!=C.key) //check client/X is an admin and isn't the sender or recipient
|
||||
X << "<B><font color='blue'>PM: [key_name(src, X, 0)]->[key_name(C, X, 0)]:</B> \blue [keywordparsedmsg]</font>" //inform X
|
||||
X << "<B><font color='blue'>PM: [key_name(src, X, 0)]->[key_name(C, X, 0)]:</B> \blue [keywordparsedmsg]</font>" //inform X
|
||||
|
||||
/proc/IrcPm(target,msg,sender)
|
||||
|
||||
var/client/C = directory[target]
|
||||
|
||||
var/static/stealthkey
|
||||
var/adminname = config.showircname ? "[sender](IRC)" : "Administrator"
|
||||
|
||||
if(!C)
|
||||
return "No client"
|
||||
|
||||
if(!stealthkey)
|
||||
stealthkey = GenIrcStealthKey()
|
||||
|
||||
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
if(!msg)
|
||||
return "No message"
|
||||
|
||||
message_admins("IRC message from [sender] to [key_name_admin(C)] : [msg]")
|
||||
log_admin("IRC PM: [sender] -> [key_name(C)] : [msg]")
|
||||
msg = emoji_parse(msg)
|
||||
|
||||
C << "<font color='red' size='4'><b>-- Administrator private message --</b></font>"
|
||||
C << "<font color='red'>Admin PM from-<b><a href='?priv_msg=[stealthkey]'>[adminname]</A></b>: [msg]</font>"
|
||||
C << "<font color='red'><i>Click on the administrator's name to reply.</i></font>"
|
||||
window_flash(C)
|
||||
//always play non-admin recipients the adminhelp sound
|
||||
C << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
C.ircreplyamount = IRCREPLYCOUNT
|
||||
|
||||
return "Message Successful"
|
||||
|
||||
/proc/GenIrcStealthKey()
|
||||
var/num = (rand(0,1000))
|
||||
var/i = 0
|
||||
while(i == 0)
|
||||
i = 1
|
||||
for(var/P in stealthminID)
|
||||
if(num == stealthminID[P])
|
||||
num++
|
||||
i = 0
|
||||
var/stealth = "@[num2text(num)]"
|
||||
stealthminID["IRCKEY"] = stealth
|
||||
return stealth
|
||||
|
||||
#undef IRCREPLYCOUNT
|
||||
@@ -118,16 +118,19 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
if(isnull(argnum))
|
||||
return
|
||||
|
||||
var/list/lst = list()
|
||||
|
||||
. = list()
|
||||
var/list/named_args = list()
|
||||
while(argnum--)
|
||||
var/named_arg = input("Leave blank for positional argument. Positional arguments will be considered as if they were added first.", "Named argument") as text|null
|
||||
var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
|
||||
if (!value["class"])
|
||||
return
|
||||
lst += value["value"]
|
||||
|
||||
return lst
|
||||
|
||||
if(named_arg)
|
||||
named_args[named_arg] = value["value"]
|
||||
else
|
||||
. += value["value"]
|
||||
if(LAZYLEN(named_args))
|
||||
. += named_args
|
||||
|
||||
/client/proc/get_callproc_returnval(returnval,procname)
|
||||
. = ""
|
||||
|
||||
@@ -35,11 +35,11 @@
|
||||
|
||||
var/list/atmos_overlay_types //gas IDs of current active gas overlays
|
||||
|
||||
/turf/open/New()
|
||||
..()
|
||||
/turf/open/Initialize()
|
||||
if(!blocks_air)
|
||||
air = new
|
||||
air.copy_from_turf(src)
|
||||
..()
|
||||
|
||||
/turf/open/Destroy()
|
||||
if(active_hotspot)
|
||||
@@ -113,11 +113,12 @@
|
||||
|
||||
/turf/open/proc/tile_graphic()
|
||||
. = new /list
|
||||
var/list/gases = air.gases
|
||||
for(var/id in gases)
|
||||
var/gas = gases[id]
|
||||
if(gas[GAS_META][META_GAS_OVERLAY] && gas[MOLES] > gas[GAS_META][META_GAS_MOLES_VISIBLE])
|
||||
. += gas[GAS_META][META_GAS_OVERLAY]
|
||||
if(air)
|
||||
var/list/gases = air.gases
|
||||
for(var/id in gases)
|
||||
var/gas = gases[id]
|
||||
if(gas[GAS_META][META_GAS_OVERLAY] && gas[MOLES] > gas[GAS_META][META_GAS_MOLES_VISIBLE])
|
||||
. += gas[GAS_META][META_GAS_OVERLAY]
|
||||
|
||||
/////////////////////////////SIMULATION///////////////////////////////////
|
||||
|
||||
|
||||
@@ -99,26 +99,28 @@
|
||||
flags_cover = MASKCOVERSEYES
|
||||
resistance_flags = FLAMMABLE
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
|
||||
|
||||
/obj/item/clothing/mask/gas/mime/attack_self(mob/user)
|
||||
cycle_mask(user)
|
||||
/obj/item/clothing/mask/gas/mime/ui_action_click(mob/user)
|
||||
if(!istype(user) || user.incapacitated())
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/gas/mime/proc/cycle_mask(mob/user)
|
||||
switch(icon_state)
|
||||
if("mime")
|
||||
icon_state = "sadmime"
|
||||
if("sadmime")
|
||||
icon_state = "scaredmime"
|
||||
if("scaredmime")
|
||||
icon_state = "sexymime"
|
||||
if("sexymime")
|
||||
icon_state = "mime"
|
||||
user.update_inv_wear_mask()
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
user << "<span class='notice'>You adjust your mask to portray a different emotion.</span>"
|
||||
return 1
|
||||
var/list/options = list()
|
||||
options["Blanc"] = "mime"
|
||||
options["Triste"] = "sadmime"
|
||||
options["Effrayé"] = "scaredmime"
|
||||
options["Excité"] ="sexymime"
|
||||
|
||||
var/choice = input(user,"To what form do you wish to Morph this mask?","Morph Mask") in options
|
||||
|
||||
if(src && choice && !user.incapacitated() && in_range(user,src))
|
||||
icon_state = options[choice]
|
||||
user.update_inv_wear_mask()
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
user << "<span class='notice'>Your Mime Mask has now morphed into [choice]!</span>"
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/mask/gas/monkeymask
|
||||
name = "monkey mask"
|
||||
@@ -170,6 +172,7 @@
|
||||
resistance_flags = FLAMMABLE
|
||||
obj_integrity = 100
|
||||
max_integrity = 100
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
dog_fashion = null
|
||||
|
||||
|
||||
@@ -186,7 +189,6 @@ obj/item/clothing/mask/gas/tiki_mask/ui_action_click(mob/user)
|
||||
|
||||
if(src && choice && !M.stat && in_range(M,src))
|
||||
icon_state = options[choice]
|
||||
item_state = options[choice]
|
||||
user.update_inv_wear_mask()
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
|
||||
@@ -268,6 +268,11 @@
|
||||
/obj/item/clothing/suit/armor/reactive/tesla
|
||||
name = "reactive tesla armor"
|
||||
desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
|
||||
siemens_coefficient = -1
|
||||
var/tesla_power = 25000
|
||||
var/tesla_range = 20
|
||||
var/tesla_boom = FALSE
|
||||
var/tesla_stun = FALSE
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/tesla/hit_reaction(mob/living/carbon/human/owner, attack_text)
|
||||
if(!active)
|
||||
@@ -277,15 +282,10 @@
|
||||
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
|
||||
sparks.set_up(1, 1, src)
|
||||
sparks.start()
|
||||
owner.visible_message("<span class='danger'>The tesla capacitors on [owner]'s reactive telsa armor are still recharging! The armor merely emits some sparks.</spawn>")
|
||||
owner.visible_message("<span class='danger'>The tesla capacitors on [owner]'s reactive tesla armor are still recharging! The armor merely emits some sparks.</spawn>")
|
||||
return
|
||||
owner.visible_message("<span class='danger'>The [src] blocks the [attack_text], sending out arcs of lightning!</span>")
|
||||
for(var/mob/living/M in view(6, owner))
|
||||
if(M == owner)
|
||||
continue
|
||||
owner.Beam(M,icon_state="lightning[rand(1, 12)]",time=5)
|
||||
M.adjustFireLoss(25)
|
||||
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
tesla_zap(owner,tesla_range,tesla_power,tesla_boom, tesla_stun)
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
typepath = /datum/round_event/ghost_role/sentience
|
||||
weight = 10
|
||||
|
||||
|
||||
/datum/round_event/ghost_role/sentience
|
||||
minimum_required = 1
|
||||
role_name = "random animal"
|
||||
var/animals = 1
|
||||
var/one = "one"
|
||||
|
||||
/datum/round_event/ghost_role/sentience/start()
|
||||
var/sentience_report = "<font size=3><b>[command_name()] Medium-Priority Update</b></font>"
|
||||
@@ -14,7 +17,7 @@
|
||||
var/pets = pick("animals/bots", "bots/animals", "pets", "simple animals", "lesser lifeforms", "\[REDACTED\]")
|
||||
var/strength = pick("human", "moderate", "lizard", "security", "command", "clown", "low", "very low", "\[REDACTED\]")
|
||||
|
||||
sentience_report += "<br><br>Based on [data], we believe that one of the station's [pets] has developed [strength] level intelligence, and the ability to communicate."
|
||||
sentience_report += "<br><br>Based on [data], we believe that [one] of the station's [pets] has developed [strength] level intelligence, and the ability to communicate."
|
||||
|
||||
print_command_report(sentience_report, "Classified [command_name()] Update")
|
||||
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg')
|
||||
@@ -36,25 +39,40 @@
|
||||
|
||||
if(!potential.len)
|
||||
return WAITING_FOR_SOMETHING
|
||||
var/mob/living/simple_animal/SA = pick(potential)
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
var/mob/dead/observer/SG = pick(candidates)
|
||||
|
||||
SA.key = SG.key
|
||||
SA.languages_spoken |= HUMAN
|
||||
SA.languages_understood |= HUMAN
|
||||
SA.sentience_act()
|
||||
var/spawned_animals = 0
|
||||
while(spawned_animals < animals && candidates.len && potential.len)
|
||||
var/mob/living/simple_animal/SA = pick_n_take(potential)
|
||||
var/mob/dead/observer/SG = pick_n_take(candidates)
|
||||
|
||||
SA.maxHealth = max(SA.maxHealth, 200)
|
||||
SA.health = SA.maxHealth
|
||||
SA.del_on_death = FALSE
|
||||
spawned_animals++
|
||||
|
||||
spawned_mobs += SA
|
||||
SA.key = SG.key
|
||||
SA.languages_spoken |= HUMAN
|
||||
SA.languages_understood |= HUMAN
|
||||
SA.sentience_act()
|
||||
|
||||
SA << "<span class='userdanger'>Hello world!</span>"
|
||||
SA << "<span class='warning'>Due to freak radiation and/or chemicals \
|
||||
and/or lucky chance, you have gained human level intelligence \
|
||||
and the ability to speak and understand human language!</span>"
|
||||
SA.maxHealth = max(SA.maxHealth, 200)
|
||||
SA.health = SA.maxHealth
|
||||
SA.del_on_death = FALSE
|
||||
|
||||
spawned_mobs += SA
|
||||
|
||||
SA << "<span class='userdanger'>Hello world!</span>"
|
||||
SA << "<span class='warning'>Due to freak radiation and/or chemicals \
|
||||
and/or lucky chance, you have gained human level intelligence \
|
||||
and the ability to speak and understand human language!</span>"
|
||||
|
||||
return SUCCESSFUL_SPAWN
|
||||
|
||||
/datum/round_event_control/sentience/all
|
||||
name = "Station-wide Human-level Intelligence"
|
||||
typepath = /datum/round_event/ghost_role/sentience/all
|
||||
weight = 0
|
||||
|
||||
/datum/round_event/ghost_role/sentience/all
|
||||
one = "all"
|
||||
animals = INFINITY // as many as there are ghosts and animals
|
||||
// cockroach pride, station wide
|
||||
|
||||
@@ -124,6 +124,12 @@
|
||||
list_reagents = list("sodiumchloride" = 20)
|
||||
possible_states = list()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/condiment/saltshaker/on_reagent_change()
|
||||
if(reagents.reagent_list.len == 0)
|
||||
icon_state = "emptyshaker"
|
||||
else
|
||||
icon_state = "saltshakersmall"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/condiment/saltshaker/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] begins to swap forms with the salt shaker! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
var/newname = "[name]"
|
||||
@@ -156,6 +162,12 @@
|
||||
list_reagents = list("blackpepper" = 20)
|
||||
possible_states = list()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/condiment/peppermill/on_reagent_change()
|
||||
if(reagents.reagent_list.len == 0)
|
||||
icon_state = "emptyshaker"
|
||||
else
|
||||
icon_state = "peppermillsmall"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/condiment/milk
|
||||
name = "space milk"
|
||||
desc = "It's milk. White and nutritious goodness!"
|
||||
|
||||
@@ -18,6 +18,15 @@ insert ascii eagle on american flag background here
|
||||
container_type = OPENCONTAINER
|
||||
var/obj/item/frying = null //What's being fried RIGHT NOW?
|
||||
var/cook_time = 0
|
||||
var/static/list/blacklisted_items = typecacheof(list(
|
||||
/obj/item/weapon/screwdriver,
|
||||
/obj/item/weapon/crowbar,
|
||||
/obj/item/weapon/wrench,
|
||||
/obj/item/weapon/wirecutters,
|
||||
/obj/item/device/multitool,
|
||||
/obj/item/weapon/weldingtool,
|
||||
/obj/item/weapon/reagent_containers/glass,
|
||||
/obj/item/weapon/storage/part_replacer))
|
||||
|
||||
/obj/item/weapon/circuitboard/machine/deep_fryer
|
||||
name = "circuit board (Deep Fryer)"
|
||||
@@ -46,8 +55,16 @@ insert ascii eagle on american flag background here
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/deepfryholder))
|
||||
user << "<span class='userdanger'>Your cooking skills are not up to the legendary Doublefry technique.</span>"
|
||||
return
|
||||
if(default_unfasten_wrench(user, I))
|
||||
return
|
||||
else if(exchange_parts(user, I))
|
||||
return
|
||||
else if(default_deconstruction_screwdriver(user, "fryer_off", "fryer_off" ,I)) //where's the open maint panel icon?!
|
||||
return
|
||||
else
|
||||
if(user.drop_item() && !frying)
|
||||
if(is_type_in_typecache(I, blacklisted_items))
|
||||
. = ..()
|
||||
else if(user.drop_item() && !frying)
|
||||
user << "<span class='notice'>You put [I] into [src].</span>"
|
||||
frying = I
|
||||
frying.forceMove(src)
|
||||
@@ -78,6 +95,7 @@ insert ascii eagle on american flag background here
|
||||
S.overlays = frying.overlays
|
||||
S.icon_state = frying.icon_state
|
||||
S.desc = frying.desc
|
||||
S.w_class = frying.w_class
|
||||
reagents.trans_to(S, 2*(cook_time/15))
|
||||
switch(cook_time)
|
||||
if(0 to 15)
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
if(V == "air")
|
||||
var/turf/open/O1 = B
|
||||
var/turf/open/O2 = T
|
||||
O1.air.copy_from(O2.air)
|
||||
O1.air.copy_from(O2.return_air())
|
||||
continue
|
||||
B.vars[V] = T.vars[V]
|
||||
toupdate += B
|
||||
|
||||
@@ -64,25 +64,25 @@
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/holodeck/Initialize(mapload)
|
||||
..()
|
||||
if(!mapload && ticker.current_state < GAME_STATE_PLAYING)
|
||||
return
|
||||
program_cache = list()
|
||||
emag_programs = list()
|
||||
for(var/typekey in subtypesof(program_type))
|
||||
var/area/holodeck/A = locate(typekey)
|
||||
if(!A || A == offline_program) continue
|
||||
if(A.contents.len == 0) continue // not loaded
|
||||
if(A.restricted)
|
||||
emag_programs += A
|
||||
else
|
||||
program_cache += A
|
||||
if(typekey == init_program)
|
||||
load_program(A,force=1)
|
||||
if(random_program && program_cache.len && init_program == null)
|
||||
load_program(pick(program_cache),force=1)
|
||||
else if(!program)
|
||||
load_program(offline_program)
|
||||
. = mapload //late-initialize, area_copy need turfs to have air
|
||||
if(!mapload)
|
||||
..()
|
||||
program_cache = list()
|
||||
emag_programs = list()
|
||||
for(var/typekey in subtypesof(program_type))
|
||||
var/area/holodeck/A = locate(typekey)
|
||||
if(!A || A == offline_program) continue
|
||||
if(A.contents.len == 0) continue // not loaded
|
||||
if(A.restricted)
|
||||
emag_programs += A
|
||||
else
|
||||
program_cache += A
|
||||
if(typekey == init_program)
|
||||
load_program(A,force=1)
|
||||
if(random_program && program_cache.len && init_program == null)
|
||||
load_program(pick(program_cache),force=1)
|
||||
else if(!program)
|
||||
load_program(offline_program)
|
||||
|
||||
/obj/machinery/computer/holodeck/power_change()
|
||||
..()
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
name = "asteroid"
|
||||
icon_state = "asteroid0"
|
||||
|
||||
/turf/open/floor/holofloor/asteroid/New()
|
||||
/turf/open/floor/holofloor/asteroid/Initialize()
|
||||
icon_state = "asteroid[pick(0,1,2,3,4,5,6,7,8,9,10,11,12)]"
|
||||
..()
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
name = "basalt"
|
||||
icon_state = "basalt0"
|
||||
|
||||
/turf/open/floor/holofloor/basalt/New()
|
||||
/turf/open/floor/holofloor/basalt/Initialize()
|
||||
icon_state = "basalt[pick(0,1,2,3,4,5,6,7,8,9,10,11,12)]"
|
||||
..()
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
icon = 'icons/turf/space.dmi'
|
||||
icon_state = "0"
|
||||
|
||||
/turf/open/floor/holofloor/space/New()
|
||||
/turf/open/floor/holofloor/space/Initialize()
|
||||
icon_state = SPACE_ICON_STATE // so realistic
|
||||
..()
|
||||
|
||||
@@ -68,11 +68,11 @@
|
||||
icon = 'icons/turf/space.dmi'
|
||||
icon_state = "speedspace_ns_1"
|
||||
|
||||
/turf/open/floor/holofloor/hyperspace/New()
|
||||
/turf/open/floor/holofloor/hyperspace/Initialize()
|
||||
icon_state = "speedspace_ns_[(x + 5*y + (y%2+1)*7)%15+1]"
|
||||
..()
|
||||
|
||||
/turf/open/floor/holofloor/hyperspace/ns/New()
|
||||
/turf/open/floor/holofloor/hyperspace/ns/Initialize()
|
||||
..()
|
||||
icon_state = "speedspace_ns_[(x + 5*y + (y%2+1)*7)%15+1]"
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = null
|
||||
|
||||
/turf/open/floor/holofloor/carpet/New()
|
||||
/turf/open/floor/holofloor/carpet/Initialize()
|
||||
..()
|
||||
addtimer(CALLBACK(src, .proc/update_icon), 1)
|
||||
|
||||
|
||||
@@ -1,40 +1,22 @@
|
||||
#define SOAPSTONE_PREFIX_FILE "strings/soapstone_prefixes.txt"
|
||||
#define SOAPSTONE_SUFFIX_FILE "soapstone_suffixes.json"
|
||||
//Vocabulary lists; soapstones use a prefix and a suffix. Optionally, they can have a prefix and suffix, then a conjunction that links another set.
|
||||
var/global/list/soapstone_prefixes = list() //Read from "strings/soapstone_prefixes.txt"; if you're adding your own, put **** where the subject should be!
|
||||
var/global/list/soapstone_suffixes = list() //Read from "strings/soapstone_suffixes.json"
|
||||
/obj/item/soapstone
|
||||
name = "chisel"
|
||||
desc = "Leave \"informative\" messages for the crew, including the crew of future shifts!\n\
|
||||
(Not suitable for engraving on shuttles, off station or on cats. Side effects may include beatings, bannings and orbital bombardment.)"
|
||||
desc = "Leave informative messages for the crew, including the crew of future shifts!\nEven if out of uses, it can still be used to remove messages.\n(Not suitable for engraving on shuttles, off station or on cats. Side effects may include beatings, bannings and orbital bombardment.)"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "soapstone"
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/tool_speed = 50
|
||||
var/remaining_uses = 3
|
||||
|
||||
var/non_dull_name
|
||||
var/w_engrave = "engrave"
|
||||
var/w_engraving = "engraving"
|
||||
var/w_chipping = "chipping"
|
||||
var/w_dull = "dull"
|
||||
|
||||
/obj/item/soapstone/New()
|
||||
. = ..()
|
||||
if(!soapstone_prefixes.len)
|
||||
soapstone_prefixes = file2list(SOAPSTONE_PREFIX_FILE, "\n")
|
||||
if(!soapstone_suffixes.len)
|
||||
soapstone_suffixes = list(\
|
||||
"Characters" = strings(SOAPSTONE_SUFFIX_FILE, "Characters"), \
|
||||
"Careers" = strings(SOAPSTONE_SUFFIX_FILE, "Careers"), \
|
||||
"Antagonists" = strings(SOAPSTONE_SUFFIX_FILE, "Antagonists"), \
|
||||
"Objects" = strings(SOAPSTONE_SUFFIX_FILE, "Objects"), \
|
||||
"Techniques" = strings(SOAPSTONE_SUFFIX_FILE, "Techniques"), \
|
||||
"Actions" = strings(SOAPSTONE_SUFFIX_FILE, "Actions"), \
|
||||
"Geography" = strings(SOAPSTONE_SUFFIX_FILE, "Geography"), \
|
||||
"Orientation" = strings(SOAPSTONE_SUFFIX_FILE, "Orientation"), \
|
||||
"Body parts" = strings(SOAPSTONE_SUFFIX_FILE, "Body parts"), \
|
||||
"Concepts" = strings(SOAPSTONE_SUFFIX_FILE, "Concepts"), \
|
||||
"Musings" = strings(SOAPSTONE_SUFFIX_FILE, "Musings"), \
|
||||
)
|
||||
random_name()
|
||||
check_name() // could start empty
|
||||
|
||||
@@ -43,6 +25,9 @@ var/global/list/soapstone_suffixes = list() //Read from "strings/soapstone_suffi
|
||||
non_dull_name = name
|
||||
if(name == "chalk" || name == "magic marker")
|
||||
desc = replacetext(desc, "engraving", "scribbling")
|
||||
w_engrave = "scribble"
|
||||
w_engraving = "scribbling"
|
||||
w_chipping = "sketching"
|
||||
if(name == "chalk")
|
||||
w_dull = "used"
|
||||
if(name == "magic marker")
|
||||
@@ -50,6 +35,9 @@ var/global/list/soapstone_suffixes = list() //Read from "strings/soapstone_suffi
|
||||
|
||||
if(name == "soapstone" || name == "chisel")
|
||||
desc = replacetext(desc, "scribbling", "engraving")
|
||||
w_engrave = initial(w_engrave)
|
||||
w_engraving = initial(w_engraving)
|
||||
w_chipping = initial(w_chipping)
|
||||
w_dull = "dull"
|
||||
|
||||
/obj/item/soapstone/examine(mob/user)
|
||||
@@ -60,48 +48,59 @@ var/global/list/soapstone_suffixes = list() //Read from "strings/soapstone_suffi
|
||||
user << "It looks like it can be used an unlimited number of times."
|
||||
|
||||
/obj/item/soapstone/afterattack(atom/target, mob/user, proximity)
|
||||
if(!remaining_uses)
|
||||
user << "<span class='warning'>[src] is [w_dull] and can't be used anymore!</span>"
|
||||
return
|
||||
var/turf/T = get_turf(target)
|
||||
if(!proximity)
|
||||
return
|
||||
var/obj/structure/chisel_message/msg = locate() in T
|
||||
if(msg)
|
||||
if(msg.creator_key != user.ckey)
|
||||
user << "<span class='warning'>There's already a message there!</span>"
|
||||
return
|
||||
else
|
||||
if(alert(user, "Erase this message?", name, "Yes", "No") == "Yes")
|
||||
user.visible_message("<span class='notice'>[user] erases [msg].</span>", "<span class='notice'>You permanently erase [msg].</span>")
|
||||
playsound(T, 'sound/items/gavel.ogg', 50, 1)
|
||||
refund_use()
|
||||
msg.persists = 0
|
||||
qdel(msg)
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
var/obj/structure/chisel_message/already_message = locate(/obj/structure/chisel_message) in T
|
||||
|
||||
var/our_message = FALSE
|
||||
if(already_message)
|
||||
our_message = already_message.creator_key == user.ckey
|
||||
|
||||
if(!remaining_uses && !already_message)
|
||||
// The dull chisel is dull.
|
||||
user << "<span class='warning'>[src] is [w_dull].</span>"
|
||||
return
|
||||
|
||||
if(!good_chisel_message_location(T))
|
||||
user << "<span class='warning'>You can't write there!</span>"
|
||||
user << "<span class='warning'>It's not appropriate to [w_engrave] on [T].</span>"
|
||||
return
|
||||
var/prefix = input(user, "Choose a prefix for your message.", name) as null|anything in soapstone_prefixes
|
||||
if(!prefix)
|
||||
|
||||
if(already_message)
|
||||
user.visible_message("<span class='notice'>[user] starts erasing [already_message].</span>", "<span class='notice'>You start erasing [already_message].</span>", "<span class='italics'>You hear a [w_chipping] sound.</span>")
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
|
||||
|
||||
// Removing our own messages refunds a charge
|
||||
|
||||
if(do_after(user, tool_speed, target=target))
|
||||
user.visible_message("<span class='notice'>[user] has erased [already_message].</span>", "<span class='notice'>You erased [already_message].</span>")
|
||||
already_message.persists = FALSE
|
||||
qdel(already_message)
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
|
||||
if(our_message)
|
||||
refund_use()
|
||||
return
|
||||
var/suffix_category_string = input(user, "Choose a suffix category.", "[prefix]...") as null|anything in soapstone_suffixes
|
||||
var/list/suffix_category = soapstone_suffixes[suffix_category_string]
|
||||
if(!suffix_category || !suffix_category.len)
|
||||
|
||||
var/message = stripped_input(user, "What would you like to [w_engrave]?", "[name] Message")
|
||||
if(!message)
|
||||
user << "You decide not to [w_engrave] anything."
|
||||
return
|
||||
var/suffix = input(user, "Choose a suffix.", "[prefix]...") as null|anything in suffix_category
|
||||
if(!suffix)
|
||||
|
||||
if(!target.Adjacent(user) && locate(/obj/structure/chisel_message) in T)
|
||||
user << "You decide not to [w_engrave] anything."
|
||||
return
|
||||
var/processed_message = replacetext(prefix, "****", suffix)
|
||||
if(!user.Adjacent(T) || !good_chisel_message_location(T) || locate(/obj/structure/chisel_message) in T)
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] writes a message onto [T]!</span>", "<span class='notice'>You write a message onto [T].</span>")
|
||||
playsound(T, 'sound/items/gavel.ogg', 50, 1)
|
||||
var/obj/structure/chisel_message/M = new(T)
|
||||
M.register(user, processed_message)
|
||||
remove_use()
|
||||
return 1
|
||||
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
|
||||
user.visible_message("<span class='notice'>[user] starts [w_engraving] a message into [T].</span>", "You start [w_engraving] a message into [T].", "<span class='italics'>You hear a [w_chipping] sound.</span>")
|
||||
if(can_use() && do_after(user, tool_speed, target=T) && can_use())
|
||||
if(!locate(/obj/structure/chisel_message in T))
|
||||
user << "You [w_engrave] a message into [T]."
|
||||
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
|
||||
var/obj/structure/chisel_message/M = new(T)
|
||||
M.register(user, message)
|
||||
remove_use()
|
||||
|
||||
/obj/item/soapstone/proc/can_use()
|
||||
if(remaining_uses == -1 || remaining_uses >= 0)
|
||||
@@ -172,34 +171,6 @@ var/global/list/soapstone_suffixes = list() //Read from "strings/soapstone_suffi
|
||||
var/map
|
||||
var/persists = TRUE
|
||||
|
||||
var/positive_ratings = 0
|
||||
var/negative_ratings = 0
|
||||
|
||||
var/list/raters = list() //Ckeys who have rated this message
|
||||
|
||||
/obj/structure/chisel_message/attack_hand(mob/user)
|
||||
if(user.ckey == creator_key)
|
||||
user << "<span class='warning'>You can't rate your own messages!</span>"
|
||||
return
|
||||
if(raters[user.ckey])
|
||||
user << "<span class='warning'>You've already rated this message!</span>"
|
||||
return
|
||||
switch(alert(user, "How would you like to rate this message?", "Message Rating", "Positive", "Negative", "Cancel"))
|
||||
if("Positive")
|
||||
for(var/client/C in clients)
|
||||
if(C.ckey == creator_key)
|
||||
C.mob << "<span class='notice'>One of your messages was rated as positive!</span>"
|
||||
user << "<span class='noticealien'>You rated this message as positive.</span>"
|
||||
positive_ratings++
|
||||
raters[user.ckey] = "positive"
|
||||
if("Negative")
|
||||
for(var/client/C in clients)
|
||||
if(C.ckey == creator_key)
|
||||
C.mob << "<span class='danger'>One of your messages was rated as negative!</span>"
|
||||
user << "<span class='danger'>You rated this message as negative.</span>"
|
||||
negative_ratings++
|
||||
raters[user.ckey] = "negative"
|
||||
|
||||
/obj/structure/chisel_message/New(newloc)
|
||||
..()
|
||||
SSpersistence.chisel_messages += src
|
||||
@@ -219,6 +190,12 @@ var/global/list/soapstone_suffixes = list() //Read from "strings/soapstone_suffi
|
||||
map = MAP_NAME
|
||||
update_icon()
|
||||
|
||||
/obj/structure/chisel_message/update_icon()
|
||||
..()
|
||||
var/hash = md5(hidden_message)
|
||||
var/newcolor = copytext(hash, 1, 7)
|
||||
add_atom_colour("#[newcolor]", FIXED_COLOUR_PRIORITY)
|
||||
|
||||
/obj/structure/chisel_message/proc/pack()
|
||||
var/list/data = list()
|
||||
data["hidden_message"] = hidden_message
|
||||
@@ -229,9 +206,6 @@ var/global/list/soapstone_suffixes = list() //Read from "strings/soapstone_suffi
|
||||
var/turf/T = get_turf(src)
|
||||
data["x"] = T.x
|
||||
data["y"] = T.y
|
||||
data["pos_ratings"] = positive_ratings
|
||||
data["neg_ratings"] = positive_ratings
|
||||
data["raters"] = raters
|
||||
return data
|
||||
|
||||
/obj/structure/chisel_message/proc/unpack(list/data)
|
||||
@@ -239,9 +213,6 @@ var/global/list/soapstone_suffixes = list() //Read from "strings/soapstone_suffi
|
||||
creator_name = data["creator_name"]
|
||||
creator_key = data["creator_key"]
|
||||
realdate = data["realdate"]
|
||||
positive_ratings = data["pos_ratings"]
|
||||
negative_ratings = data["neg_ratings"]
|
||||
raters = data["raters"]
|
||||
|
||||
var/x = data["x"]
|
||||
var/y = data["y"]
|
||||
@@ -251,10 +222,7 @@ var/global/list/soapstone_suffixes = list() //Read from "strings/soapstone_suffi
|
||||
|
||||
/obj/structure/chisel_message/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='notice'>[hidden_message]</span>"
|
||||
user << "Ratings: <span class='noticealien'>[positive_ratings]</span> <span class='danger'>[negative_ratings]</span>"
|
||||
if(raters[user.ckey])
|
||||
user << "<i>You rated this message as [raters[user.ckey]].</i>"
|
||||
user << "<span class='warning'>[hidden_message]</span>"
|
||||
|
||||
/obj/structure/chisel_message/Destroy()
|
||||
if(persists)
|
||||
|
||||
@@ -91,20 +91,29 @@
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/throw_impact(atom/hit_atom)
|
||||
/mob/living/carbon/throw_impact(atom/hit_atom, throwingdatum)
|
||||
. = ..()
|
||||
var/hurt = TRUE
|
||||
if(istype(throwingdatum, /datum/thrownthing))
|
||||
var/datum/thrownthing/D = throwingdatum
|
||||
if(iscyborg(D.thrower))
|
||||
var/mob/living/silicon/robot/R = D.thrower
|
||||
if(!R.emagged)
|
||||
hurt = FALSE
|
||||
if(hit_atom.density && isturf(hit_atom))
|
||||
Weaken(1)
|
||||
take_bodypart_damage(10)
|
||||
if(hurt)
|
||||
Weaken(1)
|
||||
take_bodypart_damage(10)
|
||||
if(iscarbon(hit_atom) && hit_atom != src)
|
||||
var/mob/living/carbon/victim = hit_atom
|
||||
if(victim.movement_type & FLYING)
|
||||
return
|
||||
victim.Weaken(1)
|
||||
Weaken(1)
|
||||
victim.take_bodypart_damage(10)
|
||||
take_bodypart_damage(10)
|
||||
visible_message("<span class='danger'>[src] crashes into [victim], knocking them both over!</span>", "<span class='userdanger'>You violently crash into [victim]!</span>")
|
||||
if(hurt)
|
||||
victim.take_bodypart_damage(10)
|
||||
take_bodypart_damage(10)
|
||||
victim.Weaken(1)
|
||||
Weaken(1)
|
||||
visible_message("<span class='danger'>[src] crashes into [victim], knocking them both over!</span>", "<span class='userdanger'>You violently crash into [victim]!</span>")
|
||||
playsound(src,'sound/weapons/punch1.ogg',50,1)
|
||||
|
||||
|
||||
@@ -231,23 +240,6 @@
|
||||
/mob/living/carbon/is_muzzled()
|
||||
return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
|
||||
|
||||
/mob/living/carbon/proc/spin(spintime, speed)
|
||||
set waitfor = 0
|
||||
var/D = dir
|
||||
while(spintime >= speed)
|
||||
sleep(speed)
|
||||
switch(D)
|
||||
if(NORTH)
|
||||
D = EAST
|
||||
if(SOUTH)
|
||||
D = WEST
|
||||
if(EAST)
|
||||
D = SOUTH
|
||||
if(WEST)
|
||||
D = NORTH
|
||||
setDir(D)
|
||||
spintime -= speed
|
||||
|
||||
/mob/living/carbon/resist_buckle()
|
||||
if(restrained())
|
||||
changeNext_move(CLICK_CD_BREAKOUT)
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0)
|
||||
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
if(tesla_shock && tesla_ignore)
|
||||
return FALSE
|
||||
shock_damage *= siemens_coeff
|
||||
@@ -190,11 +190,11 @@
|
||||
jitteriness += 1000 //High numbers for violent convulsions
|
||||
do_jitter_animation(jitteriness)
|
||||
stuttering += 2
|
||||
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
|
||||
if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun)
|
||||
Stun(2)
|
||||
spawn(20)
|
||||
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
|
||||
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
|
||||
if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun)
|
||||
Stun(3)
|
||||
Weaken(3)
|
||||
if(override)
|
||||
|
||||
@@ -436,7 +436,7 @@
|
||||
|
||||
|
||||
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
|
||||
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0)
|
||||
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
if(tesla_shock)
|
||||
var/total_coeff = 1
|
||||
if(gloves)
|
||||
@@ -447,6 +447,8 @@
|
||||
var/obj/item/clothing/suit/S = wear_suit
|
||||
if(S.siemens_coefficient <= 0)
|
||||
total_coeff -= 0.95
|
||||
else if(S.siemens_coefficient == (-1))
|
||||
total_coeff -= 1
|
||||
siemens_coeff = total_coeff
|
||||
if(tesla_ignore)
|
||||
siemens_coeff = 0
|
||||
@@ -461,7 +463,7 @@
|
||||
heart_attack = 0
|
||||
if(stat == CONSCIOUS)
|
||||
src << "<span class='notice'>You feel your heart beating again!</span>"
|
||||
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion)
|
||||
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion, stun)
|
||||
if(.)
|
||||
electrocution_animation(40)
|
||||
|
||||
@@ -754,4 +756,4 @@
|
||||
torn_items += leg_clothes
|
||||
|
||||
for(var/obj/item/I in torn_items)
|
||||
I.take_damage(damage_amount, damage_type, damage_flag, 0)
|
||||
I.take_damage(damage_amount, damage_type, damage_flag, 0)
|
||||
|
||||
@@ -1015,7 +1015,7 @@
|
||||
var/obj/item/organ/cyberimp/chest/thrusters/T = H.getorganslot("thrusters")
|
||||
if(!istype(J) && istype(C))
|
||||
J = C.jetpack
|
||||
if(istype(J) && J.allow_thrust(0.01, H)) //Prevents stacking
|
||||
if(istype(J) && J.full_speed && J.allow_thrust(0.01, H)) //Prevents stacking
|
||||
. -= 2
|
||||
else if(istype(T) && T.allow_thrust(0.01, H))
|
||||
. -= 2
|
||||
|
||||
@@ -150,4 +150,14 @@
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/monkey/can_use_guns(var/obj/item/weapon/gun/G)
|
||||
return 1
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/monkey/angry
|
||||
aggressive = TRUE
|
||||
|
||||
/mob/living/carbon/monkey/angry/Initialize()
|
||||
..()
|
||||
if(prob(10))
|
||||
var/obj/item/clothing/head/helmet/justice/escape/helmet = new(src)
|
||||
equip_to_slot_or_del(helmet,slot_head)
|
||||
helmet.attack_self(src) // todo encapsulate toggle
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user